使用libav编码MP4视频时出错

时间:2016-06-23 09:09:09

标签: c++ ffmpeg libavcodec libav

现在我正在尝试使用libav标头将一些图像编码为mp4文件。编码成功后,编码我收到一些输出,并生成一个mp4文件。但不知何故,我无法与普通玩家一起播放视频。我错过了什么吗?

这是我创建输出容器的方式:

void create_video(char *filename)
{

    AVOutputFormat *fmt;
    AVCodecContext *codecctx;
    AVFormatContext *fmtctx;
    fmt=av_guess_format(NULL,filename,NULL);
    if(!fmt)
        printf("Das Format kann nicht erkannt werden. MPEG wird verwendet");
    AVCodec *codec = avcodec_find_encoder(fmt->video_codec);
    if(codec==NULL)
        printf("Codec nicht gefunden");
    codecctx = avcodec_alloc_context3(codec);
    codecctx->codec_id = fmt->video_codec;
    codecctx->codec_type = AVMEDIA_TYPE_VIDEO;
    codecctx->gop_size = 12;
    codecctx->bit_rate = 800*280*4;
    codecctx->width = 800;
    codecctx->height = 280;

    codecctx->time_base.den = 30; 
    codecctx->time_base.num =1;
    //codecctx->time_base =(AVRational){1,FPS};
    codecctx->max_b_frames=1;
    codecctx->pix_fmt= STREAM_PIX_FMT;
    fmtctx = avformat_alloc_context();
    fmtctx->oformat = fmt;
    fmtctx->video_codec_id = fmt->video_codec;

    avcodec_open2(codecctx, codec, NULL);
    if(avcodec_open2(codecctx, codec, NULL)<0)
        printf("Error opening the codec \n");
    AVStream *VideoStream = avformat_new_stream(fmtctx,0);
    VideoStream->codecpar->codec_id=fmt->video_codec;
    VideoStream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
    VideoStream->codecpar->format = STREAM_PIX_FMT;
    VideoStream->codecpar->width=800;
    VideoStream->codecpar->height=280;
    VideoStream->time_base.den=30;
    VideoStream->time_base.num=1;
    VideoStream->codec=codecctx;

    avio_open(&fmtctx->pb,filename,AVIO_FLAG_WRITE);

    if(avformat_write_header(fmtctx,NULL)==0)
    {
        Write_Video_Frame(fmtctx,VideoStream,"1.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img002.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img003.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img004.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img005.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img006.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img007.png");
        av_write_trailer(fmtctx);
    }
}

添加帧功能:

static void Write_Video_Frame(AVFormatContext *oc, AVStream *st, char* datei)
{
    frame_count++;  
    double pts;
    int test, videoStream,frameFinished,x,y;
    AVFormatContext *pFormatCtx =avformat_alloc_context();
    int i;

    int size = WIDTH*HEIGHT;

    if (avformat_open_input(&pFormatCtx, datei, NULL, NULL) !=0)
        printf("Das Bild kann nicht geoeffnet werden!");
    test = avformat_find_stream_info(pFormatCtx, NULL);
    if(test<0)
        printf("Es konnte kein Stream von dem Bild gefunden werden. \n");

AVCodecContext *c = NULL;
AVCodecContext *pCodecCtx = NULL;
c=st->codec;

// Find the first video stream
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
  if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
    videoStream=i;

    break;
  }
// Get a pointer to the codec context for the video stream
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
if(pCodecCtx == NULL)
    printf("CodecCtx not found");
AVCodec *pCodec = NULL;

// Find the decoder for the video stream

pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
  fprintf(stderr, "Unsupported codec of the picture \n");
  }
// Oeffnet den Codec
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
    fprintf(stderr,"Error opening the codec of the picture \n");
AVFrame *pFrame;
AVFrame *pFrameYUV;
pFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();
int numBytes;
uint8_t *buffer= NULL;
numBytes=avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width,pCodecCtx->height); 
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); 
uint8_t *picture_buf = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));


struct SwsContext *sws_ctx = NULL;
av_image_alloc(    pFrameYUV->data,   //data to be filled
                   pFrameYUV->linesize,//line sizes to be filled
                   800, 280,
                   AV_PIX_FMT_YUV420P,           //pixel format
                   32                       //alingn
                   );
sws_ctx = sws_getContext(800,280,AV_PIX_FMT_RGB24,800,280,AV_PIX_FMT_YUV420P,SWS_BICUBIC,0,0,0);
if(sws_ctx==NULL)
    printf("Error");
AVPacket packet;
int zahl =0;
// initialize SWS context for software scaling
pFrameYUV->height = pFrame->height = pCodecCtx->height;
pFrameYUV->width = pFrame->width = pCodecCtx->width;
pFrameYUV->format = AV_PIX_FMT_YUV420P;
 fflush(stdout);
while (av_read_frame(pFormatCtx,&packet)>=0)
{
    if(packet.stream_index == videoStream)
    {
        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); 

        if(frameFinished)
        {
            zahl++;
            sws_scale(sws_ctx,pFrame->data,pFrame->linesize,0,pCodecCtx->height,pFrameYUV->data,pFrameYUV->linesize);
            printf("Packet size : %d \n ",packet.size);

        }
    }
    av_free_packet(&packet);
}
printf("Total frames found: %d \n",zahl);
avcodec_close(pCodecCtx);
/*Find the encoder of the stream and open it*/
pCodec=avcodec_find_encoder(c->codec_id);
if(avcodec_find_encoder(c->codec_id)==NULL)
    printf("Could not find the codec of ouput");
if(avcodec_open2(c,pCodec,NULL)<0)
    printf("Error opening the codec of output");
AVPacket encoded;
int got_packet;
for(i=0;i<30;i++)
{
av_init_packet(&encoded);

encoded.data = NULL;    // packet data will be allocated by the encoder
encoded.size = 0;
fflush(stdout);

test=avcodec_encode_video2(c,&encoded,pFrameYUV,&got_packet);
if(got_packet)
{
    printf("Got_packet= %d ",got_packet);
    test=av_interleaved_write_frame(oc,&encoded);
    printf("Test= %d ",test);
    printf("Write frame %3d (size=%5d)\n", i, encoded.size);
    av_free_packet(&encoded);
}
}

avcodec_close(c);
//av_free(c);
av_freep(&pFrameYUV->data[0]);
av_frame_free(&pFrameYUV);
count++;
}

我已经尝试设置pts值,但它会使编码失败!!!!!!!

0 个答案:

没有答案