Hi Paul,

I tried to understand the per-frame side-data (and metadata)
mechanism. Adding my notes here in case they help a future reader.

Metadata and side-data seem like similar mechanisms to add auxiliary
information to each frame. Main difference seems to be that metadata
is simpler (a key/value dictionary), while side-data allows adding any
data struct.

Metadata operation is also simpler: There are filters that generate
metadata (e.g. "signalstats" generates key-values such as
`lavfi.signalstats.YMIN=3`, while "silencedetect" generates
audio-related key-values like `lavfi.silence_start=0`). There are also
2x filters that print metadata ("vf_metadata" and "af_ametadata"). So
e.g. to see what signalstats/silencedetect are generating, you can do:

```
$ ffmpeg -i in.264 -vf signalstats,metadata=mode=print -f null -
...
[Parsed_metadata_1 @ ...] frame:0    pts:0       pts_time:0
[Parsed_metadata_1 @ ...] lavfi.signalstats.YMIN=3
...
```

or:
```
$ ffmpeg -y -i in.wav -af "silencedetect=n=-10dB:d=1,ametadata=print"
/tmp/out.wav
...
[Parsed_ametadata_1 @ ...] frame:23   pts:47104   pts_time:0.981333
[Parsed_ametadata_1 @ ...] lavfi.silence_start=0
...
```

Side-data operation is more complicated. There is some side-data
information already generated (e.g. SEI_UNREGISTERED side-data). Some
information requires explicitly asking for it. For example, the
`MOTION_VECTORS` side-data, you need to enable
AV_CODEC_FLAG2_EXPORT_MVS (which means calling ffmpeg/ffplay/ffprobe
with "-flags2 +export_mvs"). The main filter to print side-data
information is showinfo (`vf_showinfo` and `af_ashowinfo`). Now, the
`vf_showinfo` filter only knows how to dump some of the side-data
structs. In particular, it does not know how to dump MOTION_VECTORS
side-data. So, if we add the motion vectors, and then ask showinfo to
print it, we see:

```
$ ffmpeg -hide_banner -flags2 +export_mvs -export_side_data +mvs
-export_side_data +prft -export_side_data +venc_params
-export_side_data +film_grain -i /tmp/in.264 -vf showinfo -f null
/dev/null
...
-- frame 0 is a key frame: We can see SEI_UNREGISTERED and VIDEO_ENC_PARAMS info
[Parsed_showinfo_0 @ 0x308fd40] config in time_base: 1/1200000, frame_rate: 25/1
[Parsed_showinfo_0 @ 0x308fd40] config out time_base: 0/0, frame_rate: 0/0
[Parsed_showinfo_0 @ 0x308fd40] n:   0 pts:      0 pts_time:0
duration:  48000 duration_time:0.04    pos:        0 fmt:yuv420p
sar:0/1 s:1920x1080 i:P iskey:1 type:I checksum:F6BBEA9F
plane_checksum:[AFB1432E 63F2F255 2887B50D] mean:[109 119 138]
stdev:[43.0 12.7 13.3]
[Parsed_showinfo_0 @ 0x308fd40]   side data - User Data Unregistered:
[Parsed_showinfo_0 @ 0x308fd40] UUID=47564adc-5c4c-433f-94ef-c5113cd143a8
[Parsed_showinfo_0 @ 0x308fd40] User Data=01ffccccff0200e4dd42
[Parsed_showinfo_0 @ 0x308fd40]
[Parsed_showinfo_0 @ 0x308fd40]   side data - video encoding
parameters: type 1; qp=26; 8160 blocks;
[Parsed_showinfo_0 @ 0x308fd40] color_range:tv color_space:bt709
color_primaries:bt709 color_trc:bt709
...
-- frame 1 is a P-frame: we can see VIDEO_ENC_PARAMS info, and a
complain about "side-data type 8" (MOTION_VECTORS)
[Parsed_showinfo_0 @ 0x308fd40] n:   1 pts:  48000 pts_time:0.04
duration:  48000 duration_time:0.04    pos:   259304 fmt:yuv420p
sar:0/1 s:1920x1080 i:P iskey:0 type:B checksum:BC4E5C12
plane_checksum:[AEA8857A 34697DA4 805E58E5] mean:[109 119 138]
stdev:[43.0 12.6 13.3]
[Parsed_showinfo_0 @ 0x308fd40]   side data - video encoding
parameters: type 1; qp=26; 8160 blocks;
-- showinfo does not dump MOTION_VECTORS side-data
[Parsed_showinfo_0 @ 0x308fd40]   side data - unknown side data type 8
(547280 bytes)
[Parsed_showinfo_0 @ 0x308fd40]
[Parsed_showinfo_0 @ 0x308fd40] color_range:tv color_space:bt709
color_primaries:bt709 color_trc:bt709
...
```

So the best way right now to see the MVs is to use
`doc/examples/extract_mvs`, which does exactly that:

```
$ make examples -j
...
$ doc/examples/extract_mvs in.264 | head -40 | \
    csvcut -C framenum,source,flags |csvlook
| blockw | blockh |  srcx | srcy |  dstx | dsty | motion_x | motion_y
| motion_scale |
| ------ | ------ | ----- | ---- | ----- | ---- | -------- | --------
| ------------ |
|     16 |     16 |    20 |   26 |     8 |    8 |       49 |       72
|            4 |
|     16 |     16 |   152 |   15 |   136 |    8 |       65 |       28
|            4 |
|     16 |      8 |   360 |    3 |   360 |    4 |        1 |       -6
|            4 |
|     16 |      8 |   360 |   13 |   360 |   12 |       -1 |        4
|            4 |
|     16 |     16 |   440 |   10 |   440 |    8 |        3 |       10
|            4 |
|      8 |     16 |   829 |    7 |   836 |    8 |      -31 |       -6
|            4 |
|      8 |     16 |   844 |    7 |   844 |    8 |       -1 |       -4
|            4 |
```

> Yes, it's called codecview. We can help understand how it works if you ask 
> more specific questions, but something like "git grep EXPORT_DATA_MVS 
> ../libavcodec/mpeg*.c" and checking the complement code in codecview should 
> explain the basics.

codecview will get the motion vectors (assuming you asked for them),
and will overlay arrows showing the MV on top of the original video.

```
$ ffmpeg -flags2 +export_mvs -i input -vf codecview=mv=pf+bf+bb output.%04d.png
```

Adding one of the resulting frames in the next email.

-Chema


On Sat, Sep 3, 2022 at 5:08 AM Ronald S. Bultje <rsbul...@gmail.com> wrote:
>
> Hi Chema,
>
> On Fri, Sep 2, 2022 at 11:12 AM Chema Gonzalez <ch...@berkeley.edu> wrote:
>>
>> So is there a filter that already dumps this information?
>
>
> Yes, it's called codecview. We can help understand how it works if you ask 
> more specific questions, but something like "git grep EXPORT_DATA_MVS 
> ../libavcodec/mpeg*.c" and checking the complement code in codecview should 
> explain the basics.
>
> Ronald
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to