00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00038 #include "libavutil/avassert.h"
00039 #include "libavutil/pixdesc.h"
00040 #include "avcodec.h"
00041 #include "dsputil.h"
00042 #include "get_bits.h"
00043 #include "put_bits.h"
00044 #include "simple_idct.h"
00045 #include "dvdata.h"
00046
00047 typedef struct BlockInfo {
00048 const uint32_t *factor_table;
00049 const uint8_t *scan_table;
00050 uint8_t pos;
00051 void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
00052 uint8_t partial_bit_count;
00053 uint32_t partial_bit_buffer;
00054 int shift_offset;
00055 } BlockInfo;
00056
00057 static const int dv_iweight_bits = 14;
00058
00059
00060 static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
00061 {
00062 int last_index = gb->size_in_bits;
00063 const uint8_t *scan_table = mb->scan_table;
00064 const uint32_t *factor_table = mb->factor_table;
00065 int pos = mb->pos;
00066 int partial_bit_count = mb->partial_bit_count;
00067 int level, run, vlc_len, index;
00068
00069 OPEN_READER(re, gb);
00070 UPDATE_CACHE(re, gb);
00071
00072
00073 if (partial_bit_count > 0) {
00074 re_cache = re_cache >> partial_bit_count | mb->partial_bit_buffer;
00075 re_index -= partial_bit_count;
00076 mb->partial_bit_count = 0;
00077 }
00078
00079
00080 for (;;) {
00081 av_dlog(NULL, "%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16),
00082 re_index);
00083
00084 index = NEG_USR32(re_cache, TEX_VLC_BITS);
00085 vlc_len = ff_dv_rl_vlc[index].len;
00086 if (vlc_len < 0) {
00087 index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) +
00088 ff_dv_rl_vlc[index].level;
00089 vlc_len = TEX_VLC_BITS - vlc_len;
00090 }
00091 level = ff_dv_rl_vlc[index].level;
00092 run = ff_dv_rl_vlc[index].run;
00093
00094
00095 if (re_index + vlc_len > last_index) {
00096
00097 mb->partial_bit_count = last_index - re_index;
00098 mb->partial_bit_buffer = re_cache & ~(-1u >> mb->partial_bit_count);
00099 re_index = last_index;
00100 break;
00101 }
00102 re_index += vlc_len;
00103
00104 av_dlog(NULL, "run=%d level=%d\n", run, level);
00105 pos += run;
00106 if (pos >= 64)
00107 break;
00108
00109 level = (level * factor_table[pos] + (1 << (dv_iweight_bits - 1))) >> dv_iweight_bits;
00110 block[scan_table[pos]] = level;
00111
00112 UPDATE_CACHE(re, gb);
00113 }
00114 CLOSE_READER(re, gb);
00115 mb->pos = pos;
00116 }
00117
00118 static inline void bit_copy(PutBitContext *pb, GetBitContext *gb)
00119 {
00120 int bits_left = get_bits_left(gb);
00121 while (bits_left >= MIN_CACHE_BITS) {
00122 put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS));
00123 bits_left -= MIN_CACHE_BITS;
00124 }
00125 if (bits_left > 0) {
00126 put_bits(pb, bits_left, get_bits(gb, bits_left));
00127 }
00128 }
00129
00130
00131 static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
00132 {
00133 DVVideoContext *s = avctx->priv_data;
00134 DVwork_chunk *work_chunk = arg;
00135 int quant, dc, dct_mode, class1, j;
00136 int mb_index, mb_x, mb_y, last_index;
00137 int y_stride, linesize;
00138 DCTELEM *block, *block1;
00139 int c_offset;
00140 uint8_t *y_ptr;
00141 const uint8_t *buf_ptr;
00142 PutBitContext pb, vs_pb;
00143 GetBitContext gb;
00144 BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1;
00145 LOCAL_ALIGNED_16(DCTELEM, sblock, [5*DV_MAX_BPM], [64]);
00146 LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [ 80 + FF_INPUT_BUFFER_PADDING_SIZE]);
00147 LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [5*80 + FF_INPUT_BUFFER_PADDING_SIZE]);
00148 const int log2_blocksize = 3-s->avctx->lowres;
00149 int is_field_mode[5];
00150
00151 av_assert1((((int)mb_bit_buffer) & 7) == 0);
00152 av_assert1((((int)vs_bit_buffer) & 7) == 0);
00153
00154 memset(sblock, 0, 5*DV_MAX_BPM*sizeof(*sblock));
00155
00156
00157 buf_ptr = &s->buf[work_chunk->buf_offset*80];
00158 block1 = &sblock[0][0];
00159 mb1 = mb_data;
00160 init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80);
00161 for (mb_index = 0; mb_index < 5; mb_index++, mb1 += s->sys->bpm, block1 += s->sys->bpm * 64) {
00162
00163 quant = buf_ptr[3] & 0x0f;
00164 buf_ptr += 4;
00165 init_put_bits(&pb, mb_bit_buffer, 80);
00166 mb = mb1;
00167 block = block1;
00168 is_field_mode[mb_index] = 0;
00169 for (j = 0; j < s->sys->bpm; j++) {
00170 last_index = s->sys->block_sizes[j];
00171 init_get_bits(&gb, buf_ptr, last_index);
00172
00173
00174 dc = get_sbits(&gb, 9);
00175 dct_mode = get_bits1(&gb);
00176 class1 = get_bits(&gb, 2);
00177 if (DV_PROFILE_IS_HD(s->sys)) {
00178 mb->idct_put = s->idct_put[0];
00179 mb->scan_table = s->dv_zigzag[0];
00180 mb->factor_table = &s->sys->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64];
00181 is_field_mode[mb_index] |= !j && dct_mode;
00182 } else {
00183 mb->idct_put = s->idct_put[dct_mode && log2_blocksize == 3];
00184 mb->scan_table = s->dv_zigzag[dct_mode];
00185 mb->factor_table = &s->sys->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 +
00186 (quant + ff_dv_quant_offset[class1])*64];
00187 }
00188 dc = dc << 2;
00189
00190
00191 dc += 1024;
00192 block[0] = dc;
00193 buf_ptr += last_index >> 3;
00194 mb->pos = 0;
00195 mb->partial_bit_count = 0;
00196
00197 av_dlog(avctx, "MB block: %d, %d ", mb_index, j);
00198 dv_decode_ac(&gb, mb, block);
00199
00200
00201
00202 if (mb->pos >= 64)
00203 bit_copy(&pb, &gb);
00204
00205 block += 64;
00206 mb++;
00207 }
00208
00209
00210 av_dlog(avctx, "***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index);
00211 block = block1;
00212 mb = mb1;
00213 init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb));
00214 put_bits32(&pb, 0);
00215 flush_put_bits(&pb);
00216 for (j = 0; j < s->sys->bpm; j++, block += 64, mb++) {
00217 if (mb->pos < 64 && get_bits_left(&gb) > 0) {
00218 dv_decode_ac(&gb, mb, block);
00219
00220 if (mb->pos < 64)
00221 break;
00222 }
00223 }
00224
00225
00226 if (j >= s->sys->bpm)
00227 bit_copy(&vs_pb, &gb);
00228 }
00229
00230
00231 av_dlog(avctx, "***pass 3 size=%d\n", put_bits_count(&vs_pb));
00232 block = &sblock[0][0];
00233 mb = mb_data;
00234 init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb));
00235 put_bits32(&vs_pb, 0);
00236 flush_put_bits(&vs_pb);
00237 for (mb_index = 0; mb_index < 5; mb_index++) {
00238 for (j = 0; j < s->sys->bpm; j++) {
00239 if (mb->pos < 64) {
00240 av_dlog(avctx, "start %d:%d\n", mb_index, j);
00241 dv_decode_ac(&gb, mb, block);
00242 }
00243 if (mb->pos >= 64 && mb->pos < 127)
00244 av_log(avctx, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos);
00245 block += 64;
00246 mb++;
00247 }
00248 }
00249
00250
00251 block = &sblock[0][0];
00252 mb = mb_data;
00253 for (mb_index = 0; mb_index < 5; mb_index++) {
00254 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
00255
00256
00257 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
00258 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
00259 (s->sys->height >= 720 && mb_y != 134)) {
00260 y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
00261 } else {
00262 y_stride = (2 << log2_blocksize);
00263 }
00264 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize);
00265 linesize = s->picture.linesize[0] << is_field_mode[mb_index];
00266 mb[0] .idct_put(y_ptr , linesize, block + 0*64);
00267 if (s->sys->video_stype == 4) {
00268 mb[2].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 2*64);
00269 } else {
00270 mb[1].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 1*64);
00271 mb[2].idct_put(y_ptr + y_stride, linesize, block + 2*64);
00272 mb[3].idct_put(y_ptr + (1 << log2_blocksize) + y_stride, linesize, block + 3*64);
00273 }
00274 mb += 4;
00275 block += 4*64;
00276
00277
00278 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
00279 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize);
00280 for (j = 2; j; j--) {
00281 uint8_t *c_ptr = s->picture.data[j] + c_offset;
00282 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
00283 uint64_t aligned_pixels[64/8];
00284 uint8_t *pixels = (uint8_t*)aligned_pixels;
00285 uint8_t *c_ptr1, *ptr1;
00286 int x, y;
00287 mb->idct_put(pixels, 8, block);
00288 for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) {
00289 ptr1 = pixels + (1 << (log2_blocksize - 1));
00290 c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize);
00291 for (x = 0; x < (1 << (log2_blocksize - 1)); x++) {
00292 c_ptr[x] = pixels[x];
00293 c_ptr1[x] = ptr1[x];
00294 }
00295 }
00296 block += 64; mb++;
00297 } else {
00298 y_stride = (mb_y == 134) ? (1 << log2_blocksize) :
00299 s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
00300 linesize = s->picture.linesize[j] << is_field_mode[mb_index];
00301 (mb++)-> idct_put(c_ptr , linesize, block); block += 64;
00302 if (s->sys->bpm == 8) {
00303 (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64;
00304 }
00305 }
00306 }
00307 }
00308 return 0;
00309 }
00310
00311
00312
00313 static int dvvideo_decode_frame(AVCodecContext *avctx,
00314 void *data, int *data_size,
00315 AVPacket *avpkt)
00316 {
00317 uint8_t *buf = avpkt->data;
00318 int buf_size = avpkt->size;
00319 DVVideoContext *s = avctx->priv_data;
00320 const uint8_t* vsc_pack;
00321 int apt, is16_9;
00322
00323 s->sys = avpriv_dv_frame_profile2(avctx, s->sys, buf, buf_size);
00324 if (!s->sys || buf_size < s->sys->frame_size || ff_dv_init_dynamic_tables(s->sys)) {
00325 av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
00326 return -1;
00327 }
00328
00329 if (s->picture.data[0])
00330 avctx->release_buffer(avctx, &s->picture);
00331
00332 avcodec_get_frame_defaults(&s->picture);
00333 s->picture.reference = 0;
00334 s->picture.key_frame = 1;
00335 s->picture.pict_type = AV_PICTURE_TYPE_I;
00336 avctx->pix_fmt = s->sys->pix_fmt;
00337 avctx->time_base = s->sys->time_base;
00338 avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
00339 if (avctx->get_buffer(avctx, &s->picture) < 0) {
00340 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00341 return -1;
00342 }
00343 s->picture.interlaced_frame = 1;
00344 s->picture.top_field_first = 0;
00345
00346 s->buf = buf;
00347 avctx->execute(avctx, dv_decode_video_segment, s->sys->work_chunks, NULL,
00348 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
00349
00350 emms_c();
00351
00352
00353 *data_size = sizeof(AVFrame);
00354 *(AVFrame*)data = s->picture;
00355
00356
00357 vsc_pack = buf + 80*5 + 48 + 5;
00358 if ( *vsc_pack == dv_video_control ) {
00359 apt = buf[4] & 0x07;
00360 is16_9 = (vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07);
00361 avctx->sample_aspect_ratio = s->sys->sar[is16_9];
00362 }
00363
00364 return s->sys->frame_size;
00365 }
00366
00367 static int dvvideo_close(AVCodecContext *c)
00368 {
00369 DVVideoContext *s = c->priv_data;
00370
00371 if (s->picture.data[0])
00372 c->release_buffer(c, &s->picture);
00373
00374 return 0;
00375 }
00376
00377 AVCodec ff_dvvideo_decoder = {
00378 .name = "dvvideo",
00379 .type = AVMEDIA_TYPE_VIDEO,
00380 .id = AV_CODEC_ID_DVVIDEO,
00381 .priv_data_size = sizeof(DVVideoContext),
00382 .init = ff_dvvideo_init,
00383 .close = dvvideo_close,
00384 .decode = dvvideo_decode_frame,
00385 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
00386 .max_lowres = 3,
00387 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
00388 };