diff mbox

[FFmpeg-devel,v4] lavc/hevc_parser: cope with more leading_zero_8bits and update FATE

Message ID 20190111072851.25258-1-linjie.fu@intel.com
State New
Headers show

Commit Message

Fu, Linjie Jan. 11, 2019, 7:28 a.m. UTC
Given that leading_zero_8bits can be included many times at the beginning
of a NAL unit, blindly taking the startcode as 3 bytes will leave 0x00
in last frame.

When startcode is found, go back to find all leading_zero_8bits in
current buffer and pc->buffer to cut correctly.

Update the FATE checksum for fate-hevc-bsf-mp4toannexb:
The ref output has redundant 0x00 at the end of the SUFFIX_SEI:
{ 50 01 84 31 00 19 39 77 d0 7b 3f bd 1e 09 38 9a 79 41
c0 16 11 da 18 aa 0a db 2b 19 fa 47 3f 0f 67 4a 91 9c a1
12 72 67 d6 f0 8f 66 ee 95 f9 e2 b9 ba 23 9a e8 80 00 }

To verify the output of FATE:
ffmpeg -i hevc-conformance/WPP_A_ericsson_MAIN10_2.bit -c copy -flags \
        +bitexact hevc-mp4.mov
ffmpeg -i hevc-mp4.mov -c:v copy -fflags +bitexact -f hevc hevc.out

Signed-off-by: Linjie Fu <linjie.fu@intel.com>
---
[v2]: Update FATE checksum.
[v3]: Cope with more leading_zero_8bits cases.
[v4]: find leading_zero_8bits in pc->buffer to cut correctly.

 libavcodec/hevc_parser.c | 12 ++++++++----
 tests/fate/hevc.mak      |  2 +-
 2 files changed, 9 insertions(+), 5 deletions(-)

Comments

Fu, Linjie Jan. 14, 2019, 1:07 a.m. UTC | #1
> -----Original Message-----
> From: Fu, Linjie
> Sent: Friday, January 11, 2019 15:29
> To: ffmpeg-devel@ffmpeg.org
> Cc: Fu, Linjie <linjie.fu@intel.com>
> Subject: [PATCH,v4] lavc/hevc_parser: cope with more leading_zero_8bits
> and update FATE
> 
> Given that leading_zero_8bits can be included many times at the beginning
> of a NAL unit, blindly taking the startcode as 3 bytes will leave 0x00
> in last frame.
> 
> When startcode is found, go back to find all leading_zero_8bits in
> current buffer and pc->buffer to cut correctly.
> 
> Update the FATE checksum for fate-hevc-bsf-mp4toannexb:
> The ref output has redundant 0x00 at the end of the SUFFIX_SEI:
> { 50 01 84 31 00 19 39 77 d0 7b 3f bd 1e 09 38 9a 79 41
> c0 16 11 da 18 aa 0a db 2b 19 fa 47 3f 0f 67 4a 91 9c a1
> 12 72 67 d6 f0 8f 66 ee 95 f9 e2 b9 ba 23 9a e8 80 00 }
> 
> To verify the output of FATE:
> ffmpeg -i hevc-conformance/WPP_A_ericsson_MAIN10_2.bit -c copy -flags \
>         +bitexact hevc-mp4.mov
> ffmpeg -i hevc-mp4.mov -c:v copy -fflags +bitexact -f hevc hevc.out
> 
> Signed-off-by: Linjie Fu <linjie.fu@intel.com>
> ---
> [v2]: Update FATE checksum.
> [v3]: Cope with more leading_zero_8bits cases.
> [v4]: find leading_zero_8bits in pc->buffer to cut correctly.
> 
>  libavcodec/hevc_parser.c | 12 ++++++++----
>  tests/fate/hevc.mak      |  2 +-
>  2 files changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
> index 369d1338d0..f6df43a067 100644
> --- a/libavcodec/hevc_parser.c
> +++ b/libavcodec/hevc_parser.c
> @@ -267,8 +267,7 @@ static int
> hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
>          if ((nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_EOB_NUT) || nut ==
> HEVC_NAL_SEI_PREFIX ||
>              (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) {
>              if (pc->frame_start_found) {
> -                pc->frame_start_found = 0;
> -                return i - 5;
> +                goto found;
>              }
>          } else if (nut <= HEVC_NAL_RASL_R ||
>                     (nut >= HEVC_NAL_BLA_W_LP && nut <= HEVC_NAL_CRA_NUT)) {
> @@ -277,14 +276,19 @@ static int
> hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
>                  if (!pc->frame_start_found) {
>                      pc->frame_start_found = 1;
>                  } else { // First slice of next frame found
> -                    pc->frame_start_found = 0;
> -                    return i - 5;
> +                    goto found;
>                  }
>              }
>          }
>      }
> 
>      return END_NOT_FOUND;
> +
> +found:
> +    pc->frame_start_found = 0;
> +    while (i - 6 >= 0 ? !buf[i - 6] : !pc->buffer[pc->index + i - 6])
> +        i--;
> +    return i - 5;
>  }
> 
>  static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx,
> diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak
> index db3ea19340..ab8da53535 100644
> --- a/tests/fate/hevc.mak
> +++ b/tests/fate/hevc.mak
> @@ -238,7 +238,7 @@ FATE_HEVC-$(call ALLYES, HEVC_DEMUXER
> MOV_DEMUXER HEVC_MP4TOANNEXB_BSF MOV_MUXER
>  fate-hevc-bsf-mp4toannexb: tests/data/hevc-mp4.mov
>  fate-hevc-bsf-mp4toannexb: CMD = md5 -i
> $(TARGET_PATH)/tests/data/hevc-mp4.mov -c:v copy -fflags +bitexact -f
> hevc
>  fate-hevc-bsf-mp4toannexb: CMP = oneline
> -fate-hevc-bsf-mp4toannexb: REF = 1873662a3af1848c37e4eb25722c8df9
> +fate-hevc-bsf-mp4toannexb: REF = 73019329ed7f81c24f9af67c34c640c0
> 
>  fate-hevc-skiploopfilter: CMD = framemd5 -skip_loop_filter nokey -i
> $(TARGET_SAMPLES)/hevc-conformance/SAO_D_Samsung_5.bit -sws_flags
> bitexact
>  FATE_HEVC += fate-hevc-skiploopfilter
> --
> 2.17.1
 
Ping for the latest update to find the correct frame end in both current buf and pc->buffer?

---
Thanks,
Linjie
Fu, Linjie Feb. 13, 2019, 2:41 a.m. UTC | #2
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> Of Fu, Linjie

> Sent: Monday, January 14, 2019 09:08

> To: FFmpeg development discussions and patches <ffmpeg-

> devel@ffmpeg.org>

> Subject: Re: [FFmpeg-devel] [PATCH, v4] lavc/hevc_parser: cope with more

> leading_zero_8bits and update FATE

> 

> > -----Original Message-----

> > From: Fu, Linjie

> > Sent: Friday, January 11, 2019 15:29

> > To: ffmpeg-devel@ffmpeg.org

> > Cc: Fu, Linjie <linjie.fu@intel.com>

> > Subject: [PATCH,v4] lavc/hevc_parser: cope with more leading_zero_8bits

> > and update FATE

> >

> > Given that leading_zero_8bits can be included many times at the beginning

> > of a NAL unit, blindly taking the startcode as 3 bytes will leave 0x00

> > in last frame.

> >

> > When startcode is found, go back to find all leading_zero_8bits in

> > current buffer and pc->buffer to cut correctly.

> >

> > Update the FATE checksum for fate-hevc-bsf-mp4toannexb:

> > The ref output has redundant 0x00 at the end of the SUFFIX_SEI:

> > { 50 01 84 31 00 19 39 77 d0 7b 3f bd 1e 09 38 9a 79 41

> > c0 16 11 da 18 aa 0a db 2b 19 fa 47 3f 0f 67 4a 91 9c a1

> > 12 72 67 d6 f0 8f 66 ee 95 f9 e2 b9 ba 23 9a e8 80 00 }

> >

> > To verify the output of FATE:

> > ffmpeg -i hevc-conformance/WPP_A_ericsson_MAIN10_2.bit -c copy -flags

> \

> >         +bitexact hevc-mp4.mov

> > ffmpeg -i hevc-mp4.mov -c:v copy -fflags +bitexact -f hevc hevc.out

> >

> > Signed-off-by: Linjie Fu <linjie.fu@intel.com>

> > ---

> > [v2]: Update FATE checksum.

> > [v3]: Cope with more leading_zero_8bits cases.

> > [v4]: find leading_zero_8bits in pc->buffer to cut correctly.

> >

> >  libavcodec/hevc_parser.c | 12 ++++++++----

> >  tests/fate/hevc.mak      |  2 +-

> >  2 files changed, 9 insertions(+), 5 deletions(-)

> >

> > diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c

> > index 369d1338d0..f6df43a067 100644

> > --- a/libavcodec/hevc_parser.c

> > +++ b/libavcodec/hevc_parser.c

> > @@ -267,8 +267,7 @@ static int

> > hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,

> >          if ((nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_EOB_NUT) || nut ==

> > HEVC_NAL_SEI_PREFIX ||

> >              (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) {

> >              if (pc->frame_start_found) {

> > -                pc->frame_start_found = 0;

> > -                return i - 5;

> > +                goto found;

> >              }

> >          } else if (nut <= HEVC_NAL_RASL_R ||

> >                     (nut >= HEVC_NAL_BLA_W_LP && nut <= HEVC_NAL_CRA_NUT))

> {

> > @@ -277,14 +276,19 @@ static int

> > hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,

> >                  if (!pc->frame_start_found) {

> >                      pc->frame_start_found = 1;

> >                  } else { // First slice of next frame found

> > -                    pc->frame_start_found = 0;

> > -                    return i - 5;

> > +                    goto found;

> >                  }

> >              }

> >          }

> >      }

> >

> >      return END_NOT_FOUND;

> > +

> > +found:

> > +    pc->frame_start_found = 0;

> > +    while (i - 6 >= 0 ? !buf[i - 6] : !pc->buffer[pc->index + i - 6])

> > +        i--;

> > +    return i - 5;

> >  }

> >

> >  static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx,

> > diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak

> > index db3ea19340..ab8da53535 100644

> > --- a/tests/fate/hevc.mak

> > +++ b/tests/fate/hevc.mak

> > @@ -238,7 +238,7 @@ FATE_HEVC-$(call ALLYES, HEVC_DEMUXER

> > MOV_DEMUXER HEVC_MP4TOANNEXB_BSF MOV_MUXER

> >  fate-hevc-bsf-mp4toannexb: tests/data/hevc-mp4.mov

> >  fate-hevc-bsf-mp4toannexb: CMD = md5 -i

> > $(TARGET_PATH)/tests/data/hevc-mp4.mov -c:v copy -fflags +bitexact -f

> > hevc

> >  fate-hevc-bsf-mp4toannexb: CMP = oneline

> > -fate-hevc-bsf-mp4toannexb: REF = 1873662a3af1848c37e4eb25722c8df9

> > +fate-hevc-bsf-mp4toannexb: REF = 73019329ed7f81c24f9af67c34c640c0

> >

> >  fate-hevc-skiploopfilter: CMD = framemd5 -skip_loop_filter nokey -i

> > $(TARGET_SAMPLES)/hevc-conformance/SAO_D_Samsung_5.bit -

> sws_flags

> > bitexact

> >  FATE_HEVC += fate-hevc-skiploopfilter

> > --

> > 2.17.1

> 

> Ping for the latest update to find the correct frame end in both current buf

> and pc->buffer?


Any advice for the modification?  

Checked the parser in H264, there are two conditions to find the frame end:
0x 00 00 01: return i - 4
0x 00 00 00 01 or 0x 00 00 ... 00 01 (more zero bytes): return i - 5;
more zero bytes situation will be treated as 4 bytes startcode.

So another way for this is to match the behavior in H264, and treat more zero bytes as 4 bytes startcode temporary.
diff mbox

Patch

diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
index 369d1338d0..f6df43a067 100644
--- a/libavcodec/hevc_parser.c
+++ b/libavcodec/hevc_parser.c
@@ -267,8 +267,7 @@  static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
         if ((nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_EOB_NUT) || nut == HEVC_NAL_SEI_PREFIX ||
             (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) {
             if (pc->frame_start_found) {
-                pc->frame_start_found = 0;
-                return i - 5;
+                goto found;
             }
         } else if (nut <= HEVC_NAL_RASL_R ||
                    (nut >= HEVC_NAL_BLA_W_LP && nut <= HEVC_NAL_CRA_NUT)) {
@@ -277,14 +276,19 @@  static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
                 if (!pc->frame_start_found) {
                     pc->frame_start_found = 1;
                 } else { // First slice of next frame found
-                    pc->frame_start_found = 0;
-                    return i - 5;
+                    goto found;
                 }
             }
         }
     }
 
     return END_NOT_FOUND;
+
+found:
+    pc->frame_start_found = 0;
+    while (i - 6 >= 0 ? !buf[i - 6] : !pc->buffer[pc->index + i - 6])
+        i--;
+    return i - 5;
 }
 
 static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx,
diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak
index db3ea19340..ab8da53535 100644
--- a/tests/fate/hevc.mak
+++ b/tests/fate/hevc.mak
@@ -238,7 +238,7 @@  FATE_HEVC-$(call ALLYES, HEVC_DEMUXER MOV_DEMUXER HEVC_MP4TOANNEXB_BSF MOV_MUXER
 fate-hevc-bsf-mp4toannexb: tests/data/hevc-mp4.mov
 fate-hevc-bsf-mp4toannexb: CMD = md5 -i $(TARGET_PATH)/tests/data/hevc-mp4.mov -c:v copy -fflags +bitexact -f hevc
 fate-hevc-bsf-mp4toannexb: CMP = oneline
-fate-hevc-bsf-mp4toannexb: REF = 1873662a3af1848c37e4eb25722c8df9
+fate-hevc-bsf-mp4toannexb: REF = 73019329ed7f81c24f9af67c34c640c0
 
 fate-hevc-skiploopfilter: CMD = framemd5 -skip_loop_filter nokey -i $(TARGET_SAMPLES)/hevc-conformance/SAO_D_Samsung_5.bit -sws_flags bitexact
 FATE_HEVC += fate-hevc-skiploopfilter