Mercurial > libavcodec.hg
comparison dnxhddec.c @ 5468:74949d4ea79c libavcodec
dnxhd 185 interlaced support
author | bcoudurier |
---|---|
date | Sat, 04 Aug 2007 13:17:53 +0000 |
parents | 740cf5d1691e |
children | 0418cc1c3899 |
comparison
equal
deleted
inserted
replaced
5467:740cf5d1691e | 5468:74949d4ea79c |
---|---|
67 dnxhd_1238_luma_weigth, dnxhd_1238_chroma_weigth, | 67 dnxhd_1238_luma_weigth, dnxhd_1238_chroma_weigth, |
68 dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, | 68 dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, |
69 dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, | 69 dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, |
70 dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, | 70 dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, |
71 dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run }, | 71 dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run }, |
72 /* { 1243, 1920, 1080, 1, 917504, 458752, 4, 8, */ | 72 { 1243, 1920, 1080, 1, 917504, 458752, 4, 8, |
73 /* dnxhd_1243_luma_weigth, dnxhd_1243_chroma_weigth, */ | 73 dnxhd_1243_luma_weigth, dnxhd_1243_chroma_weigth, |
74 /* dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, */ | 74 dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, |
75 /* dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, */ | 75 dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, |
76 /* dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, */ | 76 dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, |
77 /* dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run }, */ | 77 dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run }, |
78 }; | 78 }; |
79 | 79 |
80 static int dnxhd_get_cid_table(int cid) | 80 static int dnxhd_get_cid_table(int cid) |
81 { | 81 { |
82 int i; | 82 int i; |
123 ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct); | 123 ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct); |
124 } | 124 } |
125 return 0; | 125 return 0; |
126 } | 126 } |
127 | 127 |
128 static int dnxhd_decode_header(DNXHDContext *ctx, uint8_t *buf, int buf_size) | 128 static int dnxhd_decode_header(DNXHDContext *ctx, uint8_t *buf, int buf_size, int first_field) |
129 { | 129 { |
130 static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; | 130 static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; |
131 int i; | 131 int i; |
132 | 132 |
133 if (buf_size < 0x280) | 133 if (buf_size < 0x280) |
135 | 135 |
136 if (memcmp(buf, header_prefix, 5)) { | 136 if (memcmp(buf, header_prefix, 5)) { |
137 av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); | 137 av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); |
138 return -1; | 138 return -1; |
139 } | 139 } |
140 if (buf[5] & 2) {/* interlaced FIXME top or bottom */ | 140 if (buf[5] & 2) { /* interlaced */ |
141 ctx->cur_field = buf[5] & 1; | |
141 ctx->picture.interlaced_frame = 1; | 142 ctx->picture.interlaced_frame = 1; |
142 av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d\n", buf[5] & 3); | 143 ctx->picture.top_field_first = first_field && ctx->cur_field == 1; |
144 av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field); | |
143 } | 145 } |
144 | 146 |
145 ctx->height = AV_RB16(buf + 0x18); | 147 ctx->height = AV_RB16(buf + 0x18); |
146 ctx->width = AV_RB16(buf + 0x1a); | 148 ctx->width = AV_RB16(buf + 0x1a); |
147 | 149 |
263 //av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale); | 265 //av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale); |
264 | 266 |
265 for (i = 0; i < 8; i++) { | 267 for (i = 0; i < 8; i++) { |
266 dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale); | 268 dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale); |
267 } | 269 } |
270 | |
271 if (ctx->picture.interlaced_frame) { | |
272 dct_linesize_luma <<= 1; | |
273 dct_linesize_chroma <<= 1; | |
274 } | |
275 | |
268 dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4); | 276 dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4); |
269 dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3); | 277 dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3); |
270 dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3); | 278 dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3); |
279 | |
280 if (ctx->cur_field) { | |
281 dest_y += ctx->picture.linesize[0]; | |
282 dest_u += ctx->picture.linesize[1]; | |
283 dest_v += ctx->picture.linesize[2]; | |
284 } | |
271 | 285 |
272 dct_offset = dct_linesize_luma << 3; | 286 dct_offset = dct_linesize_luma << 3; |
273 ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); | 287 ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); |
274 ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]); | 288 ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]); |
275 ctx->dsp.idct_put(dest_y + dct_offset, dct_linesize_luma, ctx->blocks[4]); | 289 ctx->dsp.idct_put(dest_y + dct_offset, dct_linesize_luma, ctx->blocks[4]); |
306 static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | 320 static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, |
307 uint8_t *buf, int buf_size) | 321 uint8_t *buf, int buf_size) |
308 { | 322 { |
309 DNXHDContext *ctx = avctx->priv_data; | 323 DNXHDContext *ctx = avctx->priv_data; |
310 AVFrame *picture = data; | 324 AVFrame *picture = data; |
325 int first_field = 1; | |
311 | 326 |
312 dprintf(avctx, "frame size %d\n", buf_size); | 327 dprintf(avctx, "frame size %d\n", buf_size); |
313 | 328 |
314 if (dnxhd_decode_header(ctx, buf, buf_size) < 0) | 329 decode_coding_unit: |
330 if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0) | |
315 return -1; | 331 return -1; |
316 | 332 |
317 avctx->pix_fmt = PIX_FMT_YUV422P; | 333 avctx->pix_fmt = PIX_FMT_YUV422P; |
318 if (avcodec_check_dimensions(avctx, ctx->width, ctx->height)) | 334 if (avcodec_check_dimensions(avctx, ctx->width, ctx->height)) |
319 return -1; | 335 return -1; |
320 avcodec_set_dimensions(avctx, ctx->width, ctx->height); | 336 avcodec_set_dimensions(avctx, ctx->width, ctx->height); |
321 | 337 |
338 if (first_field) { | |
322 if (ctx->picture.data[0]) | 339 if (ctx->picture.data[0]) |
323 avctx->release_buffer(avctx, &ctx->picture); | 340 avctx->release_buffer(avctx, &ctx->picture); |
324 if (avctx->get_buffer(avctx, &ctx->picture) < 0) { | 341 if (avctx->get_buffer(avctx, &ctx->picture) < 0) { |
325 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 342 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
326 return -1; | 343 return -1; |
327 } | 344 } |
345 } | |
328 | 346 |
329 dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); | 347 dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); |
348 | |
349 if (first_field && ctx->picture.interlaced_frame) { | |
350 buf += ctx->cid_table->coding_unit_size; | |
351 buf_size -= ctx->cid_table->coding_unit_size; | |
352 first_field = 0; | |
353 goto decode_coding_unit; | |
354 } | |
330 | 355 |
331 *picture = ctx->picture; | 356 *picture = ctx->picture; |
332 *data_size = sizeof(AVPicture); | 357 *data_size = sizeof(AVPicture); |
333 return buf_size; | 358 return buf_size; |
334 } | 359 } |