diff mbox

[FFmpeg-devel] lavc/h264: Output pix_fmt GRAY for monochrome input.

Message ID CAB0OVGoyQF2Gz4i0oq=xPt+_WFFvds04_qx2c17u3jnhFyXmCg@mail.gmail.com
State Superseded
Headers show

Commit Message

Carl Eugen Hoyos Aug. 7, 2018, 7:51 p.m. UTC
Hi!

Attached patch makes the h264 decoder output AV_PIX_FMT_GRAY for
monochrome h264 streams.
fate output is identical (and identical with the reference decoder) if
compared with extractplanes=y.

Please review, Carl Eugen

Comments

James Almer Aug. 7, 2018, 8:26 p.m. UTC | #1
On 8/7/2018 4:51 PM, Carl Eugen Hoyos wrote:
> Hi!
> 
> Attached patch makes the h264 decoder output AV_PIX_FMT_GRAY for
> monochrome h264 streams.
> fate output is identical (and identical with the reference decoder) if
> compared with extractplanes=y.
> 
> Please review, Carl Eugen
> 
> 
> 0001-lavc-h264-Output-pix_fmt-GRAY-for-monochrome-input.patch
> 
> 
> From 6434eff6c14698db192ec2f8777d2b4d2fdd3e8c Mon Sep 17 00:00:00 2001
> From: Carl Eugen Hoyos <ceffmpeg@gmail.com>
> Date: Tue, 7 Aug 2018 21:48:47 +0200
> Subject: [PATCH] lavc/h264: Output pix_fmt GRAY for monochrome input.
> 
> fate output is identical when compared with extractplanes=y.
> ---
>  libavcodec/h264_mb.c                               |   10 +-
>  libavcodec/h264_mb_template.c                      |   11 +-
>  libavcodec/h264_parser.c                           |    3 +
>  libavcodec/h264_slice.c                            |   17 +-
>  libavcodec/h264dec.h                               |    1 +
>  .../fate/h264-conformance-frext-hpcamolq_brcm_b    |  200 ++++++++++----------
>  .../fate/h264-conformance-frext-hpcvmolq_brcm_b    |  200 ++++++++++----------
>  7 files changed, 229 insertions(+), 213 deletions(-)
> 
> diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c
> index 3cd17b7..a269b5c 100644
> --- a/libavcodec/h264_mb.c
> +++ b/libavcodec/h264_mb.c
> @@ -250,7 +250,7 @@ static av_always_inline void mc_dir_part(const H264Context *h, H264SliceContext
>      if (!square)
>          qpix_op[luma_xy](dest_y + delta, src_y + delta, sl->mb_linesize);
>  
> -    if (CONFIG_GRAY && h->flags & AV_CODEC_FLAG_GRAY)
> +    if (CHROMA400(h) || CONFIG_GRAY && h->flags & AV_CODEC_FLAG_GRAY)
>          return;
>  
>      if (chroma_idc == 3 /* yuv444 */) {
> @@ -425,7 +425,7 @@ static av_always_inline void mc_part_weighted(const H264Context *h, H264SliceCon
>              int weight1 = 64 - weight0;
>              luma_weight_avg(dest_y, tmp_y, sl->mb_linesize,
>                              height, 5, weight0, weight1, 0);
> -            if (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
> +            if (!CHROMA400(h) && (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
>                  chroma_weight_avg(dest_cb, tmp_cb, sl->mb_uvlinesize,
>                                    chroma_height, 5, weight0, weight1, 0);
>                  chroma_weight_avg(dest_cr, tmp_cr, sl->mb_uvlinesize,
> @@ -438,7 +438,7 @@ static av_always_inline void mc_part_weighted(const H264Context *h, H264SliceCon
>                              sl->pwt.luma_weight[refn1][1][0],
>                              sl->pwt.luma_weight[refn0][0][1] +
>                              sl->pwt.luma_weight[refn1][1][1]);
> -            if (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
> +            if (!CHROMA400(h) && (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
>                  chroma_weight_avg(dest_cb, tmp_cb, sl->mb_uvlinesize, chroma_height,
>                                    sl->pwt.chroma_log2_weight_denom,
>                                    sl->pwt.chroma_weight[refn0][0][0][0],
> @@ -465,7 +465,7 @@ static av_always_inline void mc_part_weighted(const H264Context *h, H264SliceCon
>                         sl->pwt.luma_log2_weight_denom,
>                         sl->pwt.luma_weight[refn][list][0],
>                         sl->pwt.luma_weight[refn][list][1]);
> -        if (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
> +        if (!CHROMA400(h) && (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
>              if (sl->pwt.use_weight_chroma) {
>                  chroma_weight_op(dest_cb, sl->mb_uvlinesize, chroma_height,
>                                   sl->pwt.chroma_log2_weight_denom,
> @@ -566,7 +566,7 @@ static av_always_inline void xchg_mb_border(const H264Context *h, H264SliceConte
>              XCHG(sl->top_borders[top_idx][sl->mb_x + 1],
>                   src_y + (17 << pixel_shift), 1);
>          }
> -        if (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
> +        if (!CHROMA400(h) && (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
>              if (chroma444) {
>                  if (deblock_topleft) {
>                      XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1);
> diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
> index d5ea26a..2abc864 100644
> --- a/libavcodec/h264_mb_template.c
> +++ b/libavcodec/h264_mb_template.c
> @@ -52,6 +52,7 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
>      void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
>      const int block_h   = 16 >> h->chroma_y_shift;
>      const int chroma422 = CHROMA422(h);
> +    const int chroma400 = CHROMA400(h);
>  
>      dest_y  = h->cur_pic.f->data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * sl->linesize)  * 16;
>      dest_cb = h->cur_pic.f->data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * sl->uvlinesize * block_h;
> @@ -108,7 +109,7 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
>                  for (j = 0; j < 16; j++)
>                      tmp_y[j] = get_bits(&gb, bit_depth);
>              }
> -            if (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
> +            if (!chroma400 && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
>                  if (!h->ps.sps->chroma_format_idc) {

I think this becomes dead code. Your change makes sure this chunk is
never reached if the stream is chroma400, so this check here will always
be false.

>                      for (i = 0; i < block_h; i++) {
>                          uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
> @@ -133,7 +134,7 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
>          } else {
>              for (i = 0; i < 16; i++)
>                  memcpy(dest_y + i * linesize, sl->intra_pcm_ptr + i * 16, 16);
> -            if (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
> +            if (!chroma400 && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
>                  if (!h->ps.sps->chroma_format_idc) {

Same

>                      for (i = 0; i < 8; i++) {
>                          memset(dest_cb + i * uvlinesize, 1 << (bit_depth - 1), 8);
> @@ -155,7 +156,7 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
>                  xchg_mb_border(h, sl, dest_y, dest_cb, dest_cr, linesize,
>                                 uvlinesize, 1, 0, SIMPLE, PIXEL_SHIFT);
>  
> -            if (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
> +            if (!chroma400 && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
>                  h->hpc.pred8x8[sl->chroma_pred_mode](dest_cb, uvlinesize);
>                  h->hpc.pred8x8[sl->chroma_pred_mode](dest_cr, uvlinesize);
>              }
> @@ -190,7 +191,7 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
>          hl_decode_mb_idct_luma(h, sl, mb_type, SIMPLE, transform_bypass,
>                                 PIXEL_SHIFT, block_offset, linesize, dest_y, 0);
>  
> -        if ((SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) &&
> +        if ((!CHROMA400(h) && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) &&
>              (sl->cbp & 0x30)) {
>              uint8_t *dest[2] = { dest_cb, dest_cr };
>              if (transform_bypass) {
> @@ -264,7 +265,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(const H264Context *h, H264SliceCo
>      int i, j, p;
>      const int *block_offset = &h->block_offset[0];
>      const int transform_bypass = !SIMPLE && (sl->qscale == 0 && h->ps.sps->transform_bypass);
> -    const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) ? 3 : 1;
> +    const int plane_count      = !CHROMA400(h) && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) ? 3 : 1;
>  
>      for (p = 0; p < plane_count; p++) {
>          dest[p] = h->cur_pic.f->data[p] +
> diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
> index 5f9a9c4..8670b78 100644
> --- a/libavcodec/h264_parser.c
> +++ b/libavcodec/h264_parser.c
> @@ -401,16 +401,19 @@ static inline int parse_nal_units(AVCodecParserContext *s,
>              case 9:
>                  if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P9;
>                  else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P9;
> +                else if (sps->chroma_format_idc == 1) s->format = AV_PIX_FMT_GRAY9;
>                  else                                  s->format = AV_PIX_FMT_YUV420P9;
>                  break;
>              case 10:
>                  if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P10;
>                  else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P10;
> +                else if (sps->chroma_format_idc == 1) s->format = AV_PIX_FMT_GRAY10;
>                  else                                  s->format = AV_PIX_FMT_YUV420P10;
>                  break;
>              case 8:
>                  if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P;
>                  else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P;
> +                else if (sps->chroma_format_idc == 1) s->format = AV_PIX_FMT_GRAY8;

chroma_format_idc == 1 is yuv420p*, so use it here and put gray in the
last else.

>                  else                                  s->format = AV_PIX_FMT_YUV420P;
>                  break;
>              default:
> diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
> index ede9a1a..f98268a 100644
> --- a/libavcodec/h264_slice.c
> +++ b/libavcodec/h264_slice.c
> @@ -497,7 +497,7 @@ static int h264_frame_start(H264Context *h)
>  
>      if ((ret = alloc_picture(h, pic)) < 0)
>          return ret;
> -    if(!h->frame_recovered && !h->avctx->hwaccel)
> +    if(!h->frame_recovered && !h->avctx->hwaccel && !CHROMA400(h))
>          ff_color_frame(pic->f, c);
>  
>      h->cur_pic_ptr = pic;
> @@ -564,6 +564,7 @@ static av_always_inline void backup_mb_border(const H264Context *h, H264SliceCon
>      const int pixel_shift = h->pixel_shift;
>      int chroma444 = CHROMA444(h);
>      int chroma422 = CHROMA422(h);
> +    int chroma400 = CHROMA400(h);
>  
>      src_y  -= linesize;
>      src_cb -= uvlinesize;
> @@ -576,7 +577,7 @@ static av_always_inline void backup_mb_border(const H264Context *h, H264SliceCon
>                  AV_COPY128(top_border, src_y + 15 * linesize);
>                  if (pixel_shift)
>                      AV_COPY128(top_border + 16, src_y + 15 * linesize + 16);
> -                if (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
> +                if (!chroma400 && (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
>                      if (chroma444) {
>                          if (pixel_shift) {
>                              AV_COPY128(top_border + 32, src_cb + 15 * uvlinesize);
> @@ -619,7 +620,7 @@ static av_always_inline void backup_mb_border(const H264Context *h, H264SliceCon
>      if (pixel_shift)
>          AV_COPY128(top_border + 16, src_y + 16 * linesize + 16);
>  
> -    if (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
> +    if (!chroma400 && (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
>          if (chroma444) {
>              if (pixel_shift) {
>                  AV_COPY128(top_border + 32, src_cb + 16 * linesize);
> @@ -772,6 +773,8 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
>                  *fmt++ = AV_PIX_FMT_GBRP9;
>              } else
>                  *fmt++ = AV_PIX_FMT_YUV444P9;
> +        } else if (CHROMA400(h)) {
> +            *fmt++ = AV_PIX_FMT_GRAY9;
>          } else if (CHROMA422(h))
>              *fmt++ = AV_PIX_FMT_YUV422P9;
>          else
> @@ -783,6 +786,8 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
>                  *fmt++ = AV_PIX_FMT_GBRP10;
>              } else
>                  *fmt++ = AV_PIX_FMT_YUV444P10;
> +        } else if (CHROMA400(h)) {
> +            *fmt++ = AV_PIX_FMT_GRAY10;
>          } else if (CHROMA422(h))
>              *fmt++ = AV_PIX_FMT_YUV422P10;
>          else
> @@ -794,6 +799,8 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
>                  *fmt++ = AV_PIX_FMT_GBRP12;
>              } else
>                  *fmt++ = AV_PIX_FMT_YUV444P12;
> +        } else if (CHROMA400(h)) {
> +            *fmt++ = AV_PIX_FMT_GRAY12;
>          } else if (CHROMA422(h))
>              *fmt++ = AV_PIX_FMT_YUV422P12;
>          else
> @@ -805,6 +812,8 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
>                  *fmt++ = AV_PIX_FMT_GBRP14;
>              } else
>                  *fmt++ = AV_PIX_FMT_YUV444P14;
> +        } else if (CHROMA400(h)) {
> +            *fmt++ = AV_PIX_FMT_GRAY14;
>          } else if (CHROMA422(h))
>              *fmt++ = AV_PIX_FMT_YUV422P14;
>          else
> @@ -824,6 +833,8 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
>                  *fmt++ = AV_PIX_FMT_YUVJ444P;
>              else
>                  *fmt++ = AV_PIX_FMT_YUV444P;
> +        } else if (CHROMA400(h)) {
> +            *fmt++ = AV_PIX_FMT_GRAY8;
>          } else if (CHROMA422(h)) {
>              if (h->avctx->color_range == AVCOL_RANGE_JPEG)
>                  *fmt++ = AV_PIX_FMT_YUVJ422P;
> diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h
> index 1d97232..7e9fc72 100644
> --- a/libavcodec/h264dec.h
> +++ b/libavcodec/h264dec.h
> @@ -95,6 +95,7 @@
>  #endif
>  
>  #define CHROMA(h)    ((h)->ps.sps->chroma_format_idc)
> +#define CHROMA400(h) ((h)->ps.sps->chroma_format_idc == 0)
>  #define CHROMA422(h) ((h)->ps.sps->chroma_format_idc == 2)
>  #define CHROMA444(h) ((h)->ps.sps->chroma_format_idc == 3)

Seems to work, but wait for someone more familiar with h264dec to review
and confirm it's ok.
diff mbox

Patch

From 6434eff6c14698db192ec2f8777d2b4d2fdd3e8c Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <ceffmpeg@gmail.com>
Date: Tue, 7 Aug 2018 21:48:47 +0200
Subject: [PATCH] lavc/h264: Output pix_fmt GRAY for monochrome input.

fate output is identical when compared with extractplanes=y.
---
 libavcodec/h264_mb.c                               |   10 +-
 libavcodec/h264_mb_template.c                      |   11 +-
 libavcodec/h264_parser.c                           |    3 +
 libavcodec/h264_slice.c                            |   17 +-
 libavcodec/h264dec.h                               |    1 +
 .../fate/h264-conformance-frext-hpcamolq_brcm_b    |  200 ++++++++++----------
 .../fate/h264-conformance-frext-hpcvmolq_brcm_b    |  200 ++++++++++----------
 7 files changed, 229 insertions(+), 213 deletions(-)

diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c
index 3cd17b7..a269b5c 100644
--- a/libavcodec/h264_mb.c
+++ b/libavcodec/h264_mb.c
@@ -250,7 +250,7 @@  static av_always_inline void mc_dir_part(const H264Context *h, H264SliceContext
     if (!square)
         qpix_op[luma_xy](dest_y + delta, src_y + delta, sl->mb_linesize);
 
-    if (CONFIG_GRAY && h->flags & AV_CODEC_FLAG_GRAY)
+    if (CHROMA400(h) || CONFIG_GRAY && h->flags & AV_CODEC_FLAG_GRAY)
         return;
 
     if (chroma_idc == 3 /* yuv444 */) {
@@ -425,7 +425,7 @@  static av_always_inline void mc_part_weighted(const H264Context *h, H264SliceCon
             int weight1 = 64 - weight0;
             luma_weight_avg(dest_y, tmp_y, sl->mb_linesize,
                             height, 5, weight0, weight1, 0);
-            if (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
+            if (!CHROMA400(h) && (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
                 chroma_weight_avg(dest_cb, tmp_cb, sl->mb_uvlinesize,
                                   chroma_height, 5, weight0, weight1, 0);
                 chroma_weight_avg(dest_cr, tmp_cr, sl->mb_uvlinesize,
@@ -438,7 +438,7 @@  static av_always_inline void mc_part_weighted(const H264Context *h, H264SliceCon
                             sl->pwt.luma_weight[refn1][1][0],
                             sl->pwt.luma_weight[refn0][0][1] +
                             sl->pwt.luma_weight[refn1][1][1]);
-            if (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
+            if (!CHROMA400(h) && (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
                 chroma_weight_avg(dest_cb, tmp_cb, sl->mb_uvlinesize, chroma_height,
                                   sl->pwt.chroma_log2_weight_denom,
                                   sl->pwt.chroma_weight[refn0][0][0][0],
@@ -465,7 +465,7 @@  static av_always_inline void mc_part_weighted(const H264Context *h, H264SliceCon
                        sl->pwt.luma_log2_weight_denom,
                        sl->pwt.luma_weight[refn][list][0],
                        sl->pwt.luma_weight[refn][list][1]);
-        if (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
+        if (!CHROMA400(h) && (!CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
             if (sl->pwt.use_weight_chroma) {
                 chroma_weight_op(dest_cb, sl->mb_uvlinesize, chroma_height,
                                  sl->pwt.chroma_log2_weight_denom,
@@ -566,7 +566,7 @@  static av_always_inline void xchg_mb_border(const H264Context *h, H264SliceConte
             XCHG(sl->top_borders[top_idx][sl->mb_x + 1],
                  src_y + (17 << pixel_shift), 1);
         }
-        if (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
+        if (!CHROMA400(h) && (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
             if (chroma444) {
                 if (deblock_topleft) {
                     XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1);
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
index d5ea26a..2abc864 100644
--- a/libavcodec/h264_mb_template.c
+++ b/libavcodec/h264_mb_template.c
@@ -52,6 +52,7 @@  static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
     void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
     const int block_h   = 16 >> h->chroma_y_shift;
     const int chroma422 = CHROMA422(h);
+    const int chroma400 = CHROMA400(h);
 
     dest_y  = h->cur_pic.f->data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * sl->linesize)  * 16;
     dest_cb = h->cur_pic.f->data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * sl->uvlinesize * block_h;
@@ -108,7 +109,7 @@  static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
                 for (j = 0; j < 16; j++)
                     tmp_y[j] = get_bits(&gb, bit_depth);
             }
-            if (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
+            if (!chroma400 && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
                 if (!h->ps.sps->chroma_format_idc) {
                     for (i = 0; i < block_h; i++) {
                         uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
@@ -133,7 +134,7 @@  static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
         } else {
             for (i = 0; i < 16; i++)
                 memcpy(dest_y + i * linesize, sl->intra_pcm_ptr + i * 16, 16);
-            if (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
+            if (!chroma400 && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
                 if (!h->ps.sps->chroma_format_idc) {
                     for (i = 0; i < 8; i++) {
                         memset(dest_cb + i * uvlinesize, 1 << (bit_depth - 1), 8);
@@ -155,7 +156,7 @@  static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
                 xchg_mb_border(h, sl, dest_y, dest_cb, dest_cr, linesize,
                                uvlinesize, 1, 0, SIMPLE, PIXEL_SHIFT);
 
-            if (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
+            if (!chroma400 && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
                 h->hpc.pred8x8[sl->chroma_pred_mode](dest_cb, uvlinesize);
                 h->hpc.pred8x8[sl->chroma_pred_mode](dest_cr, uvlinesize);
             }
@@ -190,7 +191,7 @@  static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex
         hl_decode_mb_idct_luma(h, sl, mb_type, SIMPLE, transform_bypass,
                                PIXEL_SHIFT, block_offset, linesize, dest_y, 0);
 
-        if ((SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) &&
+        if ((!CHROMA400(h) && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) &&
             (sl->cbp & 0x30)) {
             uint8_t *dest[2] = { dest_cb, dest_cr };
             if (transform_bypass) {
@@ -264,7 +265,7 @@  static av_noinline void FUNC(hl_decode_mb_444)(const H264Context *h, H264SliceCo
     int i, j, p;
     const int *block_offset = &h->block_offset[0];
     const int transform_bypass = !SIMPLE && (sl->qscale == 0 && h->ps.sps->transform_bypass);
-    const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) ? 3 : 1;
+    const int plane_count      = !CHROMA400(h) && (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) ? 3 : 1;
 
     for (p = 0; p < plane_count; p++) {
         dest[p] = h->cur_pic.f->data[p] +
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 5f9a9c4..8670b78 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -401,16 +401,19 @@  static inline int parse_nal_units(AVCodecParserContext *s,
             case 9:
                 if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P9;
                 else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P9;
+                else if (sps->chroma_format_idc == 1) s->format = AV_PIX_FMT_GRAY9;
                 else                                  s->format = AV_PIX_FMT_YUV420P9;
                 break;
             case 10:
                 if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P10;
                 else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P10;
+                else if (sps->chroma_format_idc == 1) s->format = AV_PIX_FMT_GRAY10;
                 else                                  s->format = AV_PIX_FMT_YUV420P10;
                 break;
             case 8:
                 if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P;
                 else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P;
+                else if (sps->chroma_format_idc == 1) s->format = AV_PIX_FMT_GRAY8;
                 else                                  s->format = AV_PIX_FMT_YUV420P;
                 break;
             default:
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index ede9a1a..f98268a 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -497,7 +497,7 @@  static int h264_frame_start(H264Context *h)
 
     if ((ret = alloc_picture(h, pic)) < 0)
         return ret;
-    if(!h->frame_recovered && !h->avctx->hwaccel)
+    if(!h->frame_recovered && !h->avctx->hwaccel && !CHROMA400(h))
         ff_color_frame(pic->f, c);
 
     h->cur_pic_ptr = pic;
@@ -564,6 +564,7 @@  static av_always_inline void backup_mb_border(const H264Context *h, H264SliceCon
     const int pixel_shift = h->pixel_shift;
     int chroma444 = CHROMA444(h);
     int chroma422 = CHROMA422(h);
+    int chroma400 = CHROMA400(h);
 
     src_y  -= linesize;
     src_cb -= uvlinesize;
@@ -576,7 +577,7 @@  static av_always_inline void backup_mb_border(const H264Context *h, H264SliceCon
                 AV_COPY128(top_border, src_y + 15 * linesize);
                 if (pixel_shift)
                     AV_COPY128(top_border + 16, src_y + 15 * linesize + 16);
-                if (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
+                if (!chroma400 && (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
                     if (chroma444) {
                         if (pixel_shift) {
                             AV_COPY128(top_border + 32, src_cb + 15 * uvlinesize);
@@ -619,7 +620,7 @@  static av_always_inline void backup_mb_border(const H264Context *h, H264SliceCon
     if (pixel_shift)
         AV_COPY128(top_border + 16, src_y + 16 * linesize + 16);
 
-    if (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) {
+    if (!chroma400 && (simple || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY))) {
         if (chroma444) {
             if (pixel_shift) {
                 AV_COPY128(top_border + 32, src_cb + 16 * linesize);
@@ -772,6 +773,8 @@  static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
                 *fmt++ = AV_PIX_FMT_GBRP9;
             } else
                 *fmt++ = AV_PIX_FMT_YUV444P9;
+        } else if (CHROMA400(h)) {
+            *fmt++ = AV_PIX_FMT_GRAY9;
         } else if (CHROMA422(h))
             *fmt++ = AV_PIX_FMT_YUV422P9;
         else
@@ -783,6 +786,8 @@  static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
                 *fmt++ = AV_PIX_FMT_GBRP10;
             } else
                 *fmt++ = AV_PIX_FMT_YUV444P10;
+        } else if (CHROMA400(h)) {
+            *fmt++ = AV_PIX_FMT_GRAY10;
         } else if (CHROMA422(h))
             *fmt++ = AV_PIX_FMT_YUV422P10;
         else
@@ -794,6 +799,8 @@  static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
                 *fmt++ = AV_PIX_FMT_GBRP12;
             } else
                 *fmt++ = AV_PIX_FMT_YUV444P12;
+        } else if (CHROMA400(h)) {
+            *fmt++ = AV_PIX_FMT_GRAY12;
         } else if (CHROMA422(h))
             *fmt++ = AV_PIX_FMT_YUV422P12;
         else
@@ -805,6 +812,8 @@  static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
                 *fmt++ = AV_PIX_FMT_GBRP14;
             } else
                 *fmt++ = AV_PIX_FMT_YUV444P14;
+        } else if (CHROMA400(h)) {
+            *fmt++ = AV_PIX_FMT_GRAY14;
         } else if (CHROMA422(h))
             *fmt++ = AV_PIX_FMT_YUV422P14;
         else
@@ -824,6 +833,8 @@  static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
                 *fmt++ = AV_PIX_FMT_YUVJ444P;
             else
                 *fmt++ = AV_PIX_FMT_YUV444P;
+        } else if (CHROMA400(h)) {
+            *fmt++ = AV_PIX_FMT_GRAY8;
         } else if (CHROMA422(h)) {
             if (h->avctx->color_range == AVCOL_RANGE_JPEG)
                 *fmt++ = AV_PIX_FMT_YUVJ422P;
diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h
index 1d97232..7e9fc72 100644
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -95,6 +95,7 @@ 
 #endif
 
 #define CHROMA(h)    ((h)->ps.sps->chroma_format_idc)
+#define CHROMA400(h) ((h)->ps.sps->chroma_format_idc == 0)
 #define CHROMA422(h) ((h)->ps.sps->chroma_format_idc == 2)
 #define CHROMA444(h) ((h)->ps.sps->chroma_format_idc == 3)
 
diff --git a/tests/ref/fate/h264-conformance-frext-hpcamolq_brcm_b b/tests/ref/fate/h264-conformance-frext-hpcamolq_brcm_b
index 33e0688..e0e9045 100644
--- a/tests/ref/fate/h264-conformance-frext-hpcamolq_brcm_b
+++ b/tests/ref/fate/h264-conformance-frext-hpcamolq_brcm_b
@@ -3,103 +3,103 @@ 
 #codec_id 0: rawvideo
 #dimensions 0: 352x288
 #sar 0: 0/1
-0,          0,          0,        1,   152064, 0xac83f54f
-0,          1,          1,        1,   152064, 0x4d673b43
-0,          2,          2,        1,   152064, 0x9050731f
-0,          3,          3,        1,   152064, 0x4a0741f3
-0,          4,          4,        1,   152064, 0xb2371c28
-0,          5,          5,        1,   152064, 0x42210524
-0,          6,          6,        1,   152064, 0x385f4be5
-0,          7,          7,        1,   152064, 0xe44ec27a
-0,          8,          8,        1,   152064, 0xfc668399
-0,          9,          9,        1,   152064, 0x903fe200
-0,         10,         10,        1,   152064, 0x4da1deaa
-0,         11,         11,        1,   152064, 0x68c956ab
-0,         12,         12,        1,   152064, 0x9cfad799
-0,         13,         13,        1,   152064, 0x841ed3cd
-0,         14,         14,        1,   152064, 0x99e66b48
-0,         15,         15,        1,   152064, 0xcfa28482
-0,         16,         16,        1,   152064, 0x72f2c717
-0,         17,         17,        1,   152064, 0xd1d92c80
-0,         18,         18,        1,   152064, 0x595063eb
-0,         19,         19,        1,   152064, 0x87373979
-0,         20,         20,        1,   152064, 0xfa0e75ac
-0,         21,         21,        1,   152064, 0x0cef3592
-0,         22,         22,        1,   152064, 0xecfc9c9a
-0,         23,         23,        1,   152064, 0x5776ff23
-0,         24,         24,        1,   152064, 0x83419e37
-0,         25,         25,        1,   152064, 0x4bb31524
-0,         26,         26,        1,   152064, 0xad8e1bdc
-0,         27,         27,        1,   152064, 0x7243b6cb
-0,         28,         28,        1,   152064, 0xf016cda0
-0,         29,         29,        1,   152064, 0xa2c1d730
-0,         30,         30,        1,   152064, 0x7999d704
-0,         31,         31,        1,   152064, 0x86ad0baf
-0,         32,         32,        1,   152064, 0x35dafe62
-0,         33,         33,        1,   152064, 0xcb2f5de2
-0,         34,         34,        1,   152064, 0x3542eb82
-0,         35,         35,        1,   152064, 0xa704dd92
-0,         36,         36,        1,   152064, 0x3e50ed92
-0,         37,         37,        1,   152064, 0x2fe5428a
-0,         38,         38,        1,   152064, 0xf05dab9d
-0,         39,         39,        1,   152064, 0xef40c2a3
-0,         40,         40,        1,   152064, 0x2df8983f
-0,         41,         41,        1,   152064, 0x0a205c93
-0,         42,         42,        1,   152064, 0x505562ea
-0,         43,         43,        1,   152064, 0x24114860
-0,         44,         44,        1,   152064, 0x2eecccc1
-0,         45,         45,        1,   152064, 0xc809105f
-0,         46,         46,        1,   152064, 0x394ab285
-0,         47,         47,        1,   152064, 0xfda68f17
-0,         48,         48,        1,   152064, 0x2fd66a51
-0,         49,         49,        1,   152064, 0x3abb891a
-0,         50,         50,        1,   152064, 0x62266682
-0,         51,         51,        1,   152064, 0x68fb38e9
-0,         52,         52,        1,   152064, 0xae4b9d9b
-0,         53,         53,        1,   152064, 0xdaf8e150
-0,         54,         54,        1,   152064, 0x2fd8bf74
-0,         55,         55,        1,   152064, 0xd2ad6c38
-0,         56,         56,        1,   152064, 0x76290574
-0,         57,         57,        1,   152064, 0xaea6b9be
-0,         58,         58,        1,   152064, 0xd0d797d7
-0,         59,         59,        1,   152064, 0x87ad00b2
-0,         60,         60,        1,   152064, 0xe57d11d0
-0,         61,         61,        1,   152064, 0x25a5c567
-0,         62,         62,        1,   152064, 0x477e2202
-0,         63,         63,        1,   152064, 0xaa0618ca
-0,         64,         64,        1,   152064, 0xb5d2262b
-0,         65,         65,        1,   152064, 0xae7c135d
-0,         66,         66,        1,   152064, 0xddb86a7c
-0,         67,         67,        1,   152064, 0x59bad3ba
-0,         68,         68,        1,   152064, 0x0b155178
-0,         69,         69,        1,   152064, 0xc2f265d9
-0,         70,         70,        1,   152064, 0xb550e8a8
-0,         71,         71,        1,   152064, 0x1fef6cbc
-0,         72,         72,        1,   152064, 0xd3d4e578
-0,         73,         73,        1,   152064, 0x70d20c0d
-0,         74,         74,        1,   152064, 0xbb8e95a9
-0,         75,         75,        1,   152064, 0x2a92cda3
-0,         76,         76,        1,   152064, 0xc0a5e7e0
-0,         77,         77,        1,   152064, 0x15b99dab
-0,         78,         78,        1,   152064, 0x536d44e8
-0,         79,         79,        1,   152064, 0xe43fb4fa
-0,         80,         80,        1,   152064, 0xdb0873b0
-0,         81,         81,        1,   152064, 0xc7901e9b
-0,         82,         82,        1,   152064, 0x36b69923
-0,         83,         83,        1,   152064, 0xc6a8ac8d
-0,         84,         84,        1,   152064, 0xd7e4c595
-0,         85,         85,        1,   152064, 0x2d64cf38
-0,         86,         86,        1,   152064, 0x007878b1
-0,         87,         87,        1,   152064, 0xc9c997d4
-0,         88,         88,        1,   152064, 0xf9de12de
-0,         89,         89,        1,   152064, 0x25982d54
-0,         90,         90,        1,   152064, 0xea5eef7c
-0,         91,         91,        1,   152064, 0x108aceb2
-0,         92,         92,        1,   152064, 0x3cbac8c8
-0,         93,         93,        1,   152064, 0x581ec9e1
-0,         94,         94,        1,   152064, 0xc898bd7d
-0,         95,         95,        1,   152064, 0x142a0235
-0,         96,         96,        1,   152064, 0xf9d0aa7e
-0,         97,         97,        1,   152064, 0xb9fe0bc4
-0,         98,         98,        1,   152064, 0x21889912
-0,         99,         99,        1,   152064, 0x3fb2ab18
+0,          0,          0,        1,   101376, 0x59acef82
+0,          1,          1,        1,   101376, 0xb1733576
+0,          2,          2,        1,   101376, 0x44326d52
+0,          3,          3,        1,   101376, 0x407f3c26
+0,          4,          4,        1,   101376, 0x6142165b
+0,          5,          5,        1,   101376, 0x143eff48
+0,          6,          6,        1,   101376, 0x8f694618
+0,          7,          7,        1,   101376, 0x9d54bcad
+0,          8,          8,        1,   101376, 0x95177dcc
+0,          9,          9,        1,   101376, 0x3778dc33
+0,         10,         10,        1,   101376, 0x9f86d8dd
+0,         11,         11,        1,   101376, 0x1ed850de
+0,         12,         12,        1,   101376, 0x66e7d1cc
+0,         13,         13,        1,   101376, 0x421bce00
+0,         14,         14,        1,   101376, 0xf2b8657b
+0,         15,         15,        1,   101376, 0x27c77eb5
+0,         16,         16,        1,   101376, 0x886ac14a
+0,         17,         17,        1,   101376, 0xb33926b3
+0,         18,         18,        1,   101376, 0xf5905e1e
+0,         19,         19,        1,   101376, 0x3c1033ac
+0,         20,         20,        1,   101376, 0x82596fdf
+0,         21,         21,        1,   101376, 0x99042fc5
+0,         22,         22,        1,   101376, 0x9d8596cd
+0,         23,         23,        1,   101376, 0x9a8af956
+0,         24,         24,        1,   101376, 0xb30a986a
+0,         25,         25,        1,   101376, 0x64210f57
+0,         26,         26,        1,   101376, 0x280e160f
+0,         27,         27,        1,   101376, 0x0cdfb0fe
+0,         28,         28,        1,   101376, 0xc3bcc7d3
+0,         29,         29,        1,   101376, 0xa76dd163
+0,         30,         30,        1,   101376, 0x8843d137
+0,         31,         31,        1,   101376, 0x8ada05e2
+0,         32,         32,        1,   101376, 0xc7a9f895
+0,         33,         33,        1,   101376, 0xa3835815
+0,         34,         34,        1,   101376, 0xe217e5b5
+0,         35,         35,        1,   101376, 0x95a0d7c5
+0,         36,         36,        1,   101376, 0x733de7c5
+0,         37,         37,        1,   101376, 0x55823cbd
+0,         38,         38,        1,   101376, 0xa0b3a5d0
+0,         39,         39,        1,   101376, 0xf066bcd6
+0,         40,         40,        1,   101376, 0x73039272
+0,         41,         41,        1,   101376, 0x0ba156c6
+0,         42,         42,        1,   101376, 0xbe3e5d1d
+0,         43,         43,        1,   101376, 0x81f24293
+0,         44,         44,        1,   101376, 0x86a6c6f4
+0,         45,         45,        1,   101376, 0x75d60a92
+0,         46,         46,        1,   101376, 0x2978acb8
+0,         47,         47,        1,   101376, 0x9cfb894a
+0,         48,         48,        1,   101376, 0x9dd96484
+0,         49,         49,        1,   101376, 0xcd7f834d
+0,         50,         50,        1,   101376, 0x166660b5
+0,         51,         51,        1,   101376, 0x8455331c
+0,         52,         52,        1,   101376, 0x8d2b97ce
+0,         53,         53,        1,   101376, 0xaa29db83
+0,         54,         54,        1,   101376, 0xafe8b9a7
+0,         55,         55,        1,   101376, 0x80a8666b
+0,         56,         56,        1,   101376, 0x64a4ff98
+0,         57,         57,        1,   101376, 0x350ab3f1
+0,         58,         58,        1,   101376, 0x8aa1920a
+0,         59,         59,        1,   101376, 0xb95afad6
+0,         60,         60,        1,   101376, 0x1c970c03
+0,         61,         61,        1,   101376, 0x6eafbf9a
+0,         62,         62,        1,   101376, 0x16a01c35
+0,         63,         63,        1,   101376, 0x342612fd
+0,         64,         64,        1,   101376, 0x9eac205e
+0,         65,         65,        1,   101376, 0xc58a0d90
+0,         66,         66,        1,   101376, 0x07db64af
+0,         67,         67,        1,   101376, 0xca89cded
+0,         68,         68,        1,   101376, 0x6f6f4bab
+0,         69,         69,        1,   101376, 0x34df600c
+0,         70,         70,        1,   101376, 0x1f4fe2db
+0,         71,         71,        1,   101376, 0xafe166ef
+0,         72,         72,        1,   101376, 0x82ccdfab
+0,         73,         73,        1,   101376, 0xbcb80640
+0,         74,         74,        1,   101376, 0x22a88fdc
+0,         75,         75,        1,   101376, 0xac0bc7d6
+0,         76,         76,        1,   101376, 0xe3aae213
+0,         77,         77,        1,   101376, 0x93d697de
+0,         78,         78,        1,   101376, 0xa98f3f1b
+0,         79,         79,        1,   101376, 0x39f3af2d
+0,         80,         80,        1,   101376, 0x625a6de3
+0,         81,         81,        1,   101376, 0x683018ce
+0,         82,         82,        1,   101376, 0x19719356
+0,         83,         83,        1,   101376, 0xcc18a6c0
+0,         84,         84,        1,   101376, 0x8ae1bfc8
+0,         85,         85,        1,   101376, 0x5e86c96b
+0,         86,         86,        1,   101376, 0x87aa72e4
+0,         87,         87,        1,   101376, 0xd5b19207
+0,         88,         88,        1,   101376, 0x50b90d11
+0,         89,         89,        1,   101376, 0x055c2787
+0,         90,         90,        1,   101376, 0x0d25e9af
+0,         91,         91,        1,   101376, 0xebb5c8e5
+0,         92,         92,        1,   101376, 0x5891c2fb
+0,         93,         93,        1,   101376, 0x113ec414
+0,         94,         94,        1,   101376, 0x6982b7b0
+0,         95,         95,        1,   101376, 0xe243fc59
+0,         96,         96,        1,   101376, 0xb128a4b1
+0,         97,         97,        1,   101376, 0x7f3b05f7
+0,         98,         98,        1,   101376, 0x2b069345
+0,         99,         99,        1,   101376, 0xd402a54b
diff --git a/tests/ref/fate/h264-conformance-frext-hpcvmolq_brcm_b b/tests/ref/fate/h264-conformance-frext-hpcvmolq_brcm_b
index f722388..11d9f69 100644
--- a/tests/ref/fate/h264-conformance-frext-hpcvmolq_brcm_b
+++ b/tests/ref/fate/h264-conformance-frext-hpcvmolq_brcm_b
@@ -3,103 +3,103 @@ 
 #codec_id 0: rawvideo
 #dimensions 0: 352x288
 #sar 0: 0/1
-0,          0,          0,        1,   152064, 0xa18cfb97
-0,          1,          1,        1,   152064, 0x509b54d2
-0,          2,          2,        1,   152064, 0x1ba0fb8e
-0,          3,          3,        1,   152064, 0x43e7721f
-0,          4,          4,        1,   152064, 0xed196624
-0,          5,          5,        1,   152064, 0x4277f1e8
-0,          6,          6,        1,   152064, 0x88015cd6
-0,          7,          7,        1,   152064, 0x0f230af3
-0,          8,          8,        1,   152064, 0x91bbd664
-0,          9,          9,        1,   152064, 0x117c65dd
-0,         10,         10,        1,   152064, 0x8eebe5e8
-0,         11,         11,        1,   152064, 0xd205cc10
-0,         12,         12,        1,   152064, 0x4084a356
-0,         13,         13,        1,   152064, 0x37385081
-0,         14,         14,        1,   152064, 0xb7d34d8a
-0,         15,         15,        1,   152064, 0x96648874
-0,         16,         16,        1,   152064, 0x0623e65b
-0,         17,         17,        1,   152064, 0x7d5b0173
-0,         18,         18,        1,   152064, 0x0b6428e4
-0,         19,         19,        1,   152064, 0xf3ca22a8
-0,         20,         20,        1,   152064, 0x092e322c
-0,         21,         21,        1,   152064, 0xe82c2971
-0,         22,         22,        1,   152064, 0x29bf6111
-0,         23,         23,        1,   152064, 0x84f1ea0d
-0,         24,         24,        1,   152064, 0x45f822eb
-0,         25,         25,        1,   152064, 0x9672b2a7
-0,         26,         26,        1,   152064, 0xdb98e020
-0,         27,         27,        1,   152064, 0x729879eb
-0,         28,         28,        1,   152064, 0x3f629eae
-0,         29,         29,        1,   152064, 0x02e0ddb7
-0,         30,         30,        1,   152064, 0xbb1a0bb1
-0,         31,         31,        1,   152064, 0x9b85b55b
-0,         32,         32,        1,   152064, 0x2bae448b
-0,         33,         33,        1,   152064, 0xa8f28bfa
-0,         34,         34,        1,   152064, 0x687479da
-0,         35,         35,        1,   152064, 0xe1ec3111
-0,         36,         36,        1,   152064, 0x8afa37f1
-0,         37,         37,        1,   152064, 0x4af89faf
-0,         38,         38,        1,   152064, 0x1d9da53a
-0,         39,         39,        1,   152064, 0xdc599bcd
-0,         40,         40,        1,   152064, 0x01fb2e11
-0,         41,         41,        1,   152064, 0x2a33498e
-0,         42,         42,        1,   152064, 0x87874877
-0,         43,         43,        1,   152064, 0xdcd095c6
-0,         44,         44,        1,   152064, 0x4f14e6fb
-0,         45,         45,        1,   152064, 0x65fd165e
-0,         46,         46,        1,   152064, 0x4c267122
-0,         47,         47,        1,   152064, 0x18adf3aa
-0,         48,         48,        1,   152064, 0x74044daa
-0,         49,         49,        1,   152064, 0xa03bca1e
-0,         50,         50,        1,   152064, 0x7c1463fe
-0,         51,         51,        1,   152064, 0x688a14e3
-0,         52,         52,        1,   152064, 0x35c91c4e
-0,         53,         53,        1,   152064, 0xeaf51d07
-0,         54,         54,        1,   152064, 0xee61b9b1
-0,         55,         55,        1,   152064, 0xbab75db3
-0,         56,         56,        1,   152064, 0x199af472
-0,         57,         57,        1,   152064, 0x3bcf96db
-0,         58,         58,        1,   152064, 0x3fecdb09
-0,         59,         59,        1,   152064, 0x07be2431
-0,         60,         60,        1,   152064, 0x61432984
-0,         61,         61,        1,   152064, 0xdb12a3b9
-0,         62,         62,        1,   152064, 0xc2b8403e
-0,         63,         63,        1,   152064, 0x34c60bde
-0,         64,         64,        1,   152064, 0x08639859
-0,         65,         65,        1,   152064, 0xfc0fc556
-0,         66,         66,        1,   152064, 0x9cc27272
-0,         67,         67,        1,   152064, 0x3ef7dbb0
-0,         68,         68,        1,   152064, 0xbb74d9a3
-0,         69,         69,        1,   152064, 0x4007fc6e
-0,         70,         70,        1,   152064, 0x3d902f9b
-0,         71,         71,        1,   152064, 0xfbd0a76a
-0,         72,         72,        1,   152064, 0x4f1a4631
-0,         73,         73,        1,   152064, 0x4f58ee25
-0,         74,         74,        1,   152064, 0xd2c39501
-0,         75,         75,        1,   152064, 0x23de68d5
-0,         76,         76,        1,   152064, 0x4bf7d4ce
-0,         77,         77,        1,   152064, 0x2bdccc79
-0,         78,         78,        1,   152064, 0xc26b8f81
-0,         79,         79,        1,   152064, 0xe77fa90a
-0,         80,         80,        1,   152064, 0x48528308
-0,         81,         81,        1,   152064, 0xab19b66b
-0,         82,         82,        1,   152064, 0x04db5b4a
-0,         83,         83,        1,   152064, 0x9fade901
-0,         84,         84,        1,   152064, 0x1b7274ba
-0,         85,         85,        1,   152064, 0x387a0191
-0,         86,         86,        1,   152064, 0x2b3a8128
-0,         87,         87,        1,   152064, 0x2a0dab30
-0,         88,         88,        1,   152064, 0x5f5fc2da
-0,         89,         89,        1,   152064, 0x5a5c8150
-0,         90,         90,        1,   152064, 0xe0f5095e
-0,         91,         91,        1,   152064, 0xb87c8072
-0,         92,         92,        1,   152064, 0x08155daf
-0,         93,         93,        1,   152064, 0xc308353f
-0,         94,         94,        1,   152064, 0x2a04e8e4
-0,         95,         95,        1,   152064, 0xabe75987
-0,         96,         96,        1,   152064, 0x8733fb98
-0,         97,         97,        1,   152064, 0x810f53a0
-0,         98,         98,        1,   152064, 0xb3e4ea37
-0,         99,         99,        1,   152064, 0xb7a70980
+0,          0,          0,        1,   101376, 0x55d1f5ca
+0,          1,          1,        1,   101376, 0xf20d4f05
+0,          2,          2,        1,   101376, 0xc63ff5c1
+0,          3,          3,        1,   101376, 0x03636c52
+0,          4,          4,        1,   101376, 0x59a06057
+0,          5,          5,        1,   101376, 0xc10fec1b
+0,          6,          6,        1,   101376, 0xb4765709
+0,          7,          7,        1,   101376, 0x83cf0526
+0,          8,          8,        1,   101376, 0x67a9d097
+0,          9,          9,        1,   101376, 0x6b2d6010
+0,         10,         10,        1,   101376, 0x98cae01b
+0,         11,         11,        1,   101376, 0x17d5c643
+0,         12,         12,        1,   101376, 0x3ae39d89
+0,         13,         13,        1,   101376, 0xb0c34ab4
+0,         14,         14,        1,   101376, 0x5dd247bd
+0,         15,         15,        1,   101376, 0x94b782a7
+0,         16,         16,        1,   101376, 0x18cbe08e
+0,         17,         17,        1,   101376, 0x604dfb97
+0,         18,         18,        1,   101376, 0xbe9a2317
+0,         19,         19,        1,   101376, 0x576c1cdb
+0,         20,         20,        1,   101376, 0xa0b22c5f
+0,         21,         21,        1,   101376, 0x870e23a4
+0,         22,         22,        1,   101376, 0x831a5b44
+0,         23,         23,        1,   101376, 0xc0b5e440
+0,         24,         24,        1,   101376, 0xd47f1d1e
+0,         25,         25,        1,   101376, 0x391aacda
+0,         26,         26,        1,   101376, 0xd88eda53
+0,         27,         27,        1,   101376, 0x0f9c741e
+0,         28,         28,        1,   101376, 0x5fc798e1
+0,         29,         29,        1,   101376, 0x51c9d7ea
+0,         30,         30,        1,   101376, 0x333805e4
+0,         31,         31,        1,   101376, 0xe6c5af8e
+0,         32,         32,        1,   101376, 0x74083ebe
+0,         33,         33,        1,   101376, 0xda5f862d
+0,         34,         34,        1,   101376, 0x2c3b740d
+0,         35,         35,        1,   101376, 0x68542b44
+0,         36,         36,        1,   101376, 0x81943224
+0,         37,         37,        1,   101376, 0x99b499e2
+0,         38,         38,        1,   101376, 0xaa039f6d
+0,         39,         39,        1,   101376, 0x24339600
+0,         40,         40,        1,   101376, 0xab222844
+0,         41,         41,        1,   101376, 0xe65e43c1
+0,         42,         42,        1,   101376, 0x1a6942aa
+0,         43,         43,        1,   101376, 0xd4918ff9
+0,         44,         44,        1,   101376, 0x9a78e12e
+0,         45,         45,        1,   101376, 0x942e1091
+0,         46,         46,        1,   101376, 0xc50f6b55
+0,         47,         47,        1,   101376, 0x76e1eddd
+0,         48,         48,        1,   101376, 0x588c47dd
+0,         49,         49,        1,   101376, 0x289ac451
+0,         50,         50,        1,   101376, 0x65825e31
+0,         51,         51,        1,   101376, 0xc9e60f16
+0,         52,         52,        1,   101376, 0x7f121681
+0,         53,         53,        1,   101376, 0x15ec173a
+0,         54,         54,        1,   101376, 0x835bb3e4
+0,         55,         55,        1,   101376, 0xef2757e6
+0,         56,         56,        1,   101376, 0xbeb9eea5
+0,         57,         57,        1,   101376, 0xe8f7910e
+0,         58,         58,        1,   101376, 0x41f2d53c
+0,         59,         59,        1,   101376, 0x63811e64
+0,         60,         60,        1,   101376, 0x4d4423b7
+0,         61,         61,        1,   101376, 0x3efd9dec
+0,         62,         62,        1,   101376, 0xcafe3a71
+0,         63,         63,        1,   101376, 0xdcc80611
+0,         64,         64,        1,   101376, 0x3042928c
+0,         65,         65,        1,   101376, 0x6bebbf89
+0,         66,         66,        1,   101376, 0x267e6ca5
+0,         67,         67,        1,   101376, 0x0f6ed5e3
+0,         68,         68,        1,   101376, 0xb1b5d3d6
+0,         69,         69,        1,   101376, 0xa083f6a1
+0,         70,         70,        1,   101376, 0x18e729ce
+0,         71,         71,        1,   101376, 0x4ee6a19d
+0,         72,         72,        1,   101376, 0x205a4064
+0,         73,         73,        1,   101376, 0xcb97e858
+0,         74,         74,        1,   101376, 0x317b8f34
+0,         75,         75,        1,   101376, 0x8b1b6308
+0,         76,         76,        1,   101376, 0x384bcf01
+0,         77,         77,        1,   101376, 0x36dec6ac
+0,         78,         78,        1,   101376, 0x60f289b4
+0,         79,         79,        1,   101376, 0x67b7a33d
+0,         80,         80,        1,   101376, 0x0d937d3b
+0,         81,         81,        1,   101376, 0x8a0bb09e
+0,         82,         82,        1,   101376, 0x8b3e557d
+0,         83,         83,        1,   101376, 0x2fa1e334
+0,         84,         84,        1,   101376, 0xdaa36eed
+0,         85,         85,        1,   101376, 0xe604fbb5
+0,         86,         86,        1,   101376, 0x46387b5b
+0,         87,         87,        1,   101376, 0x2d4fa563
+0,         88,         88,        1,   101376, 0xd400bd0d
+0,         89,         89,        1,   101376, 0x83897b83
+0,         90,         90,        1,   101376, 0xa6070391
+0,         91,         91,        1,   101376, 0x9fbd7aa5
+0,         92,         92,        1,   101376, 0x54b257e2
+0,         93,         93,        1,   101376, 0x84ec2f72
+0,         94,         94,        1,   101376, 0x2942e317
+0,         95,         95,        1,   101376, 0x18cc53ba
+0,         96,         96,        1,   101376, 0x7569f5cb
+0,         97,         97,        1,   101376, 0xdc644dd3
+0,         98,         98,        1,   101376, 0x71c8e46a
+0,         99,         99,        1,   101376, 0x2f3303b3
-- 
1.7.10.4