Mercurial > libavcodec.hg
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 |