i am studying the MPEG compression, in particular how are "labeled" the macroblocks with ffmpeg, using the command:
ffmpeg -debug mb_type -i input.mp4 out.mp4
From theory, i know that typically a macroblock is a 16x16 (pixels) block.
So if a frame is e.g. 1920x1080 i suppose that the macroblocks are
(1920*1080)/(16*16) = 8100
Now, analysing the ffmpeg report, I've seen that for each frame there are many many less macroblocks (labelled with some "characters" indicating their type).
Can you explain me why this happens? Is a (mine) theory error?
I've seen that "visualizing" macroblocks with -debug vis_mb_type there some gray blocks.. corresponding to the (macro)blocks not satisfying any criteria ffmpeg is looking for.. maybe in my example for each frame there are
8100 - #"gray" macroblocks
Is this possible? And why?
This has nothing to do with gray macroblocks, which are IS_SKIP and/or IS_DIRECT (the wiki page is not up to date it seems).
libavcodec/mpegutils.c logs using av_log(), which in turn has a line limit of LINE_SZ = 1024 characters. If you subtract the characters needed for first -debug mb_type header:
New frame, type: B [h264 @ 000001c0241c1cc0]
that is 46 characters. 1024 - 46 = 978. It logs 3 characters per macroblock, so 978/3 = 326 mbs fit on one line without truncation, equivalent to 326*16 = 5216 pixels, which should be enough for most use cases.
Additionally, it looks like log messages from different threads are mixed up. To prevent this, frame and/or slice level threading must be disabled with -thread_type none.
You could also implement your own av_log callback to circumvent both limits, logging into different buffers according to the current thread.