2 * This file is part of FFmpeg.
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "libavutil/common.h"
24 #include "libavutil/dict.h"
25 #include "libavutil/error.h"
26 #include "libavutil/video_enc_params.h"
28 #include "libavformat/avformat.h"
30 #include "libavcodec/avcodec.h"
32 static int decode_read(AVCodecContext
*decoder
, AVFrame
*frame
, int flush
, int max_frames
)
34 const int ret_done
= flush
? AVERROR_EOF
: AVERROR(EAGAIN
);
38 (max_frames
== 0 || decoder
->frame_number
< max_frames
)) {
41 ret
= avcodec_receive_frame(decoder
, frame
);
43 return (ret
== ret_done
) ? 0 : ret
;
45 fprintf(stdout
, "frame %d\n", decoder
->frame_number
- 1);
47 sd
= av_frame_get_side_data(frame
, AV_FRAME_DATA_VIDEO_ENC_PARAMS
);
49 AVVideoEncParams
*par
= (AVVideoEncParams
*)sd
->data
;
51 fprintf(stdout
, "AVVideoEncParams %d\n", par
->type
);
52 fprintf(stdout
, "qp %d\n", par
->qp
);
53 for (int i
= 0; i
< FF_ARRAY_ELEMS(par
->delta_qp
); i
++)
54 for (int j
= 0; j
< FF_ARRAY_ELEMS(par
->delta_qp
[i
]); j
++) {
55 if (par
->delta_qp
[i
][j
])
56 fprintf(stdout
, "delta_qp[%d][%d] %"PRId32
"\n", i
, j
, par
->delta_qp
[i
][j
]);
60 fprintf(stdout
, "nb_blocks %d\n", par
->nb_blocks
);
61 for (int i
= 0; i
< par
->nb_blocks
; i
++) {
62 AVVideoBlockParams
*b
= av_video_enc_params_block(par
, i
);
64 fprintf(stdout
, "block %d %d:%d %dx%d %"PRId32
"\n",
65 i
, b
->src_x
, b
->src_y
, b
->w
, b
->h
, b
->delta_qp
);
70 av_frame_unref(frame
);
72 if (max_frames
&& decoder
->frame_number
== max_frames
)
76 return (max_frames
== 0 || decoder
->frame_number
< max_frames
) ? 0 : 1;
79 static int decoder_init(AVFormatContext
*demuxer
, int stream_idx
,
80 AVCodecContext
**dec
, AVDictionary
**opts
)
85 if (stream_idx
< 0 || stream_idx
>= demuxer
->nb_streams
)
86 return AVERROR(EINVAL
);
88 codec
= avcodec_find_decoder(demuxer
->streams
[stream_idx
]->codecpar
->codec_id
);
90 return AVERROR_DECODER_NOT_FOUND
;
92 *dec
= avcodec_alloc_context3(codec
);
94 return AVERROR(ENOMEM
);
96 ret
= avcodec_open2(*dec
, NULL
, opts
);
103 int main(int argc
, char **argv
)
105 AVFormatContext
*demuxer
= NULL
;
106 AVCodecContext
*decoder
= NULL
;
107 AVDictionary
*opts
= NULL
;
109 AVPacket
*pkt
= NULL
;
110 AVFrame
*frame
= NULL
;
112 unsigned int stream_idx
, max_frames
;
113 const char *filename
, *thread_type
= NULL
, *nb_threads
= NULL
;
117 fprintf(stderr
, "Usage: %s <input file> <stream index> <max frame count> [<thread count> <thread type>]\n", argv
[0]);
122 stream_idx
= strtol(argv
[2], NULL
, 0);
123 max_frames
= strtol(argv
[3], NULL
, 0);
125 nb_threads
= argv
[4];
126 thread_type
= argv
[5];
129 ret
= av_dict_set(&opts
, "threads", nb_threads
, 0);
130 ret
|= av_dict_set(&opts
, "thread_type", thread_type
, 0);
131 ret
|= av_dict_set(&opts
, "export_side_data", "venc_params", 0);
133 ret
= avformat_open_input(&demuxer
, filename
, NULL
, NULL
);
135 fprintf(stderr
, "Error opening input file: %d\n", ret
);
139 ret
= decoder_init(demuxer
, stream_idx
, &decoder
, &opts
);
141 fprintf(stderr
, "Error initializing decoder\n");
145 pkt
= av_packet_alloc();
146 frame
= av_frame_alloc();
147 if (!pkt
|| !frame
) {
148 ret
= AVERROR(ENOMEM
);
153 ret
= av_read_frame(demuxer
, pkt
);
156 if (pkt
->stream_index
!= stream_idx
) {
157 av_packet_unref(pkt
);
161 ret
= avcodec_send_packet(decoder
, pkt
);
163 fprintf(stderr
, "Error decoding: %d\n", ret
);
166 av_packet_unref(pkt
);
168 ret
= decode_read(decoder
, frame
, 0, max_frames
);
170 fprintf(stderr
, "Error decoding: %d\n", ret
);
172 } else if (ret
> 0) {
179 avcodec_send_packet(decoder
, NULL
);
180 ret
= decode_read(decoder
, frame
, 1, max_frames
);
182 fprintf(stderr
, "Error flushing: %d\n", ret
);
189 av_packet_free(&pkt
);
190 av_frame_free(&frame
);
191 avcodec_free_context(&decoder
);
192 avformat_close_input(&demuxer
);