libavcodec/svq3.c
8b82a956
 /*
406792e7
  * Copyright (c) 2003 The FFmpeg Project
8b82a956
  *
b78e7197
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
8b82a956
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
b78e7197
  * version 2.1 of the License, or (at your option) any later version.
8b82a956
  *
b78e7197
  * FFmpeg is distributed in the hope that it will be useful,
8b82a956
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
b78e7197
  * License along with FFmpeg; if not, write to the Free Software
5509bffa
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
e5a389a1
  */
 
 /*
8b82a956
  * How to use this decoder:
  * SVQ3 data is transported within Apple Quicktime files. Quicktime files
89a79364
  * have stsd atoms to describe media trak properties. A stsd atom for a
  * video trak contains 1 or more ImageDescription atoms. These atoms begin
  * with the 4-byte length of the atom followed by the codec fourcc. Some
  * decoders need information in this atom to operate correctly. Such
  * is the case with SVQ3. In order to get the best use out of this decoder,
  * the calling app must make the SVQ3 ImageDescription atom available
8b82a956
  * via the AVCodecContext's extradata[_size] field:
  *
115329f1
  * AVCodecContext.extradata = pointer to ImageDescription, first characters
89a79364
  * are expected to be 'S', 'V', 'Q', and '3', NOT the 4-byte atom length
115329f1
  * AVCodecContext.extradata_size = size of ImageDescription atom memory
  * buffer (which will be the same as the ImageDescription atom size field
89a79364
  * from the QT file, minus 4 bytes since the length is missing)
  *
  * You will know you have these parameters passed correctly when the decoder
  * correctly decodes this file:
ddaf298c
  *  http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov
8b82a956
  */
903d58f6
 #include "internal.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h264.h"
 
a7d2861d
 #include "h264data.h" // FIXME FIXME FIXME
903d58f6
 
188d3c51
 #include "h264_mvpred.h"
903d58f6
 #include "golomb.h"
 #include "rectangle.h"
 #include "vdpau_internal.h"
 
b250f9c6
 #if CONFIG_ZLIB
c4864924
 #include <zlib.h>
 #endif
 
2be3fe39
 #include "svq1.h"
75d5156a
 #include "svq3.h"
2be3fe39
 
8b82a956
 /**
ba87f080
  * @file
8b82a956
  * svq3 decoder.
  */
 
8811679c
 typedef struct {
     H264Context h;
2c541554
     Picture *cur_pic;
     Picture *next_pic;
     Picture *last_pic;
8811679c
     int halfpel_flag;
     int thirdpel_flag;
     int unknown_flag;
     int next_slice_index;
     uint32_t watermark_key;
2264c110
     uint8_t *buf;
     int buf_size;
2c541554
     int adaptive_quant;
     int next_p_frame_damaged;
     int h_edge_pos;
     int v_edge_pos;
     int last_frame_output;
8811679c
 } SVQ3Context;
 
115329f1
 #define FULLPEL_MODE  1
 #define HALFPEL_MODE  2
94d44f45
 #define THIRDPEL_MODE 3
2e26c8d2
 #define PREDICT_MODE  4
115329f1
 
f7a8c179
 /* dual scan (from some older h264 draft)
a7d2861d
  * o-->o-->o   o
  *         |  /|
  * o   o   o / o
  * | / |   |/  |
  * o   o   o   o
  *   /
  * o-->o-->o-->o
  */
76de302d
 static const uint8_t svq3_scan[16] = {
a7d2861d
     0 + 0 * 4, 1 + 0 * 4, 2 + 0 * 4, 2 + 1 * 4,
     2 + 2 * 4, 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4,
     0 + 1 * 4, 0 + 2 * 4, 1 + 1 * 4, 1 + 2 * 4,
     0 + 3 * 4, 1 + 3 * 4, 2 + 3 * 4, 3 + 3 * 4,
8b82a956
 };
 
 static const uint8_t svq3_pred_0[25][2] = {
76de302d
     { 0, 0 },
     { 1, 0 }, { 0, 1 },
     { 0, 2 }, { 1, 1 }, { 2, 0 },
     { 3, 0 }, { 2, 1 }, { 1, 2 }, { 0, 3 },
     { 0, 4 }, { 1, 3 }, { 2, 2 }, { 3, 1 }, { 4, 0 },
     { 4, 1 }, { 3, 2 }, { 2, 3 }, { 1, 4 },
     { 2, 4 }, { 3, 3 }, { 4, 2 },
     { 4, 3 }, { 3, 4 },
     { 4, 4 }
8b82a956
 };
 
 static const int8_t svq3_pred_1[6][6][5] = {
a7d2861d
     { { 2, -1, -1, -1, -1 }, { 2, 1, -1, -1, -1 }, { 1, 2, -1, -1, -1 },
       { 2,  1, -1, -1, -1 }, { 1, 2, -1, -1, -1 }, { 1, 2, -1, -1, -1 } },
     { { 0,  2, -1, -1, -1 }, { 0, 2,  1,  4,  3 }, { 0, 1,  2,  4,  3 },
       { 0,  2,  1,  4,  3 }, { 2, 0,  1,  3,  4 }, { 0, 4,  2,  1,  3 } },
     { { 2,  0, -1, -1, -1 }, { 2, 1,  0,  4,  3 }, { 1, 2,  4,  0,  3 },
       { 2,  1,  0,  4,  3 }, { 2, 1,  4,  3,  0 }, { 1, 2,  4,  0,  3 } },
     { { 2,  0, -1, -1, -1 }, { 2, 0,  1,  4,  3 }, { 1, 2,  0,  4,  3 },
       { 2,  1,  0,  4,  3 }, { 2, 1,  3,  4,  0 }, { 2, 4,  1,  0,  3 } },
     { { 0,  2, -1, -1, -1 }, { 0, 2,  1,  3,  4 }, { 1, 2,  3,  0,  4 },
       { 2,  0,  1,  3,  4 }, { 2, 1,  3,  0,  4 }, { 2, 0,  4,  3,  1 } },
     { { 0,  2, -1, -1, -1 }, { 0, 2,  4,  1,  3 }, { 1, 4,  2,  0,  3 },
       { 4,  2,  0,  1,  3 }, { 2, 0,  1,  4,  3 }, { 4, 2,  1,  0,  3 } },
8b82a956
 };
 
a7d2861d
 static const struct {
     uint8_t run;
     uint8_t level;
 } svq3_dct_tables[2][16] = {
76de302d
     { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 0, 2 }, { 3, 1 }, { 4, 1 }, { 5, 1 },
       { 0, 3 }, { 1, 2 }, { 2, 2 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 0, 4 } },
     { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 0, 2 }, { 2, 1 }, { 0, 3 }, { 0, 4 }, { 0, 5 },
       { 3, 1 }, { 4, 1 }, { 1, 2 }, { 1, 3 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 } }
8b82a956
 };
 
 static const uint32_t svq3_dequant_coeff[32] = {
a7d2861d
      3881,  4351,  4890,  5481,   6154,   6914,   7761,   8718,
      9781, 10987, 12339, 13828,  15523,  17435,  19561,  21873,
     24552, 27656, 30847, 34870,  38807,  43747,  49103,  54683,
     61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533
8b82a956
 };
 
88bd7fdc
 void ff_svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp)
a7d2861d
 {
76de302d
     const int qmul = svq3_dequant_coeff[qp];
8b82a956
 #define stride 16
     int i;
     int temp[16];
a7d2861d
     static const uint8_t x_offset[4] = { 0, 1 * stride, 4 * stride, 5 * stride };
 
     for (i = 0; i < 4; i++) {
         const int z0 = 13 * (input[4 * i + 0] +      input[4 * i + 2]);
         const int z1 = 13 * (input[4 * i + 0] -      input[4 * i + 2]);
         const int z2 =  7 *  input[4 * i + 1] - 17 * input[4 * i + 3];
         const int z3 = 17 *  input[4 * i + 1] +  7 * input[4 * i + 3];
 
         temp[4 * i + 0] = z0 + z3;
         temp[4 * i + 1] = z1 + z2;
         temp[4 * i + 2] = z1 - z2;
         temp[4 * i + 3] = z0 - z3;
8b82a956
     }
 
a7d2861d
     for (i = 0; i < 4; i++) {
         const int offset = x_offset[i];
         const int z0     = 13 * (temp[4 * 0 + i] +      temp[4 * 2 + i]);
         const int z1     = 13 * (temp[4 * 0 + i] -      temp[4 * 2 + i]);
         const int z2     =  7 *  temp[4 * 1 + i] - 17 * temp[4 * 3 + i];
         const int z3     = 17 *  temp[4 * 1 + i] +  7 * temp[4 * 3 + i];
 
af1ede06
         output[stride *  0 + offset] = (z0 + z3) * qmul + 0x80000 >> 20;
         output[stride *  2 + offset] = (z1 + z2) * qmul + 0x80000 >> 20;
         output[stride *  8 + offset] = (z1 - z2) * qmul + 0x80000 >> 20;
         output[stride * 10 + offset] = (z0 - z3) * qmul + 0x80000 >> 20;
8b82a956
     }
 }
 #undef stride
 
88bd7fdc
 void ff_svq3_add_idct_c(uint8_t *dst, int16_t *block,
a7d2861d
                         int stride, int qp, int dc)
7f8205da
 {
76de302d
     const int qmul = svq3_dequant_coeff[qp];
8b82a956
     int i;
 
     if (dc) {
af1ede06
         dc       = 13 * 13 * (dc == 1 ? 1538 * block[0]
                                       : qmul * (block[0] >> 3) / 2);
8b82a956
         block[0] = 0;
     }
 
76de302d
     for (i = 0; i < 4; i++) {
a7d2861d
         const int z0 = 13 * (block[0 + 4 * i] +      block[2 + 4 * i]);
         const int z1 = 13 * (block[0 + 4 * i] -      block[2 + 4 * i]);
         const int z2 =  7 *  block[1 + 4 * i] - 17 * block[3 + 4 * i];
         const int z3 = 17 *  block[1 + 4 * i] +  7 * block[3 + 4 * i];
 
         block[0 + 4 * i] = z0 + z3;
         block[1 + 4 * i] = z1 + z2;
         block[2 + 4 * i] = z1 - z2;
         block[3 + 4 * i] = z0 - z3;
8b82a956
     }
 
76de302d
     for (i = 0; i < 4; i++) {
a7d2861d
         const int z0 = 13 * (block[i + 4 * 0] +      block[i + 4 * 2]);
         const int z1 = 13 * (block[i + 4 * 0] -      block[i + 4 * 2]);
         const int z2 =  7 *  block[i + 4 * 1] - 17 * block[i + 4 * 3];
         const int z3 = 17 *  block[i + 4 * 1] +  7 * block[i + 4 * 3];
76de302d
         const int rr = (dc + 0x80000);
 
af1ede06
         dst[i + stride * 0] = av_clip_uint8(dst[i + stride * 0] + ((z0 + z3) * qmul + rr >> 20));
         dst[i + stride * 1] = av_clip_uint8(dst[i + stride * 1] + ((z1 + z2) * qmul + rr >> 20));
         dst[i + stride * 2] = av_clip_uint8(dst[i + stride * 2] + ((z1 - z2) * qmul + rr >> 20));
         dst[i + stride * 3] = av_clip_uint8(dst[i + stride * 3] + ((z0 - z3) * qmul + rr >> 20));
8b82a956
     }
1acd7d59
 
     memset(block, 0, 16 * sizeof(int16_t));
8b82a956
 }
 
88bd7fdc
 static inline int svq3_decode_block(GetBitContext *gb, int16_t *block,
7f8205da
                                     int index, const int type)
 {
76de302d
     static const uint8_t *const scan_patterns[4] =
     { luma_dc_zigzag_scan, zigzag_scan, svq3_scan, chroma_dc_scan };
8b82a956
 
5c076205
     int run, level, sign, limit;
9a2e7911
     unsigned vlc;
af1ede06
     const int intra           = 3 * type >> 2;
76de302d
     const uint8_t *const scan = scan_patterns[type];
8b82a956
 
76de302d
     for (limit = (16 >> intra); index < 16; index = limit, limit += 8) {
         for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) {
7dee5f04
             if ((int32_t)vlc < 0)
a7d2861d
                 return -1;
8b82a956
 
5c076205
             sign     = (vlc & 1) ? 0 : -1;
9a2e7911
             vlc      = vlc + 1 >> 1;
a7d2861d
 
             if (type == 3) {
                 if (vlc < 3) {
                     run   = 0;
                     level = vlc;
                 } else if (vlc < 4) {
                     run   = 1;
                     level = 1;
                 } else {
af1ede06
                     run   = vlc & 0x3;
                     level = (vlc + 9 >> 2) - run;
a7d2861d
                 }
             } else {
0e097616
                 if (vlc < 16U) {
a7d2861d
                     run   = svq3_dct_tables[intra][vlc].run;
                     level = svq3_dct_tables[intra][vlc].level;
                 } else if (intra) {
af1ede06
                     run   = vlc & 0x7;
0e097616
                     level = (vlc >> 3) + ((run == 0) ? 8 : ((run < 2) ? 2 : ((run < 5) ? 0 : -1)));
a7d2861d
                 } else {
af1ede06
                     run   = vlc & 0xF;
0e097616
                     level = (vlc >> 4) + ((run == 0) ? 4 : ((run < 3) ? 2 : ((run < 10) ? 1 : 0)));
a7d2861d
                 }
             }
8b82a956
 
0e097616
 
a7d2861d
             if ((index += run) >= limit)
                 return -1;
 
             block[scan[index]] = (level ^ sign) - sign;
76de302d
         }
8b82a956
 
76de302d
         if (type != 2) {
             break;
         }
8b82a956
     }
 
76de302d
     return 0;
8b82a956
 }
 
2c541554
 static inline void svq3_mc_dir_part(SVQ3Context *s,
7f8205da
                                     int x, int y, int width, int height,
                                     int mx, int my, int dxy,
                                     int thirdpel, int dir, int avg)
 {
2c541554
     H264Context *h     = &s->h;
     const Picture *pic = (dir == 0) ? s->last_pic : s->next_pic;
76de302d
     uint8_t *src, *dest;
     int i, emu = 0;
a7d2861d
     int blocksize = 2 - (width >> 3); // 16->0, 8->1, 4->2
76de302d
 
     mx += x;
     my += y;
8b82a956
 
af1ede06
     if (mx < 0 || mx >= s->h_edge_pos - width  - 1 ||
         my < 0 || my >= s->v_edge_pos - height - 1) {
51513b98
         emu = 1;
af1ede06
         mx = av_clip(mx, -16, s->h_edge_pos - width  + 15);
         my = av_clip(my, -16, s->v_edge_pos - height + 15);
8b82a956
     }
 
76de302d
     /* form component predictions */
2c541554
     dest = h->cur_pic.f.data[0] + x + y * h->linesize;
     src  = pic->f.data[0] + mx + my * h->linesize;
76de302d
 
     if (emu) {
2c541554
         h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, h->linesize,
8c53d39e
                                  width + 1, height + 1,
                                  mx, my, s->h_edge_pos, s->v_edge_pos);
2c541554
         src = h->edge_emu_buffer;
8b82a956
     }
76de302d
     if (thirdpel)
2c541554
         (avg ? h->dsp.avg_tpel_pixels_tab
              : h->dsp.put_tpel_pixels_tab)[dxy](dest, src, h->linesize,
a7d2861d
                                                 width, height);
76de302d
     else
2c541554
         (avg ? h->dsp.avg_pixels_tab
              : h->dsp.put_pixels_tab)[blocksize][dxy](dest, src, h->linesize,
a7d2861d
                                                       height);
76de302d
 
2c541554
     if (!(h->flags & CODEC_FLAG_GRAY)) {
af1ede06
         mx     = mx + (mx < (int) x) >> 1;
         my     = my + (my < (int) y) >> 1;
         width  = width  >> 1;
         height = height >> 1;
76de302d
         blocksize++;
 
         for (i = 1; i < 3; i++) {
2c541554
             dest = h->cur_pic.f.data[i] + (x >> 1) + (y >> 1) * h->uvlinesize;
             src  = pic->f.data[i] + mx + my * h->uvlinesize;
76de302d
 
             if (emu) {
2c541554
                 h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, h->uvlinesize,
8c53d39e
                                          width + 1, height + 1,
                                          mx, my, (s->h_edge_pos >> 1),
                                          s->v_edge_pos >> 1);
2c541554
                 src = h->edge_emu_buffer;
76de302d
             }
             if (thirdpel)
2c541554
                 (avg ? h->dsp.avg_tpel_pixels_tab
                      : h->dsp.put_tpel_pixels_tab)[dxy](dest, src,
                                                         h->uvlinesize,
a7d2861d
                                                         width, height);
76de302d
             else
2c541554
                 (avg ? h->dsp.avg_pixels_tab
                      : h->dsp.put_pixels_tab)[blocksize][dxy](dest, src,
                                                               h->uvlinesize,
a7d2861d
                                                               height);
76de302d
         }
     }
8b82a956
 }
 
2c541554
 static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,
a7d2861d
                               int dir, int avg)
7f8205da
 {
76de302d
     int i, j, k, mx, my, dx, dy, x, y;
2c541554
     H264Context *h          = &s->h;
a7d2861d
     const int part_width    = ((size & 5) == 4) ? 4 : 16 >> (size & 1);
     const int part_height   = 16 >> ((unsigned)(size + 1) / 3);
     const int extra_width   = (mode == PREDICT_MODE) ? -16 * 6 : 0;
     const int h_edge_pos    = 6 * (s->h_edge_pos - part_width)  - extra_width;
     const int v_edge_pos    = 6 * (s->v_edge_pos - part_height) - extra_width;
 
     for (i = 0; i < 16; i += part_height)
76de302d
         for (j = 0; j < 16; j += part_width) {
2c541554
             const int b_xy = (4 * h->mb_x + (j >> 2)) +
                              (4 * h->mb_y + (i >> 2)) * h->b_stride;
76de302d
             int dxy;
2c541554
             x = 16 * h->mb_x + j;
             y = 16 * h->mb_y + i;
af1ede06
             k = (j >> 2 & 1) + (i >> 1 & 2) +
                 (j >> 1 & 4) + (i      & 8);
76de302d
 
             if (mode != PREDICT_MODE) {
af1ede06
                 pred_motion(h, k, part_width >> 2, dir, 1, &mx, &my);
76de302d
             } else {
2c541554
                 mx = s->next_pic->f.motion_val[0][b_xy][0] << 1;
                 my = s->next_pic->f.motion_val[0][b_xy][1] << 1;
76de302d
 
                 if (dir == 0) {
af1ede06
                     mx = mx * h->frame_num_offset /
                          h->prev_frame_num_offset + 1 >> 1;
                     my = my * h->frame_num_offset /
                          h->prev_frame_num_offset + 1 >> 1;
76de302d
                 } else {
af1ede06
                     mx = mx * (h->frame_num_offset - h->prev_frame_num_offset) /
                          h->prev_frame_num_offset + 1 >> 1;
                     my = my * (h->frame_num_offset - h->prev_frame_num_offset) /
                          h->prev_frame_num_offset + 1 >> 1;
76de302d
                 }
             }
 
             /* clip motion vector prediction to frame border */
a7d2861d
             mx = av_clip(mx, extra_width - 6 * x, h_edge_pos - 6 * x);
             my = av_clip(my, extra_width - 6 * y, v_edge_pos - 6 * y);
76de302d
 
             /* get (optional) motion vector differential */
             if (mode == PREDICT_MODE) {
                 dx = dy = 0;
             } else {
2c541554
                 dy = svq3_get_se_golomb(&h->gb);
                 dx = svq3_get_se_golomb(&h->gb);
76de302d
 
                 if (dx == INVALID_VLC || dy == INVALID_VLC) {
2c541554
                     av_log(h->avctx, AV_LOG_ERROR, "invalid MV vlc\n");
76de302d
                     return -1;
                 }
             }
 
             /* compute motion vector */
             if (mode == THIRDPEL_MODE) {
                 int fx, fy;
af1ede06
                 mx  = (mx + 1 >> 1) + dx;
                 my  = (my + 1 >> 1) + dy;
                 fx  = (unsigned)(mx + 0x3000) / 3 - 0x1000;
                 fy  = (unsigned)(my + 0x3000) / 3 - 0x1000;
a7d2861d
                 dxy = (mx - 3 * fx) + 4 * (my - 3 * fy);
 
                 svq3_mc_dir_part(s, x, y, part_width, part_height,
                                  fx, fy, dxy, 1, dir, avg);
76de302d
                 mx += mx;
                 my += my;
             } else if (mode == HALFPEL_MODE || mode == PREDICT_MODE) {
af1ede06
                 mx  = (unsigned)(mx + 1 + 0x3000) / 3 + dx - 0x1000;
                 my  = (unsigned)(my + 1 + 0x3000) / 3 + dy - 0x1000;
a7d2861d
                 dxy = (mx & 1) + 2 * (my & 1);
76de302d
 
a7d2861d
                 svq3_mc_dir_part(s, x, y, part_width, part_height,
                                  mx >> 1, my >> 1, dxy, 0, dir, avg);
76de302d
                 mx *= 3;
                 my *= 3;
             } else {
af1ede06
                 mx = (unsigned)(mx + 3 + 0x6000) / 6 + dx - 0x1000;
                 my = (unsigned)(my + 3 + 0x6000) / 6 + dy - 0x1000;
76de302d
 
a7d2861d
                 svq3_mc_dir_part(s, x, y, part_width, part_height,
                                  mx, my, 0, 0, dir, avg);
76de302d
                 mx *= 6;
                 my *= 6;
             }
 
             /* update mv_cache */
             if (mode != PREDICT_MODE) {
a7d2861d
                 int32_t mv = pack16to32(mx, my);
76de302d
 
                 if (part_height == 8 && i < 8) {
a7d2861d
                     AV_WN32A(h->mv_cache[dir][scan8[k] + 1 * 8], mv);
76de302d
 
a7d2861d
                     if (part_width == 8 && j < 8)
                         AV_WN32A(h->mv_cache[dir][scan8[k] + 1 + 1 * 8], mv);
76de302d
                 }
a7d2861d
                 if (part_width == 8 && j < 8)
366b72f1
                     AV_WN32A(h->mv_cache[dir][scan8[k] + 1], mv);
a7d2861d
                 if (part_width == 4 || part_height == 4)
366b72f1
                     AV_WN32A(h->mv_cache[dir][scan8[k]], mv);
76de302d
             }
 
             /* write back motion vectors */
2c541554
             fill_rectangle(h->cur_pic.f.motion_val[dir][b_xy],
657ccb5a
                            part_width >> 2, part_height >> 2, h->b_stride,
                            pack16to32(mx, my), 4);
bb270c08
         }
2e26c8d2
 
76de302d
     return 0;
2e26c8d2
 }
 
2c541554
 static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
7f8205da
 {
2c541554
     H264Context *h = &s->h;
76de302d
     int i, j, k, m, dir, mode;
     int cbp = 0;
     uint32_t vlc;
     int8_t *top, *left;
a7d2861d
     const int mb_xy         = h->mb_xy;
2c541554
     const int b_xy          = 4 * h->mb_x + 4 * h->mb_y * h->b_stride;
76de302d
 
2c541554
     h->top_samples_available      = (h->mb_y == 0) ? 0x33FF : 0xFFFF;
     h->left_samples_available     = (h->mb_x == 0) ? 0x5F5F : 0xFFFF;
76de302d
     h->topright_samples_available = 0xFFFF;
 
     if (mb_type == 0) {           /* SKIP */
2c541554
         if (h->pict_type == AV_PICTURE_TYPE_P ||
             s->next_pic->f.mb_type[mb_xy] == -1) {
             svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16,
a7d2861d
                              0, 0, 0, 0, 0, 0);
76de302d
 
2c541554
             if (h->pict_type == AV_PICTURE_TYPE_B)
                 svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16,
a7d2861d
                                  0, 0, 0, 0, 1, 1);
76de302d
 
             mb_type = MB_TYPE_SKIP;
         } else {
2c541554
             mb_type = FFMIN(s->next_pic->f.mb_type[mb_xy], 6);
             if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 0, 0) < 0)
76de302d
                 return -1;
2c541554
             if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 1, 1) < 0)
76de302d
                 return -1;
8b82a956
 
76de302d
             mb_type = MB_TYPE_16x16;
bb270c08
         }
76de302d
     } else if (mb_type < 8) {     /* INTER */
2c541554
         if (s->thirdpel_flag && s->halfpel_flag == !get_bits1(&h->gb))
76de302d
             mode = THIRDPEL_MODE;
2c541554
         else if (s->halfpel_flag &&
                  s->thirdpel_flag == !get_bits1(&h->gb))
76de302d
             mode = HALFPEL_MODE;
a7d2861d
         else
76de302d
             mode = FULLPEL_MODE;
8b82a956
 
76de302d
         /* fill caches */
         /* note ref_cache should contain here:
a7d2861d
          *  ????????
          *  ???11111
          *  N??11111
          *  N??11111
          *  N??11111
          */
76de302d
 
         for (m = 0; m < 2; m++) {
2c541554
             if (h->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {
a7d2861d
                 for (i = 0; i < 4; i++)
                     AV_COPY32(h->mv_cache[m][scan8[0] - 1 + i * 8],
2c541554
                               h->cur_pic.f.motion_val[m][b_xy - 1 + i * h->b_stride]);
76de302d
             } else {
a7d2861d
                 for (i = 0; i < 4; i++)
                     AV_ZERO32(h->mv_cache[m][scan8[0] - 1 + i * 8]);
76de302d
             }
2c541554
             if (h->mb_y > 0) {
a7d2861d
                 memcpy(h->mv_cache[m][scan8[0] - 1 * 8],
2c541554
                        h->cur_pic.f.motion_val[m][b_xy - h->b_stride],
a7d2861d
                        4 * 2 * sizeof(int16_t));
                 memset(&h->ref_cache[m][scan8[0] - 1 * 8],
2c541554
                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
76de302d
 
2c541554
                 if (h->mb_x < h->mb_width - 1) {
a7d2861d
                     AV_COPY32(h->mv_cache[m][scan8[0] + 4 - 1 * 8],
2c541554
                               h->cur_pic.f.motion_val[m][b_xy - h->b_stride + 4]);
a7d2861d
                     h->ref_cache[m][scan8[0] + 4 - 1 * 8] =
2c541554
                         (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 ||
                          h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;
a7d2861d
                 } else
                     h->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE;
2c541554
                 if (h->mb_x > 0) {
a7d2861d
                     AV_COPY32(h->mv_cache[m][scan8[0] - 1 - 1 * 8],
2c541554
                               h->cur_pic.f.motion_val[m][b_xy - h->b_stride - 1]);
a7d2861d
                     h->ref_cache[m][scan8[0] - 1 - 1 * 8] =
2c541554
                         (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;
a7d2861d
                 } else
                     h->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE;
             } else
                 memset(&h->ref_cache[m][scan8[0] - 1 * 8 - 1],
                        PART_NOT_AVAILABLE, 8);
76de302d
 
2c541554
             if (h->pict_type != AV_PICTURE_TYPE_B)
76de302d
                 break;
bb270c08
         }
8b82a956
 
76de302d
         /* decode motion vector(s) and form prediction(s) */
2c541554
         if (h->pict_type == AV_PICTURE_TYPE_P) {
             if (svq3_mc_dir(s, mb_type - 1, mode, 0, 0) < 0)
76de302d
                 return -1;
ce5e49b0
         } else {        /* AV_PICTURE_TYPE_B */
76de302d
             if (mb_type != 2) {
2c541554
                 if (svq3_mc_dir(s, 0, mode, 0, 0) < 0)
76de302d
                     return -1;
             } else {
a7d2861d
                 for (i = 0; i < 4; i++)
2c541554
                     memset(h->cur_pic.f.motion_val[0][b_xy + i * h->b_stride],
a7d2861d
                            0, 4 * 2 * sizeof(int16_t));
76de302d
             }
             if (mb_type != 1) {
2c541554
                 if (svq3_mc_dir(s, 0, mode, 1, mb_type == 3) < 0)
76de302d
                     return -1;
             } else {
a7d2861d
                 for (i = 0; i < 4; i++)
2c541554
                     memset(h->cur_pic.f.motion_val[1][b_xy + i * h->b_stride],
a7d2861d
                            0, 4 * 2 * sizeof(int16_t));
76de302d
             }
bb270c08
         }
8b82a956
 
76de302d
         mb_type = MB_TYPE_16x16;
     } else if (mb_type == 8 || mb_type == 33) {   /* INTRA4x4 */
a7d2861d
         memset(h->intra4x4_pred_mode_cache, -1, 8 * 5 * sizeof(int8_t));
76de302d
 
         if (mb_type == 8) {
2c541554
             if (h->mb_x > 0) {
a7d2861d
                 for (i = 0; i < 4; i++)
                     h->intra4x4_pred_mode_cache[scan8[0] - 1 + i * 8] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6 - i];
                 if (h->intra4x4_pred_mode_cache[scan8[0] - 1] == -1)
76de302d
                     h->left_samples_available = 0x5F5F;
             }
2c541554
             if (h->mb_y > 0) {
                 h->intra4x4_pred_mode_cache[4 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 0];
                 h->intra4x4_pred_mode_cache[5 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 1];
                 h->intra4x4_pred_mode_cache[6 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 2];
                 h->intra4x4_pred_mode_cache[7 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 3];
76de302d
 
a7d2861d
                 if (h->intra4x4_pred_mode_cache[4 + 8 * 0] == -1)
76de302d
                     h->top_samples_available = 0x33FF;
             }
 
             /* decode prediction codes for luma blocks */
a7d2861d
             for (i = 0; i < 16; i += 2) {
2c541554
                 vlc = svq3_get_ue_golomb(&h->gb);
76de302d
 
0e097616
                 if (vlc >= 25U) {
2c541554
                     av_log(h->avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc);
76de302d
                     return -1;
                 }
 
a7d2861d
                 left = &h->intra4x4_pred_mode_cache[scan8[i] - 1];
                 top  = &h->intra4x4_pred_mode_cache[scan8[i] - 8];
76de302d
 
                 left[1] = svq3_pred_1[top[0] + 1][left[0] + 1][svq3_pred_0[vlc][0]];
                 left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]];
 
a7d2861d
                 if (left[1] == -1 || left[2] == -1) {
2c541554
                     av_log(h->avctx, AV_LOG_ERROR, "weird prediction\n");
76de302d
                     return -1;
                 }
             }
         } else {    /* mb_type == 33, DC_128_PRED block type */
a7d2861d
             for (i = 0; i < 4; i++)
                 memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_PRED, 4);
884182b3
         }
8b82a956
 
3b7ebeb4
         write_back_intra_pred_mode(h);
8b82a956
 
76de302d
         if (mb_type == 8) {
2bedc0e8
             ff_h264_check_intra4x4_pred_mode(h);
da3b9756
 
2c541554
             h->top_samples_available  = (h->mb_y == 0) ? 0x33FF : 0xFFFF;
             h->left_samples_available = (h->mb_x == 0) ? 0x5F5F : 0xFFFF;
76de302d
         } else {
a7d2861d
             for (i = 0; i < 4; i++)
                 memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_128_PRED, 4);
da3b9756
 
76de302d
             h->top_samples_available  = 0x33FF;
             h->left_samples_available = 0x5F5F;
         }
da3b9756
 
76de302d
         mb_type = MB_TYPE_INTRA4x4;
     } else {                      /* INTRA16x16 */
         dir = i_mb_type_info[mb_type - 8].pred_mode;
a7d2861d
         dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1;
8b82a956
 
a7d2861d
         if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) == -1) {
2c541554
             av_log(h->avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n");
76de302d
             return -1;
         }
8b82a956
 
a7d2861d
         cbp     = i_mb_type_info[mb_type - 8].cbp;
76de302d
         mb_type = MB_TYPE_INTRA16x16;
884182b3
     }
8b82a956
 
2c541554
     if (!IS_INTER(mb_type) && h->pict_type != AV_PICTURE_TYPE_I) {
a7d2861d
         for (i = 0; i < 4; i++)
2c541554
             memset(h->cur_pic.f.motion_val[0][b_xy + i * h->b_stride],
a7d2861d
                    0, 4 * 2 * sizeof(int16_t));
2c541554
         if (h->pict_type == AV_PICTURE_TYPE_B) {
a7d2861d
             for (i = 0; i < 4; i++)
2c541554
                 memset(h->cur_pic.f.motion_val[1][b_xy + i * h->b_stride],
a7d2861d
                        0, 4 * 2 * sizeof(int16_t));
76de302d
         }
8b82a956
     }
76de302d
     if (!IS_INTRA4x4(mb_type)) {
a7d2861d
         memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy], DC_PRED, 8);
da3b9756
     }
2c541554
     if (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B) {
a7d2861d
         memset(h->non_zero_count_cache + 8, 0, 14 * 8 * sizeof(uint8_t));
884182b3
     }
2e26c8d2
 
a7d2861d
     if (!IS_INTRA16x16(mb_type) &&
2c541554
         (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B)) {
b7fe35c9
         if ((vlc = svq3_get_ue_golomb(&h->gb)) >= 48U){
2c541554
             av_log(h->avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc);
76de302d
             return -1;
         }
8b82a956
 
a7d2861d
         cbp = IS_INTRA(mb_type) ? golomb_to_intra4x4_cbp[vlc]
                                 : golomb_to_inter_cbp[vlc];
884182b3
     }
a7d2861d
     if (IS_INTRA16x16(mb_type) ||
2c541554
         (h->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {
         h->qscale += svq3_get_se_golomb(&h->gb);
8b82a956
 
2c541554
         if (h->qscale > 31u) {
             av_log(h->avctx, AV_LOG_ERROR, "qscale:%d\n", h->qscale);
bb270c08
             return -1;
         }
8b82a956
     }
76de302d
     if (IS_INTRA16x16(mb_type)) {
a7d2861d
         AV_ZERO128(h->mb_luma_dc[0] + 0);
         AV_ZERO128(h->mb_luma_dc[0] + 8);
2c541554
         if (svq3_decode_block(&h->gb, h->mb_luma_dc[0], 0, 1)) {
             av_log(h->avctx, AV_LOG_ERROR,
a7d2861d
                    "error while decoding intra luma dc\n");
76de302d
             return -1;
884182b3
         }
76de302d
     }
8b82a956
 
76de302d
     if (cbp) {
         const int index = IS_INTRA16x16(mb_type) ? 1 : 0;
2c541554
         const int type  = ((h->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);
76de302d
 
a7d2861d
         for (i = 0; i < 4; i++)
76de302d
             if ((cbp & (1 << i))) {
                 for (j = 0; j < 4; j++) {
a7d2861d
                     k = index ? (1 * (j & 1) + 2 * (i & 1) +
                                  2 * (j & 2) + 4 * (i & 2))
                               : (4 * i + j);
                     h->non_zero_count_cache[scan8[k]] = 1;
 
2c541554
                     if (svq3_decode_block(&h->gb, &h->mb[16 * k], index, type)) {
                         av_log(h->avctx, AV_LOG_ERROR,
a7d2861d
                                "error while decoding block\n");
76de302d
                         return -1;
                     }
                 }
             }
8b82a956
 
76de302d
         if ((cbp & 0x30)) {
a7d2861d
             for (i = 1; i < 3; ++i)
2c541554
                 if (svq3_decode_block(&h->gb, &h->mb[16 * 16 * i], 0, 3)) {
                     av_log(h->avctx, AV_LOG_ERROR,
a7d2861d
                            "error while decoding chroma dc block\n");
                     return -1;
                 }
76de302d
 
             if ((cbp & 0x20)) {
11177a4d
                 for (i = 1; i < 3; i++) {
                     for (j = 0; j < 4; j++) {
a7d2861d
                         k                                 = 16 * i + j;
                         h->non_zero_count_cache[scan8[k]] = 1;
11177a4d
 
2c541554
                         if (svq3_decode_block(&h->gb, &h->mb[16 * k], 1, 1)) {
                             av_log(h->avctx, AV_LOG_ERROR,
a7d2861d
                                    "error while decoding chroma ac block\n");
11177a4d
                             return -1;
                         }
76de302d
                     }
                 }
             }
bb270c08
         }
8b82a956
     }
 
a7d2861d
     h->cbp                              = cbp;
2c541554
     h->cur_pic.f.mb_type[mb_xy] = mb_type;
8b82a956
 
a7d2861d
     if (IS_INTRA(mb_type))
45b7bd7c
         h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8, 1);
8b82a956
 
76de302d
     return 0;
8b82a956
 }
 
8811679c
 static int svq3_decode_slice_header(AVCodecContext *avctx)
7f8205da
 {
2c541554
     SVQ3Context *s = avctx->priv_data;
     H264Context *h    = &s->h;
a7d2861d
     const int mb_xy   = h->mb_xy;
76de302d
     int i, header;
288bb3da
     unsigned slice_id;
da3b9756
 
2c541554
     header = get_bits(&h->gb, 8);
da3b9756
 
76de302d
     if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) {
         /* TODO: what? */
8811679c
         av_log(avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header);
76de302d
         return -1;
     } else {
af1ede06
         int length = header >> 5 & 3;
da3b9756
 
2c541554
         s->next_slice_index = get_bits_count(&h->gb) +
                               8 * show_bits(&h->gb, 8 * length) +
                               8 * length;
da3b9756
 
2c541554
         if (s->next_slice_index > h->gb.size_in_bits) {
8811679c
             av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n");
76de302d
             return -1;
a7d2861d
         }
da3b9756
 
2c541554
         h->gb.size_in_bits = s->next_slice_index - 8 * (length - 1);
         skip_bits(&h->gb, 8);
da3b9756
 
2c541554
         if (s->watermark_key) {
             uint32_t header = AV_RL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1]);
             AV_WL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1],
                     header ^ s->watermark_key);
76de302d
         }
         if (length > 0) {
2c541554
             memcpy((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3],
                    &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1);
76de302d
         }
2c541554
         skip_bits_long(&h->gb, 0);
da3b9756
     }
 
2c541554
     if ((slice_id = svq3_get_ue_golomb(&h->gb)) >= 3) {
         av_log(h->avctx, AV_LOG_ERROR, "illegal slice type %d \n", slice_id);
76de302d
         return -1;
     }
da3b9756
 
288bb3da
     h->slice_type = golomb_to_pict_type[slice_id];
da3b9756
 
76de302d
     if ((header & 0x9F) == 2) {
2c541554
         i              = (h->mb_num < 64) ? 6 : (1 + av_log2(h->mb_num - 1));
         h->mb_skip_run = get_bits(&h->gb, i) -
                          (h->mb_y * h->mb_width + h->mb_x);
76de302d
     } else {
2c541554
         skip_bits1(&h->gb);
         h->mb_skip_run = 0;
76de302d
     }
da3b9756
 
2c541554
     h->slice_num      = get_bits(&h->gb, 8);
     h->qscale         = get_bits(&h->gb, 5);
     s->adaptive_quant = get_bits1(&h->gb);
da3b9756
 
76de302d
     /* unknown fields */
2c541554
     skip_bits1(&h->gb);
da3b9756
 
2c541554
     if (s->unknown_flag)
         skip_bits1(&h->gb);
da3b9756
 
2c541554
     skip_bits1(&h->gb);
     skip_bits(&h->gb, 2);
da3b9756
 
2c541554
     while (get_bits1(&h->gb))
         skip_bits(&h->gb, 8);
da3b9756
 
76de302d
     /* reset intra predictors and invalidate motion vector references */
2c541554
     if (h->mb_x > 0) {
a7d2861d
         memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - 1] + 3,
                -1, 4 * sizeof(int8_t));
2c541554
         memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - h->mb_x],
                -1, 8 * sizeof(int8_t) * h->mb_x);
76de302d
     }
2c541554
     if (h->mb_y > 0) {
         memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - h->mb_stride],
                -1, 8 * sizeof(int8_t) * (h->mb_width - h->mb_x));
76de302d
 
2c541554
         if (h->mb_x > 0)
             h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] = -1;
da3b9756
     }
 
76de302d
     return 0;
da3b9756
 }
 
5ef251e5
 static av_cold int svq3_decode_init(AVCodecContext *avctx)
7f8205da
 {
2c541554
     SVQ3Context *s = avctx->priv_data;
     H264Context *h = &s->h;
f4cca718
     int m;
76de302d
     unsigned char *extradata;
9e1db721
     unsigned char *extradata_end;
76de302d
     unsigned int size;
9e1db721
     int marker_found = 0;
76de302d
 
2c541554
     s->cur_pic  = av_mallocz(sizeof(*s->cur_pic));
     s->last_pic = av_mallocz(sizeof(*s->last_pic));
     s->next_pic = av_mallocz(sizeof(*s->next_pic));
     if (!s->next_pic || !s->last_pic || !s->cur_pic) {
         av_freep(&s->cur_pic);
         av_freep(&s->last_pic);
         av_freep(&s->next_pic);
         return AVERROR(ENOMEM);
     }
 
903d58f6
     if (ff_h264_decode_init(avctx) < 0)
f4cca718
         return -1;
 
2c541554
     h->flags           = avctx->flags;
a7d2861d
     h->is_complex      = 1;
28a613b0
     h->sps.chroma_format_idc = 1;
2c541554
     h->picture_structure = PICT_FRAME;
a7d2861d
     avctx->pix_fmt     = avctx->codec->pix_fmts[0];
76de302d
 
d9ebb00d
     h->chroma_qp[0] = h->chroma_qp[1] = 4;
2c541554
     h->chroma_x_shift = h->chroma_y_shift = 1;
d9ebb00d
 
2c541554
     s->halfpel_flag  = 1;
     s->thirdpel_flag = 1;
     s->unknown_flag  = 0;
d9ebb00d
 
     /* prowl for the "SEQH" marker in the extradata */
     extradata     = (unsigned char *)avctx->extradata;
     extradata_end = avctx->extradata + avctx->extradata_size;
     if (extradata) {
         for (m = 0; m + 8 < avctx->extradata_size; m++) {
             if (!memcmp(extradata, "SEQH", 4)) {
                 marker_found = 1;
                 break;
9e1db721
             }
d9ebb00d
             extradata++;
76de302d
         }
d9ebb00d
     }
8b82a956
 
d9ebb00d
     /* if a match was found, parse the extra data */
     if (marker_found) {
         GetBitContext gb;
         int frame_size_code;
 
         size = AV_RB32(&extradata[4]);
         if (size > extradata_end - extradata - 8)
             return AVERROR_INVALIDDATA;
         init_get_bits(&gb, extradata + 8, size * 8);
 
         /* 'frame size code' and optional 'width, height' */
         frame_size_code = get_bits(&gb, 3);
         switch (frame_size_code) {
         case 0:
             avctx->width  = 160;
             avctx->height = 120;
             break;
         case 1:
             avctx->width  = 128;
             avctx->height =  96;
             break;
         case 2:
             avctx->width  = 176;
             avctx->height = 144;
             break;
         case 3:
             avctx->width  = 352;
             avctx->height = 288;
             break;
         case 4:
             avctx->width  = 704;
             avctx->height = 576;
             break;
         case 5:
             avctx->width  = 240;
             avctx->height = 180;
             break;
         case 6:
             avctx->width  = 320;
             avctx->height = 240;
             break;
         case 7:
             avctx->width  = get_bits(&gb, 12);
             avctx->height = get_bits(&gb, 12);
             break;
         }
8b82a956
 
2c541554
         s->halfpel_flag  = get_bits1(&gb);
         s->thirdpel_flag = get_bits1(&gb);
8b82a956
 
d9ebb00d
         /* unknown fields */
         skip_bits1(&gb);
         skip_bits1(&gb);
         skip_bits1(&gb);
         skip_bits1(&gb);
8b82a956
 
2c541554
         h->low_delay = get_bits1(&gb);
1e002b60
 
d9ebb00d
         /* unknown field */
         skip_bits1(&gb);
76de302d
 
d9ebb00d
         while (get_bits1(&gb))
             skip_bits(&gb, 8);
76de302d
 
2c541554
         s->unknown_flag  = get_bits1(&gb);
         avctx->has_b_frames = !h->low_delay;
         if (s->unknown_flag) {
b250f9c6
 #if CONFIG_ZLIB
d9ebb00d
             unsigned watermark_width  = svq3_get_ue_golomb(&gb);
             unsigned watermark_height = svq3_get_ue_golomb(&gb);
             int u1                    = svq3_get_ue_golomb(&gb);
             int u2                    = get_bits(&gb, 8);
             int u3                    = get_bits(&gb, 2);
             int u4                    = svq3_get_ue_golomb(&gb);
             unsigned long buf_len     = watermark_width *
                                         watermark_height * 4;
             int offset                = get_bits_count(&gb) + 7 >> 3;
             uint8_t *buf;
 
8b7568cc
             if (watermark_height <= 0 || (uint64_t)watermark_width*4 > UINT_MAX/watermark_height)
d9ebb00d
                 return -1;
76de302d
 
d9ebb00d
             buf = av_malloc(buf_len);
             av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n",
                    watermark_width, watermark_height);
             av_log(avctx, AV_LOG_DEBUG,
                    "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n",
                    u1, u2, u3, u4, offset);
             if (uncompress(buf, &buf_len, extradata + 8 + offset,
                            size - offset) != Z_OK) {
a7d2861d
                 av_log(avctx, AV_LOG_ERROR,
d9ebb00d
                        "could not uncompress watermark logo\n");
                 av_free(buf);
76de302d
                 return -1;
             }
2c541554
             s->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0);
             s->watermark_key = s->watermark_key << 16 | s->watermark_key;
d9ebb00d
             av_log(avctx, AV_LOG_DEBUG,
2c541554
                    "watermark key %#x\n", s->watermark_key);
d9ebb00d
             av_free(buf);
 #else
             av_log(avctx, AV_LOG_ERROR,
                    "this svq3 file contains watermark which need zlib support compiled in\n");
             return -1;
 #endif
76de302d
         }
d9ebb00d
     }
cdca7c37
 
2c541554
     h->width  = avctx->width;
     h->height = avctx->height;
     h->mb_width  = (h->width + 15) / 16;
     h->mb_height = (h->height + 15) / 16;
     h->mb_stride = h->mb_width + 1;
     h->mb_num    = h->mb_width * h->mb_height;
     h->b_stride = 4 * h->mb_width;
     s->h_edge_pos = h->mb_width * 16;
     s->v_edge_pos = h->mb_height * 16;
cdca7c37
 
d9ebb00d
     if (ff_h264_alloc_tables(h) < 0) {
         av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");
         return AVERROR(ENOMEM);
da3b9756
     }
76de302d
 
f4cca718
     return 0;
 }
 
2c541554
 static int get_buffer(AVCodecContext *avctx, Picture *pic)
 {
     SVQ3Context *s = avctx->priv_data;
     H264Context *h = &s->h;
     const int big_mb_num    = h->mb_stride * (h->mb_height + 1) + 1;
     const int mb_array_size = h->mb_stride * h->mb_height;
     const int b4_stride     = h->mb_width * 4 + 1;
     const int b4_array_size = b4_stride * h->mb_height * 4;
     int ret;
 
     if (!pic->motion_val_base[0]) {
         int i;
 
         pic->mb_type_base = av_mallocz((big_mb_num + h->mb_stride) * sizeof(uint32_t));
         if (!pic->mb_type_base)
             return AVERROR(ENOMEM);
         pic->f.mb_type = pic->mb_type_base + 2 * h->mb_stride + 1;
 
         for (i = 0; i < 2; i++) {
             pic->motion_val_base[i] = av_mallocz(2 * (b4_array_size + 4) * sizeof(int16_t));
             pic->f.ref_index[i]     = av_mallocz(4 * mb_array_size);
             if (!pic->motion_val_base[i] || !pic->f.ref_index[i])
                 return AVERROR(ENOMEM);
 
             pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
         }
     }
     pic->f.motion_subsample_log2 = 2;
     pic->f.reference = !(h->pict_type == AV_PICTURE_TYPE_B);
 
     ret = ff_get_buffer(avctx, &pic->f);
51513b98
     if (!h->edge_emu_buffer) {
         h->edge_emu_buffer = av_mallocz(pic->f.linesize[0] * 17);
         if (!h->edge_emu_buffer)
             return AVERROR(ENOMEM);
     }
2c541554
 
     h->linesize   = pic->f.linesize[0];
     h->uvlinesize = pic->f.linesize[1];
 
     return ret;
 }
 
a7d2861d
 static int svq3_decode_frame(AVCodecContext *avctx, void *data,
df9b9567
                              int *got_frame, AVPacket *avpkt)
f4cca718
 {
2c541554
     SVQ3Context *s     = avctx->priv_data;
     H264Context *h     = &s->h;
a7d2861d
     int buf_size       = avpkt->size;
b7fe35c9
     int left;
2264c110
     uint8_t *buf;
2c541554
     int ret, m, i;
f4cca718
 
76de302d
     /* special case for last picture */
     if (buf_size == 0) {
2c541554
         if (s->next_pic->f.data[0] && !h->low_delay && !s->last_frame_output) {
             *(AVFrame *) data   = s->next_pic->f;
             s->last_frame_output = 1;
df9b9567
             *got_frame          = 1;
76de302d
         }
         return 0;
da3b9756
     }
8b82a956
 
2c541554
     h->mb_x = h->mb_y = h->mb_xy = 0;
8b82a956
 
b7fe35c9
     if (s->watermark_key) {
         av_fast_malloc(&s->buf, &s->buf_size,
f44967b1
                        buf_size+FF_INPUT_BUFFER_PADDING_SIZE);
b7fe35c9
         if (!s->buf)
2264c110
             return AVERROR(ENOMEM);
b7fe35c9
         memcpy(s->buf, avpkt->data, buf_size);
         buf = s->buf;
2264c110
     } else {
         buf = avpkt->data;
     }
 
b7fe35c9
     init_get_bits(&h->gb, buf, 8 * buf_size);
2264c110
 
8811679c
     if (svq3_decode_slice_header(avctx))
76de302d
         return -1;
8b82a956
 
2c541554
     h->pict_type = h->slice_type;
8b82a956
 
2c541554
     if (h->pict_type != AV_PICTURE_TYPE_B)
         FFSWAP(Picture*, s->next_pic, s->last_pic);
 
     if (s->cur_pic->f.data[0])
         avctx->release_buffer(avctx, &s->cur_pic->f);
8b82a956
 
8ed2ae09
     /* for skipping the frame */
2c541554
     s->cur_pic->f.pict_type = h->pict_type;
     s->cur_pic->f.key_frame = (h->pict_type == AV_PICTURE_TYPE_I);
76de302d
 
2c541554
     ret = get_buffer(avctx, s->cur_pic);
     if (ret < 0)
         return ret;
 
     h->cur_pic_ptr = s->cur_pic;
     h->cur_pic     = *s->cur_pic;
 
     for (i = 0; i < 16; i++) {
         h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
         h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
     }
     for (i = 0; i < 16; i++) {
         h->block_offset[16 + i]      =
         h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
         h->block_offset[48 + 16 + i] =
         h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
     }
 
     if (h->pict_type != AV_PICTURE_TYPE_I) {
         if (!s->last_pic->f.data[0]) {
             av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
             ret = get_buffer(avctx, s->last_pic);
             if (ret < 0)
                 return ret;
             memset(s->last_pic->f.data[0], 0, avctx->height * s->last_pic->f.linesize[0]);
             memset(s->last_pic->f.data[1], 0x80, (avctx->height / 2) *
                    s->last_pic->f.linesize[1]);
             memset(s->last_pic->f.data[2], 0x80, (avctx->height / 2) *
                    s->last_pic->f.linesize[2]);
         }
 
         if (h->pict_type == AV_PICTURE_TYPE_B && !s->next_pic->f.data[0]) {
             av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
             ret = get_buffer(avctx, s->next_pic);
             if (ret < 0)
                 return ret;
             memset(s->next_pic->f.data[0], 0, avctx->height * s->next_pic->f.linesize[0]);
             memset(s->next_pic->f.data[1], 0x80, (avctx->height / 2) *
                    s->next_pic->f.linesize[1]);
             memset(s->next_pic->f.data[2], 0x80, (avctx->height / 2) *
                    s->next_pic->f.linesize[2]);
         }
     }
 
     if (avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(h->avctx, AV_LOG_DEBUG,
                "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n",
                av_get_picture_type_char(h->pict_type),
                s->halfpel_flag, s->thirdpel_flag,
                s->adaptive_quant, h->qscale, h->slice_num);
 
     if (avctx->skip_frame >= AVDISCARD_NONREF && h->pict_type == AV_PICTURE_TYPE_B ||
         avctx->skip_frame >= AVDISCARD_NONKEY && h->pict_type != AV_PICTURE_TYPE_I ||
af1ede06
         avctx->skip_frame >= AVDISCARD_ALL)
76de302d
         return 0;
 
     if (s->next_p_frame_damaged) {
2c541554
         if (h->pict_type == AV_PICTURE_TYPE_B)
76de302d
             return 0;
         else
             s->next_p_frame_damaged = 0;
     }
da3b9756
 
2c541554
     if (h->pict_type == AV_PICTURE_TYPE_B) {
af1ede06
         h->frame_num_offset = h->slice_num - h->prev_frame_num;
8b82a956
 
a7d2861d
         if (h->frame_num_offset < 0)
76de302d
             h->frame_num_offset += 256;
a7d2861d
         if (h->frame_num_offset == 0 ||
             h->frame_num_offset >= h->prev_frame_num_offset) {
2c541554
             av_log(h->avctx, AV_LOG_ERROR, "error in B-frame picture id\n");
76de302d
             return -1;
         }
     } else {
a7d2861d
         h->prev_frame_num        = h->frame_num;
         h->frame_num             = h->slice_num;
af1ede06
         h->prev_frame_num_offset = h->frame_num - h->prev_frame_num;
da3b9756
 
a7d2861d
         if (h->prev_frame_num_offset < 0)
76de302d
             h->prev_frame_num_offset += 256;
da3b9756
     }
 
a7d2861d
     for (m = 0; m < 2; m++) {
76de302d
         int i;
a7d2861d
         for (i = 0; i < 4; i++) {
76de302d
             int j;
             for (j = -1; j < 4; j++)
a7d2861d
                 h->ref_cache[m][scan8[0] + 8 * i + j] = 1;
76de302d
             if (i < 3)
a7d2861d
                 h->ref_cache[m][scan8[0] + 8 * i + j] = PART_NOT_AVAILABLE;
76de302d
         }
da3b9756
     }
 
2c541554
     for (h->mb_y = 0; h->mb_y < h->mb_height; h->mb_y++) {
         for (h->mb_x = 0; h->mb_x < h->mb_width; h->mb_x++) {
9a2e7911
             unsigned mb_type;
2c541554
             h->mb_xy = h->mb_x + h->mb_y * h->mb_stride;
da3b9756
 
2c541554
             if ((get_bits_count(&h->gb) + 7) >= h->gb.size_in_bits &&
                 ((get_bits_count(&h->gb) & 7) == 0 ||
                  show_bits(&h->gb, -get_bits_count(&h->gb) & 7) == 0)) {
                 skip_bits(&h->gb, s->next_slice_index - get_bits_count(&h->gb));
                 h->gb.size_in_bits = 8 * buf_size;
da3b9756
 
8811679c
                 if (svq3_decode_slice_header(avctx))
76de302d
                     return -1;
da3b9756
 
76de302d
                 /* TODO: support s->mb_skip_run */
             }
da3b9756
 
2c541554
             mb_type = svq3_get_ue_golomb(&h->gb);
da3b9756
 
2c541554
             if (h->pict_type == AV_PICTURE_TYPE_I)
76de302d
                 mb_type += 8;
2c541554
             else if (h->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4)
76de302d
                 mb_type += 4;
2c541554
             if (mb_type > 33 || svq3_decode_mb(s, mb_type)) {
                 av_log(h->avctx, AV_LOG_ERROR,
                        "error while decoding MB %d %d\n", h->mb_x, h->mb_y);
76de302d
                 return -1;
             }
8b82a956
 
a1f1ca96
             if (mb_type != 0 || h->cbp)
a7d2861d
                 ff_h264_hl_decode_mb(h);
8b82a956
 
2c541554
             if (h->pict_type != AV_PICTURE_TYPE_B && !h->low_delay)
                 h->cur_pic.f.mb_type[h->mb_x + h->mb_y * h->mb_stride] =
                     (h->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
76de302d
         }
2e26c8d2
 
51513b98
         ff_draw_horiz_band(avctx, NULL, s->cur_pic, s->last_pic->f.data[0] ? s->last_pic : NULL,
                            16 * h->mb_y, 16, h->picture_structure, 0, 0,
2c541554
                            h->low_delay, h->mb_height * 16, h->mb_width * 16);
8b82a956
     }
4c701ac8
 
b7fe35c9
     left = buf_size*8 - get_bits_count(&h->gb);
b0e7a932
 
b7fe35c9
     if (h->mb_y != h->mb_height || h->mb_x != h->mb_width) {
         av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, h->mb_y, h->mb_x, left);
b0e7a932
         //av_hex_dump(stderr, buf+buf_size-8, 8);
     }
 
     if (left < 0) {
         av_log(avctx, AV_LOG_ERROR, "frame num %d left %d\n", avctx->frame_number, left);
         return -1;
     }
 
2c541554
     if (h->pict_type == AV_PICTURE_TYPE_B || h->low_delay)
         *(AVFrame *)data = s->cur_pic->f;
a7d2861d
     else
2c541554
         *(AVFrame *)data = s->last_pic->f;
da3b9756
 
76de302d
     /* Do not output the last pic after seeking. */
2c541554
     if (s->last_pic->f.data[0] || h->low_delay)
df9b9567
         *got_frame = 1;
da3b9756
 
2c541554
     if (h->pict_type != AV_PICTURE_TYPE_B) {
         FFSWAP(Picture*, s->cur_pic, s->next_pic);
     }
 
76de302d
     return buf_size;
8b82a956
 }
 
2c541554
 static void free_picture(AVCodecContext *avctx, Picture *pic)
 {
     int i;
     for (i = 0; i < 2; i++) {
         av_freep(&pic->motion_val_base[i]);
         av_freep(&pic->f.ref_index[i]);
     }
     av_freep(&pic->mb_type_base);
 
     if (pic->f.data[0])
         avctx->release_buffer(avctx, &pic->f);
     av_freep(&pic);
 }
 
8811679c
 static int svq3_decode_end(AVCodecContext *avctx)
 {
2c541554
     SVQ3Context *s = avctx->priv_data;
     H264Context *h = &s->h;
8811679c
 
2c541554
     free_picture(avctx, s->cur_pic);
     free_picture(avctx, s->next_pic);
     free_picture(avctx, s->last_pic);
8811679c
 
2c541554
     ff_h264_free_context(h);
8811679c
 
b7fe35c9
     av_freep(&s->buf);
     s->buf_size = 0;
51513b98
     av_freep(&h->edge_emu_buffer);
2264c110
 
8811679c
     return 0;
 }
8b82a956
 
e7e2df27
 AVCodec ff_svq3_decoder = {
ec6402b7
     .name           = "svq3",
     .type           = AVMEDIA_TYPE_VIDEO,
36ef5369
     .id             = AV_CODEC_ID_SVQ3,
ec6402b7
     .priv_data_size = sizeof(SVQ3Context),
     .init           = svq3_decode_init,
     .close          = svq3_decode_end,
     .decode         = svq3_decode_frame,
a7d2861d
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND |
                       CODEC_CAP_DR1             |
00c3b67b
                       CODEC_CAP_DELAY,
     .long_name      = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"),
a7d2861d
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P,
                                                      AV_PIX_FMT_NONE},
8b82a956
 };