diff mbox series

[FFmpeg-devel] avcodec/vvcdec: fix seeking for open GOP

Message ID TYSPR06MB643335CF683E01E8EC21AE0AAA412@TYSPR06MB6433.apcprd06.prod.outlook.com
State Accepted
Commit 88a040386a0ea95306d8d8fdf9400f6214c89e7d
Headers show
Series [FFmpeg-devel] avcodec/vvcdec: fix seeking for open GOP | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Nuo Mi Feb. 3, 2024, 10:34 a.m. UTC
how to reproduce:
wget https://media.xiph.org/video/derf/y4m/students_cif.y4m
vvencapp --input students_cif.y4m --preset faster --output students.266
MP4Box -add students.266:fps=30000/1001:par=12:11 -new students.mp4
ffplay testudents.mp4
---
 libavcodec/vvc/vvc_refs.c | 6 ++++++
 libavcodec/vvc/vvc_refs.h | 1 +
 libavcodec/vvc/vvcdec.c   | 6 ++++++
 3 files changed, 13 insertions(+)

Comments

James Almer Feb. 3, 2024, 11:54 a.m. UTC | #1
On 2/3/2024 7:34 AM, Nuo Mi wrote:
> how to reproduce:
> wget https://media.xiph.org/video/derf/y4m/students_cif.y4m
> vvencapp --input students_cif.y4m --preset faster --output students.266
> MP4Box -add students.266:fps=30000/1001:par=12:11 -new students.mp4

Can't you do this with ffmpeg? mp4 muxing support was added recently, 
and we have a parser to find frame boundaries from raw bitstreams.

> ffplay testudents.mp4
> ---
>   libavcodec/vvc/vvc_refs.c | 6 ++++++
>   libavcodec/vvc/vvc_refs.h | 1 +
>   libavcodec/vvc/vvcdec.c   | 6 ++++++
>   3 files changed, 13 insertions(+)
> 
> diff --git a/libavcodec/vvc/vvc_refs.c b/libavcodec/vvc/vvc_refs.c
> index bf503e429e..e1895d1cca 100644
> --- a/libavcodec/vvc/vvc_refs.c
> +++ b/libavcodec/vvc/vvc_refs.c
> @@ -80,6 +80,12 @@ void ff_vvc_clear_refs(VVCFrameContext *fc)
>               VVC_FRAME_FLAG_SHORT_REF | VVC_FRAME_FLAG_LONG_REF);
>   }
>   
> +void ff_vvc_flush_dpb(VVCFrameContext *fc)
> +{
> +    for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
> +        ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
> +}
> +
>   static void free_progress(FFRefStructOpaque unused, void *obj)
>   {
>       FrameProgress *p = (FrameProgress *)obj;
> diff --git a/libavcodec/vvc/vvc_refs.h b/libavcodec/vvc/vvc_refs.h
> index cd3b5f5632..eba4422fb4 100644
> --- a/libavcodec/vvc/vvc_refs.h
> +++ b/libavcodec/vvc/vvc_refs.h
> @@ -33,6 +33,7 @@ int ff_vvc_frame_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc);
>   int ff_vvc_slice_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc);
>   void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags);
>   void ff_vvc_clear_refs(VVCFrameContext *fc);
> +void ff_vvc_flush_dpb(VVCFrameContext *fc);
>   
>   typedef enum VVCProgress {
>       VVC_PROGRESS_MV,
> diff --git a/libavcodec/vvc/vvcdec.c b/libavcodec/vvc/vvcdec.c
> index 83ee472ce6..1a050600eb 100644
> --- a/libavcodec/vvc/vvcdec.c
> +++ b/libavcodec/vvc/vvcdec.c
> @@ -922,9 +922,15 @@ static av_cold void vvc_decode_flush(AVCodecContext *avctx)
>   {
>       VVCContext *s  = avctx->priv_data;
>       int got_output = 0;
> +    VVCFrameContext *last;
>   
>       while (s->nb_delayed)
>           wait_delayed_frame(s, NULL, &got_output);
> +
> +    last = get_frame_context(s, s->fcs, s->nb_frames - 1);
> +    ff_vvc_flush_dpb(last);
> +
> +    s->eos = 1;
>   }
>   
>   static av_cold int vvc_decode_free(AVCodecContext *avctx)
Nuo Mi Feb. 3, 2024, 12:17 p.m. UTC | #2
On Sat, Feb 3, 2024 at 7:54 PM James Almer <jamrial@gmail.com> wrote:

> On 2/3/2024 7:34 AM, Nuo Mi wrote:
> > how to reproduce:
> > wget https://media.xiph.org/video/derf/y4m/students_cif.y4m
> > vvencapp --input students_cif.y4m --preset faster --output students.266
> > MP4Box -add students.266:fps=30000/1001:par=12:11 -new students.mp4
>
> Can't you do this with ffmpeg? mp4 muxing support was added recently,
> and we have a parser to find frame boundaries from raw bitstreams.
>
> Yes, we can
ffmpeg -i students.266 -c:v copy students.mp4
But the reporter used the mp4box
see:  https://github.com/ffvvc/FFmpeg/issues/190#issuecomment-1924169765
James Almer Feb. 3, 2024, 12:21 p.m. UTC | #3
On 2/3/2024 9:17 AM, Nuo Mi wrote:
> On Sat, Feb 3, 2024 at 7:54 PM James Almer <jamrial@gmail.com> wrote:
> 
>> On 2/3/2024 7:34 AM, Nuo Mi wrote:
>>> how to reproduce:
>>> wget https://media.xiph.org/video/derf/y4m/students_cif.y4m
>>> vvencapp --input students_cif.y4m --preset faster --output students.266
>>> MP4Box -add students.266:fps=30000/1001:par=12:11 -new students.mp4
>>
>> Can't you do this with ffmpeg? mp4 muxing support was added recently,
>> and we have a parser to find frame boundaries from raw bitstreams.
>>
>> Yes, we can
> ffmpeg -i students.266 -c:v copy students.mp4
> But the reporter used the mp4box
> see:  https://github.com/ffvvc/FFmpeg/issues/190#issuecomment-1924169765

That's ok, just wanted to know why not use ffmpeg for this. If it 
couldn't remux the file, then that'd be something we should fix.
Nuo Mi Feb. 3, 2024, 1:19 p.m. UTC | #4
On Sat, Feb 3, 2024 at 8:21 PM James Almer <jamrial@gmail.com> wrote:

> On 2/3/2024 9:17 AM, Nuo Mi wrote:
> > On Sat, Feb 3, 2024 at 7:54 PM James Almer <jamrial@gmail.com> wrote:
> >
> >> On 2/3/2024 7:34 AM, Nuo Mi wrote:
> >>> how to reproduce:
> >>> wget https://media.xiph.org/video/derf/y4m/students_cif.y4m
> >>> vvencapp --input students_cif.y4m --preset faster --output students.266
> >>> MP4Box -add students.266:fps=30000/1001:par=12:11 -new students.mp4
> >>
> >> Can't you do this with ffmpeg? mp4 muxing support was added recently,
> >> and we have a parser to find frame boundaries from raw bitstreams.
> >>
> >> Yes, we can
> > ffmpeg -i students.266 -c:v copy students.mp4
> > But the reporter used the mp4box
> > see:  https://github.com/ffvvc/FFmpeg/issues/190#issuecomment-1924169765
>
> That's ok, just wanted to know why not use ffmpeg for this. If it
> couldn't remux the file, then that'd be something we should fix.
>
Ts demux has an issue for both HEVC and VVC. If you use ffplay on a TS
file, you will see corrupted frames after a seek.
The main reason is that the demuxer does not send the key frame after a
seek; instead, it sends many frames before the key frame.
Not sure if it's a feature or a bug in the demuxer

you can reproduce it with
wget https://s3.amazonaws.com/x265.org/video/Tears_400_x265.mp4 && ffmpeg
-i Tears_400_x265.mp4 -c:v copy tos.ts
ffplay tos.ts

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
Nuo Mi Feb. 5, 2024, 2:16 p.m. UTC | #5
On Sat, Feb 3, 2024 at 6:35 PM Nuo Mi <nuomi2021@gmail.com> wrote:

> how to reproduce:
> wget https://media.xiph.org/video/derf/y4m/students_cif.y4m
> vvencapp --input students_cif.y4m --preset faster --output students.266
> MP4Box -add students.266:fps=30000/1001:par=12:11 -new students.mp4
> ffplay students.mp4

Applied, thanks James for the review

> ---
>  libavcodec/vvc/vvc_refs.c | 6 ++++++
>  libavcodec/vvc/vvc_refs.h | 1 +
>  libavcodec/vvc/vvcdec.c   | 6 ++++++
>  3 files changed, 13 insertions(+)
>
> diff --git a/libavcodec/vvc/vvc_refs.c b/libavcodec/vvc/vvc_refs.c
> index bf503e429e..e1895d1cca 100644
> --- a/libavcodec/vvc/vvc_refs.c
> +++ b/libavcodec/vvc/vvc_refs.c
> @@ -80,6 +80,12 @@ void ff_vvc_clear_refs(VVCFrameContext *fc)
>              VVC_FRAME_FLAG_SHORT_REF | VVC_FRAME_FLAG_LONG_REF);
>  }
>
> +void ff_vvc_flush_dpb(VVCFrameContext *fc)
> +{
> +    for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
> +        ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
> +}
> +
>  static void free_progress(FFRefStructOpaque unused, void *obj)
>  {
>      FrameProgress *p = (FrameProgress *)obj;
> diff --git a/libavcodec/vvc/vvc_refs.h b/libavcodec/vvc/vvc_refs.h
> index cd3b5f5632..eba4422fb4 100644
> --- a/libavcodec/vvc/vvc_refs.h
> +++ b/libavcodec/vvc/vvc_refs.h
> @@ -33,6 +33,7 @@ int ff_vvc_frame_rpl(VVCContext *s, VVCFrameContext *fc,
> SliceContext *sc);
>  int ff_vvc_slice_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext
> *sc);
>  void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags);
>  void ff_vvc_clear_refs(VVCFrameContext *fc);
> +void ff_vvc_flush_dpb(VVCFrameContext *fc);
>
>  typedef enum VVCProgress {
>      VVC_PROGRESS_MV,
> diff --git a/libavcodec/vvc/vvcdec.c b/libavcodec/vvc/vvcdec.c
> index 83ee472ce6..1a050600eb 100644
> --- a/libavcodec/vvc/vvcdec.c
> +++ b/libavcodec/vvc/vvcdec.c
> @@ -922,9 +922,15 @@ static av_cold void vvc_decode_flush(AVCodecContext
> *avctx)
>  {
>      VVCContext *s  = avctx->priv_data;
>      int got_output = 0;
> +    VVCFrameContext *last;
>
>      while (s->nb_delayed)
>          wait_delayed_frame(s, NULL, &got_output);
> +
> +    last = get_frame_context(s, s->fcs, s->nb_frames - 1);
> +    ff_vvc_flush_dpb(last);
> +
> +    s->eos = 1;
>  }
>
>  static av_cold int vvc_decode_free(AVCodecContext *avctx)
> --
> 2.25.1
>
>
diff mbox series

Patch

diff --git a/libavcodec/vvc/vvc_refs.c b/libavcodec/vvc/vvc_refs.c
index bf503e429e..e1895d1cca 100644
--- a/libavcodec/vvc/vvc_refs.c
+++ b/libavcodec/vvc/vvc_refs.c
@@ -80,6 +80,12 @@  void ff_vvc_clear_refs(VVCFrameContext *fc)
             VVC_FRAME_FLAG_SHORT_REF | VVC_FRAME_FLAG_LONG_REF);
 }
 
+void ff_vvc_flush_dpb(VVCFrameContext *fc)
+{
+    for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
+        ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
+}
+
 static void free_progress(FFRefStructOpaque unused, void *obj)
 {
     FrameProgress *p = (FrameProgress *)obj;
diff --git a/libavcodec/vvc/vvc_refs.h b/libavcodec/vvc/vvc_refs.h
index cd3b5f5632..eba4422fb4 100644
--- a/libavcodec/vvc/vvc_refs.h
+++ b/libavcodec/vvc/vvc_refs.h
@@ -33,6 +33,7 @@  int ff_vvc_frame_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc);
 int ff_vvc_slice_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc);
 void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags);
 void ff_vvc_clear_refs(VVCFrameContext *fc);
+void ff_vvc_flush_dpb(VVCFrameContext *fc);
 
 typedef enum VVCProgress {
     VVC_PROGRESS_MV,
diff --git a/libavcodec/vvc/vvcdec.c b/libavcodec/vvc/vvcdec.c
index 83ee472ce6..1a050600eb 100644
--- a/libavcodec/vvc/vvcdec.c
+++ b/libavcodec/vvc/vvcdec.c
@@ -922,9 +922,15 @@  static av_cold void vvc_decode_flush(AVCodecContext *avctx)
 {
     VVCContext *s  = avctx->priv_data;
     int got_output = 0;
+    VVCFrameContext *last;
 
     while (s->nb_delayed)
         wait_delayed_frame(s, NULL, &got_output);
+
+    last = get_frame_context(s, s->fcs, s->nb_frames - 1);
+    ff_vvc_flush_dpb(last);
+
+    s->eos = 1;
 }
 
 static av_cold int vvc_decode_free(AVCodecContext *avctx)