[FFmpeg-cvslog] h264: fix 4:2:2 PCM-macroblocks decoding

Anton Mitrofanov git at videolan.org
Thu Apr 5 22:44:32 CEST 2012


ffmpeg | branch: master | Anton Mitrofanov <BugMaster at narod.ru> | Mon Apr  2 09:25:19 2012 -0700| [14af74e9a001f0544ee2362b624344154c4e8a0c] | committer: Diego Biurrun

h264: fix 4:2:2 PCM-macroblocks decoding

Fixes bug 239.

Signed-off-by: Ronald S. Bultje <rsbultje at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=14af74e9a001f0544ee2362b624344154c4e8a0c
---

 libavcodec/h264.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index fe11686..6a1a8b6 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -2138,10 +2138,12 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple,
 
     if (!simple && IS_INTRA_PCM(mb_type)) {
         if (pixel_shift) {
+            static const uint16_t mb_sizes[4] = { 256, 384, 512, 768 };
             const int bit_depth = h->sps.bit_depth_luma;
             int j;
             GetBitContext gb;
-            init_get_bits(&gb, (uint8_t *)h->mb, 384 * bit_depth);
+            init_get_bits(&gb, (uint8_t *)h->mb,
+                          mb_sizes[h->sps.chroma_format_idc] * bit_depth);
 
             for (i = 0; i < 16; i++) {
                 uint16_t *tmp_y = (uint16_t *)(dest_y + i * linesize);
@@ -2175,7 +2177,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple,
             }
         } else {
             for (i = 0; i < 16; i++)
-                memcpy(dest_y + i * linesize, h->mb + i * 8, 16);
+                memcpy(dest_y + i * linesize, (uint8_t *)h->mb + i * 16, 16);
             if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
                 if (!h->sps.chroma_format_idc) {
                     for (i = 0; i < block_h; i++) {
@@ -2183,9 +2185,11 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple,
                         memset(dest_cr + i * uvlinesize, 128, 8);
                     }
                 } else {
+                    uint8_t *src_cb = (uint8_t *)h->mb + 256;
+                    uint8_t *src_cr = (uint8_t *)h->mb + 256 + block_h * 8;
                     for (i = 0; i < block_h; i++) {
-                        memcpy(dest_cb + i * uvlinesize, h->mb + 128 + i * 4, 8);
-                        memcpy(dest_cr + i * uvlinesize, h->mb + 160 + i * 4, 8);
+                        memcpy(dest_cb + i * uvlinesize, src_cb + i * 8, 8);
+                        memcpy(dest_cr + i * uvlinesize, src_cr + i * 8, 8);
                     }
                 }
             }
@@ -2374,7 +2378,8 @@ static av_always_inline void hl_decode_mb_444_internal(H264Context *h,
         } else {
             for (p = 0; p < plane_count; p++)
                 for (i = 0; i < 16; i++)
-                    memcpy(dest[p] + i * linesize, h->mb + p * 128 + i * 8, 16);
+                    memcpy(dest[p] + i * linesize,
+                           (uint8_t *)h->mb + p * 256 + i * 16, 16);
         }
     } else {
         if (IS_INTRA(mb_type)) {



More information about the ffmpeg-cvslog mailing list