【问题标题】:c++ videoplayer ffmpeg: get pixel data?c++ videoplayer ffmpeg:获取像素数据?
【发布时间】:2016-06-10 17:22:02
【问题描述】:

我想获取一帧的像素数据。我发现了这个(在原始版本中作为旧代码)并更改了一些东西。

我有这个代码:

AVFormatContext *pFormatCtx;
pFormatCtx = avformat_alloc_context();
// Open file
if (int err = avformat_open_input(&pFormatCtx, file, NULL, 0) != 0)
{
    exit(2);
}
// Get infromation about streams
if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
{
    exit(2);
}

// # video stream
int videoStreamIndex = -1;
AVCodecContext *pVideoCodecCtx;
AVCodec *pVideoCodec;
int res = 0;
int width = 0;
int height = 0;
for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
{
    if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
    {
        videoStreamIndex = i;
        pVideoCodecCtx = pFormatCtx->streams[i]->codec;
        // Find decoder
        pVideoCodec = avcodec_find_decoder(pVideoCodecCtx->codec_id);
        if (pVideoCodec)
        {
            // Open decoder
            res = !(avcodec_open2(pVideoCodecCtx, pVideoCodec, NULL) < 0);
            width = pVideoCodecCtx->coded_width;
            height = pVideoCodecCtx->coded_height;
        }
        break;
    }
}
// Frame width
width = pFormatCtx->streams[videoStreamIndex]->codec->width;
// Frame height
height = pFormatCtx->streams[videoStreamIndex]->codec->height;


AVPacket packet;
int got_picture_ptr;
AVPacket *avpkt;
AVFrame * pOutFrame;
pOutFrame = av_frame_alloc();
AVFrame * rgbOutFrame = av_frame_alloc();

if (!pOutFrame) {
    fprintf(stderr, "Could not allocate video frame\n");
    exit(1);
}

while (av_read_frame(pFormatCtx, &packet) >= 0)
{
    if (packet.stream_index == videoStreamIndex) 
    {
        // Decode packeg to frame.
        int videoFrameBytes = avcodec_decode_video2(pVideoCodecCtx, pOutFrame,
            &got_picture_ptr, &packet);

        // Create context
        SwsContext* pImgConvertCtx = sws_getContext(pVideoCodecCtx->width,
            pVideoCodecCtx->height,
            pVideoCodecCtx->pix_fmt,
            pVideoCodecCtx->width, pVideoCodecCtx->height,
            AV_PIX_FMT_YUV420P,
            SWS_BICUBIC, NULL, NULL, NULL);
        // Convert frame
        sws_scale(pImgConvertCtx, pOutFrame->data, pOutFrame->linesize,
            width, height, rgbOutFrame->data, rgbOutFrame->linesize);
    }

}

我知道,SwsContextsws_scale 的代码是错误的,但我想知道,我在哪里可以找到我的帧的像素数据...(以及它以哪种格式存储)。

有人可以帮我吗?

【问题讨论】:

    标签: c++ ffmpeg video-processing


    【解决方案1】:

    像素数据存储在data字段中。

    根据文档:

    uint8_t* AVFrame::data[AV_NUM_DATA_POINTERS]

    指向图片/通道平面的指针。

    查看here了解更多信息。

    一般来说,您的代码有点误导,而且相当有缺陷。我可以指出一些缺点:

    1) 您不需要在每个传入的视频数据包上创建新的SwsContext。只需在while 循环之前创建一次即可。

    2) 接下来,您有一个rgbOutFrame,但创建了SwsContext 以缩放为YUV420 像素格式。看起来很奇怪。

    3) 此外,avcodec_decode_video2 被调用,但你既不检查返回值也不检查 got_picture_ptr 标志。这种做法真的容易出错。

    等等……

    希望它能帮助您改进您的程序并获得必要的结果。

    【讨论】:

    • 感谢您的快速回答,但我仍然有一些问题:什么是画板?我应该怎么做才能得到像素值?
    • 我尝试对位置 i 的值使用类似 frame->data[0][i] 的东西,但它是一个 uint8_t(我想到了 rgba)。但是当我像 rgba 一样使用它时,只有 alpha 值的值不为零......请帮助:/
    • @3DExtended 尝试将sws_getContext更改为rgb,而不是yuv420
    • 我这样做了,但并没有改变什么:/我使用 AV_PIX_FMT_RGB24 作为所需的输出格式
    • @3DExtended 您可以将您的整个程序与本教程进行比较:dranger.com/ffmpeg/tutorial01.html。它应该有助于解决问题。
    猜你喜欢
    • 2011-11-14
    • 2014-03-29
    • 2013-11-06
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 2011-08-29
    相关资源
    最近更新 更多