comparison dv.c @ 7715:e8f71784062e libavcodec

Intial implementation of the DV100 (AKA DVCPRO HD) decoder and demuxer as specified in SMPTE 370M
author romansh
date Thu, 28 Aug 2008 22:41:00 +0000
parents 5b1991f9f129
children dbcdd0165e55
comparison
equal deleted inserted replaced
7714:f0f8bb920b24 7715:e8f71784062e
6 * DV encoder 6 * DV encoder
7 * Copyright (c) 2003 Roman Shaposhnik. 7 * Copyright (c) 2003 Roman Shaposhnik.
8 * 8 *
9 * 50 Mbps (DVCPRO50) support 9 * 50 Mbps (DVCPRO50) support
10 * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com> 10 * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
11 *
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
11 * 15 *
12 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth 16 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
13 * of DV technical info. 17 * of DV technical info.
14 * 18 *
15 * This file is part of FFmpeg. 19 * This file is part of FFmpeg.
49 AVCodecContext *avctx; 53 AVCodecContext *avctx;
50 uint8_t *buf; 54 uint8_t *buf;
51 55
52 uint8_t dv_zigzag[2][64]; 56 uint8_t dv_zigzag[2][64];
53 uint32_t dv_idct_factor[2][2][22][64]; 57 uint32_t dv_idct_factor[2][2][22][64];
58 uint32_t dv100_idct_factor[4][4][16][64];
54 59
55 void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size); 60 void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size);
56 void (*fdct[2])(DCTELEM *block); 61 void (*fdct[2])(DCTELEM *block);
57 void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block); 62 void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block);
58 } DVVideoContext; 63 } DVVideoContext;
59 64
60 /* MultiThreading - dv_anchor applies to entire DV codec, not just the avcontext */ 65 /* MultiThreading - dv_anchor applies to entire DV codec, not just the avcontext */
61 /* one element is needed for each video segment in a DV frame */ 66 /* one element is needed for each video segment in a DV frame */
62 /* at most there are 2 DIF channels * 12 DIF sequences * 27 video segments (PAL 50Mbps) */ 67 /* at most there are 4 DIF channels * 12 DIF sequences * 27 video segments (1080i50) */
63 #define DV_ANCHOR_SIZE (2*12*27) 68 #define DV_ANCHOR_SIZE (4*12*27)
64 69
65 static void* dv_anchor[DV_ANCHOR_SIZE]; 70 static void* dv_anchor[DV_ANCHOR_SIZE];
66 71
67 #define TEX_VLC_BITS 9 72 #define TEX_VLC_BITS 9
68 73
97 s->dv_idct_factor[1][0][q][i] = s->dv_idct_factor[0][0][q][i]<<1; 102 s->dv_idct_factor[1][0][q][i] = s->dv_idct_factor[0][0][q][i]<<1;
98 103
99 /* 248 table */ 104 /* 248 table */
100 s->dv_idct_factor[0][1][q][i] = dv_iweight_248[i]<<(dv_quant_shifts[q][a] + 1); 105 s->dv_idct_factor[0][1][q][i] = dv_iweight_248[i]<<(dv_quant_shifts[q][a] + 1);
101 s->dv_idct_factor[1][1][q][i] = s->dv_idct_factor[0][1][q][i]<<1; 106 s->dv_idct_factor[1][1][q][i] = s->dv_idct_factor[0][1][q][i]<<1;
107 }
108 }
109 }
110
111 for(a = 0; a < 4; a++) {
112 for(q = 0; q < 16; q++) {
113 for(i = 1; i < 64; i++) {
114 s->dv100_idct_factor[0][a][q][i]= (dv100_qstep[q]<<(a+9))*dv_iweight_1080_y[i];
115 s->dv100_idct_factor[1][a][q][i]= (dv100_qstep[q]<<(a+9))*dv_iweight_1080_c[i];
116 s->dv100_idct_factor[2][a][q][i]= (dv100_qstep[q]<<(a+9))*dv_iweight_720_y[i];
117 s->dv100_idct_factor[3][a][q][i]= (dv100_qstep[q]<<(a+9))*dv_iweight_720_c[i];
102 } 118 }
103 } 119 }
104 } 120 }
105 } 121 }
106 122
347 const uint8_t *buf_ptr1, 363 const uint8_t *buf_ptr1,
348 const uint16_t *mb_pos_ptr) 364 const uint16_t *mb_pos_ptr)
349 { 365 {
350 int quant, dc, dct_mode, class1, j; 366 int quant, dc, dct_mode, class1, j;
351 int mb_index, mb_x, mb_y, v, last_index; 367 int mb_index, mb_x, mb_y, v, last_index;
368 int y_stride, i;
352 DCTELEM *block, *block1; 369 DCTELEM *block, *block1;
353 int c_offset; 370 int c_offset;
354 uint8_t *y_ptr; 371 uint8_t *y_ptr;
355 const uint8_t *buf_ptr; 372 const uint8_t *buf_ptr;
356 PutBitContext pb, vs_pb; 373 PutBitContext pb, vs_pb;
358 BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1; 375 BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1;
359 DECLARE_ALIGNED_16(DCTELEM, sblock[5*DV_MAX_BPM][64]); 376 DECLARE_ALIGNED_16(DCTELEM, sblock[5*DV_MAX_BPM][64]);
360 DECLARE_ALIGNED_8(uint8_t, mb_bit_buffer[80 + 4]); /* allow some slack */ 377 DECLARE_ALIGNED_8(uint8_t, mb_bit_buffer[80 + 4]); /* allow some slack */
361 DECLARE_ALIGNED_8(uint8_t, vs_bit_buffer[5 * 80 + 4]); /* allow some slack */ 378 DECLARE_ALIGNED_8(uint8_t, vs_bit_buffer[5 * 80 + 4]); /* allow some slack */
362 const int log2_blocksize= 3-s->avctx->lowres; 379 const int log2_blocksize= 3-s->avctx->lowres;
380 int is_field_mode[5];
363 381
364 assert((((int)mb_bit_buffer)&7)==0); 382 assert((((int)mb_bit_buffer)&7)==0);
365 assert((((int)vs_bit_buffer)&7)==0); 383 assert((((int)vs_bit_buffer)&7)==0);
366 384
367 memset(sblock, 0, sizeof(sblock)); 385 memset(sblock, 0, sizeof(sblock));
376 quant = buf_ptr[3] & 0x0f; 394 quant = buf_ptr[3] & 0x0f;
377 buf_ptr += 4; 395 buf_ptr += 4;
378 init_put_bits(&pb, mb_bit_buffer, 80); 396 init_put_bits(&pb, mb_bit_buffer, 80);
379 mb = mb1; 397 mb = mb1;
380 block = block1; 398 block = block1;
399 is_field_mode[mb_index] = 0;
381 for(j = 0;j < s->sys->bpm; j++) { 400 for(j = 0;j < s->sys->bpm; j++) {
382 last_index = s->sys->block_sizes[j]; 401 last_index = s->sys->block_sizes[j];
383 init_get_bits(&gb, buf_ptr, last_index); 402 init_get_bits(&gb, buf_ptr, last_index);
384 403
385 /* get the dc */ 404 /* get the dc */
386 dc = get_sbits(&gb, 9); 405 dc = get_sbits(&gb, 9);
387 dct_mode = get_bits1(&gb); 406 dct_mode = get_bits1(&gb);
388 class1 = get_bits(&gb, 2); 407 class1 = get_bits(&gb, 2);
389 mb->idct_put = s->idct_put[dct_mode && log2_blocksize==3]; 408 if (DV_PROFILE_IS_HD(s->sys)) {
390 mb->scan_table = s->dv_zigzag[dct_mode]; 409 mb->idct_put = s->idct_put[0];
391 mb->factor_table = s->dv_idct_factor[class1 == 3][dct_mode] 410 mb->scan_table = s->dv_zigzag[0];
392 [quant + dv_quant_offset[class1]]; 411 mb->factor_table = s->dv100_idct_factor[((s->sys->height == 720)<<1)&(j < 4)][class1][quant];
412 is_field_mode[mb_index] |= !j && dct_mode;
413 } else {
414 mb->idct_put = s->idct_put[dct_mode && log2_blocksize==3];
415 mb->scan_table = s->dv_zigzag[dct_mode];
416 mb->factor_table = s->dv_idct_factor[class1 == 3][dct_mode]
417 [quant + dv_quant_offset[class1]];
418 }
393 dc = dc << 2; 419 dc = dc << 2;
394 /* convert to unsigned because 128 is not added in the 420 /* convert to unsigned because 128 is not added in the
395 standard IDCT */ 421 standard IDCT */
396 dc += 1024; 422 dc += 1024;
397 block[0] = dc; 423 block[0] = dc;
463 mb = mb_data; 489 mb = mb_data;
464 for(mb_index = 0; mb_index < 5; mb_index++) { 490 for(mb_index = 0; mb_index < 5; mb_index++) {
465 v = *mb_pos_ptr++; 491 v = *mb_pos_ptr++;
466 mb_x = v & 0xff; 492 mb_x = v & 0xff;
467 mb_y = v >> 8; 493 mb_y = v >> 8;
494 /* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */
495 if (s->sys->height == 720 && ((s->buf[1]>>2)&0x3) == 0) {
496 mb_y -= (mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */
497 }
498
499 /* idct_put'ting luminance */
500 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
501 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
502 (s->sys->height >= 720 && mb_y != 134)) {
503 y_stride = (s->picture.linesize[0]<<((!is_field_mode[mb_index])*log2_blocksize)) - (2<<log2_blocksize);
504 } else {
505 y_stride = 0;
506 }
468 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<<log2_blocksize); 507 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<<log2_blocksize);
508 for(j = 0; j < 2; j++, y_ptr += y_stride) {
509 for (i=0; i<2; i++, block += 64, mb++, y_ptr += (1<<log2_blocksize))
510 if (s->sys->pix_fmt == PIX_FMT_YUV422P && s->sys->width == 720 && i)
511 y_ptr -= (1<<log2_blocksize);
512 else
513 mb->idct_put(y_ptr, s->picture.linesize[0]<<is_field_mode[mb_index], block);
514 }
515
516 /* idct_put'ting chrominance */
469 c_offset = (((mb_y>>(s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] + 517 c_offset = (((mb_y>>(s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
470 (mb_x>>((s->sys->pix_fmt == PIX_FMT_YUV411P)?2:1)))<<log2_blocksize); 518 (mb_x>>((s->sys->pix_fmt == PIX_FMT_YUV411P)?2:1)))<<log2_blocksize);
471 519 for(j=2; j; j--) {
472 for(j = 0;j < 6; j++) { 520 uint8_t *c_ptr = s->picture.data[j] + c_offset;
473 if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */ 521 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
474 if (j == 0 || j == 2) { 522 uint64_t aligned_pixels[64/8];
475 /* Y0 Y1 */ 523 uint8_t *pixels = (uint8_t*)aligned_pixels;
476 mb->idct_put(y_ptr + ((j >> 1)<<log2_blocksize), 524 uint8_t *c_ptr1, *ptr1;
477 s->picture.linesize[0], block); 525 int x, y;
478 } else if(j > 3) { 526 mb->idct_put(pixels, 8, block);
479 /* Cr Cb */ 527 for(y = 0; y < (1<<log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) {
480 mb->idct_put(s->picture.data[6 - j] + c_offset, 528 ptr1= pixels + (1<<(log2_blocksize-1));
481 s->picture.linesize[6 - j], block); 529 c_ptr1 = c_ptr + (s->picture.linesize[j]<<log2_blocksize);
482 } 530 for(x=0; x < (1<<(log2_blocksize-1)); x++) {
483 /* note: j=1 and j=3 are "dummy" blocks in 4:2:2 */ 531 c_ptr[x]= pixels[x];
484 } else { /* 4:1:1 or 4:2:0 */ 532 c_ptr1[x]= ptr1[x];
485 if (j < 4) { 533 }
486 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { 534 }
487 /* NOTE: at end of line, the macroblock is handled as 420 */ 535 block += 64; mb++;
488 mb->idct_put(y_ptr + (j<<log2_blocksize), s->picture.linesize[0], block); 536 } else {
489 } else { 537 y_stride = (mb_y == 134) ? (1<<log2_blocksize) :
490 mb->idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<<log2_blocksize), 538 s->picture.linesize[j]<<((!is_field_mode[mb_index])*log2_blocksize);
491 s->picture.linesize[0], block); 539 for (i=0; i<(1<<(s->sys->bpm==8)); i++, block += 64, mb++, c_ptr += y_stride)
492 } 540 mb->idct_put(c_ptr, s->picture.linesize[j]<<is_field_mode[mb_index], block);
493 } else { 541 }
494 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
495 uint64_t aligned_pixels[64/8];
496 uint8_t *pixels= (uint8_t*)aligned_pixels;
497 uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1;
498 int x, y, linesize;
499 /* NOTE: at end of line, the macroblock is handled as 420 */
500 mb->idct_put(pixels, 8, block);
501 linesize = s->picture.linesize[6 - j];
502 c_ptr = s->picture.data[6 - j] + c_offset;
503 ptr = pixels;
504 for(y = 0;y < (1<<log2_blocksize); y++) {
505 ptr1= ptr + (1<<(log2_blocksize-1));
506 c_ptr1 = c_ptr + (linesize<<log2_blocksize);
507 for(x=0; x < (1<<(log2_blocksize-1)); x++){
508 c_ptr[x]= ptr[x]; c_ptr1[x]= ptr1[x];
509 }
510 c_ptr += linesize;
511 ptr += 8;
512 }
513 } else {
514 /* don't ask me why they inverted Cb and Cr ! */
515 mb->idct_put(s->picture.data[6 - j] + c_offset,
516 s->picture.linesize[6 - j], block);
517 }
518 }
519 }
520 block += 64;
521 mb++;
522 } 542 }
523 } 543 }
524 } 544 }
525 545
526 #ifdef DV_CODEC_TINY_TARGET 546 #ifdef DV_CODEC_TINY_TARGET
966 int chan_offset = chan * s->sys->difseg_size * 150 * 80; 986 int chan_offset = chan * s->sys->difseg_size * 150 * 80;
967 987
968 /* DIF sequence */ 988 /* DIF sequence */
969 int seq = chan_slice / 27; 989 int seq = chan_slice / 27;
970 990
991 /* in 1080i50 and 720p50 some seq are unused */
992 if ((DV_PROFILE_IS_1080i50(s->sys) && chan != 0 && seq == 11) ||
993 (DV_PROFILE_IS_720p50(s->sys) && seq > 9))
994 return 0;
995
971 dv_decode_video_segment(s, &s->buf[(seq*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset], 996 dv_decode_video_segment(s, &s->buf[(seq*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset],
972 &s->sys->video_place[slice*5]); 997 &s->sys->video_place[slice*5]);
973 return 0; 998 return 0;
974 } 999 }
975 1000