【问题标题】:AVFrame to RGB - decoding artifactsAVFrame 到 RGB - 解码伪影
【发布时间】:2012-12-22 08:08:53
【问题描述】:

我想以编程方式将 mp4 视频文件(使用 h264 编解码器)转换为单个 RGB 图像。使用命令行如下所示:

ffmpeg -i test1080.mp4 -r 30 image-%3d.jpg

使用此命令可以生成一组漂亮的图片。但是当我尝试以编程方式做同样的事情时,一些图像(可能是 B 和 P 帧)看起来很奇怪(例如,有一些带有差异信息的扭曲区域等)。读取和转换代码如下:

AVFrame *frame = avcodec_alloc_frame();
AVFrame *frameRGB = avcodec_alloc_frame();

AVPacket packet;

int buffer_size=avpicture_get_size(PIX_FMT_RGB24, m_codecCtx->width,
    m_codecCtx->height);
uint8_t *buffer = new uint8_t[buffer_size];

avpicture_fill((AVPicture *)frameRGB, buffer, PIX_FMT_RGB24,
    m_codecCtx->width, m_codecCtx->height);

while (true)
{
    // Read one packet into `packet`
    if (av_read_frame(m_formatCtx, &packet) < 0) {
        break;  // End of stream. Done decoding.
    }

    if (avcodec_decode_video(m_codecCtx, frame, &buffer_size, packet.data, packet.size) < 1) {
        break;  // Error in decoding
    }

    if (!buffer_size) {
        break;
    }

    // Convert
    img_convert((AVPicture *)frameRGB, PIX_FMT_RGB24, (AVPicture*)frame,
        m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height);

    // RGB data is now available in frameRGB for further processing
}

如何转换视频流,使每张最终图像显示所有图像数据,从而使 B 帧和 P 帧的信息包含在所有帧中?

[编辑:] 显示工件的示例图像在这里:http://imageshack.us/photo/my-images/201/sampleq.jpg/

问候,

【问题讨论】:

    标签: image ffmpeg h.264 libavcodec libavformat


    【解决方案1】:

    如果avcodec_decode_video的第三个参数返回一个空值,并不代表错误。这意味着框架还没有准备好。您需要继续读取帧,直到值变为非零。

    if (!buffer_size) {
        continue;
    }
    

    UPD

    尝试添加检查并仅显示关键帧,这将有助于隔离问题。

    while (true)
    {
      // Read one packet into `packet`
      if (av_read_frame(m_formatCtx, &packet) < 0) {
        break;  // End of stream. Done decoding.
      }
    
      if (avcodec_decode_video(m_codecCtx, frame, &buffer_size,
          packet.data, packet.size) < 1)
      {
        break;  // Error in decoding
      }
    
      if (!buffer_size) {
        continue; // <-- It's important!
      }
    
      // check for key frame
      if (packet.flags & AV_PKT_FLAG_KEY)
      {
        // Convert
        img_convert((AVPicture *)frameRGB, PIX_FMT_RGB24, (AVPicture*)frame,
          m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height);
      } 
    }
    

    【讨论】:

    • 感谢您的提示。我已经尝试过这个,但结果是一样的。我检查了 ffmpeg 实用程序如何进行转换,这涉及更多步骤。目前我正试图弄清楚到底什么是必要的。
    • 你能分享带有工件的示例图像吗?
    猜你喜欢
    • 2020-10-06
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2012-04-12
    • 2019-04-26
    • 2010-11-06
    • 1970-01-01
    相关资源
    最近更新 更多