3 * Copyright (c) 2002 Fabrice Bellard
4 * Copyright (c) 2004 Roman Shaposhnik
7 * Copyright (c) 2003 Roman Shaposhnik
9 * 50 Mbps (DVCPRO50) support
10 * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
12 * 100 Mbps (DVCPRO HD) support
13 * Initial code by Daniel Maas <dmaas@maasdigital.com> (funded by BBC R&D)
14 * Final code by Roman Shaposhnik
16 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
17 * of DV technical info.
19 * This file is part of FFmpeg.
21 * FFmpeg is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU Lesser General Public
23 * License as published by the Free Software Foundation; either
24 * version 2.1 of the License, or (at your option) any later version.
26 * FFmpeg is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
31 * 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
41 #include "libavutil/pixdesc.h"
46 #include "simple_idct.h"
49 #include "dv_tablegen.h"
54 typedef struct DVVideoContext {
57 AVCodecContext *avctx;
60 uint8_t dv_zigzag[2][64];
62 void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size);
63 void (*fdct[2])(DCTELEM *block);
64 void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block);
65 me_cmp_func ildct_cmp;
68 #define TEX_VLC_BITS 9
70 /* XXX: also include quantization */
71 static RL_VLC_ELEM dv_rl_vlc[1184];
73 static inline int dv_work_pool_size(const DVprofile *d)
75 int size = d->n_difchan*d->difseg_size*27;
76 if (DV_PROFILE_IS_1080i50(d))
78 if (DV_PROFILE_IS_720p50(d))
83 static inline void dv_calc_mb_coordinates(const DVprofile *d, int chan, int seq, int slot,
86 static const uint8_t off[] = { 2, 6, 8, 0, 4 };
87 static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 };
88 static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 };
89 static const uint8_t shuf3[] = { 18, 9, 27, 0, 36 };
91 static const uint8_t l_start[] = {0, 4, 9, 13, 18, 22, 27, 31, 36, 40};
92 static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 };
94 static const uint8_t serpent1[] = {0, 1, 2, 2, 1, 0,
99 static const uint8_t serpent2[] = {0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
100 0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
103 static const uint8_t remap[][2] = {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, /* dummy */
104 { 0, 0}, { 0, 1}, { 0, 2}, { 0, 3}, {10, 0},
105 {10, 1}, {10, 2}, {10, 3}, {20, 0}, {20, 1},
106 {20, 2}, {20, 3}, {30, 0}, {30, 1}, {30, 2},
107 {30, 3}, {40, 0}, {40, 1}, {40, 2}, {40, 3},
108 {50, 0}, {50, 1}, {50, 2}, {50, 3}, {60, 0},
109 {60, 1}, {60, 2}, {60, 3}, {70, 0}, {70, 1},
110 {70, 2}, {70, 3}, { 0,64}, { 0,65}, { 0,66},
111 {10,64}, {10,65}, {10,66}, {20,64}, {20,65},
112 {20,66}, {30,64}, {30,65}, {30,66}, {40,64},
113 {40,65}, {40,66}, {50,64}, {50,65}, {50,66},
114 {60,64}, {60,65}, {60,66}, {70,64}, {70,65},
115 {70,66}, { 0,67}, {20,67}, {40,67}, {60,67}};
120 for (m=0; m<5; m++) {
123 blk = (chan*11+seq)*27+slot;
125 if (chan == 0 && seq == 11) {
134 i = (4*chan + blk + off[m])%11;
137 x = shuf1[m] + (chan&1)*9 + k%9;
138 y = (i*3+k/9)*2 + (chan>>1) + 1;
140 tbl[m] = (x<<1)|(y<<9);
143 blk = (chan*10+seq)*27+slot;
145 i = (4*chan + (seq/5) + 2*blk + off[m])%10;
148 x = shuf1[m]+(chan&1)*9 + k%9;
149 y = (i*3+k/9)*2 + (chan>>1) + 4;
152 x = remap[y][0]+((x-80)<<(y>59));
155 tbl[m] = (x<<1)|(y<<9);
158 blk = (chan*10+seq)*27+slot;
160 i = (4*chan + (seq/5) + 2*blk + off[m])%10;
161 k = (blk/5)%27 + (i&1)*3;
163 x = shuf2[m] + k%6 + 6*(chan&1);
164 y = l_start[i] + k/6 + 45*(chan>>1);
165 tbl[m] = (x<<1)|(y<<9);
168 switch (d->pix_fmt) {
169 case PIX_FMT_YUV422P:
170 x = shuf3[m] + slot/3;
172 ((((seq + off[m]) % d->difseg_size)<<1) + chan)*3;
173 tbl[m] = (x<<1)|(y<<8);
175 case PIX_FMT_YUV420P:
176 x = shuf3[m] + slot/3;
178 ((seq + off[m]) % d->difseg_size)*3;
179 tbl[m] = (x<<1)|(y<<9);
181 case PIX_FMT_YUV411P:
182 i = (seq + off[m]) % d->difseg_size;
183 k = slot + ((m==1||m==2)?3:0);
185 x = l_start_shuffled[m] + k/6;
186 y = serpent2[k] + i*6;
189 tbl[m] = (x<<2)|(y<<8);
198 static int dv_init_dynamic_tables(const DVprofile *d)
201 uint32_t *factor1, *factor2;
202 const int *iweight1, *iweight2;
204 if (!d->work_chunks[dv_work_pool_size(d)-1].buf_offset) {
206 for (c=0; c<d->n_difchan; c++) {
207 for (s=0; s<d->difseg_size; s++) {
209 for (j=0; j<27; j++) {
211 if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
212 !(DV_PROFILE_IS_720p50(d) && s > 9)) {
213 dv_calc_mb_coordinates(d, c, s, j, &d->work_chunks[i].mb_coordinates[0]);
214 d->work_chunks[i++].buf_offset = p;
222 if (!d->idct_factor[DV_PROFILE_IS_HD(d)?8191:5631]) {
223 factor1 = &d->idct_factor[0];
224 factor2 = &d->idct_factor[DV_PROFILE_IS_HD(d)?4096:2816];
225 if (d->height == 720) {
226 iweight1 = &dv_iweight_720_y[0];
227 iweight2 = &dv_iweight_720_c[0];
229 iweight1 = &dv_iweight_1080_y[0];
230 iweight2 = &dv_iweight_1080_c[0];
232 if (DV_PROFILE_IS_HD(d)) {
233 for (c = 0; c < 4; c++) {
234 for (s = 0; s < 16; s++) {
235 for (i = 0; i < 64; i++) {
236 *factor1++ = (dv100_qstep[s] << (c + 9)) * iweight1[i];
237 *factor2++ = (dv100_qstep[s] << (c + 9)) * iweight2[i];
242 iweight1 = &dv_iweight_88[0];
243 for (j = 0; j < 2; j++, iweight1 = &dv_iweight_248[0]) {
244 for (s = 0; s < 22; s++) {
245 for (i = c = 0; c < 4; c++) {
246 for (; i < dv_quant_areas[c]; i++) {
247 *factor1 = iweight1[i] << (dv_quant_shifts[s][c] + 1);
248 *factor2++ = (*factor1++) << 1;
259 static av_cold int dvvideo_init(AVCodecContext *avctx)
261 DVVideoContext *s = avctx->priv_data;
268 uint16_t new_dv_vlc_bits[NB_DV_VLC*2];
269 uint8_t new_dv_vlc_len[NB_DV_VLC*2];
270 uint8_t new_dv_vlc_run[NB_DV_VLC*2];
271 int16_t new_dv_vlc_level[NB_DV_VLC*2];
275 /* it's faster to include sign bit in a generic VLC parsing scheme */
276 for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
277 new_dv_vlc_bits[j] = dv_vlc_bits[i];
278 new_dv_vlc_len[j] = dv_vlc_len[i];
279 new_dv_vlc_run[j] = dv_vlc_run[i];
280 new_dv_vlc_level[j] = dv_vlc_level[i];
282 if (dv_vlc_level[i]) {
283 new_dv_vlc_bits[j] <<= 1;
287 new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1;
288 new_dv_vlc_len[j] = dv_vlc_len[i] + 1;
289 new_dv_vlc_run[j] = dv_vlc_run[i];
290 new_dv_vlc_level[j] = -dv_vlc_level[i];
294 /* NOTE: as a trick, we use the fact the no codes are unused
295 to accelerate the parsing of partial codes */
296 init_vlc(&dv_vlc, TEX_VLC_BITS, j,
297 new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0);
298 assert(dv_vlc.table_size == 1184);
300 for (i = 0; i < dv_vlc.table_size; i++){
301 int code = dv_vlc.table[i][0];
302 int len = dv_vlc.table[i][1];
305 if (len < 0){ //more bits needed
309 run = new_dv_vlc_run [code] + 1;
310 level = new_dv_vlc_level[code];
312 dv_rl_vlc[i].len = len;
313 dv_rl_vlc[i].level = level;
314 dv_rl_vlc[i].run = run;
318 dv_vlc_map_tableinit();
321 /* Generic DSP setup */
322 dsputil_init(&dsp, avctx);
323 ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp);
324 s->get_pixels = dsp.get_pixels;
325 s->ildct_cmp = dsp.ildct_cmp[5];
328 s->fdct[0] = dsp.fdct;
329 s->idct_put[0] = dsp.idct_put;
330 for (i = 0; i < 64; i++)
331 s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]];
334 s->fdct[1] = dsp.fdct248;
335 s->idct_put[1] = ff_simple_idct248_put; // FIXME: need to add it to DSP
337 for (i = 0; i < 64; i++){
338 int j = ff_zigzag248_direct[i];
339 s->dv_zigzag[1][i] = dsp.idct_permutation[(j & 7) + (j & 8) * 4 + (j & 48) / 2];
342 memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);
344 avctx->coded_frame = &s->picture;
346 avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
351 static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
353 if (!avpriv_dv_codec_profile(avctx)) {
354 av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video\n",
355 avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
359 return dvvideo_init(avctx);
362 typedef struct BlockInfo {
363 const uint32_t *factor_table;
364 const uint8_t *scan_table;
365 uint8_t pos; /* position in block */
366 void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
367 uint8_t partial_bit_count;
368 uint32_t partial_bit_buffer;
372 /* bit budget for AC only in 5 MBs */
373 static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
374 static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
376 static inline int put_bits_left(PutBitContext* s)
378 return (s->buf_end - s->buf) * 8 - put_bits_count(s);
381 /* decode AC coefficients */
382 static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
384 int last_index = gb->size_in_bits;
385 const uint8_t *scan_table = mb->scan_table;
386 const uint32_t *factor_table = mb->factor_table;
388 int partial_bit_count = mb->partial_bit_count;
389 int level, run, vlc_len, index;
392 UPDATE_CACHE(re, gb);
394 /* if we must parse a partial VLC, we do it here */
395 if (partial_bit_count > 0) {
396 re_cache = re_cache >> partial_bit_count | mb->partial_bit_buffer;
397 re_index -= partial_bit_count;
398 mb->partial_bit_count = 0;
401 /* get the AC coefficients until last_index is reached */
403 av_dlog(NULL, "%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16),
405 /* our own optimized GET_RL_VLC */
406 index = NEG_USR32(re_cache, TEX_VLC_BITS);
407 vlc_len = dv_rl_vlc[index].len;
409 index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level;
410 vlc_len = TEX_VLC_BITS - vlc_len;
412 level = dv_rl_vlc[index].level;
413 run = dv_rl_vlc[index].run;
415 /* gotta check if we're still within gb boundaries */
416 if (re_index + vlc_len > last_index) {
417 /* should be < 16 bits otherwise a codeword could have been parsed */
418 mb->partial_bit_count = last_index - re_index;
419 mb->partial_bit_buffer = re_cache & ~(-1u >> mb->partial_bit_count);
420 re_index = last_index;
425 av_dlog(NULL, "run=%d level=%d\n", run, level);
430 level = (level * factor_table[pos] + (1 << (dv_iweight_bits - 1))) >> dv_iweight_bits;
431 block[scan_table[pos]] = level;
433 UPDATE_CACHE(re, gb);
435 CLOSE_READER(re, gb);
439 static inline void bit_copy(PutBitContext *pb, GetBitContext *gb)
441 int bits_left = get_bits_left(gb);
442 while (bits_left >= MIN_CACHE_BITS) {
443 put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS));
444 bits_left -= MIN_CACHE_BITS;
447 put_bits(pb, bits_left, get_bits(gb, bits_left));
451 static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y)
453 *mb_x = work_chunk->mb_coordinates[m] & 0xff;
454 *mb_y = work_chunk->mb_coordinates[m] >> 8;
456 /* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */
457 if (s->sys->height == 720 && !(s->buf[1]&0x0C)) {
458 *mb_y -= (*mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */
462 /* mb_x and mb_y are in units of 8 pixels */
463 static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
465 DVVideoContext *s = avctx->priv_data;
466 DVwork_chunk *work_chunk = arg;
467 int quant, dc, dct_mode, class1, j;
468 int mb_index, mb_x, mb_y, last_index;
469 int y_stride, linesize;
470 DCTELEM *block, *block1;
473 const uint8_t *buf_ptr;
474 PutBitContext pb, vs_pb;
476 BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1;
477 LOCAL_ALIGNED_16(DCTELEM, sblock, [5*DV_MAX_BPM], [64]);
478 LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [ 80 + FF_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
479 LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [5*80 + FF_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
480 const int log2_blocksize = 3-s->avctx->lowres;
481 int is_field_mode[5];
483 assert((((int)mb_bit_buffer) & 7) == 0);
484 assert((((int)vs_bit_buffer) & 7) == 0);
486 memset(sblock, 0, 5*DV_MAX_BPM*sizeof(*sblock));
488 /* pass 1: read DC and AC coefficients in blocks */
489 buf_ptr = &s->buf[work_chunk->buf_offset*80];
490 block1 = &sblock[0][0];
492 init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80);
493 for (mb_index = 0; mb_index < 5; mb_index++, mb1 += s->sys->bpm, block1 += s->sys->bpm * 64) {
495 quant = buf_ptr[3] & 0x0f;
497 init_put_bits(&pb, mb_bit_buffer, 80);
500 is_field_mode[mb_index] = 0;
501 for (j = 0; j < s->sys->bpm; j++) {
502 last_index = s->sys->block_sizes[j];
503 init_get_bits(&gb, buf_ptr, last_index);
506 dc = get_sbits(&gb, 9);
507 dct_mode = get_bits1(&gb);
508 class1 = get_bits(&gb, 2);
509 if (DV_PROFILE_IS_HD(s->sys)) {
510 mb->idct_put = s->idct_put[0];
511 mb->scan_table = s->dv_zigzag[0];
512 mb->factor_table = &s->sys->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64];
513 is_field_mode[mb_index] |= !j && dct_mode;
515 mb->idct_put = s->idct_put[dct_mode && log2_blocksize == 3];
516 mb->scan_table = s->dv_zigzag[dct_mode];
517 mb->factor_table = &s->sys->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 +
518 (quant + dv_quant_offset[class1])*64];
521 /* convert to unsigned because 128 is not added in the
525 buf_ptr += last_index >> 3;
527 mb->partial_bit_count = 0;
529 av_dlog(avctx, "MB block: %d, %d ", mb_index, j);
530 dv_decode_ac(&gb, mb, block);
532 /* write the remaining bits in a new buffer only if the
541 /* pass 2: we can do it just after */
542 av_dlog(avctx, "***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index);
545 init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb));
546 put_bits32(&pb, 0); // padding must be zeroed
548 for (j = 0; j < s->sys->bpm; j++, block += 64, mb++) {
549 if (mb->pos < 64 && get_bits_left(&gb) > 0) {
550 dv_decode_ac(&gb, mb, block);
551 /* if still not finished, no need to parse other blocks */
556 /* all blocks are finished, so the extra bytes can be used at
557 the video segment level */
558 if (j >= s->sys->bpm)
559 bit_copy(&vs_pb, &gb);
562 /* we need a pass over the whole video segment */
563 av_dlog(avctx, "***pass 3 size=%d\n", put_bits_count(&vs_pb));
564 block = &sblock[0][0];
566 init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb));
567 put_bits32(&vs_pb, 0); // padding must be zeroed
568 flush_put_bits(&vs_pb);
569 for (mb_index = 0; mb_index < 5; mb_index++) {
570 for (j = 0; j < s->sys->bpm; j++) {
572 av_dlog(avctx, "start %d:%d\n", mb_index, j);
573 dv_decode_ac(&gb, mb, block);
575 if (mb->pos >= 64 && mb->pos < 127)
576 av_log(avctx, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos);
582 /* compute idct and place blocks */
583 block = &sblock[0][0];
585 for (mb_index = 0; mb_index < 5; mb_index++) {
586 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
588 /* idct_put'ting luminance */
589 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
590 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
591 (s->sys->height >= 720 && mb_y != 134)) {
592 y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
594 y_stride = (2 << log2_blocksize);
596 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize);
597 linesize = s->picture.linesize[0] << is_field_mode[mb_index];
598 mb[0] .idct_put(y_ptr , linesize, block + 0*64);
599 if (s->sys->video_stype == 4) { /* SD 422 */
600 mb[2].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 2*64);
602 mb[1].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 1*64);
603 mb[2].idct_put(y_ptr + y_stride, linesize, block + 2*64);
604 mb[3].idct_put(y_ptr + (1 << log2_blocksize) + y_stride, linesize, block + 3*64);
609 /* idct_put'ting chrominance */
610 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
611 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize);
612 for (j = 2; j; j--) {
613 uint8_t *c_ptr = s->picture.data[j] + c_offset;
614 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
615 uint64_t aligned_pixels[64/8];
616 uint8_t *pixels = (uint8_t*)aligned_pixels;
617 uint8_t *c_ptr1, *ptr1;
619 mb->idct_put(pixels, 8, block);
620 for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) {
621 ptr1 = pixels + (1 << (log2_blocksize - 1));
622 c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize);
623 for (x = 0; x < (1 << (log2_blocksize - 1)); x++) {
624 c_ptr[x] = pixels[x];
630 y_stride = (mb_y == 134) ? (1 << log2_blocksize) :
631 s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
632 linesize = s->picture.linesize[j] << is_field_mode[mb_index];
633 (mb++)-> idct_put(c_ptr , linesize, block); block += 64;
634 if (s->sys->bpm == 8) {
635 (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64;
644 /* Converts run and level (where level != 0) pair into VLC, returning bit size */
645 static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
648 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
649 *vlc = dv_vlc_map[run][level].vlc | sign;
650 size = dv_vlc_map[run][level].size;
653 if (level < DV_VLC_MAP_LEV_SIZE) {
654 *vlc = dv_vlc_map[0][level].vlc | sign;
655 size = dv_vlc_map[0][level].size;
657 *vlc = 0xfe00 | (level << 1) | sign;
661 *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
662 (0x1f80 | (run - 1))) << size;
663 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
670 static av_always_inline int dv_rl2vlc_size(int run, int level)
674 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
675 size = dv_vlc_map[run][level].size;
678 size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
680 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
686 static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
688 *vlc = dv_vlc_map[run][l].vlc | sign;
689 return dv_vlc_map[run][l].size;
692 static av_always_inline int dv_rl2vlc_size(int run, int l)
694 return dv_vlc_map[run][l].size;
698 typedef struct EncBlockInfo {
708 uint8_t partial_bit_count;
709 uint32_t partial_bit_buffer; /* we can't use uint16_t here */
712 static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi,
713 PutBitContext* pb_pool,
714 PutBitContext* pb_end)
717 PutBitContext* pb = pb_pool;
718 int size = bi->partial_bit_count;
719 uint32_t vlc = bi->partial_bit_buffer;
721 bi->partial_bit_count = bi->partial_bit_buffer = 0;
723 /* Find suitable storage space */
724 for (; size > (bits_left = put_bits_left(pb)); pb++) {
727 put_bits(pb, bits_left, vlc >> size);
728 vlc = vlc & ((1 << size) - 1);
730 if (pb + 1 >= pb_end) {
731 bi->partial_bit_count = size;
732 bi->partial_bit_buffer = vlc;
738 put_bits(pb, size, vlc);
740 if (bi->cur_ac >= 64)
743 /* Construct the next VLC */
745 bi->cur_ac = bi->next[prev];
746 if (bi->cur_ac < 64){
747 size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
749 size = 4; vlc = 6; /* End Of Block stamp */
755 static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) {
756 if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
757 int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400;
759 int is = s->ildct_cmp(NULL, data , NULL, linesize<<1, 4) +
760 s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
768 static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
771 const uint8_t* zigzag_scan;
772 LOCAL_ALIGNED_16(DCTELEM, blk, [64]);
774 /* We offer two different methods for class number assignment: the
775 method suggested in SMPTE 314M Table 22, and an improved
776 method. The SMPTE method is very conservative; it assigns class
777 3 (i.e. severe quantization) to any block where the largest AC
778 component is greater than 36. FFmpeg's DV encoder tracks AC bit
779 consumption precisely, so there is no need to bias most blocks
780 towards strongly lossy compression. Instead, we assign class 2
781 to most blocks, and use class 3 only when strictly necessary
782 (for blocks whose largest AC component exceeds 255). */
784 #if 0 /* SMPTE spec method */
785 static const int classes[] = {12, 24, 36, 0xffff};
786 #else /* improved FFmpeg method */
787 static const int classes[] = {-1, -1, 255, 0xffff};
789 int max = classes[0];
792 assert((((int)blk) & 15) == 0);
794 bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
795 bi->partial_bit_count = 0;
796 bi->partial_bit_buffer = 0;
799 bi->dct_mode = dv_guess_dct_mode(s, data, linesize);
800 s->get_pixels(blk, data, linesize);
801 s->fdct[bi->dct_mode](blk);
803 /* We rely on the fact that encoding all zeros leads to an immediate EOB,
804 which is precisely what the spec calls for in the "dummy" blocks. */
805 memset(blk, 0, 64*sizeof(*blk));
810 zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
811 weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
813 for (area = 0; area < 4; area++) {
814 bi->prev[area] = prev;
815 bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
816 for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) {
817 int level = blk[zigzag_scan[i]];
819 if (level + 15 > 30U) {
820 bi->sign[i] = (level >> 31) & 1;
821 /* weight it and and shift down into range, adding for rounding */
822 /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT
823 AND the 2x doubling of the weights */
824 level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4);
828 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level);
835 for (bi->cno = 0; max > classes[bi->cno]; bi->cno++);
843 for (area = 0; area < 4; area++) {
844 bi->prev[area] = prev;
845 bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
846 for (; i < mb_area_start[area+1]; i = bi->next[i]) {
850 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
859 return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
862 static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
865 int i, j, k, a, prev, a2;
868 size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24;
871 for (i = 0; i < 5; i++) {
877 for (j = 0; j < 6; j++, b++) {
878 for (a = 0; a < 4; a++) {
879 if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) {
880 b->bit_size[a] = 1; // 4 areas 4 bits for EOB :)
883 assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
884 for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) {
887 b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
890 if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
891 for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++)
894 assert(b->mb[b->next[k]]);
895 b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
896 -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]);
897 assert(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k));
900 b->next[prev] = b->next[k];
905 size[i] += b->bit_size[a];
908 if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
911 } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
914 for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){
916 size[0] = 5 * 6 * 4; //EOB
917 for (j = 0; j < 6 *5; j++, b++) {
919 for (k = b->next[prev]; k < 64; k = b->next[k]) {
920 if (b->mb[k] < a && b->mb[k] > -a){
921 b->next[prev] = b->next[k];
923 size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
931 static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
933 DVVideoContext *s = avctx->priv_data;
934 DVwork_chunk *work_chunk = arg;
936 int mb_x, mb_y, c_offset, linesize, y_stride;
939 LOCAL_ALIGNED_8(uint8_t, scratch, [64]);
940 EncBlockInfo enc_blks[5*DV_MAX_BPM];
941 PutBitContext pbs[5*DV_MAX_BPM];
943 EncBlockInfo* enc_blk;
945 int qnos[5] = {15, 15, 15, 15, 15}; /* No quantization */
946 int* qnosp = &qnos[0];
948 dif = &s->buf[work_chunk->buf_offset*80];
949 enc_blk = &enc_blks[0];
950 for (mb_index = 0; mb_index < 5; mb_index++) {
951 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
953 /* initializing luminance blocks */
954 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
955 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
956 (s->sys->height >= 720 && mb_y != 134)) {
957 y_stride = s->picture.linesize[0] << 3;
961 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3);
962 linesize = s->picture.linesize[0];
964 if (s->sys->video_stype == 4) { /* SD 422 */
966 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
967 dv_init_enc_block(enc_blk+1, NULL , linesize, s, 0) +
968 dv_init_enc_block(enc_blk+2, y_ptr + 8 , linesize, s, 0) +
969 dv_init_enc_block(enc_blk+3, NULL , linesize, s, 0);
972 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
973 dv_init_enc_block(enc_blk+1, y_ptr + 8 , linesize, s, 0) +
974 dv_init_enc_block(enc_blk+2, y_ptr + y_stride, linesize, s, 0) +
975 dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
979 /* initializing chrominance blocks */
980 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
981 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << 3);
982 for (j = 2; j; j--) {
983 uint8_t *c_ptr = s->picture.data[j] + c_offset;
984 linesize = s->picture.linesize[j];
985 y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3);
986 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
988 uint8_t* b = scratch;
989 for (i = 0; i < 8; i++) {
990 d = c_ptr + (linesize << 3);
991 b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
992 b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3];
1000 vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1);
1001 if (s->sys->bpm == 8) {
1002 vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
1007 if (vs_total_ac_bits < vs_bit_size)
1008 dv_guess_qnos(&enc_blks[0], qnosp);
1010 /* DIF encoding process */
1011 for (j=0; j<5*s->sys->bpm;) {
1017 /* First pass over individual cells only */
1018 for (i=0; i<s->sys->bpm; i++, j++) {
1019 int sz = s->sys->block_sizes[i]>>3;
1021 init_put_bits(&pbs[j], dif, sz);
1022 put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2);
1023 put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
1024 put_bits(&pbs[j], 2, enc_blks[j].cno);
1026 dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
1030 /* Second pass over each MB space */
1031 pb = &pbs[start_mb];
1032 for (i=0; i<s->sys->bpm; i++) {
1033 if (enc_blks[start_mb+i].partial_bit_count)
1034 pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
1038 /* Third and final pass over the whole video segment space */
1040 for (j=0; j<5*s->sys->bpm; j++) {
1041 if (enc_blks[j].partial_bit_count)
1042 pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
1043 if (enc_blks[j].partial_bit_count)
1044 av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n");
1047 for (j=0; j<5*s->sys->bpm; j++) {
1049 int size = pbs[j].size_in_bits >> 3;
1050 flush_put_bits(&pbs[j]);
1051 pos = put_bits_count(&pbs[j]) >> 3;
1053 av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n");
1056 memset(pbs[j].buf + pos, 0xff, size - pos);
1062 #if CONFIG_DVVIDEO_DECODER
1063 /* NOTE: exactly one frame must be given (120000 bytes for NTSC,
1064 144000 bytes for PAL - or twice those for 50Mbps) */
1065 static int dvvideo_decode_frame(AVCodecContext *avctx,
1066 void *data, int *data_size,
1069 const uint8_t *buf = avpkt->data;
1070 int buf_size = avpkt->size;
1071 DVVideoContext *s = avctx->priv_data;
1072 const uint8_t* vsc_pack;
1075 s->sys = avpriv_dv_frame_profile2(avctx, s->sys, buf, buf_size);
1076 if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys)) {
1077 av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
1078 return -1; /* NOTE: we only accept several full frames */
1081 if (s->picture.data[0])
1082 avctx->release_buffer(avctx, &s->picture);
1084 avcodec_get_frame_defaults(&s->picture);
1085 s->picture.reference = 0;
1086 s->picture.key_frame = 1;
1087 s->picture.pict_type = AV_PICTURE_TYPE_I;
1088 avctx->pix_fmt = s->sys->pix_fmt;
1089 avctx->time_base = s->sys->time_base;
1090 avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
1091 if (avctx->get_buffer(avctx, &s->picture) < 0) {
1092 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
1095 s->picture.interlaced_frame = 1;
1096 s->picture.top_field_first = 0;
1099 avctx->execute(avctx, dv_decode_video_segment, s->sys->work_chunks, NULL,
1100 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
1105 *data_size = sizeof(AVFrame);
1106 *(AVFrame*)data = s->picture;
1108 /* Determine the codec's sample_aspect ratio from the packet */
1109 vsc_pack = buf + 80*5 + 48 + 5;
1110 if ( *vsc_pack == dv_video_control ) {
1111 apt = buf[4] & 0x07;
1112 is16_9 = (vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07);
1113 avctx->sample_aspect_ratio = s->sys->sar[is16_9];
1116 return s->sys->frame_size;
1118 #endif /* CONFIG_DVVIDEO_DECODER */
1121 static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
1125 * Here's what SMPTE314M says about these two:
1126 * (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical
1127 * as track application IDs (APTn = 001, AP1n =
1128 * 001, AP2n = 001, AP3n = 001), if the source signal
1129 * comes from a digital VCR. If the signal source is
1130 * unknown, all bits for these data shall be set to 1.
1131 * (page 12) STYPE: STYPE defines a signal type of video signal
1132 * 00000b = 4:1:1 compression
1133 * 00100b = 4:2:2 compression
1135 * Now, I've got two problems with these statements:
1136 * 1. it looks like APT == 111b should be a safe bet, but it isn't.
1137 * It seems that for PAL as defined in IEC 61834 we have to set
1138 * APT to 000 and for SMPTE314M to 001.
1139 * 2. It is not at all clear what STYPE is used for 4:2:0 PAL
1140 * compression scheme (if any).
1142 int apt = (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0 : 1);
1145 if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17) /* 16:9 */
1148 buf[0] = (uint8_t)pack_id;
1150 case dv_header525: /* I can't imagine why these two weren't defined as real */
1151 case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */
1152 buf[1] = 0xf8 | /* reserved -- always 1 */
1153 (apt & 0x07); /* APT: Track application ID */
1154 buf[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */
1155 (0x0f << 3) | /* reserved -- always 1 */
1156 (apt & 0x07); /* AP1: Audio application ID */
1157 buf[3] = (0 << 7) | /* TF2: video data is 0 - valid; 1 - invalid */
1158 (0x0f << 3) | /* reserved -- always 1 */
1159 (apt & 0x07); /* AP2: Video application ID */
1160 buf[4] = (0 << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */
1161 (0x0f << 3) | /* reserved -- always 1 */
1162 (apt & 0x07); /* AP3: Subcode application ID */
1164 case dv_video_source:
1165 buf[1] = 0xff; /* reserved -- always 1 */
1166 buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
1167 (1 << 6) | /* following CLF is valid - 0, invalid - 1 */
1168 (3 << 4) | /* CLF: color frames ID (see ITU-R BT.470-4) */
1169 0xf; /* reserved -- always 1 */
1170 buf[3] = (3 << 6) | /* reserved -- always 1 */
1171 (c->sys->dsf << 5) | /* system: 60fields/50fields */
1172 c->sys->video_stype; /* signal type video compression */
1173 buf[4] = 0xff; /* VISC: 0xff -- no information */
1175 case dv_video_control:
1176 buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
1177 0x3f; /* reserved -- always 1 */
1178 buf[2] = 0xc8 | /* reserved -- always b11001xxx */
1180 buf[3] = (1 << 7) | /* frame/field flag 1 -- frame, 0 -- field */
1181 (1 << 6) | /* first/second field flag 0 -- field 2, 1 -- field 1 */
1182 (1 << 5) | /* frame change flag 0 -- same picture as before, 1 -- different */
1183 (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */
1184 0xc; /* reserved -- always b1100 */
1185 buf[4] = 0xff; /* reserved -- always 1 */
1188 buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
1193 #if CONFIG_DVVIDEO_ENCODER
1194 static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num,
1195 uint8_t seq_num, uint8_t dif_num,
1198 buf[0] = (uint8_t)t; /* Section type */
1199 buf[1] = (seq_num << 4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */
1200 (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */
1201 7; /* reserved -- always 1 */
1202 buf[2] = dif_num; /* DIF block number Video: 0-134, Audio: 0-8 */
1207 static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf)
1209 if (syb_num == 0 || syb_num == 6) {
1210 buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
1211 (0 << 4) | /* AP3 (Subcode application ID) */
1212 0x0f; /* reserved -- always 1 */
1214 else if (syb_num == 11) {
1215 buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
1216 0x7f; /* reserved -- always 1 */
1219 buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
1220 (0 << 4) | /* APT (Track application ID) */
1221 0x0f; /* reserved -- always 1 */
1223 buf[1] = 0xf0 | /* reserved -- always 1 */
1224 (syb_num & 0x0f); /* SSYB number 0 - 11 */
1225 buf[2] = 0xff; /* reserved -- always 1 */
1229 static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
1233 for (chan = 0; chan < c->sys->n_difchan; chan++) {
1234 for (i = 0; i < c->sys->difseg_size; i++) {
1235 memset(buf, 0xff, 80 * 6); /* first 6 DIF blocks are for control data */
1237 /* DV header: 1DIF */
1238 buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
1239 buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
1240 buf += 72; /* unused bytes */
1242 /* DV subcode: 2DIFs */
1243 for (j = 0; j < 2; j++) {
1244 buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
1245 for (k = 0; k < 6; k++)
1246 buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
1247 buf += 29; /* unused bytes */
1250 /* DV VAUX: 3DIFS */
1251 for (j = 0; j < 3; j++) {
1252 buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
1253 buf += dv_write_pack(dv_video_source, c, buf);
1254 buf += dv_write_pack(dv_video_control, c, buf);
1256 buf += dv_write_pack(dv_video_source, c, buf);
1257 buf += dv_write_pack(dv_video_control, c, buf);
1258 buf += 4*5 + 2; /* unused bytes */
1261 /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */
1262 for (j = 0; j < 135; j++) {
1264 memset(buf, 0xff, 80);
1265 buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
1266 buf += 77; /* audio control & shuffled PCM audio */
1268 buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
1269 buf += 77; /* 1 video macroblock: 1 bytes control
1270 4 * 14 bytes Y 8x8 data
1271 10 bytes Cr 8x8 data
1272 10 bytes Cb 8x8 data */
1279 static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size,
1282 DVVideoContext *s = c->priv_data;
1284 s->sys = avpriv_dv_codec_profile(c);
1285 if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys))
1288 c->pix_fmt = s->sys->pix_fmt;
1289 s->picture = *((AVFrame *)data);
1290 s->picture.key_frame = 1;
1291 s->picture.pict_type = AV_PICTURE_TYPE_I;
1294 c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
1295 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
1299 dv_format_frame(s, buf);
1301 return s->sys->frame_size;
1305 static int dvvideo_close(AVCodecContext *c)
1307 DVVideoContext *s = c->priv_data;
1309 if (s->picture.data[0])
1310 c->release_buffer(c, &s->picture);
1316 #if CONFIG_DVVIDEO_ENCODER
1317 AVCodec ff_dvvideo_encoder = {
1319 .type = AVMEDIA_TYPE_VIDEO,
1320 .id = CODEC_ID_DVVIDEO,
1321 .priv_data_size = sizeof(DVVideoContext),
1322 .init = dvvideo_init_encoder,
1323 .encode = dvvideo_encode_frame,
1324 .capabilities = CODEC_CAP_SLICE_THREADS,
1325 .pix_fmts = (const enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE},
1326 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
1328 #endif // CONFIG_DVVIDEO_ENCODER
1330 #if CONFIG_DVVIDEO_DECODER
1331 AVCodec ff_dvvideo_decoder = {
1333 .type = AVMEDIA_TYPE_VIDEO,
1334 .id = CODEC_ID_DVVIDEO,
1335 .priv_data_size = sizeof(DVVideoContext),
1336 .init = dvvideo_init,
1337 .close = dvvideo_close,
1338 .decode = dvvideo_decode_frame,
1339 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
1341 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),