【问题标题】:Segmentation Fault accessing qpscale_table in AVFrame在 AVFrame 中访问 qpscale_table 的分段错误
【发布时间】:2020-07-12 11:52:12
【问题描述】:

我正在稍微修改这个文件:https://gist.github.com/yohhoy/f0444d3fc47f2bb2d0e2 此代码对视频进行解码,并在播放过程中从帧像素中生成 opencv Mats。

特别是我只想抓取具有特定宏块相关数据的帧。我正在尝试获取这样的数据:

total_qp = get_total_qp(decframe->qscale_table, mb_width, mb_height, mb_stride);

但是,每当我尝试通过迭代该数组来访问数据时,都会出现分段错误:

static float get_total_qp(int8_t *qscale_table, int mb_width, int mb_height, int mb_stride)
{
    int mb_count = mb_height * mb_width;
    int y, x;
    float qp_total = 0.0f;
    for (y = 0; y < mb_height; y++) {
        for (x = 0; x < mb_width; x++) {
            qp_total += qscale_table[x + y * mb_stride]; <-- SEGFAULT here
        }
    }
    return qp_total;
}

我也尝试过发送: frame-&gt;qscale_table

我已经尝试填充它,但它自己无法编译,因为它找不到该函数:

int8_t *qscale_table = av_frame_get_qp_table(decframe->qscale_table, &mb_stride, &qscale_type);

所以我的问题是: 给定一个 AVFrame* 我如何确保 qscale_table 已填充并访问它?

【问题讨论】:

  • 几乎 100% 的机会 x + y * mb_stride 正在读取数组的末尾。您应该在调试器中查看并验证。另一种可能性是qscale_table 是垃圾或NULL。断言可以捕捉到这一点。
  • @MichaelDorgan 打印数据显示(我认为) qscale_table 确实为 NULL。因此我的问题是 - 我如何填充它?我认为它是作为解码过程的一部分填充的 - 至少,它与 ffmpeg 一起使用,这就是您可以调试 QP 值的原因。那么我在这里错过了什么?

标签: c++11 h.264 libavcodec


【解决方案1】:

事实证明,在 h264dec.c 中进行解码后,qpscale_table 并没有导出到解码帧上。

为了检索值,我必须修改 h264dec 中的 finalize_frame 方法以将 qscale_table 导出到框架上,如下所示:

static int h264_export_qp_table(H264Context *h, AVFrame *f, H264Picture *p, int qp_type)
{
    AVBufferRef *ref = av_buffer_ref(p->qscale_table_buf);
    int offset = 2*h->mb_stride + 1;
    if(!ref)
        return AVERROR(ENOMEM);
    av_assert0(ref->size >= offset + h->mb_stride * ((f->height+15)/16));
    ref->size -= offset;
    ref->data += offset;
    return av_frame_set_qp_table(f, ref, h->mb_stride, f->qscale_type);
}

并将调用添加到finalize_frame:

...
        if (CONFIG_MPEGVIDEO) {
            ff_print_debug_info2(h->avctx, dst, NULL,
                                 out->mb_type,
                                 out->qscale_table,
                                 out->motion_val,
                                 NULL,
                                 h->mb_width, h->mb_height, h->mb_stride, 1);
            // NT: make the qscale_table accessible!
            h264_export_qp_table(h, dst, out, FF_QSCALE_TYPE_H264);
        }
...

然后使用这些指令重新编译 FFmpeg:https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 2020-02-06
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 2016-02-26
    • 2023-03-03
    相关资源
    最近更新 更多