使用ffmpeg库进行编码失败

时间:2012-06-24 18:25:45

标签: encoding ffmpeg

我花了一些时间查看ffmpeg库并进行设置,我正在打开一个.flv文件。读取和解码以及帧,现在我正在尝试将其编码为MP4,但我的数据包最终为空。

我的代码如下

int main (){

    avformat_open_input(&pFC, "c://wav//test2.flv", NULL, NULL);

    po = av_find_stream_info(pFC);

    //ADD LOGIC TO FIND VIDEO STREAM
    pCodecC = pFC->streams[0]->codec;

    decoder = avcodec_find_decoder(pCodecC->codec_id);
    encoder = avcodec_find_encoder(pCodecC->codec_id);
    po = avcodec_open(pCodecC, decoder);

    pCodecE =  avcodec_alloc_context3(encoder);
    /* put sample parameters */
    pCodecE->bit_rate = 400000;
    /* resolution must be a multiple of two */
    pCodecE->width = 352;
    pCodecE->height = 288;
    /* frames per second */
    pCodecE->time_base.den = 25;
    pCodecE->time_base.num = 1;
    pCodecE->gop_size = 10; /* emit one intra frame every ten frames */
    pCodecE->max_b_frames=1;
    pCodecE->pix_fmt = PIX_FMT_YUV420P;

    if(pCodecC->codec_id == CODEC_ID_H264)
        av_opt_set(pCodecE->priv_data, "preset", "slow", 0);

    po =  avcodec_open2(pCodecE, encoder, NULL);

    AVFrame *pFrame;
    // Allocate an AVFrame structure



    // Allocate video frame
    pFrame=avcodec_alloc_frame();
    int frameFinished = 0;
    int frame = 0;
    int gotpacket = 0;

    while(av_read_frame(pFC, &packet) >= 0)
    {
        if(packet.stream_index==0) //the video stream is 0
        {
            int len = avcodec_decode_video2(pCodecC, pFrame, &frameFinished, &packet);
            if(frameFinished)
            {
                printf("frame # %i", frame);

                po =avcodec_encode_video2(pCodecE, &spacket, pFrame, &gotpacket);
                if(gotpacket)
                {
                    printf("packet recieved");
                }
                frame++;
            }
        }
        av_free_packet(&packet);
    }


    printf("encoding done");

    return 0;
}

基本上一切都可以达到

 po =avcodec_encode_video2(pCodecE, &spacket, pFrame, &gotpacket);

&gotpacket返回0,如空帧中所示。

不确定我做错了什么。

2 个答案:

答案 0 :(得分:0)

正如文件所说。帧可以在内部缓冲。在这种情况下,您将拥有gotpacket == 0。当您继续写图像时,您将在某个时刻gotpacket != 0

我猜你也可以尝试通过为帧传递NULL来刷新编码器。我没想过这个想法。

祝你好运。

答案 1 :(得分:0)

我发现在pFrame中增加pts(在每次编码之后)修复了这个问题。

pFrame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);

其中video_st是输出流。