3232#include "libavutil/imgutils.h"
3333#include "libavutil/motion_vector.h"
3434#include "libavutil/opt.h"
35+ #include "libavutil/video_enc_params.h"
3536#include "avfilter.h"
3637#include "qp_table.h"
3738#include "internal.h"
@@ -52,6 +53,7 @@ typedef struct CodecViewContext {
5253 unsigned mv_type ;
5354 int hsub , vsub ;
5455 int qp ;
56+ int block ;
5557} CodecViewContext ;
5658
5759#define OFFSET (x ) offsetof(CodecViewContext, x)
@@ -73,6 +75,7 @@ static const AVOption codecview_options[] = {
7375 CONST ("if" , "I-frames" , FRAME_TYPE_I , "frame_type" ),
7476 CONST ("pf" , "P-frames" , FRAME_TYPE_P , "frame_type" ),
7577 CONST ("bf" , "B-frames" , FRAME_TYPE_B , "frame_type" ),
78+ { "block" , "set block partitioning structure to visualize" , OFFSET (block ), AV_OPT_TYPE_BOOL , {.i64 = 0 }, 0 , 1 , FLAGS },
7679 { NULL }
7780};
7881
@@ -210,6 +213,21 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex,
210213 draw_line (buf , sx , sy , ex , ey , w , h , stride , color );
211214}
212215
216+ static void draw_block_rectangle (uint8_t * buf , int sx , int sy , int w , int h , int stride , int color )
217+ {
218+ for (int x = sx ; x < sx + w ; x ++ )
219+ buf [x ] = color ;
220+
221+ for (int y = sy ; y < sy + h ; y ++ ) {
222+ buf [sx ] = color ;
223+ buf [sx + w - 1 ] = color ;
224+ buf += stride ;
225+ }
226+
227+ for (int x = sx ; x < sx + w ; x ++ )
228+ buf [x ] = color ;
229+ }
230+
213231static int filter_frame (AVFilterLink * inlink , AVFrame * frame )
214232{
215233 AVFilterContext * ctx = inlink -> dst ;
@@ -247,6 +265,23 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
247265 av_freep (& qp_table );
248266 }
249267
268+ if (s -> block ) {
269+ AVFrameSideData * sd = av_frame_get_side_data (frame , AV_FRAME_DATA_VIDEO_ENC_PARAMS );
270+ if (sd ) {
271+ AVVideoEncParams * par = (AVVideoEncParams * )sd -> data ;
272+ const int stride = frame -> linesize [0 ];
273+
274+ if (par -> nb_blocks ) {
275+ for (int block_idx = 0 ; block_idx < par -> nb_blocks ; block_idx ++ ) {
276+ AVVideoBlockParams * b = av_video_enc_params_block (par , block_idx );
277+ uint8_t * buf = frame -> data [0 ] + b -> src_y * stride ;
278+
279+ draw_block_rectangle (buf , b -> src_x , b -> src_y , b -> w , b -> h , stride , 100 );
280+ }
281+ }
282+ }
283+ }
284+
250285 if (s -> mv || s -> mv_type ) {
251286 AVFrameSideData * sd = av_frame_get_side_data (frame , AV_FRAME_DATA_MOTION_VECTORS );
252287 if (sd ) {
0 commit comments