dv.c 11.2 KB
Newer Older
1 2
/*
 * DV decoder
3 4
 * Copyright (c) 2002 Fabrice Bellard
 * Copyright (c) 2004 Roman Shaposhnik
5
 *
6
 * DV encoder
7
 * Copyright (c) 2003 Roman Shaposhnik
8
 *
Daniel Maas's avatar
Daniel Maas committed
9 10 11
 * 50 Mbps (DVCPRO50) support
 * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
 *
12 13 14 15
 * 100 Mbps (DVCPRO HD) support
 * Initial code by Daniel Maas <dmaas@maasdigital.com> (funded by BBC R&D)
 * Final code by Roman Shaposhnik
 *
16 17 18
 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
 * of DV technical info.
 *
19 20 21
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
22 23
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
24
 * version 2.1 of the License, or (at your option) any later version.
25
 *
26
 * FFmpeg is distributed in the hope that it will be useful,
27 28 29 30 31
 * 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
32
 * License along with FFmpeg; if not, write to the Free Software
33
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
34
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
35 36

/**
37
 * @file
38
 * DV codec.
Michael Niedermayer's avatar
Michael Niedermayer committed
39
 */
40

41
#include "libavutil/internal.h"
42
#include "libavutil/pixdesc.h"
43
#include "avcodec.h"
44
#include "get_bits.h"
45
#include "internal.h"
46
#include "put_bits.h"
47
#include "simple_idct.h"
48
#include "dvdata.h"
49
#include "dv.h"
50 51

/* XXX: also include quantization */
52
RL_VLC_ELEM ff_dv_rl_vlc[1184];
53

54 55 56
static inline void dv_calc_mb_coordinates(const DVprofile *d, int chan, int seq, int slot,
                                          uint16_t *tbl)
{
57 58 59 60
    static const uint8_t off[] = { 2, 6, 8, 0, 4 };
    static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 };
    static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 };
    static const uint8_t shuf3[] = { 18, 9, 27, 0, 36 };
61

62 63
    static const uint8_t l_start[] = {0, 4, 9, 13, 18, 22, 27, 31, 36, 40};
    static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 };
64

65
    static const uint8_t serpent1[] = {0, 1, 2, 2, 1, 0,
66 67 68 69
                                       0, 1, 2, 2, 1, 0,
                                       0, 1, 2, 2, 1, 0,
                                       0, 1, 2, 2, 1, 0,
                                       0, 1, 2};
70
    static const uint8_t serpent2[] = {0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
71 72 73
                                       0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
                                       0, 1, 2, 3, 4, 5};

74
    static const uint8_t remap[][2] = {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, /* dummy */
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
                                       { 0, 0}, { 0, 1}, { 0, 2}, { 0, 3}, {10, 0},
                                       {10, 1}, {10, 2}, {10, 3}, {20, 0}, {20, 1},
                                       {20, 2}, {20, 3}, {30, 0}, {30, 1}, {30, 2},
                                       {30, 3}, {40, 0}, {40, 1}, {40, 2}, {40, 3},
                                       {50, 0}, {50, 1}, {50, 2}, {50, 3}, {60, 0},
                                       {60, 1}, {60, 2}, {60, 3}, {70, 0}, {70, 1},
                                       {70, 2}, {70, 3}, { 0,64}, { 0,65}, { 0,66},
                                       {10,64}, {10,65}, {10,66}, {20,64}, {20,65},
                                       {20,66}, {30,64}, {30,65}, {30,66}, {40,64},
                                       {40,65}, {40,66}, {50,64}, {50,65}, {50,66},
                                       {60,64}, {60,65}, {60,66}, {70,64}, {70,65},
                                       {70,66}, { 0,67}, {20,67}, {40,67}, {60,67}};

    int i, k, m;
    int x, y, blk;

    for (m=0; m<5; m++) {
         switch (d->width) {
         case 1440:
              blk = (chan*11+seq)*27+slot;

              if (chan == 0 && seq == 11) {
                  x = m*27+slot;
                  if (x<90) {
                      y = 0;
                  } else {
                      x = (x - 90)*2;
                      y = 67;
                  }
              } else {
                  i = (4*chan + blk + off[m])%11;
                  k = (blk/11)%27;

                  x = shuf1[m] + (chan&1)*9 + k%9;
                  y = (i*3+k/9)*2 + (chan>>1) + 1;
              }
              tbl[m] = (x<<1)|(y<<9);
              break;
         case 1280:
              blk = (chan*10+seq)*27+slot;

              i = (4*chan + (seq/5) + 2*blk + off[m])%10;
              k = (blk/5)%27;

              x = shuf1[m]+(chan&1)*9 + k%9;
              y = (i*3+k/9)*2 + (chan>>1) + 4;

              if (x >= 80) {
                  x = remap[y][0]+((x-80)<<(y>59));
                  y = remap[y][1];
              }
              tbl[m] = (x<<1)|(y<<9);
              break;
       case 960:
              blk = (chan*10+seq)*27+slot;

              i = (4*chan + (seq/5) + 2*blk + off[m])%10;
              k = (blk/5)%27 + (i&1)*3;

              x = shuf2[m] + k%6 + 6*(chan&1);
              y = l_start[i] + k/6 + 45*(chan>>1);
              tbl[m] = (x<<1)|(y<<9);
              break;
        case 720:
              switch (d->pix_fmt) {
140
              case AV_PIX_FMT_YUV422P:
141 142 143 144 145
                   x = shuf3[m] + slot/3;
                   y = serpent1[slot] +
                       ((((seq + off[m]) % d->difseg_size)<<1) + chan)*3;
                   tbl[m] = (x<<1)|(y<<8);
                   break;
146
              case AV_PIX_FMT_YUV420P:
147 148 149 150 151
                   x = shuf3[m] + slot/3;
                   y = serpent1[slot] +
                       ((seq + off[m]) % d->difseg_size)*3;
                   tbl[m] = (x<<1)|(y<<9);
                   break;
152
              case AV_PIX_FMT_YUV411P:
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
                   i = (seq + off[m]) % d->difseg_size;
                   k = slot + ((m==1||m==2)?3:0);

                   x = l_start_shuffled[m] + k/6;
                   y = serpent2[k] + i*6;
                   if (x>21)
                       y = y*2 - i*6;
                   tbl[m] = (x<<2)|(y<<8);
                   break;
              }
        default:
              break;
        }
    }
}

169 170 171 172 173 174 175 176 177
/* quantization quanta by QNO for DV100 */
static const uint8_t dv100_qstep[16] = {
    1, /* QNO = 0 and 1 both have no quantization */
    1,
    2, 3, 4, 5, 6, 7, 8, 16, 18, 20, 22, 24, 28, 52
};

static const uint8_t dv_quant_areas[4]  = { 6, 21, 43, 64 };

178
int ff_dv_init_dynamic_tables(const DVprofile *d)
179
{
180
    int j,i,c,s,p;
181 182
    uint32_t *factor1, *factor2;
    const int *iweight1, *iweight2;
183

Roman Shaposhnik's avatar
Roman Shaposhnik committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197
    if (!d->work_chunks[dv_work_pool_size(d)-1].buf_offset) {
        p = i = 0;
        for (c=0; c<d->n_difchan; c++) {
            for (s=0; s<d->difseg_size; s++) {
                p += 6;
                for (j=0; j<27; j++) {
                    p += !(j%3);
                    if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
                        !(DV_PROFILE_IS_720p50(d) && s > 9)) {
                          dv_calc_mb_coordinates(d, c, s, j, &d->work_chunks[i].mb_coordinates[0]);
                          d->work_chunks[i++].buf_offset = p;
                    }
                    p += 5;
                }
198 199 200 201
            }
        }
    }

202 203 204 205
    if (!d->idct_factor[DV_PROFILE_IS_HD(d)?8191:5631]) {
        factor1 = &d->idct_factor[0];
        factor2 = &d->idct_factor[DV_PROFILE_IS_HD(d)?4096:2816];
        if (d->height == 720) {
206 207
            iweight1 = &ff_dv_iweight_720_y[0];
            iweight2 = &ff_dv_iweight_720_c[0];
208
        } else {
209 210
            iweight1 = &ff_dv_iweight_1080_y[0];
            iweight2 = &ff_dv_iweight_1080_c[0];
Reimar Döffinger's avatar
Reimar Döffinger committed
211
        }
212 213 214 215 216 217 218 219
        if (DV_PROFILE_IS_HD(d)) {
            for (c = 0; c < 4; c++) {
                for (s = 0; s < 16; s++) {
                    for (i = 0; i < 64; i++) {
                        *factor1++ = (dv100_qstep[s] << (c + 9)) * iweight1[i];
                        *factor2++ = (dv100_qstep[s] << (c + 9)) * iweight2[i];
                    }
                }
220
            }
221
        } else {
222 223
            iweight1 = &ff_dv_iweight_88[0];
            for (j = 0; j < 2; j++, iweight1 = &ff_dv_iweight_248[0]) {
224 225 226
                for (s = 0; s < 22; s++) {
                    for (i = c = 0; c < 4; c++) {
                        for (; i < dv_quant_areas[c]; i++) {
227
                            *factor1   = iweight1[i] << (ff_dv_quant_shifts[s][c] + 1);
228
                            *factor2++ = (*factor1++) << 1;
Reimar Döffinger's avatar
Reimar Döffinger committed
229 230 231
                        }
                    }
                }
232 233 234
            }
        }
    }
235

236 237 238
    return 0;
}

239
av_cold int ff_dvvideo_init(AVCodecContext *avctx)
240
{
241
    DVVideoContext *s = avctx->priv_data;
242
    DSPContext dsp;
Diego Biurrun's avatar
Diego Biurrun committed
243
    static int done = 0;
244
    int i, j;
245 246

    if (!done) {
247
        VLC dv_vlc;
248
        uint16_t new_dv_vlc_bits[NB_DV_VLC*2];
Diego Biurrun's avatar
Diego Biurrun committed
249 250 251
        uint8_t  new_dv_vlc_len[NB_DV_VLC*2];
        uint8_t  new_dv_vlc_run[NB_DV_VLC*2];
        int16_t  new_dv_vlc_level[NB_DV_VLC*2];
252 253 254

        done = 1;

255
        /* it's faster to include sign bit in a generic VLC parsing scheme */
Diego Biurrun's avatar
Diego Biurrun committed
256
        for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
257 258 259 260
            new_dv_vlc_bits[j]  = ff_dv_vlc_bits[i];
            new_dv_vlc_len[j]   = ff_dv_vlc_len[i];
            new_dv_vlc_run[j]   = ff_dv_vlc_run[i];
            new_dv_vlc_level[j] = ff_dv_vlc_level[i];
261

262
            if (ff_dv_vlc_level[i]) {
263 264 265 266
                new_dv_vlc_bits[j] <<= 1;
                new_dv_vlc_len[j]++;

                j++;
267 268 269 270
                new_dv_vlc_bits[j]  = (ff_dv_vlc_bits[i] << 1) | 1;
                new_dv_vlc_len[j]   =  ff_dv_vlc_len[i] + 1;
                new_dv_vlc_run[j]   =  ff_dv_vlc_run[i];
                new_dv_vlc_level[j] = -ff_dv_vlc_level[i];
271 272
            }
        }
273

274 275
        /* NOTE: as a trick, we use the fact the no codes are unused
           to accelerate the parsing of partial codes */
276
        init_vlc(&dv_vlc, TEX_VLC_BITS, j,
277
                 new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0);
Michael Niedermayer's avatar
Michael Niedermayer committed
278
        av_assert1(dv_vlc.table_size == 1184);
279

Diego Biurrun's avatar
Diego Biurrun committed
280 281 282
        for (i = 0; i < dv_vlc.table_size; i++){
            int code = dv_vlc.table[i][0];
            int len  = dv_vlc.table[i][1];
283
            int level, run;
284

Diego Biurrun's avatar
Diego Biurrun committed
285 286 287
            if (len < 0){ //more bits needed
                run   = 0;
                level = code;
288
            } else {
Diego Biurrun's avatar
Diego Biurrun committed
289 290
                run   = new_dv_vlc_run  [code] + 1;
                level = new_dv_vlc_level[code];
291
            }
292 293 294
            ff_dv_rl_vlc[i].len   = len;
            ff_dv_rl_vlc[i].level = level;
            ff_dv_rl_vlc[i].run   = run;
295
        }
296
        ff_free_vlc(&dv_vlc);
297
    }
298

299
    /* Generic DSP setup */
300
    memset(&dsp,0, sizeof(dsp));
301
    ff_dsputil_init(&dsp, avctx);
302
    ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp);
303
    s->get_pixels = dsp.get_pixels;
304
    s->ildct_cmp = dsp.ildct_cmp[5];
305

306
    /* 88DCT setup */
Diego Biurrun's avatar
Diego Biurrun committed
307
    s->fdct[0]     = dsp.fdct;
308
    s->idct_put[0] = dsp.idct_put;
Diego Biurrun's avatar
Diego Biurrun committed
309
    for (i = 0; i < 64; i++)
310
       s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]];
311

312
    /* 248DCT setup */
Diego Biurrun's avatar
Diego Biurrun committed
313
    s->fdct[1]     = dsp.fdct248;
314
    s->idct_put[1] = ff_simple_idct248_put;  // FIXME: need to add it to DSP
Michael Niedermayer's avatar
Michael Niedermayer committed
315 316 317 318 319 320 321
    if (avctx->lowres){
        for (i = 0; i < 64; i++){
            int j = ff_zigzag248_direct[i];
            s->dv_zigzag[1][i] = dsp.idct_permutation[(j & 7) + (j & 8) * 4 + (j & 48) / 2];
        }
    }else
        memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);
322

Diego Biurrun's avatar
Diego Biurrun committed
323
    s->avctx = avctx;
324
    avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
325

326 327 328
    return 0;
}