在 AVFrame 中访问 qpscale_table 时出现分段错误
Segmentation Fault accessing qpscale_table in AVFrame
我正在稍微修改这个文件: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->qscale_table
我试过填充它,但它自己无法编译,因为它找不到该函数:
int8_t *qscale_table = av_frame_get_qp_table(decframe->qscale_table, &mb_stride, &qscale_type);
所以我的问题是:
给定 AVFrame*
我如何确保 qscale_table
被填充并访问它?
事实证明,qpscale_table 在解码发生在 h264dec.c 之后并没有导出到解码帧中。
为了检索值,我必须修改 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
我正在稍微修改这个文件: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->qscale_table
我试过填充它,但它自己无法编译,因为它找不到该函数:
int8_t *qscale_table = av_frame_get_qp_table(decframe->qscale_table, &mb_stride, &qscale_type);
所以我的问题是:
给定 AVFrame*
我如何确保 qscale_table
被填充并访问它?
事实证明,qpscale_table 在解码发生在 h264dec.c 之后并没有导出到解码帧中。
为了检索值,我必须修改 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