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

/**
 * @file dv.c
34
 * DV codec.
Michael Niedermayer's avatar
Michael Niedermayer committed
35
 */
36
#define ALT_BITSTREAM_READER
37 38
#include "avcodec.h"
#include "dsputil.h"
39
#include "bitstream.h"
40
#include "simple_idct.h"
41
#include "dvdata.h"
42

Michael Niedermayer's avatar
Michael Niedermayer committed
43 44 45
//#undef NDEBUG
//#include <assert.h>

46
typedef struct DVVideoContext {
47
    const DVprofile* sys;
48
    AVFrame picture;
Michael Niedermayer's avatar
Michael Niedermayer committed
49
    AVCodecContext *avctx;
50
    uint8_t *buf;
51

52
    uint8_t dv_zigzag[2][64];
53
    uint8_t dv_idct_shift[2][2][22][64];
54

55
    void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size);
56
    void (*fdct[2])(DCTELEM *block);
57
    void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block);
58
} DVVideoContext;
59

Daniel Maas's avatar
Daniel Maas committed
60 61 62 63 64 65
/* MultiThreading - dv_anchor applies to entire DV codec, not just the avcontext */
/* one element is needed for each video segment in a DV frame */
/* at most there are 2 DIF channels * 12 DIF sequences * 27 video segments (PAL 50Mbps) */
#define DV_ANCHOR_SIZE (2*12*27)

static void* dv_anchor[DV_ANCHOR_SIZE];
66

67
#define TEX_VLC_BITS 9
68 69 70 71 72

#ifdef DV_CODEC_TINY_TARGET
#define DV_VLC_MAP_RUN_SIZE 15
#define DV_VLC_MAP_LEV_SIZE 23
#else
73
#define DV_VLC_MAP_RUN_SIZE  64
Michael Niedermayer's avatar
Michael Niedermayer committed
74
#define DV_VLC_MAP_LEV_SIZE 512 //FIXME sign was removed so this should be /2 but needs check
75 76
#endif

77
/* XXX: also include quantization */
78
static RL_VLC_ELEM dv_rl_vlc[1184];
79 80 81 82
/* VLC encoding lookup table */
static struct dv_vlc_pair {
   uint32_t vlc;
   uint8_t  size;
83
} dv_vlc_map[DV_VLC_MAP_RUN_SIZE][DV_VLC_MAP_LEV_SIZE];
84

85
static void dv_build_unquantize_tables(DVVideoContext *s, uint8_t* perm)
86
{
87
    int i, q, j;
88 89

    /* NOTE: max left shift is 6 */
90
    for(q = 0; q < 22; q++) {
91
        /* 88DCT */
92 93
        for(i = 1; i < 64; i++) {
            /* 88 table */
94
            j = perm[i];
95
            s->dv_idct_shift[0][0][q][j] =
96
                dv_quant_shifts[q][dv_88_areas[i]] + 1;
97
            s->dv_idct_shift[1][0][q][j] = s->dv_idct_shift[0][0][q][j] + 1;
98
        }
99

100
        /* 248DCT */
101 102
        for(i = 1; i < 64; i++) {
            /* 248 table */
103
            s->dv_idct_shift[0][1][q][i] =
104
                dv_quant_shifts[q][dv_248_areas[i]] + 1;
105
            s->dv_idct_shift[1][1][q][i] = s->dv_idct_shift[0][1][q][i] + 1;
106 107 108 109
        }
    }
}

110
static av_cold int dvvideo_init(AVCodecContext *avctx)
111
{
112
    DVVideoContext *s = avctx->priv_data;
113
    DSPContext dsp;
114
    static int done=0;
115
    int i, j;
116 117

    if (!done) {
118
        VLC dv_vlc;
119 120 121 122
        uint16_t new_dv_vlc_bits[NB_DV_VLC*2];
        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];
123 124 125

        done = 1;

126
        /* dv_anchor lets each thread know its Id */
Daniel Maas's avatar
Daniel Maas committed
127
        for (i=0; i<DV_ANCHOR_SIZE; i++)
128
            dv_anchor[i] = (void*)(size_t)i;
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147

        /* it's faster to include sign bit in a generic VLC parsing scheme */
        for (i=0, j=0; i<NB_DV_VLC; i++, j++) {
            new_dv_vlc_bits[j] = dv_vlc_bits[i];
            new_dv_vlc_len[j] = dv_vlc_len[i];
            new_dv_vlc_run[j] = dv_vlc_run[i];
            new_dv_vlc_level[j] = dv_vlc_level[i];

            if (dv_vlc_level[i]) {
                new_dv_vlc_bits[j] <<= 1;
                new_dv_vlc_len[j]++;

                j++;
                new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1;
                new_dv_vlc_len[j] = dv_vlc_len[i] + 1;
                new_dv_vlc_run[j] = dv_vlc_run[i];
                new_dv_vlc_level[j] = -dv_vlc_level[i];
            }
        }
148

149 150
        /* NOTE: as a trick, we use the fact the no codes are unused
           to accelerate the parsing of partial codes */
151
        init_vlc(&dv_vlc, TEX_VLC_BITS, j,
152
                 new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0);
153
        assert(dv_vlc.table_size == 1184);
154

155 156 157 158
        for(i = 0; i < dv_vlc.table_size; i++){
            int code= dv_vlc.table[i][0];
            int len = dv_vlc.table[i][1];
            int level, run;
159

160 161 162 163
            if(len<0){ //more bits needed
                run= 0;
                level= code;
            } else {
164 165
                run=   new_dv_vlc_run[code] + 1;
                level= new_dv_vlc_level[code];
166
            }
167 168 169
            dv_rl_vlc[i].len = len;
            dv_rl_vlc[i].level = level;
            dv_rl_vlc[i].run = run;
170
        }
171
        free_vlc(&dv_vlc);
172

173
        for (i = 0; i < NB_DV_VLC - 1; i++) {
174
           if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)
175
               continue;
176 177
#ifdef DV_CODEC_TINY_TARGET
           if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)
178
               continue;
179
#endif
180

181 182
           if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0)
               continue;
183

184 185 186 187 188 189
           dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc = dv_vlc_bits[i] <<
                                                            (!!dv_vlc_level[i]);
           dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size = dv_vlc_len[i] +
                                                             (!!dv_vlc_level[i]);
        }
        for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) {
190
#ifdef DV_CODEC_TINY_TARGET
191 192 193 194 195 196 197 198
           for (j = 1; j < DV_VLC_MAP_LEV_SIZE; j++) {
              if (dv_vlc_map[i][j].size == 0) {
                  dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc |
                            (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size));
                  dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size +
                                          dv_vlc_map[0][j].size;
              }
           }
199
#else
200 201 202 203 204 205 206 207 208 209 210 211
           for (j = 1; j < DV_VLC_MAP_LEV_SIZE/2; j++) {
              if (dv_vlc_map[i][j].size == 0) {
                  dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc |
                            (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size));
                  dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size +
                                          dv_vlc_map[0][j].size;
              }
              dv_vlc_map[i][((uint16_t)(-j))&0x1ff].vlc =
                                            dv_vlc_map[i][j].vlc | 1;
              dv_vlc_map[i][((uint16_t)(-j))&0x1ff].size =
                                            dv_vlc_map[i][j].size;
           }
212
#endif
213
        }
214
    }
215

216 217 218
    /* Generic DSP setup */
    dsputil_init(&dsp, avctx);
    s->get_pixels = dsp.get_pixels;
219

220 221 222 223 224
    /* 88DCT setup */
    s->fdct[0] = dsp.fdct;
    s->idct_put[0] = dsp.idct_put;
    for (i=0; i<64; i++)
       s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]];
225

226 227
    /* 248DCT setup */
    s->fdct[1] = dsp.fdct248;
228
    s->idct_put[1] = ff_simple_idct248_put;  // FIXME: need to add it to DSP
Michael Niedermayer's avatar
Michael Niedermayer committed
229 230 231 232 233 234 235
    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);
236

237
    /* XXX: do it only for constant case */
238
    dv_build_unquantize_tables(s, dsp.idct_permutation);
239

240
    avctx->coded_frame = &s->picture;
Michael Niedermayer's avatar
Michael Niedermayer committed
241
    s->avctx= avctx;
242

243 244 245
    return 0;
}

246
// #define VLC_DEBUG
247
// #define printf(...) av_log(NULL, AV_LOG_ERROR, __VA_ARGS__)
248

249
typedef struct BlockInfo {
250 251
    const uint8_t *shift_table;
    const uint8_t *scan_table;
252
    const int *iweight_table;
253 254 255 256
    uint8_t pos; /* position in block */
    uint8_t dct_mode;
    uint8_t partial_bit_count;
    uint16_t partial_bit_buffer;
257 258
    int shift_offset;
} BlockInfo;
259 260

/* block size in bits */
261
static const uint16_t block_sizes[6] = {
262 263
    112, 112, 112, 112, 80, 80
};
264 265 266
/* bit budget for AC only in 5 MBs */
static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
/* see dv_88_areas and dv_248_areas for details */
267
static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
268

269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
static inline int get_bits_left(GetBitContext *s)
{
    return s->size_in_bits - get_bits_count(s);
}

static inline int get_bits_size(GetBitContext *s)
{
    return s->size_in_bits;
}

static inline int put_bits_left(PutBitContext* s)
{
    return (s->buf_end - s->buf) * 8 - put_bits_count(s);
}

284
/* decode ac coefs */
285
static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
286
{
287
    int last_index = get_bits_size(gb);
288 289
    const uint8_t *scan_table = mb->scan_table;
    const uint8_t *shift_table = mb->shift_table;
290
    const int *iweight_table = mb->iweight_table;
291
    int pos = mb->pos;
292 293
    int partial_bit_count = mb->partial_bit_count;
    int level, pos1, run, vlc_len, index;
294

295
    OPEN_READER(re, gb);
296
    UPDATE_CACHE(re, gb);
297

298 299
    /* if we must parse a partial vlc, we do it here */
    if (partial_bit_count > 0) {
300
        re_cache = ((unsigned)re_cache >> partial_bit_count) |
301 302 303
                   (mb->partial_bit_buffer << (sizeof(re_cache)*8 - partial_bit_count));
        re_index -= partial_bit_count;
        mb->partial_bit_count = 0;
304 305 306 307 308
    }

    /* get the AC coefficients until last_index is reached */
    for(;;) {
#ifdef VLC_DEBUG
309
        printf("%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16), re_index);
310
#endif
311 312
        /* our own optimized GET_RL_VLC */
        index = NEG_USR32(re_cache, TEX_VLC_BITS);
313
        vlc_len = dv_rl_vlc[index].len;
314 315 316 317 318
        if (vlc_len < 0) {
            index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level;
            vlc_len = TEX_VLC_BITS - vlc_len;
        }
        level = dv_rl_vlc[index].level;
319 320 321 322 323 324 325 326 327 328 329
        run = dv_rl_vlc[index].run;

        /* gotta check if we're still within gb boundaries */
        if (re_index + vlc_len > last_index) {
            /* should be < 16 bits otherwise a codeword could have been parsed */
            mb->partial_bit_count = last_index - re_index;
            mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count);
            re_index = last_index;
            break;
        }
        re_index += vlc_len;
330 331

#ifdef VLC_DEBUG
332
        printf("run=%d level=%d\n", run, level);
333
#endif
334 335 336
        pos += run;
        if (pos >= 64)
            break;
337

Michael Niedermayer's avatar
Michael Niedermayer committed
338
        pos1 = scan_table[pos];
339 340 341 342 343 344
        level <<= shift_table[pos1];

        /* unweigh, round, and shift down */
        level = (level*iweight_table[pos] + (1 << (dv_iweight_bits-1))) >> dv_iweight_bits;

        block[pos1] = level;
345 346

        UPDATE_CACHE(re, gb);
347
    }
348
    CLOSE_READER(re, gb);
349
    mb->pos = pos;
350 351
}

352
static inline void bit_copy(PutBitContext *pb, GetBitContext *gb)
353
{
354
    int bits_left = get_bits_left(gb);
Michael Niedermayer's avatar
Michael Niedermayer committed
355 356 357
    while (bits_left >= MIN_CACHE_BITS) {
        put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS));
        bits_left -= MIN_CACHE_BITS;
358 359 360 361 362 363 364
    }
    if (bits_left > 0) {
        put_bits(pb, bits_left, get_bits(gb, bits_left));
    }
}

/* mb_x and mb_y are in units of 8 pixels */
365
static inline void dv_decode_video_segment(DVVideoContext *s,
Michael Niedermayer's avatar
Michael Niedermayer committed
366
                                           const uint8_t *buf_ptr1,
367
                                           const uint16_t *mb_pos_ptr)
368 369 370 371
{
    int quant, dc, dct_mode, class1, j;
    int mb_index, mb_x, mb_y, v, last_index;
    DCTELEM *block, *block1;
372
    int c_offset;
373 374
    uint8_t *y_ptr;
    void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
Michael Niedermayer's avatar
Michael Niedermayer committed
375
    const uint8_t *buf_ptr;
376
    PutBitContext pb, vs_pb;
377 378
    GetBitContext gb;
    BlockInfo mb_data[5 * 6], *mb, *mb1;
379
    DECLARE_ALIGNED_16(DCTELEM, sblock[5*6][64]);
380 381
    DECLARE_ALIGNED_8(uint8_t, mb_bit_buffer[80 + 4]); /* allow some slack */
    DECLARE_ALIGNED_8(uint8_t, vs_bit_buffer[5 * 80 + 4]); /* allow some slack */
Michael Niedermayer's avatar
Michael Niedermayer committed
382
    const int log2_blocksize= 3-s->avctx->lowres;
383

Michael Niedermayer's avatar
Michael Niedermayer committed
384 385
    assert((((int)mb_bit_buffer)&7)==0);
    assert((((int)vs_bit_buffer)&7)==0);
386

387
    memset(sblock, 0, sizeof(sblock));
388 389 390

    /* pass 1 : read DC and AC coefficients in blocks */
    buf_ptr = buf_ptr1;
391
    block1 = &sblock[0][0];
392
    mb1 = mb_data;
393
    init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80);
394
    for(mb_index = 0; mb_index < 5; mb_index++, mb1 += 6, block1 += 6 * 64) {
395 396 397
        /* skip header */
        quant = buf_ptr[3] & 0x0f;
        buf_ptr += 4;
398
        init_put_bits(&pb, mb_bit_buffer, 80);
399
        mb = mb1;
400 401
        block = block1;
        for(j = 0;j < 6; j++) {
402
            last_index = block_sizes[j];
403
            init_get_bits(&gb, buf_ptr, last_index);
404

405
            /* get the dc */
406
            dc = get_sbits(&gb, 9);
407
            dct_mode = get_bits1(&gb);
408 409
            mb->dct_mode = dct_mode;
            mb->scan_table = s->dv_zigzag[dct_mode];
410
            mb->iweight_table = dct_mode ? dv_iweight_248 : dv_iweight_88;
411
            class1 = get_bits(&gb, 2);
412
            mb->shift_table = s->dv_idct_shift[class1 == 3][dct_mode]
413 414 415 416 417 418 419
                [quant + dv_quant_offset[class1]];
            dc = dc << 2;
            /* convert to unsigned because 128 is not added in the
               standard IDCT */
            dc += 1024;
            block[0] = dc;
            buf_ptr += last_index >> 3;
420 421
            mb->pos = 0;
            mb->partial_bit_count = 0;
422

423 424 425
#ifdef VLC_DEBUG
            printf("MB block: %d, %d ", mb_index, j);
#endif
426
            dv_decode_ac(&gb, mb, block);
427 428 429

            /* write the remaining bits  in a new buffer only if the
               block is finished */
430
            if (mb->pos >= 64)
431
                bit_copy(&pb, &gb);
432

433
            block += 64;
434
            mb++;
435
        }
436

437 438
        /* pass 2 : we can do it just after */
#ifdef VLC_DEBUG
439
        printf("***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index);
440 441
#endif
        block = block1;
442
        mb = mb1;
443
        init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb));
444
        flush_put_bits(&pb);
445
        for(j = 0;j < 6; j++, block += 64, mb++) {
446 447
            if (mb->pos < 64 && get_bits_left(&gb) > 0) {
                dv_decode_ac(&gb, mb, block);
448
                /* if still not finished, no need to parse other blocks */
449 450
                if (mb->pos < 64)
                    break;
451 452 453 454
            }
        }
        /* all blocks are finished, so the extra bytes can be used at
           the video segment level */
455
        if (j >= 6)
456
            bit_copy(&vs_pb, &gb);
457 458 459 460
    }

    /* we need a pass other the whole video segment */
#ifdef VLC_DEBUG
461
    printf("***pass 3 size=%d\n", put_bits_count(&vs_pb));
462
#endif
463
    block = &sblock[0][0];
464
    mb = mb_data;
465
    init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb));
466
    flush_put_bits(&vs_pb);
467 468
    for(mb_index = 0; mb_index < 5; mb_index++) {
        for(j = 0;j < 6; j++) {
469
            if (mb->pos < 64) {
470 471 472
#ifdef VLC_DEBUG
                printf("start %d:%d\n", mb_index, j);
#endif
473
                dv_decode_ac(&gb, mb, block);
474
            }
475 476
            if (mb->pos >= 64 && mb->pos < 127)
                av_log(NULL, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos);
477
            block += 64;
478
            mb++;
479 480
        }
    }
481

482
    /* compute idct and place blocks */
483
    block = &sblock[0][0];
484 485 486 487 488
    mb = mb_data;
    for(mb_index = 0; mb_index < 5; mb_index++) {
        v = *mb_pos_ptr++;
        mb_x = v & 0xff;
        mb_y = v >> 8;
Daniel Maas's avatar
Daniel Maas committed
489 490
        if (s->sys->pix_fmt == PIX_FMT_YUV422P) {
            y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + (mb_x>>1))<<log2_blocksize);
Michael Niedermayer's avatar
Michael Niedermayer committed
491
            c_offset = ((mb_y * s->picture.linesize[1] + (mb_x >> 2))<<log2_blocksize);
Daniel Maas's avatar
Daniel Maas committed
492 493 494 495 496 497 498
        } else { /* 4:1:1 or 4:2:0 */
            y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<<log2_blocksize);
            if (s->sys->pix_fmt == PIX_FMT_YUV411P)
                c_offset = ((mb_y * s->picture.linesize[1] + (mb_x >> 2))<<log2_blocksize);
            else /* 4:2:0 */
                c_offset = (((mb_y >> 1) * s->picture.linesize[1] + (mb_x >> 1))<<log2_blocksize);
        }
499
        for(j = 0;j < 6; j++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
500
            idct_put = s->idct_put[mb->dct_mode && log2_blocksize==3];
Daniel Maas's avatar
Daniel Maas committed
501 502 503 504
            if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */
                if (j == 0 || j == 2) {
                    /* Y0 Y1 */
                    idct_put(y_ptr + ((j >> 1)<<log2_blocksize),
505
                             s->picture.linesize[0], block);
Daniel Maas's avatar
Daniel Maas committed
506 507 508 509
                } else if(j > 3) {
                    /* Cr Cb */
                    idct_put(s->picture.data[6 - j] + c_offset,
                             s->picture.linesize[6 - j], block);
510
                }
Daniel Maas's avatar
Daniel Maas committed
511 512 513 514 515 516 517 518 519
                /* note: j=1 and j=3 are "dummy" blocks in 4:2:2 */
            } else { /* 4:1:1 or 4:2:0 */
                if (j < 4) {
                    if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) {
                        /* NOTE: at end of line, the macroblock is handled as 420 */
                        idct_put(y_ptr + (j<<log2_blocksize), s->picture.linesize[0], block);
                    } else {
                        idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<<log2_blocksize),
                                 s->picture.linesize[0], block);
520 521
                    }
                } else {
Daniel Maas's avatar
Daniel Maas committed
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
                    if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
                        uint64_t aligned_pixels[64/8];
                        uint8_t *pixels= (uint8_t*)aligned_pixels;
                        uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1;
                        int x, y, linesize;
                        /* NOTE: at end of line, the macroblock is handled as 420 */
                        idct_put(pixels, 8, block);
                        linesize = s->picture.linesize[6 - j];
                        c_ptr = s->picture.data[6 - j] + c_offset;
                        ptr = pixels;
                        for(y = 0;y < (1<<log2_blocksize); y++) {
                            ptr1= ptr + (1<<(log2_blocksize-1));
                            c_ptr1 = c_ptr + (linesize<<log2_blocksize);
                            for(x=0; x < (1<<(log2_blocksize-1)); x++){
                                c_ptr[x]= ptr[x]; c_ptr1[x]= ptr1[x];
                            }
                            c_ptr += linesize;
                            ptr += 8;
                        }
                    } else {
                        /* don't ask me why they inverted Cb and Cr ! */
                        idct_put(s->picture.data[6 - j] + c_offset,
                                 s->picture.linesize[6 - j], block);
                    }
546
                }
547 548
            }
            block += 64;
549
            mb++;
550 551 552 553
        }
    }
}

554
#ifdef DV_CODEC_TINY_TARGET
555
/* Converts run and level (where level != 0) pair into vlc, returning bit size */
556
static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
557 558
{
    int size;
559 560
    if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
        *vlc = dv_vlc_map[run][level].vlc | sign;
561
        size = dv_vlc_map[run][level].size;
562
    }
563
    else {
564
        if (level < DV_VLC_MAP_LEV_SIZE) {
565 566 567
            *vlc = dv_vlc_map[0][level].vlc | sign;
            size = dv_vlc_map[0][level].size;
        } else {
568
            *vlc = 0xfe00 | (level << 1) | sign;
569 570 571 572 573 574 575
            size = 16;
        }
        if (run) {
            *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
                                  (0x1f80 | (run - 1))) << size;
            size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
        }
576
    }
577

578 579 580
    return size;
}

581
static av_always_inline int dv_rl2vlc_size(int run, int level)
582 583
{
    int size;
584

585
    if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
586
        size = dv_vlc_map[run][level].size;
587
    }
588
    else {
589 590 591 592
        size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
        if (run) {
            size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
        }
593 594 595 596
    }
    return size;
}
#else
597
static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
598
{
Michael Niedermayer's avatar
Michael Niedermayer committed
599 600
    *vlc = dv_vlc_map[run][l].vlc | sign;
    return dv_vlc_map[run][l].size;
601 602
}

603
static av_always_inline int dv_rl2vlc_size(int run, int l)
604
{
Michael Niedermayer's avatar
Michael Niedermayer committed
605
    return dv_vlc_map[run][l].size;
606 607 608
}
#endif

609
typedef struct EncBlockInfo {
610 611
    int area_q[4];
    int bit_size[4];
Michael Niedermayer's avatar
Michael Niedermayer committed
612
    int prev[5];
613
    int cur_ac;
614 615
    int cno;
    int dct_mode;
Michael Niedermayer's avatar
Michael Niedermayer committed
616 617 618
    DCTELEM mb[64];
    uint8_t next[64];
    uint8_t sign[64];
619 620
    uint8_t partial_bit_count;
    uint32_t partial_bit_buffer; /* we can't use uint16_t here */
621 622
} EncBlockInfo;

623
static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi, PutBitContext* pb_pool,
Michael Niedermayer's avatar
Michael Niedermayer committed
624
                                       PutBitContext* pb_end)
625
{
Michael Niedermayer's avatar
Michael Niedermayer committed
626
    int prev;
627 628 629 630
    int bits_left;
    PutBitContext* pb = pb_pool;
    int size = bi->partial_bit_count;
    uint32_t vlc = bi->partial_bit_buffer;
Michael Niedermayer's avatar
Michael Niedermayer committed
631

632
    bi->partial_bit_count = bi->partial_bit_buffer = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
633
    for(;;){
634
       /* Find suitable storage space */
635
       for (; size > (bits_left = put_bits_left(pb)); pb++) {
636 637
          if (bits_left) {
              size -= bits_left;
638 639 640 641 642 643 644 645
              put_bits(pb, bits_left, vlc >> size);
              vlc = vlc & ((1<<size)-1);
          }
          if (pb + 1 >= pb_end) {
              bi->partial_bit_count = size;
              bi->partial_bit_buffer = vlc;
              return pb;
          }
646
       }
647

648 649
       /* Store VLC */
       put_bits(pb, size, vlc);
650

Michael Niedermayer's avatar
Michael Niedermayer committed
651 652
       if(bi->cur_ac>=64)
           break;
653

654
       /* Construct the next VLC */
Michael Niedermayer's avatar
Michael Niedermayer committed
655 656 657 658 659
       prev= bi->cur_ac;
       bi->cur_ac = bi->next[prev];
       if(bi->cur_ac < 64){
           size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
       } else {
660 661
           size = 4; vlc = 6; /* End Of Block stamp */
       }
Michael Niedermayer's avatar
Michael Niedermayer committed
662 663
    }
    return pb;
664 665
}

666
static av_always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi,
667
                                              const uint8_t* zigzag_scan, const int *weight, int bias)
668
{
669
    int i, area;
670 671 672 673 674 675 676 677 678 679 680
    /* We offer two different methods for class number assignment: the
       method suggested in SMPTE 314M Table 22, and an improved
       method. The SMPTE method is very conservative; it assigns class
       3 (i.e. severe quantization) to any block where the largest AC
       component is greater than 36. ffmpeg's DV encoder tracks AC bit
       consumption precisely, so there is no need to bias most blocks
       towards strongly lossy compression. Instead, we assign class 2
       to most blocks, and use class 3 only when strictly necessary
       (for blocks whose largest AC component exceeds 255). */

#if 0 /* SMPTE spec method */
Michael Niedermayer's avatar
Michael Niedermayer committed
681
    static const int classes[] = {12, 24, 36, 0xffff};
682 683 684 685
#else /* improved ffmpeg method */
    static const int classes[] = {-1, -1, 255, 0xffff};
#endif
    int max=classes[0];
Michael Niedermayer's avatar
Michael Niedermayer committed
686
    int prev=0;
687

688 689
    bi->mb[0] = blk[0];

690
    for (area = 0; area < 4; area++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
691 692
       bi->prev[area] = prev;
       bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
693
       for (i=mb_area_start[area]; i<mb_area_start[area+1]; i++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
694
          int level = blk[zigzag_scan[i]];
695

Michael Niedermayer's avatar
Michael Niedermayer committed
696 697
          if (level+15 > 30U) {
              bi->sign[i] = (level>>31)&1;
698 699 700
              /* weigh it and and shift down into range, adding for rounding */
              /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT
                 AND the 2x doubling of the weights */
701
              level = (FFABS(level) * weight[i] + (1<<(dv_weight_bits+3))) >> (dv_weight_bits+4);
702
              bi->mb[i] = level;
Michael Niedermayer's avatar
Michael Niedermayer committed
703 704 705 706 707
              if(level>max) max= level;
              bi->bit_size[area] += dv_rl2vlc_size(i - prev  - 1, level);
              bi->next[prev]= i;
              prev= i;
          }
708
       }
709
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
710 711 712
    bi->next[prev]= i;
    for(bi->cno = 0; max > classes[bi->cno]; bi->cno++);

713
    bi->cno += bias;
714

Michael Niedermayer's avatar
Michael Niedermayer committed
715
    if (bi->cno >= 3) {
716
        bi->cno = 3;
Michael Niedermayer's avatar
Michael Niedermayer committed
717 718 719 720 721 722 723
        prev=0;
        i= bi->next[prev];
        for (area = 0; area < 4; area++) {
            bi->prev[area] = prev;
            bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
            for (; i<mb_area_start[area+1]; i= bi->next[i]) {
                bi->mb[i] >>=1;
724

Michael Niedermayer's avatar
Michael Niedermayer committed
725 726 727 728 729 730 731 732
                if (bi->mb[i]) {
                    bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
                    bi->next[prev]= i;
                    prev= i;
                }
            }
        }
        bi->next[prev]= i;
733
    }
734 735
}

Michael Niedermayer's avatar
Michael Niedermayer committed
736
//FIXME replace this by dsputil
737
#define SC(x, y) ((s[x] - s[y]) ^ ((s[x] - s[y]) >> 7))
738
static av_always_inline int dv_guess_dct_mode(DCTELEM *blk) {
739 740 741 742
    DCTELEM *s;
    int score88 = 0;
    int score248 = 0;
    int i;
743

744 745 746
    /* Compute 8-8 score (small values give a better chance for 8-8 DCT) */
    s = blk;
    for(i=0; i<7; i++) {
747
        score88 += SC(0,  8) + SC(1, 9) + SC(2, 10) + SC(3, 11) +
748
                   SC(4, 12) + SC(5,13) + SC(6, 14) + SC(7, 15);
749 750 751 752 753 754
        s += 8;
    }
    /* Compute 2-4-8 score (small values give a better chance for 2-4-8 DCT) */
    s = blk;
    for(i=0; i<6; i++) {
        score248 += SC(0, 16) + SC(1,17) + SC(2, 18) + SC(3, 19) +
755
                    SC(4, 20) + SC(5,21) + SC(6, 22) + SC(7, 23);
756
        s += 8;
757
    }
758 759 760 761 762 763 764

    return (score88 - score248 > -10);
}

static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
{
    int size[5];
765
    int i, j, k, a, prev, a2;
766
    EncBlockInfo* b;
Michael Niedermayer's avatar
Michael Niedermayer committed
767

768
    size[0] = size[1] = size[2] = size[3] = size[4] = 1<<24;
769 770 771 772
    do {
       b = blks;
       for (i=0; i<5; i++) {
          if (!qnos[i])
773
              continue;
774

775 776
          qnos[i]--;
          size[i] = 0;
777
          for (j=0; j<6; j++, b++) {
778 779 780 781
             for (a=0; a<4; a++) {
                if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) {
                    b->bit_size[a] = 1; // 4 areas 4 bits for EOB :)
                    b->area_q[a]++;
Michael Niedermayer's avatar
Michael Niedermayer committed
782
                    prev= b->prev[a];
783
                    assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
Michael Niedermayer's avatar
Michael Niedermayer committed
784
                    for (k= b->next[prev] ; k<mb_area_start[a+1]; k= b->next[k]) {
785 786
                       b->mb[k] >>= 1;
                       if (b->mb[k]) {
Michael Niedermayer's avatar
Michael Niedermayer committed
787
                           b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
788
                           prev= k;
Michael Niedermayer's avatar
Michael Niedermayer committed
789
                       } else {
790
                           if(b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
791 792
                                for(a2=a+1; b->next[k] >= mb_area_start[a2+1]; a2++)
                                    b->prev[a2] = prev;
793 794 795 796
                                assert(a2<4);
                                assert(b->mb[b->next[k]]);
                                b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
                                                  -dv_rl2vlc_size(b->next[k] -    k - 1, b->mb[b->next[k]]);
797 798
                                assert(b->prev[a2]==k && (a2+1 >= 4 || b->prev[a2+1]!=k));
                                b->prev[a2] = prev;
799
                           }
Michael Niedermayer's avatar
Michael Niedermayer committed
800 801
                           b->next[prev] = b->next[k];
                       }
802
                    }
Michael Niedermayer's avatar
Michael Niedermayer committed
803
                    b->prev[a+1]= prev;
804 805 806 807
                }
                size[i] += b->bit_size[a];
             }
          }
808 809
          if(vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
                return;
810
       }
811 812 813 814 815
    } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);


    for(a=2; a==2 || vs_total_ac_bits < size[0]; a+=a){
        b = blks;
Michael Niedermayer's avatar
Michael Niedermayer committed
816
        size[0] = 5*6*4; //EOB
817 818 819 820 821 822 823 824 825 826 827 828
        for (j=0; j<6*5; j++, b++) {
            prev= b->prev[0];
            for (k= b->next[prev]; k<64; k= b->next[k]) {
                if(b->mb[k] < a && b->mb[k] > -a){
                    b->next[prev] = b->next[k];
                }else{
                    size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
                    prev= k;
                }
            }
        }
    }
829 830
}

831 832
static inline void dv_encode_video_segment(DVVideoContext *s,
                                           uint8_t *dif,
833 834 835
                                           const uint16_t *mb_pos_ptr)
{
    int mb_index, i, j, v;
836
    int mb_x, mb_y, c_offset, linesize;
837 838
    uint8_t*  y_ptr;
    uint8_t*  data;
839
    uint8_t*  ptr;
840
    int       do_edge_wrap;
841
    DECLARE_ALIGNED_16(DCTELEM, block[64]);
842
    EncBlockInfo  enc_blks[5*6];
843
    PutBitContext pbs[5*6];
844
    PutBitContext* pb;
845
    EncBlockInfo* enc_blk;
846 847
    int       vs_bit_size = 0;
    int       qnos[5];
848

849
    assert((((int)block) & 15) == 0);
850

851
    enc_blk = &enc_blks[0];
852
    pb = &pbs[0];
853 854 855 856
    for(mb_index = 0; mb_index < 5; mb_index++) {
        v = *mb_pos_ptr++;
        mb_x = v & 0xff;
        mb_y = v >> 8;
Daniel Maas's avatar
Daniel Maas committed
857 858 859 860 861 862 863 864 865 866
        if (s->sys->pix_fmt == PIX_FMT_YUV422P) {
            y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 4);
        } else { /* 4:1:1 */
            y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8);
        }
        if (s->sys->pix_fmt == PIX_FMT_YUV420P) {
            c_offset = (((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8));
        } else { /* 4:2:2 or 4:1:1 */
            c_offset = ((mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8));
        }
867 868
        do_edge_wrap = 0;
        qnos[mb_index] = 15; /* No quantization */
869
        ptr = dif + mb_index*80 + 4;
870
        for(j = 0;j < 6; j++) {
Daniel Maas's avatar
Daniel Maas committed
871 872 873 874 875 876 877 878 879 880
            int dummy = 0;
            if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */
                if (j == 0 || j == 2) {
                    /* Y0 Y1 */
                    data = y_ptr + ((j>>1) * 8);
                    linesize = s->picture.linesize[0];
                } else if (j > 3) {
                    /* Cr Cb */
                    data = s->picture.data[6 - j] + c_offset;
                    linesize = s->picture.linesize[6 - j];
881
                } else {
Daniel Maas's avatar
Daniel Maas committed
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901
                    /* j=1 and j=3 are "dummy" blocks, used for AC data only */
                    data = 0;
                    linesize = 0;
                    dummy = 1;
                }
            } else { /* 4:1:1 or 4:2:0 */
                if (j < 4) {  /* Four Y blocks */
                    /* NOTE: at end of line, the macroblock is handled as 420 */
                    if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) {
                        data = y_ptr + (j * 8);
                    } else {
                        data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]);
                    }
                    linesize = s->picture.linesize[0];
                } else {      /* Cr and Cb blocks */
                    /* don't ask Fabrice why they inverted Cb and Cr ! */
                    data = s->picture.data[6 - j] + c_offset;
                    linesize = s->picture.linesize[6 - j];
                    if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8))
                        do_edge_wrap = 1;
902
                }
903 904 905 906 907 908 909 910 911
            }

            /* Everything is set up -- now just copy data -> DCT block */
            if (do_edge_wrap) {  /* Edge wrap copy: 4x16 -> 8x8 */
                uint8_t* d;
                DCTELEM *b = block;
                for (i=0;i<8;i++) {
                   d = data + 8 * linesize;
                   b[0] = data[0]; b[1] = data[1]; b[2] = data[2]; b[3] = data[3];
912
                   b[4] =    d[0]; b[5] =    d[1]; b[6] =    d[2]; b[7] =    d[3];
913 914 915 916
                   data += linesize;
                   b += 8;
                }
            } else {             /* Simple copy: 8x8 -> 8x8 */
Daniel Maas's avatar
Daniel Maas committed
917 918
                if (!dummy)
                    s->get_pixels(block, data, linesize);
919
            }
920

Michael Niedermayer's avatar
Michael Niedermayer committed
921 922 923 924
            if(s->avctx->flags & CODEC_FLAG_INTERLACED_DCT)
                enc_blk->dct_mode = dv_guess_dct_mode(block);
            else
                enc_blk->dct_mode = 0;
925 926 927 928
            enc_blk->area_q[0] = enc_blk->area_q[1] = enc_blk->area_q[2] = enc_blk->area_q[3] = 0;
            enc_blk->partial_bit_count = 0;
            enc_blk->partial_bit_buffer = 0;
            enc_blk->cur_ac = 0;
929

Daniel Maas's avatar
Daniel Maas committed
930 931 932 933 934 935 936
            if (dummy) {
                /* We rely on the fact that encoding all zeros leads to an immediate EOB,
                   which is precisely what the spec calls for in the "dummy" blocks. */
                memset(block, 0, sizeof(block));
            } else {
                s->fdct[enc_blk->dct_mode](block);
            }
937

938
            dv_set_class_number(block, enc_blk,
939 940 941
                                enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct,
                                enc_blk->dct_mode ? dv_weight_248 : dv_weight_88,
                                j/4);
942

943
            init_put_bits(pb, ptr, block_sizes[j]/8);
944 945 946 947 948 949 950 951 952
            put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024 + 2) >> 2));
            put_bits(pb, 1, enc_blk->dct_mode);
            put_bits(pb, 2, enc_blk->cno);

            vs_bit_size += enc_blk->bit_size[0] + enc_blk->bit_size[1] +
                           enc_blk->bit_size[2] + enc_blk->bit_size[3];
            ++enc_blk;
            ++pb;
            ptr += block_sizes[j]/8;
953 954 955
        }
    }

956 957
    if (vs_total_ac_bits < vs_bit_size)
        dv_guess_qnos(&enc_blks[0], &qnos[0]);
958 959

    for (i=0; i<5; i++) {
960 961
       dif[i*80 + 3] = qnos[i];
    }
962

963 964
    /* First pass over individual cells only */
    for (j=0; j<5*6; j++)
Michael Niedermayer's avatar
Michael Niedermayer committed
965
       dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
966

967
    /* Second pass over each MB space */
Michael Niedermayer's avatar
Michael Niedermayer committed
968 969 970 971 972 973
    for (j=0; j<5*6; j+=6) {
        pb= &pbs[j];
        for (i=0; i<6; i++) {
            if (enc_blks[i+j].partial_bit_count)
                pb=dv_encode_ac(&enc_blks[i+j], pb, &pbs[j+6]);
        }
974 975
    }

976
    /* Third and final pass over the whole vides segment space */
Michael Niedermayer's avatar
Michael Niedermayer committed
977
    pb= &pbs[0];
978
    for (j=0; j<5*6; j++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
979 980
       if (enc_blks[j].partial_bit_count)
           pb=dv_encode_ac(&enc_blks[j], pb, &pbs[6*5]);
981 982
       if (enc_blks[j].partial_bit_count)
            av_log(NULL, AV_LOG_ERROR, "ac bitstream overflow\n");
983
    }
984 985 986

    for (j=0; j<5*6; j++)
       flush_put_bits(&pbs[j]);
987 988
}

989 990 991
static int dv_decode_mt(AVCodecContext *avctx, void* sl)
{
    DVVideoContext *s = avctx->priv_data;
Falk Hüffner's avatar
Falk Hüffner committed
992
    int slice = (size_t)sl;
Daniel Maas's avatar
Daniel Maas committed
993 994 995 996 997 998 999 1000 1001 1002 1003

    /* which DIF channel is this? */
    int chan = slice / (s->sys->difseg_size * 27);

    /* slice within the DIF channel */
    int chan_slice = slice % (s->sys->difseg_size * 27);

    /* byte offset of this channel's data */
    int chan_offset = chan * s->sys->difseg_size * 150 * 80;

    dv_decode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset],
1004
                            &s->sys->video_place[slice*5]);
1005 1006 1007
    return 0;
}

1008
#ifdef CONFIG_ENCODERS
1009 1010 1011
static int dv_encode_mt(AVCodecContext *avctx, void* sl)
{
    DVVideoContext *s = avctx->priv_data;
Falk Hüffner's avatar
Falk Hüffner committed
1012
    int slice = (size_t)sl;
Daniel Maas's avatar
Daniel Maas committed
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023

    /* which DIF channel is this? */
    int chan = slice / (s->sys->difseg_size * 27);

    /* slice within the DIF channel */
    int chan_slice = slice % (s->sys->difseg_size * 27);

    /* byte offset of this channel's data */
    int chan_offset = chan * s->sys->difseg_size * 150 * 80;

    dv_encode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset],
1024
                            &s->sys->video_place[slice*5]);
1025 1026
    return 0;
}
1027
#endif
1028

1029
#ifdef CONFIG_DECODERS
1030
/* NOTE: exactly one frame must be given (120000 bytes for NTSC,
Daniel Maas's avatar
Daniel Maas committed
1031
   144000 bytes for PAL - or twice those for 50Mbps) */
1032
static int dvvideo_decode_frame(AVCodecContext *avctx,
1033
                                 void *data, int *data_size,
Michael Niedermayer's avatar
Michael Niedermayer committed
1034
                                 const uint8_t *buf, int buf_size)
1035
{
1036
    DVVideoContext *s = avctx->priv_data;
1037

1038 1039 1040
    s->sys = dv_frame_profile(buf);
    if (!s->sys || buf_size < s->sys->frame_size)
        return -1; /* NOTE: we only accept several full frames */
1041

1042 1043
    if(s->picture.data[0])
        avctx->release_buffer(avctx, &s->picture);
1044

1045
    s->picture.reference = 0;
1046 1047
    s->picture.key_frame = 1;
    s->picture.pict_type = FF_I_TYPE;
1048
    avctx->pix_fmt = s->sys->pix_fmt;
Michael Niedermayer's avatar
Michael Niedermayer committed
1049
    avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
Michael Niedermayer's avatar
Michael Niedermayer committed
1050
    if(avctx->get_buffer(avctx, &s->picture) < 0) {
1051
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1052
        return -1;
Zdenek Kabelac's avatar
Zdenek Kabelac committed
1053
    }
1054
    s->picture.interlaced_frame = 1;
1055
    s->picture.top_field_first = 0;
Zdenek Kabelac's avatar
Zdenek Kabelac committed
1056

1057
    s->buf = buf;
1058
    avctx->execute(avctx, dv_decode_mt, (void**)&dv_anchor[0], NULL,
Daniel Maas's avatar
Daniel Maas committed
1059
                   s->sys->n_difchan * s->sys->difseg_size * 27);
1060

1061 1062
    emms_c();

1063
    /* return image */
1064 1065
    *data_size = sizeof(AVFrame);
    *(AVFrame*)data= s->picture;
1066

1067
    return s->sys->frame_size;
1068
}
1069
#endif
1070

1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193

static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c, uint8_t* buf)
{
    /*
     * Here's what SMPTE314M says about these two:
     *    (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical
     *             as track application IDs (APTn = 001, AP1n =
     *             001, AP2n = 001, AP3n = 001), if the source signal
     *             comes from a digital VCR. If the signal source is
     *             unknown, all bits for these data shall be set to 1.
     *    (page 12) STYPE: STYPE defines a signal type of video signal
     *                     00000b = 4:1:1 compression
     *                     00100b = 4:2:2 compression
     *                     XXXXXX = Reserved
     * Now, I've got two problems with these statements:
     *   1. it looks like APT == 111b should be a safe bet, but it isn't.
     *      It seems that for PAL as defined in IEC 61834 we have to set
     *      APT to 000 and for SMPTE314M to 001.
     *   2. It is not at all clear what STYPE is used for 4:2:0 PAL
     *      compression scheme (if any).
     */
    int apt = (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0 : 1);
    int stype = (c->sys->pix_fmt == PIX_FMT_YUV422P ? 4 : 0);

    uint8_t aspect = 0;
    if((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) == 17) /* 16:9 */
        aspect = 0x02;

    buf[0] = (uint8_t)pack_id;
    switch (pack_id) {
    case dv_header525: /* I can't imagine why these two weren't defined as real */
    case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */
          buf[1] = 0xf8 |               /* reserved -- always 1 */
                   (apt & 0x07);        /* APT: Track application ID */
          buf[2] = (0 << 7)    | /* TF1: audio data is 0 - valid; 1 - invalid */
                   (0x0f << 3) | /* reserved -- always 1 */
                   (apt & 0x07); /* AP1: Audio application ID */
          buf[3] = (0 << 7)    | /* TF2: video data is 0 - valid; 1 - invalid */
                   (0x0f << 3) | /* reserved -- always 1 */
                   (apt & 0x07); /* AP2: Video application ID */
          buf[4] = (0 << 7)    | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */
                   (0x0f << 3) | /* reserved -- always 1 */
                   (apt & 0x07); /* AP3: Subcode application ID */
          break;
    case dv_video_source:
          buf[1] = 0xff; /* reserved -- always 1 */
          buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
                   (1 << 6) | /* following CLF is valid - 0, invalid - 1 */
                   (3 << 4) | /* CLF: color frames id (see ITU-R BT.470-4) */
                   0xf; /* reserved -- always 1 */
          buf[3] = (3 << 6) | /* reserved -- always 1 */
                   (c->sys->dsf << 5) | /*  system: 60fields/50fields */
                   stype; /* signal type video compression */
          buf[4] = 0xff; /* VISC: 0xff -- no information */
          break;
    case dv_video_control:
          buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
                   0x3f; /* reserved -- always 1 */
          buf[2] = 0xc8 | /* reserved -- always b11001xxx */
                   aspect;
          buf[3] = (1 << 7) | /* Frame/field flag 1 -- frame, 0 -- field */
                   (1 << 6) | /* First/second field flag 0 -- field 2, 1 -- field 1 */
                   (1 << 5) | /* Frame change flag 0 -- same picture as before, 1 -- different */
                   (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */
                   0xc; /* reserved -- always b1100 */
          buf[4] = 0xff; /* reserved -- always 1 */
          break;
    default:
          buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
    }
    return 5;
}

static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
{
    int chan, i, j, k;

    for (chan = 0; chan < c->sys->n_difchan; chan++) {
        for (i = 0; i < c->sys->difseg_size; i++) {
            memset(buf, 0xff, 80 * 6); /* First 6 DIF blocks are for control data */

            /* DV header: 1DIF */
            buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
            buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
            buf += 72; /* unused bytes */

            /* DV subcode: 2DIFs */
            for (j = 0; j < 2; j++) {
                buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
                for (k = 0; k < 6; k++)
                     buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
                buf += 29; /* unused bytes */
            }

            /* DV VAUX: 3DIFS */
            for (j = 0; j < 3; j++) {
                buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
                buf += dv_write_pack(dv_video_source,  c, buf);
                buf += dv_write_pack(dv_video_control, c, buf);
                buf += 7*5;
                buf += dv_write_pack(dv_video_source,  c, buf);
                buf += dv_write_pack(dv_video_control, c, buf);
                buf += 4*5 + 2; /* unused bytes */
            }

            /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */
            for (j = 0; j < 135; j++) {
                if (j%15 == 0) {
                    memset(buf, 0xff, 80);
                    buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
                    buf += 77; /* audio control & shuffled PCM audio */
                }
                buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
                buf += 77; /* 1 video macro block: 1 bytes control
                              4 * 14 bytes Y 8x8 data
                              10 bytes Cr 8x8 data
                              10 bytes Cb 8x8 data */
            }
        }
    }
}


1194
#ifdef CONFIG_ENCODERS
1195
static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size,
1196
                                void *data)
1197
{
1198
    DVVideoContext *s = c->priv_data;
1199 1200 1201

    s->sys = dv_codec_profile(c);
    if (!s->sys)
1202
        return -1;
1203 1204 1205
    if(buf_size < s->sys->frame_size)
        return -1;

1206 1207
    c->pix_fmt = s->sys->pix_fmt;
    s->picture = *((AVFrame *)data);
1208 1209
    s->picture.key_frame = 1;
    s->picture.pict_type = FF_I_TYPE;
1210

1211
    s->buf = buf;
1212
    c->execute(c, dv_encode_mt, (void**)&dv_anchor[0], NULL,
Daniel Maas's avatar
Daniel Maas committed
1213
               s->sys->n_difchan * s->sys->difseg_size * 27);
1214

1215
    emms_c();
Daniel Maas's avatar
Daniel Maas committed
1216

1217
    dv_format_frame(s, buf);
Daniel Maas's avatar
Daniel Maas committed
1218

1219 1220
    return s->sys->frame_size;
}
1221
#endif
1222

1223 1224
static int dvvideo_close(AVCodecContext *c)
{
1225 1226 1227 1228
    DVVideoContext *s = c->priv_data;

    if(s->picture.data[0])
        c->release_buffer(c, &s->picture);
1229 1230 1231 1232 1233

    return 0;
}


1234
#ifdef CONFIG_DVVIDEO_ENCODER
1235 1236 1237 1238 1239 1240 1241
AVCodec dvvideo_encoder = {
    "dvvideo",
    CODEC_TYPE_VIDEO,
    CODEC_ID_DVVIDEO,
    sizeof(DVVideoContext),
    dvvideo_init,
    dvvideo_encode_frame,
1242
    .pix_fmts = (enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, -1},
1243
    .long_name = "DV (Digital Video)",
1244
};
1245
#endif // CONFIG_DVVIDEO_ENCODER
1246

1247
#ifdef CONFIG_DVVIDEO_DECODER
1248 1249 1250 1251
AVCodec dvvideo_decoder = {
    "dvvideo",
    CODEC_TYPE_VIDEO,
    CODEC_ID_DVVIDEO,
1252
    sizeof(DVVideoContext),
1253
    dvvideo_init,
1254
    NULL,
1255
    dvvideo_close,
1256
    dvvideo_decode_frame,
Zdenek Kabelac's avatar
Zdenek Kabelac committed
1257
    CODEC_CAP_DR1,
1258 1259
    NULL,
    .long_name = "DV (Digital Video)",
1260
};
1261
#endif