FFMPEG avcodec_decode_video2 got_picture_ptr 不同的行为

标签 ffmpeg

我目前正在将我们的 FFMPEG 库使用从相当旧的版本(0.5)更新到 2.8。作为更改的一部分,已将 avcodec_decode_video 替换为 avcodec_decode_video2。但是,与旧的 avcodec_decode_video 相比,我注意到 avcodec_decode_video2 的功能方式存在很大差异。对于相同的数据包(相同的数据),'avcodec_decode_video2' 给出 got_picture_ptr 作为 zeo,而旧的 'avcodec_decode_video' 给出一个非零值。在此处描述的示例中,我使用 VideoCodec:H264-MPEG-4 AVC(第 10 部分)和 AudioCodec:MPEG AAC 音频(我在 FLV_Sample.Hex FLV_Sample_Hex 中附加了 FLV 文件的十六进制版本的一部分)对 FLV 文件进行解码)。原flv文件太大)。对于第一个 AVPacket(从 av_read_frame 获得),'avcodec_decode_video2' 的 got_picture_ptr 为零,但旧的 'avcodec_decode_video' 给出 296(我将获得的整个 AVPacket 数据和从文件 FFMPEG_Decoding_Packet_Info.txt FFMPEG_Decoding_Packet_Info 中的两个函数获得的输出附加)。继续,新的“avcodec_decode_video2”一直给出“零”,直到第 23 个数据包给出 1。所以它不像 avcodec_decode_video2 一直给出零。我的主要困境是不确定这种行为差异是否是由于“avcodec_decode_video2”的变化或我在使用解码器时犯的任何错误。我在下面放了一段用于使用解码器的代码。任何建议都会有所帮助。

AVFormatContext *pFormatCtx;
AVCodecContext  *pCodecCtx;
AVCodec         *pCodec;
AVFrame         *pFrameRGB;

#if FFMPEG_2_8
avformat_open_input(&pFormatCtx, strFileName, NULL, NULL) ;
#else
av_open_input_file(&pFormatCtx, strFileName, NULL, 0, NULL) ;
#endif //FFMPEG_2_8

size_t videoStream=pFormatCtx->nb_streams;
bool streamFound = false ;
for(size_t i=0; i<pFormatCtx->nb_streams; i++)
{
    #if FFMPEG_2_8
    if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
    #else
    if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
    #endif //FFMPEG_2_8
    {
        videoStream = i;
        streamFound = true ; 
        break;
    }
}

if(streamFound)
{
    pCodecCtx=pFormatCtx->streams[videoStream]->codec;

    // Find the decoder for the video stream
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL)
        return false; // Codec not found

    // Open codec
    #if FFMPEG_2_8
    if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
    #else
    if(avcodec_open(pCodecCtx, pCodec)<0)
    #endif //FFMPEG_2_8
    {
        return false; // Could not open codec
    }

    #if FFMPEG_2_8
    pFrameRGB=av_frame_alloc() ;
    #else
    pFrameRGB=avcodec_alloc_frame();
    #endif //FFMPEG_2_8
    if(pFrameRGB==NULL)
            return false; //No Memory

    while(true)
    {
        AVPacket packet ;

        if (av_read_frame(pFormatCtx, &packet) < 0)
        {
            break ;
        }


        int frameFinished;
        if (packet.stream_index == videoStream)
        {
            #if FFMPEG_2_8
            avcodec_decode_video2(pCodecCtx, pFrameRGB, &frameFinished, &packet);
            #else
            avcodec_decode_video(pCodecCtx, pFrameRGB, &frameFinished, packet.data, packet.size);
            #endif //FFMPEG_2_8
        }

        if(frameFinished !=0)
        {
            break ;
        }
    }
}

最佳答案

我确实有几乎相同的实现,在最新的 2.8.1 版本上工作。我不知道旧版本(0.5),但你对新版本的实现似乎很好。

我猜关于“got_picture_ptr”的一件事,但不确定。 JFYI,解码顺序和显示顺序在 H264 中是不同的。可能是早期版本的 FFMPEG 用于按解码顺序而不是显示顺序给出图片。在这种情况下,您将看到每个数据包解码的非零值,从第一个数据包开始。

在某些时候,ffmpeg 会更正此问题以按显示顺序给出图片。因此,您可能不会从第一个数据包解码中观察到非零值。

我想您的应用程序运行良好,无论这种差异如何。

关于FFMPEG avcodec_decode_video2 got_picture_ptr 不同的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33697031/

相关文章:

python - 无法在 subproces.call 中运行 ffmpeg

iOS用修改后的源代码编译ffmpeg

ffmpeg - PyGTK ProgressBar 在子进程启动之前显示一些东西

ffmpeg - 使用 ffmpeg 编码原始 nv12 帧

php - ffmpeg:按需进行 1 帧操作

iphone - FFMPEG 无法为 iPhone 配置

android - 使用 ffmpeg 创建带有图像的视频时出错

linux - FFMPEG 屏幕捕获问题

audio - 我怎样才能生成qcelp

ffmpeg - 将 ffmpeg 用于传入的 youtube HLS 直播并输出到 rtmp