[Libav-user] extract min/max/avg QP-values per frame

siriannalisa siriannalisa at gmail.com
Tue May 5 21:21:09 CEST 2015


Hi,

I'm trying to create a function that will output the following information
for a H.264 stream:

Frame_type: I ; pkt_size: 67839 ; qp_min=26 ; qp_max=38; qp_avg=30
Frame_type: P ; pkt_size: 2060 ; qp_min=30 ; qp_max=41; qp_avg=35
Frame_type: P ; pkt_size: 2469 ; qp_min=30 ; qp_max=38; qp_avg=35
Frame_type: P ; pkt_size: 3956 ; qp_min=30 ; qp_max=38; qp_avg=35
:
.

My current code is based upon ffmpeg/doc/examples/demuxing_decoding.c
Getting the frame type and the pkt_size is no problem but I cannot find a
way to get the
qp-values!

If I enable debug using `-debug qp`, the qp values gets written to the log
in function
ff_print_debug_info2() in libavcodec/mpegvideo.v:2258
That function is called from h264_decode_frame() in libavcodec/h264.c:1834

But I fail to find a way to get the qp-values for a frame from my function.
Any help would be greatly appreciated!

My function currently looks like this:

static int decode_packet(int *got_frame, int cached)
{
    int ret = 0;
    int decoded = pkt.size;
    int x, y;
    int mb_width = (video_dec_ctx->width + 15) / 16;
    int mb_height = (video_dec_ctx->height + 15) / 16;
    int mb_stride = mb_width + 1;

    *got_frame = 0;

    if (pkt.stream_index == video_stream_idx) {
        /* decode video frame */
        ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
        if (ret < 0) {
            fprintf(stderr, "Error decoding video frame (%s)\n",
av_err2str(ret));
            return ret;
        }
        if (video_dec_ctx->width != width || video_dec_ctx->height !=
height ||
            video_dec_ctx->pix_fmt != pix_fmt) {
            /* To handle this change, one could call av_image_alloc again
and
             * decode the following frames into another rawvideo file. */
            fprintf(stderr, "Error: Width, height and pixel format have to
be "
                    "constant in a rawvideo file, but the width, height or "
                    "pixel format of the input video changed:\n"
                    "old: width = %d, height = %d, format = %s\n"
                    "new: width = %d, height = %d, format = %s\n",
                    width, height, av_get_pix_fmt_name(pix_fmt),
                    video_dec_ctx->width, video_dec_ctx->height,
                    av_get_pix_fmt_name(video_dec_ctx->pix_fmt));
            return -1;
        }

        if (*got_frame) {

            fprintf(stderr,"Frame_type: %c ; pkt_size: %d\n",
                    av_get_picture_type_char(frame->pict_type),
                    av_frame_get_pkt_size(frame));

// This one of many ways that I have tried, all results in a segfault...
#if 0
            AVBufferRef* qp_table_buf = av_buffer_ref(frame->qp_table_buf);
//            qscale_table = qscale_table_buf->data + 2 * s->mb_stride + 1;
            int8_t* qscale_table = qp_table_buf->data;

            for (y = 0; y < mb_height; y++) {
                for (x = 0; x < mb_width; x++) {
//                        printf("%2d", qscale_table[x + y * mb_stride]);
                        printf("%2d", qscale_table[x + y * mb_stride]);
                }
            }

#endif
        }
    }

    /* If we use the new API with reference counting, we own the data and
need
     * to de-reference it when we don't use it anymore */
    if (*got_frame && api_mode == API_MODE_NEW_API_REF_COUNT)
        av_frame_unref(frame);

    return decoded;
}

The complete code can be found in:

https://gist.github.com/figgis/ea9ac513cdd99a10abf1

or by doing a

git clone https://gist.github.com/ea9ac513cdd99a10abf1.git

cheers
/Fredrik
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20150505/a6605865/attachment.html>


More information about the Libav-user mailing list