Opened 3 months ago

Closed 3 months ago

Last modified 3 months ago

#7565 closed defect (needs_more_info)

Duplicate framre count in analyze_interlaced_flag option of idet filtrer

Reported by: ponpon Owned by:
Priority: normal Component: undetermined
Version: unspecified Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

LL. 288-294 of vf_idet.c

            if (idet->last_type == PROGRESSIVE) {
                idet->interlaced_flag_accuracy --;
                idet->analyze_interlaced_flag --;
            } else if (idet->last_type != UNDETERMINED) {
                idet->interlaced_flag_accuracy ++;
                idet->analyze_interlaced_flag --;
            }

Is this a duplicate count of a progressive frame because else if (idet->last_type != UNDETERMINED includes idet->last_type == PROGRESSIVE.
If so, I have a patch for it. Is it needed?

Change History (4)

comment:1 Changed 3 months ago by cehoyos

  • Resolution set to needs_more_info
  • Status changed from new to closed

Please test current FFmpeg git head, provide the complete, uncut console output, an input sample and explain what is wrong about idet's output.

comment:2 follow-up: Changed 3 months ago by ponpon

Sorry for not enough explanation.

The parameter, interlaced_flag_accuracy, is used in accuracy that frames are interlaced or progressive.analyze_interlaced_flag is used to count down frames to research which they are interlaced or progressive.

I think idet offsets accuracy in

            if (idet->last_type == PROGRESSIVE) {
                idet->interlaced_flag_accuracy --;

and

            } else if (idet->last_type != UNDETERMINED) {
                idet->interlaced_flag_accuracy ++;

and duplicately counts down frames in

idet->analyze_interlaced_flag --;

and

idet->analyze_interlaced_flag --;

This is because idet->last_type != UNDETERMINED means idet->last_type == PROGRESSIVE, last_type == TFF, or idet->last_type == BFF.

Before my patch (speed=77.6x) is faster than after it (69.5x). Does this means idet terminates researches by double count down? My misunderstanding?

Source: https://media.xiph.org/video/derf/y4m/football_422_ntsc.y4m
Before the patch

ffmpeg -i football_422_ntsc.y4m -vf setfield=tff,idet=intl_thres=1.35:analyze_interlaced_flag=500 -f null -
ffmpeg version N-92499-gfe9b990ec9 Copyright (c) 2000-2018 the FFmpeg developers
  built with clang version 5.0.2 (tags/RELEASE_502/final)
  configuration: --prefix= --cc=clang-mp-5.0 --cxx=clang++-mp-5.0
  libavutil      56. 23.101 / 56. 23.101
  libavcodec     58. 39.100 / 58. 39.100
  libavformat    58. 22.100 / 58. 22.100
  libavdevice    58.  6.100 / 58.  6.100
  libavfilter     7. 46.100 /  7. 46.100
  libswscale      5.  4.100 /  5.  4.100
  libswresample   3.  4.100 /  3.  4.100
Input #0, yuv4mpegpipe, from 'football_422_ntsc.y4m':
  Duration: 00:00:12.00, start: 0.000000, bitrate: 167963 kb/s
    Stream #0:0: Video: rawvideo (Y42B / 0x42323459), yuv422p(progressive), 720x486, SAR 4320:4379 DAR 6400:4379, 30 fps, 30 tbr, 30 tbn, 30 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> wrapped_avframe (native))
Press [q] to stop, [?] for help
Output #0, null, to 'pipe:':
  Metadata:
    encoder         : Lavf58.22.100
    Stream #0:0: Video: wrapped_avframe, yuv422p, 720x486 [SAR 4320:4379 DAR 6400:4379], q=2-31, 200 kb/s, 30 fps, 30 tbn, 30 tbc
    Metadata:
      encoder         : Lavc58.39.100 wrapped_avframe
frame=  360 fps=0.0 q=-0.0 Lsize=N/A time=00:00:12.00 bitrate=N/A speed=77.6x    
video:188kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_idet_1 @ 0x7fe3dd5004c0] Repeated Fields: Neither:   360 Top:     0 Bottom:     0
[Parsed_idet_1 @ 0x7fe3dd5004c0] Single frame detection: TFF:     0 BFF:     0 Progressive:   342 Undetermined:    18
[Parsed_idet_1 @ 0x7fe3dd5004c0] Multi frame detection: TFF:     0 BFF:     0 Progressive:   360 Undetermined:     0

Before the patch

ffmpeg -i football_422_ntsc.y4m -vf setfield=tff,idet=intl_thres=1.35:analyze_interlaced_flag=500 -f null -
ffmpeg version N-92499-gfe9b990ec9 Copyright (c) 2000-2018 the FFmpeg developers
  built with clang version 5.0.2 (tags/RELEASE_502/final)
  configuration: --prefix= --cc=clang-mp-5.0 --cxx=clang++-mp-5.0
  libavutil      56. 23.101 / 56. 23.101
  libavcodec     58. 39.100 / 58. 39.100
  libavformat    58. 22.100 / 58. 22.100
  libavdevice    58.  6.100 / 58.  6.100
  libavfilter     7. 46.100 /  7. 46.100
  libswscale      5.  4.100 /  5.  4.100
  libswresample   3.  4.100 /  3.  4.100
Input #0, yuv4mpegpipe, from 'football_422_ntsc.y4m':
  Duration: 00:00:12.00, start: 0.000000, bitrate: 167963 kb/s
    Stream #0:0: Video: rawvideo (Y42B / 0x42323459), yuv422p(progressive), 720x486, SAR 4320:4379 DAR 6400:4379, 30 fps, 30 tbr, 30 tbn, 30 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> wrapped_avframe (native))
Press [q] to stop, [?] for help
Output #0, null, to 'pipe:':
  Metadata:
    encoder         : Lavf58.22.100
    Stream #0:0: Video: wrapped_avframe, yuv422p, 720x486 [SAR 4320:4379 DAR 6400:4379], q=2-31, 200 kb/s, 30 fps, 30 tbn, 30 tbc
    Metadata:
      encoder         : Lavc58.39.100 wrapped_avframe
frame=  360 fps=0.0 q=-0.0 Lsize=N/A time=00:00:12.00 bitrate=N/A speed=69.5x    
video:188kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_idet_1 @ 0x7fb3f3d0ea80] Repeated Fields: Neither:   360 Top:     0 Bottom:     0
[Parsed_idet_1 @ 0x7fb3f3d0ea80] Single frame detection: TFF:     0 BFF:     0 Progressive:   342 Undetermined:    18
[Parsed_idet_1 @ 0x7fb3f3d0ea80] Multi frame detection: TFF:     0 BFF:     0 Progressive:   360 Undetermined:     0

My patch

diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c
index 02ae2edcb9..8c355ee2f9 100644
--- a/libavfilter/vf_idet.c
+++ b/libavfilter/vf_idet.c
@@ -285,12 +285,14 @@ static int filter_frame(AVFilterLink *link, AVFrame *picref)
         if (idet->cur->interlaced_frame) {
             idet->cur->interlaced_frame = 0;
             filter(ctx);
-            if (idet->last_type == PROGRESSIVE) {
-                idet->interlaced_flag_accuracy --;
-                idet->analyze_interlaced_flag --;
-            } else if (idet->last_type != UNDETERMINED) {
-                idet->interlaced_flag_accuracy ++;
-                idet->analyze_interlaced_flag --;
+            if (idet->last_type != UNDETERMINED) {
+                if (idet->last_type == PROGRESSIVE) {
+                    idet->interlaced_flag_accuracy --;
+                    idet->analyze_interlaced_flag --;
+                } else {
+                    idet->interlaced_flag_accuracy ++;
+                    idet->analyze_interlaced_flag --;
+                }
             }
             if (idet->analyze_interlaced_flag == 1) {
                 ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));

comment:3 in reply to: ↑ 2 ; follow-up: Changed 3 months ago by MarkZV

Replying to ponpon:

This is because idet->last_type != UNDETERMINED means idet->last_type == PROGRESSIVE, last_type == TFF, or idet->last_type == BFF.

It is inside of an else clause, so does not apply to idet->last_type == PROGRESSIVE.

Even in the output you provided, the change had no impact on the counts. It is expected that the speed will vary on every run.

comment:4 in reply to: ↑ 3 Changed 3 months ago by ponpon

Replying to MarkZV:
Thank you for your reply.
I think you are right in else {foo}. In the master, not else {foo} but else if (idet->last_type != UNDETERMINED) is used.
I think this results in early termination and a decrease in accuracy.

Note: See TracTickets for help on using tickets.