FFMpeg 编码解码问题。
extern "C"
{
#include <libavutil/imgutils.h>
//引入头文件
#include <libavformat/avformat.h>
//引入时间
#include <libavutil/time.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}
int avError(int errNum) {
char buf[1024];
av_strerror(errNum, buf, sizeof(buf));
printf("%s\n",buf);
return -1;
}
int main()
{
av_register_all();
avformat_network_init();
const char *inUrl = "drj.flv";
AVFormatContext *pInputCtx = NULL;
int ret = avformat_open_input(&pInputCtx, inUrl, 0, NULL);
if (ret < 0){
return avError(ret);
}
ret = avformat_find_stream_info(pInputCtx, 0);
if (ret != 0){
return avError(ret);
}
av_dump_format(pInputCtx, 0, inUrl, 0);
AVFormatContext * pOutputCtx = NULL;
ret = avformat_alloc_output_context2(&pOutputCtx, NULL, "flv", "rtmp://192.168.1.9/live/demo3");
if (ret < 0){
return avError(ret);
}
int vStream = -1;
for (int i = 0; i < pInputCtx->nb_streams; i++){
AVStream *out = avformat_new_stream(pOutputCtx, pInputCtx->streams[i]->codec->codec);
if (!out){
return avError(0);
}
if(pInputCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
vStream=i;
}
ret = avcodec_parameters_copy(out->codecpar, pInputCtx->streams[i]->codecpar);
if (ret < 0){
return avError(ret);
}
out->codec->codec_tag = 0;
}
if(vStream==-1){
return -1; // Didn't find a video stream
}
AVCodecContext*pDecodecCtx=pInputCtx->streams[vStream]->codec;
AVCodec*pDeodec=avcodec_find_decoder(pDecodecCtx->codec_id);
if(pDeodec==NULL){
return -1; // Codec not found
}
if(avcodec_open2(pDecodecCtx, pDeodec, 0)<0){
return -1; // Could not open codec
}
av_dump_format(pOutputCtx, 0, "rtmp://192.168.1.9/live/demo3", 1);
ret = avio_open(&pOutputCtx->pb, "rtmp://192.168.1.9/live/demo3", AVIO_FLAG_WRITE);
if (ret < 0){
avError(ret);
}
ret = avformat_write_header(pOutputCtx, 0);
if (ret < 0){
avError(ret);
}
// Allocate an AVFrame structure
AVFrame*pFrame264=av_frame_alloc();
if(pFrame264==NULL){
return -1;
}
AVCodec *pEncodec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!pEncodec){
fprintf(stderr, "Codec not found\n");
return -1;
}
AVCodecContext *pEncodecCtx = avcodec_alloc_context3(pEncodec);
if (!pEncodecCtx){
fprintf(stderr, "Codec not found\n");
return -1;
}
pEncodecCtx->bit_rate = pDecodecCtx->bit_rate;// put sample parameters
pEncodecCtx->width =1280;//
pEncodecCtx->height = 550;//
pEncodecCtx->time_base.num = 1;//(AVRational){1,25};
pEncodecCtx->time_base.den = 25;
pEncodecCtx->gop_size = 250; // emit one intra frame every ten frames
pEncodecCtx->max_b_frames=1;
pEncodecCtx->qmin = 10;
pEncodecCtx->qmax = 51;
pEncodecCtx->thread_count = 1;
pEncodecCtx->codec_id = AV_CODEC_ID_H264;
pEncodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pEncodecCtx->pix_fmt = pDecodecCtx->pix_fmt;//PIX_FMT_RGB24;
if (pOutputCtx->oformat->flags & AVFMT_GLOBALHEADER)
{
pEncodecCtx->flags |= AV_CODEC_FLAG_QSCALE;
}
// Open codec
AVDictionary *param = 0;
av_dict_set(¶m, "preset", "fast", 0);
av_dict_set(¶m, "tune", "zerolatency", 0);
if(avcodec_open2(pEncodecCtx, pEncodec, ¶m)<0)
{
avError(ret);
return -1;
}
AVPacket avPacket;
av_init_packet(&avPacket);
AVPacket avOutPacket;
while (true){
long long startTime = av_gettime();
int nRet = av_read_frame(pInputCtx, &avPacket);
if (nRet < 0){
break;
}
if(avPacket.stream_index == vStream){
//从此开始,如果把下面代码去掉,直接 av_interleaved_write_frame(pOutputCtx, &avPacket)就没有任何问题,但如果加上就有问题。
avcodec_send_packet(pDecodecCtx, &avPacket);
avcodec_receive_frame(pDecodecCtx,pFrame264);
av_init_packet(&avOutPacket);
avOutPacket.data = NULL;
avOutPacket.size = 0;
nRet = avcodec_send_frame(pEncodecCtx,pFrame264);
if (nRet < 0){
fprintf(stderr, "avcodec_send_frame - 2 failed [%d]!\n", AVERROR(nRet));
avError(nRet);
return -7;
}
nRet = avcodec_receive_packet(pEncodecCtx,&avOutPacket);
if (nRet < 0){
fprintf(stderr, "avcodec_receive_packet failed [%d]!\n", nRet);
avError(nRet);
return -7;
}
//到此为止
nRet = av_interleaved_write_frame(pOutputCtx, &avOutPacket);
if (nRet < 0){
fprintf(stderr, "av_interleaved_write_frame failed [%d]!\n", nRet);
avError(nRet);
break;
}
}
else{
nRet = av_interleaved_write_frame(pOutputCtx, &avPacket);
if (nRet < 0){
break;
}
}
}
return 0;
}
大神们,上面是我的代码,如果去掉注释的那几行代码,直接写入到rtmp read出来的AVPacket是正常播放,但如果加上那几行发送解码之后再编码的AVPacket就不行,我这显示的问题是avcodec_receive_packet那个函数返回-11,提示错误Resource temporarily unavailable。