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
37 * @file libavcodec/dv.c
40 #define ALT_BITSTREAM_READER
45 #include "simple_idct.h"
51 typedef struct DVVideoContext {
54 AVCodecContext *avctx;
57 uint8_t dv_zigzag[2][64];
59 void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size);
60 void (*fdct[2])(DCTELEM *block);
61 void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block);
62 me_cmp_func ildct_cmp;
65 #define TEX_VLC_BITS 9
68 #define DV_VLC_MAP_RUN_SIZE 15
69 #define DV_VLC_MAP_LEV_SIZE 23
71 #define DV_VLC_MAP_RUN_SIZE 64
72 #define DV_VLC_MAP_LEV_SIZE 512 //FIXME sign was removed so this should be /2 but needs check
75 /* XXX: also include quantization */
76 static RL_VLC_ELEM dv_rl_vlc[1184];
77 /* VLC encoding lookup table */
78 static struct dv_vlc_pair {
81 } dv_vlc_map[DV_VLC_MAP_RUN_SIZE][DV_VLC_MAP_LEV_SIZE];
83 static inline int dv_work_pool_size(const DVprofile *d)
85 int size = d->n_difchan*d->difseg_size*27;
86 if (DV_PROFILE_IS_1080i50(d))
88 if (DV_PROFILE_IS_720p50(d))
93 static inline void dv_calc_mb_coordinates(const DVprofile *d, int chan, int seq, int slot,
96 static const uint8_t off[] = { 2, 6, 8, 0, 4 };
97 static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 };
98 static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 };
99 static const uint8_t shuf3[] = { 18, 9, 27, 0, 36 };
101 static const uint8_t l_start[] = {0, 4, 9, 13, 18, 22, 27, 31, 36, 40};
102 static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 };
104 static const uint8_t serpent1[] = {0, 1, 2, 2, 1, 0,
109 static const uint8_t serpent2[] = {0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
110 0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
113 static const uint8_t remap[][2] = {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, /* dummy */
114 { 0, 0}, { 0, 1}, { 0, 2}, { 0, 3}, {10, 0},
115 {10, 1}, {10, 2}, {10, 3}, {20, 0}, {20, 1},
116 {20, 2}, {20, 3}, {30, 0}, {30, 1}, {30, 2},
117 {30, 3}, {40, 0}, {40, 1}, {40, 2}, {40, 3},
118 {50, 0}, {50, 1}, {50, 2}, {50, 3}, {60, 0},
119 {60, 1}, {60, 2}, {60, 3}, {70, 0}, {70, 1},
120 {70, 2}, {70, 3}, { 0,64}, { 0,65}, { 0,66},
121 {10,64}, {10,65}, {10,66}, {20,64}, {20,65},
122 {20,66}, {30,64}, {30,65}, {30,66}, {40,64},
123 {40,65}, {40,66}, {50,64}, {50,65}, {50,66},
124 {60,64}, {60,65}, {60,66}, {70,64}, {70,65},
125 {70,66}, { 0,67}, {20,67}, {40,67}, {60,67}};
130 for (m=0; m<5; m++) {
133 blk = (chan*11+seq)*27+slot;
135 if (chan == 0 && seq == 11) {
144 i = (4*chan + blk + off[m])%11;
147 x = shuf1[m] + (chan&1)*9 + k%9;
148 y = (i*3+k/9)*2 + (chan>>1) + 1;
150 tbl[m] = (x<<1)|(y<<9);
153 blk = (chan*10+seq)*27+slot;
155 i = (4*chan + (seq/5) + 2*blk + off[m])%10;
158 x = shuf1[m]+(chan&1)*9 + k%9;
159 y = (i*3+k/9)*2 + (chan>>1) + 4;
162 x = remap[y][0]+((x-80)<<(y>59));
165 tbl[m] = (x<<1)|(y<<9);
168 blk = (chan*10+seq)*27+slot;
170 i = (4*chan + (seq/5) + 2*blk + off[m])%10;
171 k = (blk/5)%27 + (i&1)*3;
173 x = shuf2[m] + k%6 + 6*(chan&1);
174 y = l_start[i] + k/6 + 45*(chan>>1);
175 tbl[m] = (x<<1)|(y<<9);
178 switch (d->pix_fmt) {
179 case PIX_FMT_YUV422P:
180 x = shuf3[m] + slot/3;
182 ((((seq + off[m]) % d->difseg_size)<<1) + chan)*3;
183 tbl[m] = (x<<1)|(y<<8);
185 case PIX_FMT_YUV420P:
186 x = shuf3[m] + slot/3;
188 ((seq + off[m]) % d->difseg_size)*3;
189 tbl[m] = (x<<1)|(y<<9);
191 case PIX_FMT_YUV411P:
192 i = (seq + off[m]) % d->difseg_size;
193 k = slot + ((m==1||m==2)?3:0);
195 x = l_start_shuffled[m] + k/6;
196 y = serpent2[k] + i*6;
199 tbl[m] = (x<<2)|(y<<8);
208 static int dv_init_dynamic_tables(const DVprofile *d)
211 uint32_t *factor1, *factor2;
212 const int *iweight1, *iweight2;
214 if (!d->work_chunks[dv_work_pool_size(d)-1].buf_offset) {
216 for (c=0; c<d->n_difchan; c++) {
217 for (s=0; s<d->difseg_size; s++) {
219 for (j=0; j<27; j++) {
221 if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
222 !(DV_PROFILE_IS_720p50(d) && s > 9)) {
223 dv_calc_mb_coordinates(d, c, s, j, &d->work_chunks[i].mb_coordinates[0]);
224 d->work_chunks[i++].buf_offset = p;
232 if (!d->idct_factor[DV_PROFILE_IS_HD(d)?8191:5631]) {
233 factor1 = &d->idct_factor[0];
234 factor2 = &d->idct_factor[DV_PROFILE_IS_HD(d)?4096:2816];
235 if (d->height == 720) {
236 iweight1 = &dv_iweight_720_y[0];
237 iweight2 = &dv_iweight_720_c[0];
239 iweight1 = &dv_iweight_1080_y[0];
240 iweight2 = &dv_iweight_1080_c[0];
242 if (DV_PROFILE_IS_HD(d)) {
243 for (c = 0; c < 4; c++) {
244 for (s = 0; s < 16; s++) {
245 for (i = 0; i < 64; i++) {
246 *factor1++ = (dv100_qstep[s] << (c + 9)) * iweight1[i];
247 *factor2++ = (dv100_qstep[s] << (c + 9)) * iweight2[i];
252 iweight1 = &dv_iweight_88[0];
253 for (j = 0; j < 2; j++, iweight1 = &dv_iweight_248[0]) {
254 for (s = 0; s < 22; s++) {
255 for (i = c = 0; c < 4; c++) {
256 for (; i < dv_quant_areas[c]; i++) {
257 *factor1 = iweight1[i] << (dv_quant_shifts[s][c] + 1);
258 *factor2++ = (*factor1++) << 1;
269 static av_cold int dvvideo_init(AVCodecContext *avctx)
271 DVVideoContext *s = avctx->priv_data;
278 uint16_t new_dv_vlc_bits[NB_DV_VLC*2];
279 uint8_t new_dv_vlc_len[NB_DV_VLC*2];
280 uint8_t new_dv_vlc_run[NB_DV_VLC*2];
281 int16_t new_dv_vlc_level[NB_DV_VLC*2];
285 /* it's faster to include sign bit in a generic VLC parsing scheme */
286 for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
287 new_dv_vlc_bits[j] = dv_vlc_bits[i];
288 new_dv_vlc_len[j] = dv_vlc_len[i];
289 new_dv_vlc_run[j] = dv_vlc_run[i];
290 new_dv_vlc_level[j] = dv_vlc_level[i];
292 if (dv_vlc_level[i]) {
293 new_dv_vlc_bits[j] <<= 1;
297 new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1;
298 new_dv_vlc_len[j] = dv_vlc_len[i] + 1;
299 new_dv_vlc_run[j] = dv_vlc_run[i];
300 new_dv_vlc_level[j] = -dv_vlc_level[i];
304 /* NOTE: as a trick, we use the fact the no codes are unused
305 to accelerate the parsing of partial codes */
306 init_vlc(&dv_vlc, TEX_VLC_BITS, j,
307 new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0);
308 assert(dv_vlc.table_size == 1184);
310 for (i = 0; i < dv_vlc.table_size; i++){
311 int code = dv_vlc.table[i][0];
312 int len = dv_vlc.table[i][1];
315 if (len < 0){ //more bits needed
319 run = new_dv_vlc_run [code] + 1;
320 level = new_dv_vlc_level[code];
322 dv_rl_vlc[i].len = len;
323 dv_rl_vlc[i].level = level;
324 dv_rl_vlc[i].run = run;
328 for (i = 0; i < NB_DV_VLC - 1; i++) {
329 if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)
332 if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)
336 if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0)
339 dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc =
340 dv_vlc_bits[i] << (!!dv_vlc_level[i]);
341 dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size =
342 dv_vlc_len[i] + (!!dv_vlc_level[i]);
344 for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) {
346 for (j = 1; j < DV_VLC_MAP_LEV_SIZE; j++) {
347 if (dv_vlc_map[i][j].size == 0) {
348 dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc |
349 (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size));
350 dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size +
351 dv_vlc_map[0][j].size;
355 for (j = 1; j < DV_VLC_MAP_LEV_SIZE/2; j++) {
356 if (dv_vlc_map[i][j].size == 0) {
357 dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc |
358 (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size));
359 dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size +
360 dv_vlc_map[0][j].size;
362 dv_vlc_map[i][((uint16_t)(-j))&0x1ff].vlc =
363 dv_vlc_map[i][j].vlc | 1;
364 dv_vlc_map[i][((uint16_t)(-j))&0x1ff].size =
365 dv_vlc_map[i][j].size;
371 /* Generic DSP setup */
372 dsputil_init(&dsp, avctx);
373 ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp);
374 s->get_pixels = dsp.get_pixels;
375 s->ildct_cmp = dsp.ildct_cmp[5];
378 s->fdct[0] = dsp.fdct;
379 s->idct_put[0] = dsp.idct_put;
380 for (i = 0; i < 64; i++)
381 s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]];
384 s->fdct[1] = dsp.fdct248;
385 s->idct_put[1] = ff_simple_idct248_put; // FIXME: need to add it to DSP
387 for (i = 0; i < 64; i++){
388 int j = ff_zigzag248_direct[i];
389 s->dv_zigzag[1][i] = dsp.idct_permutation[(j & 7) + (j & 8) * 4 + (j & 48) / 2];
392 memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);
394 avctx->coded_frame = &s->picture;
396 avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
401 static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
403 if (!ff_dv_codec_profile(avctx)) {
404 av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video\n",
405 avctx->width, avctx->height, avcodec_get_pix_fmt_name(avctx->pix_fmt));
409 return dvvideo_init(avctx);
413 // #define printf(...) av_log(NULL, AV_LOG_ERROR, __VA_ARGS__)
415 typedef struct BlockInfo {
416 const uint32_t *factor_table;
417 const uint8_t *scan_table;
418 uint8_t pos; /* position in block */
419 void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
420 uint8_t partial_bit_count;
421 uint16_t partial_bit_buffer;
425 /* bit budget for AC only in 5 MBs */
426 static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
427 /* see dv_88_areas and dv_248_areas for details */
428 static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
430 static inline int put_bits_left(PutBitContext* s)
432 return (s->buf_end - s->buf) * 8 - put_bits_count(s);
435 /* decode ac coefficients */
436 static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
438 int last_index = gb->size_in_bits;
439 const uint8_t *scan_table = mb->scan_table;
440 const uint32_t *factor_table = mb->factor_table;
442 int partial_bit_count = mb->partial_bit_count;
443 int level, run, vlc_len, index;
446 UPDATE_CACHE(re, gb);
448 /* if we must parse a partial vlc, we do it here */
449 if (partial_bit_count > 0) {
450 re_cache = ((unsigned)re_cache >> partial_bit_count) |
451 (mb->partial_bit_buffer << (sizeof(re_cache) * 8 - partial_bit_count));
452 re_index -= partial_bit_count;
453 mb->partial_bit_count = 0;
456 /* get the AC coefficients until last_index is reached */
459 printf("%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16), re_index);
461 /* our own optimized GET_RL_VLC */
462 index = NEG_USR32(re_cache, TEX_VLC_BITS);
463 vlc_len = dv_rl_vlc[index].len;
465 index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level;
466 vlc_len = TEX_VLC_BITS - vlc_len;
468 level = dv_rl_vlc[index].level;
469 run = dv_rl_vlc[index].run;
471 /* gotta check if we're still within gb boundaries */
472 if (re_index + vlc_len > last_index) {
473 /* should be < 16 bits otherwise a codeword could have been parsed */
474 mb->partial_bit_count = last_index - re_index;
475 mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count);
476 re_index = last_index;
482 printf("run=%d level=%d\n", run, level);
488 level = (level * factor_table[pos] + (1 << (dv_iweight_bits - 1))) >> dv_iweight_bits;
489 block[scan_table[pos]] = level;
491 UPDATE_CACHE(re, gb);
493 CLOSE_READER(re, gb);
497 static inline void bit_copy(PutBitContext *pb, GetBitContext *gb)
499 int bits_left = get_bits_left(gb);
500 while (bits_left >= MIN_CACHE_BITS) {
501 put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS));
502 bits_left -= MIN_CACHE_BITS;
505 put_bits(pb, bits_left, get_bits(gb, bits_left));
509 static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y)
511 *mb_x = work_chunk->mb_coordinates[m] & 0xff;
512 *mb_y = work_chunk->mb_coordinates[m] >> 8;
514 /* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */
515 if (s->sys->height == 720 && !(s->buf[1]&0x0C)) {
516 *mb_y -= (*mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */
520 /* mb_x and mb_y are in units of 8 pixels */
521 static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
523 DVVideoContext *s = avctx->priv_data;
524 DVwork_chunk *work_chunk = arg;
525 int quant, dc, dct_mode, class1, j;
526 int mb_index, mb_x, mb_y, last_index;
527 int y_stride, linesize;
528 DCTELEM *block, *block1;
531 const uint8_t *buf_ptr;
532 PutBitContext pb, vs_pb;
534 BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1;
535 DECLARE_ALIGNED_16(DCTELEM, sblock)[5*DV_MAX_BPM][64];
536 DECLARE_ALIGNED_16(uint8_t, mb_bit_buffer)[80 + 4]; /* allow some slack */
537 DECLARE_ALIGNED_16(uint8_t, vs_bit_buffer)[5 * 80 + 4]; /* allow some slack */
538 const int log2_blocksize = 3-s->avctx->lowres;
539 int is_field_mode[5];
541 assert((((int)mb_bit_buffer) & 7) == 0);
542 assert((((int)vs_bit_buffer) & 7) == 0);
544 memset(sblock, 0, sizeof(sblock));
546 /* pass 1 : read DC and AC coefficients in blocks */
547 buf_ptr = &s->buf[work_chunk->buf_offset*80];
548 block1 = &sblock[0][0];
550 init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80);
551 for (mb_index = 0; mb_index < 5; mb_index++, mb1 += s->sys->bpm, block1 += s->sys->bpm * 64) {
553 quant = buf_ptr[3] & 0x0f;
555 init_put_bits(&pb, mb_bit_buffer, 80);
558 is_field_mode[mb_index] = 0;
559 for (j = 0; j < s->sys->bpm; j++) {
560 last_index = s->sys->block_sizes[j];
561 init_get_bits(&gb, buf_ptr, last_index);
564 dc = get_sbits(&gb, 9);
565 dct_mode = get_bits1(&gb);
566 class1 = get_bits(&gb, 2);
567 if (DV_PROFILE_IS_HD(s->sys)) {
568 mb->idct_put = s->idct_put[0];
569 mb->scan_table = s->dv_zigzag[0];
570 mb->factor_table = &s->sys->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64];
571 is_field_mode[mb_index] |= !j && dct_mode;
573 mb->idct_put = s->idct_put[dct_mode && log2_blocksize == 3];
574 mb->scan_table = s->dv_zigzag[dct_mode];
575 mb->factor_table = &s->sys->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 +
576 (quant + dv_quant_offset[class1])*64];
579 /* convert to unsigned because 128 is not added in the
583 buf_ptr += last_index >> 3;
585 mb->partial_bit_count = 0;
588 printf("MB block: %d, %d ", mb_index, j);
590 dv_decode_ac(&gb, mb, block);
592 /* write the remaining bits in a new buffer only if the
601 /* pass 2 : we can do it just after */
603 printf("***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index);
607 init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb));
609 for (j = 0; j < s->sys->bpm; j++, block += 64, mb++) {
610 if (mb->pos < 64 && get_bits_left(&gb) > 0) {
611 dv_decode_ac(&gb, mb, block);
612 /* if still not finished, no need to parse other blocks */
617 /* all blocks are finished, so the extra bytes can be used at
618 the video segment level */
619 if (j >= s->sys->bpm)
620 bit_copy(&vs_pb, &gb);
623 /* we need a pass other the whole video segment */
625 printf("***pass 3 size=%d\n", put_bits_count(&vs_pb));
627 block = &sblock[0][0];
629 init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb));
630 flush_put_bits(&vs_pb);
631 for (mb_index = 0; mb_index < 5; mb_index++) {
632 for (j = 0; j < s->sys->bpm; j++) {
635 printf("start %d:%d\n", mb_index, j);
637 dv_decode_ac(&gb, mb, block);
639 if (mb->pos >= 64 && mb->pos < 127)
640 av_log(avctx, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos);
646 /* compute idct and place blocks */
647 block = &sblock[0][0];
649 for (mb_index = 0; mb_index < 5; mb_index++) {
650 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
652 /* idct_put'ting luminance */
653 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
654 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
655 (s->sys->height >= 720 && mb_y != 134)) {
656 y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
658 y_stride = (2 << log2_blocksize);
660 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize);
661 linesize = s->picture.linesize[0] << is_field_mode[mb_index];
662 mb[0] .idct_put(y_ptr , linesize, block + 0*64);
663 if (s->sys->video_stype == 4) { /* SD 422 */
664 mb[2].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 2*64);
666 mb[1].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 1*64);
667 mb[2].idct_put(y_ptr + y_stride, linesize, block + 2*64);
668 mb[3].idct_put(y_ptr + (1 << log2_blocksize) + y_stride, linesize, block + 3*64);
673 /* idct_put'ting chrominance */
674 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
675 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize);
676 for (j = 2; j; j--) {
677 uint8_t *c_ptr = s->picture.data[j] + c_offset;
678 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
679 uint64_t aligned_pixels[64/8];
680 uint8_t *pixels = (uint8_t*)aligned_pixels;
681 uint8_t *c_ptr1, *ptr1;
683 mb->idct_put(pixels, 8, block);
684 for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) {
685 ptr1 = pixels + (1 << (log2_blocksize - 1));
686 c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize);
687 for (x = 0; x < (1 << (log2_blocksize - 1)); x++) {
688 c_ptr[x] = pixels[x];
694 y_stride = (mb_y == 134) ? (1 << log2_blocksize) :
695 s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
696 linesize = s->picture.linesize[j] << is_field_mode[mb_index];
697 (mb++)-> idct_put(c_ptr , linesize, block); block += 64;
698 if (s->sys->bpm == 8) {
699 (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64;
708 /* Converts run and level (where level != 0) pair into vlc, returning bit size */
709 static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
712 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
713 *vlc = dv_vlc_map[run][level].vlc | sign;
714 size = dv_vlc_map[run][level].size;
717 if (level < DV_VLC_MAP_LEV_SIZE) {
718 *vlc = dv_vlc_map[0][level].vlc | sign;
719 size = dv_vlc_map[0][level].size;
721 *vlc = 0xfe00 | (level << 1) | sign;
725 *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
726 (0x1f80 | (run - 1))) << size;
727 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
734 static av_always_inline int dv_rl2vlc_size(int run, int level)
738 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
739 size = dv_vlc_map[run][level].size;
742 size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
744 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
750 static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
752 *vlc = dv_vlc_map[run][l].vlc | sign;
753 return dv_vlc_map[run][l].size;
756 static av_always_inline int dv_rl2vlc_size(int run, int l)
758 return dv_vlc_map[run][l].size;
762 typedef struct EncBlockInfo {
772 uint8_t partial_bit_count;
773 uint32_t partial_bit_buffer; /* we can't use uint16_t here */
776 static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi,
777 PutBitContext* pb_pool,
778 PutBitContext* pb_end)
781 PutBitContext* pb = pb_pool;
782 int size = bi->partial_bit_count;
783 uint32_t vlc = bi->partial_bit_buffer;
785 bi->partial_bit_count = bi->partial_bit_buffer = 0;
787 /* Find suitable storage space */
788 for (; size > (bits_left = put_bits_left(pb)); pb++) {
791 put_bits(pb, bits_left, vlc >> size);
792 vlc = vlc & ((1 << size) - 1);
794 if (pb + 1 >= pb_end) {
795 bi->partial_bit_count = size;
796 bi->partial_bit_buffer = vlc;
802 put_bits(pb, size, vlc);
804 if (bi->cur_ac >= 64)
807 /* Construct the next VLC */
809 bi->cur_ac = bi->next[prev];
810 if (bi->cur_ac < 64){
811 size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
813 size = 4; vlc = 6; /* End Of Block stamp */
819 static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) {
820 if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
821 int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400;
823 int is = s->ildct_cmp(NULL, data , NULL, linesize<<1, 4) +
824 s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
832 static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
835 const uint8_t* zigzag_scan;
836 DECLARE_ALIGNED_16(DCTELEM, blk)[64];
838 /* We offer two different methods for class number assignment: the
839 method suggested in SMPTE 314M Table 22, and an improved
840 method. The SMPTE method is very conservative; it assigns class
841 3 (i.e. severe quantization) to any block where the largest AC
842 component is greater than 36. FFmpeg's DV encoder tracks AC bit
843 consumption precisely, so there is no need to bias most blocks
844 towards strongly lossy compression. Instead, we assign class 2
845 to most blocks, and use class 3 only when strictly necessary
846 (for blocks whose largest AC component exceeds 255). */
848 #if 0 /* SMPTE spec method */
849 static const int classes[] = {12, 24, 36, 0xffff};
850 #else /* improved FFmpeg method */
851 static const int classes[] = {-1, -1, 255, 0xffff};
853 int max = classes[0];
856 assert((((int)blk) & 15) == 0);
858 bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
859 bi->partial_bit_count = 0;
860 bi->partial_bit_buffer = 0;
863 bi->dct_mode = dv_guess_dct_mode(s, data, linesize);
864 s->get_pixels(blk, data, linesize);
865 s->fdct[bi->dct_mode](blk);
867 /* We rely on the fact that encoding all zeros leads to an immediate EOB,
868 which is precisely what the spec calls for in the "dummy" blocks. */
869 memset(blk, 0, sizeof(blk));
874 zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
875 weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
877 for (area = 0; area < 4; area++) {
878 bi->prev[area] = prev;
879 bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
880 for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) {
881 int level = blk[zigzag_scan[i]];
883 if (level + 15 > 30U) {
884 bi->sign[i] = (level >> 31) & 1;
885 /* weigh it and and shift down into range, adding for rounding */
886 /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT
887 AND the 2x doubling of the weights */
888 level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4);
892 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level);
899 for (bi->cno = 0; max > classes[bi->cno]; bi->cno++);
907 for (area = 0; area < 4; area++) {
908 bi->prev[area] = prev;
909 bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
910 for (; i < mb_area_start[area+1]; i = bi->next[i]) {
914 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
923 return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
926 static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
929 int i, j, k, a, prev, a2;
932 size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24;
935 for (i = 0; i < 5; i++) {
941 for (j = 0; j < 6; j++, b++) {
942 for (a = 0; a < 4; a++) {
943 if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) {
944 b->bit_size[a] = 1; // 4 areas 4 bits for EOB :)
947 assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
948 for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) {
951 b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
954 if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
955 for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++)
958 assert(b->mb[b->next[k]]);
959 b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
960 -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]);
961 assert(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k));
964 b->next[prev] = b->next[k];
969 size[i] += b->bit_size[a];
972 if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
975 } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
978 for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){
980 size[0] = 5 * 6 * 4; //EOB
981 for (j = 0; j < 6 *5; j++, b++) {
983 for (k = b->next[prev]; k < 64; k = b->next[k]) {
984 if (b->mb[k] < a && b->mb[k] > -a){
985 b->next[prev] = b->next[k];
987 size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
995 static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
997 DVVideoContext *s = avctx->priv_data;
998 DVwork_chunk *work_chunk = arg;
1000 int mb_x, mb_y, c_offset, linesize, y_stride;
1003 uint8_t scratch[64];
1004 EncBlockInfo enc_blks[5*DV_MAX_BPM];
1005 PutBitContext pbs[5*DV_MAX_BPM];
1007 EncBlockInfo* enc_blk;
1008 int vs_bit_size = 0;
1009 int qnos[5] = {15, 15, 15, 15, 15}; /* No quantization */
1010 int* qnosp = &qnos[0];
1012 dif = &s->buf[work_chunk->buf_offset*80];
1013 enc_blk = &enc_blks[0];
1014 for (mb_index = 0; mb_index < 5; mb_index++) {
1015 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
1017 /* initializing luminance blocks */
1018 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
1019 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
1020 (s->sys->height >= 720 && mb_y != 134)) {
1021 y_stride = s->picture.linesize[0] << 3;
1025 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3);
1026 linesize = s->picture.linesize[0];
1028 if (s->sys->video_stype == 4) { /* SD 422 */
1030 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
1031 dv_init_enc_block(enc_blk+1, NULL , linesize, s, 0) +
1032 dv_init_enc_block(enc_blk+2, y_ptr + 8 , linesize, s, 0) +
1033 dv_init_enc_block(enc_blk+3, NULL , linesize, s, 0);
1036 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
1037 dv_init_enc_block(enc_blk+1, y_ptr + 8 , linesize, s, 0) +
1038 dv_init_enc_block(enc_blk+2, y_ptr + y_stride, linesize, s, 0) +
1039 dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
1043 /* initializing chrominance blocks */
1044 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
1045 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << 3);
1046 for (j = 2; j; j--) {
1047 uint8_t *c_ptr = s->picture.data[j] + c_offset;
1048 linesize = s->picture.linesize[j];
1049 y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3);
1050 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
1052 uint8_t* b = scratch;
1053 for (i = 0; i < 8; i++) {
1054 d = c_ptr + (linesize << 3);
1055 b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
1056 b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3];
1064 vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1);
1065 if (s->sys->bpm == 8) {
1066 vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
1071 if (vs_total_ac_bits < vs_bit_size)
1072 dv_guess_qnos(&enc_blks[0], qnosp);
1074 /* DIF encoding process */
1075 for (j=0; j<5*s->sys->bpm;) {
1081 /* First pass over individual cells only */
1082 for (i=0; i<s->sys->bpm; i++, j++) {
1083 int sz = s->sys->block_sizes[i]>>3;
1085 init_put_bits(&pbs[j], dif, sz);
1086 put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2);
1087 put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
1088 put_bits(&pbs[j], 2, enc_blks[j].cno);
1090 dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
1094 /* Second pass over each MB space */
1095 pb = &pbs[start_mb];
1096 for (i=0; i<s->sys->bpm; i++) {
1097 if (enc_blks[start_mb+i].partial_bit_count)
1098 pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
1102 /* Third and final pass over the whole video segment space */
1104 for (j=0; j<5*s->sys->bpm; j++) {
1105 if (enc_blks[j].partial_bit_count)
1106 pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
1107 if (enc_blks[j].partial_bit_count)
1108 av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n");
1111 for (j=0; j<5*s->sys->bpm; j++) {
1113 int size = pbs[j].size_in_bits >> 3;
1114 flush_put_bits(&pbs[j]);
1115 pos = put_bits_count(&pbs[j]) >> 3;
1117 av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n");
1120 memset(pbs[j].buf + pos, 0xff, size - pos);
1126 #if CONFIG_DVVIDEO_DECODER
1127 /* NOTE: exactly one frame must be given (120000 bytes for NTSC,
1128 144000 bytes for PAL - or twice those for 50Mbps) */
1129 static int dvvideo_decode_frame(AVCodecContext *avctx,
1130 void *data, int *data_size,
1133 const uint8_t *buf = avpkt->data;
1134 int buf_size = avpkt->size;
1135 DVVideoContext *s = avctx->priv_data;
1137 s->sys = ff_dv_frame_profile(s->sys, buf, buf_size);
1138 if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys)) {
1139 av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
1140 return -1; /* NOTE: we only accept several full frames */
1143 if (s->picture.data[0])
1144 avctx->release_buffer(avctx, &s->picture);
1146 s->picture.reference = 0;
1147 s->picture.key_frame = 1;
1148 s->picture.pict_type = FF_I_TYPE;
1149 avctx->pix_fmt = s->sys->pix_fmt;
1150 avctx->time_base = s->sys->time_base;
1151 avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
1152 if (avctx->get_buffer(avctx, &s->picture) < 0) {
1153 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
1156 s->picture.interlaced_frame = 1;
1157 s->picture.top_field_first = 0;
1160 avctx->execute(avctx, dv_decode_video_segment, s->sys->work_chunks, NULL,
1161 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
1166 *data_size = sizeof(AVFrame);
1167 *(AVFrame*)data = s->picture;
1169 return s->sys->frame_size;
1171 #endif /* CONFIG_DVVIDEO_DECODER */
1174 static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
1178 * Here's what SMPTE314M says about these two:
1179 * (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical
1180 * as track application IDs (APTn = 001, AP1n =
1181 * 001, AP2n = 001, AP3n = 001), if the source signal
1182 * comes from a digital VCR. If the signal source is
1183 * unknown, all bits for these data shall be set to 1.
1184 * (page 12) STYPE: STYPE defines a signal type of video signal
1185 * 00000b = 4:1:1 compression
1186 * 00100b = 4:2:2 compression
1188 * Now, I've got two problems with these statements:
1189 * 1. it looks like APT == 111b should be a safe bet, but it isn't.
1190 * It seems that for PAL as defined in IEC 61834 we have to set
1191 * APT to 000 and for SMPTE314M to 001.
1192 * 2. It is not at all clear what STYPE is used for 4:2:0 PAL
1193 * compression scheme (if any).
1195 int apt = (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0 : 1);
1198 if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17) /* 16:9 */
1201 buf[0] = (uint8_t)pack_id;
1203 case dv_header525: /* I can't imagine why these two weren't defined as real */
1204 case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */
1205 buf[1] = 0xf8 | /* reserved -- always 1 */
1206 (apt & 0x07); /* APT: Track application ID */
1207 buf[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */
1208 (0x0f << 3) | /* reserved -- always 1 */
1209 (apt & 0x07); /* AP1: Audio application ID */
1210 buf[3] = (0 << 7) | /* TF2: video data is 0 - valid; 1 - invalid */
1211 (0x0f << 3) | /* reserved -- always 1 */
1212 (apt & 0x07); /* AP2: Video application ID */
1213 buf[4] = (0 << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */
1214 (0x0f << 3) | /* reserved -- always 1 */
1215 (apt & 0x07); /* AP3: Subcode application ID */
1217 case dv_video_source:
1218 buf[1] = 0xff; /* reserved -- always 1 */
1219 buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
1220 (1 << 6) | /* following CLF is valid - 0, invalid - 1 */
1221 (3 << 4) | /* CLF: color frames ID (see ITU-R BT.470-4) */
1222 0xf; /* reserved -- always 1 */
1223 buf[3] = (3 << 6) | /* reserved -- always 1 */
1224 (c->sys->dsf << 5) | /* system: 60fields/50fields */
1225 c->sys->video_stype; /* signal type video compression */
1226 buf[4] = 0xff; /* VISC: 0xff -- no information */
1228 case dv_video_control:
1229 buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
1230 0x3f; /* reserved -- always 1 */
1231 buf[2] = 0xc8 | /* reserved -- always b11001xxx */
1233 buf[3] = (1 << 7) | /* frame/field flag 1 -- frame, 0 -- field */
1234 (1 << 6) | /* first/second field flag 0 -- field 2, 1 -- field 1 */
1235 (1 << 5) | /* frame change flag 0 -- same picture as before, 1 -- different */
1236 (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */
1237 0xc; /* reserved -- always b1100 */
1238 buf[4] = 0xff; /* reserved -- always 1 */
1241 buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
1246 #if CONFIG_DVVIDEO_ENCODER
1247 static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
1251 for (chan = 0; chan < c->sys->n_difchan; chan++) {
1252 for (i = 0; i < c->sys->difseg_size; i++) {
1253 memset(buf, 0xff, 80 * 6); /* first 6 DIF blocks are for control data */
1255 /* DV header: 1DIF */
1256 buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
1257 buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
1258 buf += 72; /* unused bytes */
1260 /* DV subcode: 2DIFs */
1261 for (j = 0; j < 2; j++) {
1262 buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
1263 for (k = 0; k < 6; k++)
1264 buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
1265 buf += 29; /* unused bytes */
1268 /* DV VAUX: 3DIFS */
1269 for (j = 0; j < 3; j++) {
1270 buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
1271 buf += dv_write_pack(dv_video_source, c, buf);
1272 buf += dv_write_pack(dv_video_control, c, buf);
1274 buf += dv_write_pack(dv_video_source, c, buf);
1275 buf += dv_write_pack(dv_video_control, c, buf);
1276 buf += 4*5 + 2; /* unused bytes */
1279 /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */
1280 for (j = 0; j < 135; j++) {
1282 memset(buf, 0xff, 80);
1283 buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
1284 buf += 77; /* audio control & shuffled PCM audio */
1286 buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
1287 buf += 77; /* 1 video macroblock: 1 bytes control
1288 4 * 14 bytes Y 8x8 data
1289 10 bytes Cr 8x8 data
1290 10 bytes Cb 8x8 data */
1297 static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size,
1300 DVVideoContext *s = c->priv_data;
1302 s->sys = ff_dv_codec_profile(c);
1303 if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys))
1306 c->pix_fmt = s->sys->pix_fmt;
1307 s->picture = *((AVFrame *)data);
1308 s->picture.key_frame = 1;
1309 s->picture.pict_type = FF_I_TYPE;
1312 c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
1313 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
1317 dv_format_frame(s, buf);
1319 return s->sys->frame_size;
1323 static int dvvideo_close(AVCodecContext *c)
1325 DVVideoContext *s = c->priv_data;
1327 if (s->picture.data[0])
1328 c->release_buffer(c, &s->picture);
1334 #if CONFIG_DVVIDEO_ENCODER
1335 AVCodec dvvideo_encoder = {
1339 sizeof(DVVideoContext),
1340 dvvideo_init_encoder,
1341 dvvideo_encode_frame,
1342 .pix_fmts = (const enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE},
1343 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
1345 #endif // CONFIG_DVVIDEO_ENCODER
1347 #if CONFIG_DVVIDEO_DECODER
1348 AVCodec dvvideo_decoder = {
1352 sizeof(DVVideoContext),
1356 dvvideo_decode_frame,
1359 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),