Mercurial > libavcodec.hg
annotate dnxhddec.c @ 12483:0159a19bfff7 libavcodec
aacdec: Rework channel mapping compatibility hacks.
For a PCE based configuration map the channels solely based on tags.
For an indexed configuration map the channels solely based on position.
This works with all known exotic samples including al17, elem_id0, bad_concat,
and lfe_is_sce.
author | alexc |
---|---|
date | Fri, 10 Sep 2010 18:01:48 +0000 |
parents | ffb3668ff7af |
children |
rev | line source |
---|---|
4687 | 1 /* |
2 * VC3/DNxHD decoder. | |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8291
diff
changeset
|
3 * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com> |
4687 | 4 * |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 //#define TRACE | |
23 //#define DEBUG | |
24 | |
12372
914f484bb476
Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents:
11560
diff
changeset
|
25 #include "libavcore/imgutils.h" |
4687 | 26 #include "avcodec.h" |
9428 | 27 #include "get_bits.h" |
4687 | 28 #include "dnxhddata.h" |
29 #include "dsputil.h" | |
30 | |
31 typedef struct { | |
32 AVCodecContext *avctx; | |
33 AVFrame picture; | |
34 GetBitContext gb; | |
35 int cid; ///< compression id | |
36 unsigned int width, height; | |
37 unsigned int mb_width, mb_height; | |
38 uint32_t mb_scan_index[68]; /* max for 1080p */ | |
39 int cur_field; ///< current interlaced field | |
40 VLC ac_vlc, dc_vlc, run_vlc; | |
41 int last_dc[3]; | |
42 DSPContext dsp; | |
11369 | 43 DECLARE_ALIGNED(16, DCTELEM, blocks)[8][64]; |
10093 | 44 ScanTable scantable; |
4687 | 45 const CIDEntry *cid_table; |
46 } DNXHDContext; | |
47 | |
48 #define DNXHD_VLC_BITS 9 | |
5794
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
49 #define DNXHD_DC_VLC_BITS 7 |
4687 | 50 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6448
diff
changeset
|
51 static av_cold int dnxhd_decode_init(AVCodecContext *avctx) |
4687 | 52 { |
53 DNXHDContext *ctx = avctx->priv_data; | |
54 | |
55 ctx->avctx = avctx; | |
56 dsputil_init(&ctx->dsp, avctx); | |
57 avctx->coded_frame = &ctx->picture; | |
58 ctx->picture.type = FF_I_TYPE; | |
59 return 0; | |
60 } | |
61 | |
62 static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) | |
63 { | |
64 if (!ctx->cid_table) { | |
65 int index; | |
66 | |
5473 | 67 if ((index = ff_dnxhd_get_cid_table(cid)) < 0) { |
4687 | 68 av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %d\n", cid); |
69 return -1; | |
70 } | |
5473 | 71 ctx->cid_table = &ff_dnxhd_cid_table[index]; |
4687 | 72 init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257, |
5465 | 73 ctx->cid_table->ac_bits, 1, 1, |
74 ctx->cid_table->ac_codes, 2, 2, 0); | |
5794
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
75 init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, ctx->cid_table->bit_depth+4, |
5465 | 76 ctx->cid_table->dc_bits, 1, 1, |
77 ctx->cid_table->dc_codes, 1, 1, 0); | |
4687 | 78 init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62, |
5465 | 79 ctx->cid_table->run_bits, 1, 1, |
80 ctx->cid_table->run_codes, 2, 2, 0); | |
4687 | 81 |
82 ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct); | |
83 } | |
84 return 0; | |
85 } | |
86 | |
6233 | 87 static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field) |
4687 | 88 { |
89 static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; | |
90 int i; | |
91 | |
92 if (buf_size < 0x280) | |
93 return -1; | |
94 | |
95 if (memcmp(buf, header_prefix, 5)) { | |
96 av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); | |
97 return -1; | |
98 } | |
5468 | 99 if (buf[5] & 2) { /* interlaced */ |
100 ctx->cur_field = buf[5] & 1; | |
4687 | 101 ctx->picture.interlaced_frame = 1; |
6212 | 102 ctx->picture.top_field_first = first_field ^ ctx->cur_field; |
5468 | 103 av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field); |
4687 | 104 } |
105 | |
106 ctx->height = AV_RB16(buf + 0x18); | |
107 ctx->width = AV_RB16(buf + 0x1a); | |
108 | |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
109 dprintf(ctx->avctx, "width %d, heigth %d\n", ctx->width, ctx->height); |
4687 | 110 |
5791 | 111 if (buf[0x21] & 0x40) { |
4687 | 112 av_log(ctx->avctx, AV_LOG_ERROR, "10 bit per component\n"); |
113 return -1; | |
114 } | |
115 | |
116 ctx->cid = AV_RB32(buf + 0x28); | |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
117 dprintf(ctx->avctx, "compression id %d\n", ctx->cid); |
4687 | 118 |
119 if (dnxhd_init_vlc(ctx, ctx->cid) < 0) | |
120 return -1; | |
121 | |
5464 | 122 if (buf_size < ctx->cid_table->coding_unit_size) { |
4687 | 123 av_log(ctx->avctx, AV_LOG_ERROR, "incorrect frame size\n"); |
124 return -1; | |
125 } | |
126 | |
127 ctx->mb_width = ctx->width>>4; | |
128 ctx->mb_height = buf[0x16d]; | |
129 | |
11424 | 130 dprintf(ctx->avctx, "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height); |
131 | |
132 if ((ctx->height+15)>>4 == ctx->mb_height && ctx->picture.interlaced_frame) | |
133 ctx->height <<= 1; | |
134 | |
135 if (ctx->mb_height > 68 || | |
136 (ctx->mb_height<<ctx->picture.interlaced_frame) > (ctx->height+15)>>4) { | |
137 av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big: %d\n", ctx->mb_height); | |
4687 | 138 return -1; |
139 } | |
140 | |
141 for (i = 0; i < ctx->mb_height; i++) { | |
142 ctx->mb_scan_index[i] = AV_RB32(buf + 0x170 + (i<<2)); | |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
143 dprintf(ctx->avctx, "mb scan index %d\n", ctx->mb_scan_index[i]); |
4687 | 144 if (buf_size < ctx->mb_scan_index[i] + 0x280) { |
145 av_log(ctx->avctx, AV_LOG_ERROR, "invalid mb scan index\n"); | |
146 return -1; | |
147 } | |
148 } | |
149 | |
150 return 0; | |
151 } | |
152 | |
153 static int dnxhd_decode_dc(DNXHDContext *ctx) | |
154 { | |
155 int len; | |
156 | |
157 len = get_vlc2(&ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1); | |
158 return len ? get_xbits(&ctx->gb, len) : 0; | |
159 } | |
160 | |
161 static void dnxhd_decode_dct_block(DNXHDContext *ctx, DCTELEM *block, int n, int qscale) | |
162 { | |
163 int i, j, index, index2; | |
164 int level, component, sign; | |
165 const uint8_t *weigth_matrix; | |
166 | |
167 if (n&2) { | |
168 component = 1 + (n&1); | |
5795 | 169 weigth_matrix = ctx->cid_table->chroma_weight; |
4687 | 170 } else { |
171 component = 0; | |
5795 | 172 weigth_matrix = ctx->cid_table->luma_weight; |
4687 | 173 } |
174 | |
175 ctx->last_dc[component] += dnxhd_decode_dc(ctx); | |
176 block[0] = ctx->last_dc[component]; | |
177 //av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]); | |
178 for (i = 1; ; i++) { | |
179 index = get_vlc2(&ctx->gb, ctx->ac_vlc.table, DNXHD_VLC_BITS, 2); | |
180 //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index); | |
5466 | 181 level = ctx->cid_table->ac_level[index]; |
4687 | 182 if (!level) { /* EOB */ |
183 //av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n"); | |
184 return; | |
185 } | |
186 sign = get_sbits(&ctx->gb, 1); | |
187 | |
5466 | 188 if (ctx->cid_table->ac_index_flag[index]) { |
189 level += get_bits(&ctx->gb, ctx->cid_table->index_bits)<<6; | |
4687 | 190 } |
191 | |
5466 | 192 if (ctx->cid_table->ac_run_flag[index]) { |
4687 | 193 index2 = get_vlc2(&ctx->gb, ctx->run_vlc.table, DNXHD_VLC_BITS, 2); |
5466 | 194 i += ctx->cid_table->run[index2]; |
4687 | 195 } |
196 | |
5792 | 197 if (i > 63) { |
198 av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i); | |
199 return; | |
200 } | |
201 | |
4687 | 202 j = ctx->scantable.permutated[i]; |
203 //av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j); | |
204 //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weigth %d\n", level, weigth_matrix[i]); | |
205 level = (2*level+1) * qscale * weigth_matrix[i]; | |
5794
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
206 if (ctx->cid_table->bit_depth == 10) { |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
207 if (weigth_matrix[i] != 8) |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
208 level += 8; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
209 level >>= 4; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
210 } else { |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
211 if (weigth_matrix[i] != 32) |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
212 level += 32; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
213 level >>= 6; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
214 } |
4687 | 215 //av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level); |
5793 | 216 block[j] = (level^sign) - sign; |
4687 | 217 } |
218 } | |
219 | |
220 static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) | |
221 { | |
222 int dct_linesize_luma = ctx->picture.linesize[0]; | |
223 int dct_linesize_chroma = ctx->picture.linesize[1]; | |
224 uint8_t *dest_y, *dest_u, *dest_v; | |
225 int dct_offset; | |
226 int qscale, i; | |
227 | |
228 qscale = get_bits(&ctx->gb, 11); | |
229 skip_bits1(&ctx->gb); | |
230 //av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale); | |
231 | |
232 for (i = 0; i < 8; i++) { | |
8291 | 233 ctx->dsp.clear_block(ctx->blocks[i]); |
4687 | 234 dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale); |
235 } | |
5468 | 236 |
237 if (ctx->picture.interlaced_frame) { | |
238 dct_linesize_luma <<= 1; | |
239 dct_linesize_chroma <<= 1; | |
240 } | |
241 | |
4687 | 242 dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4); |
243 dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3); | |
244 dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3); | |
245 | |
5468 | 246 if (ctx->cur_field) { |
247 dest_y += ctx->picture.linesize[0]; | |
248 dest_u += ctx->picture.linesize[1]; | |
249 dest_v += ctx->picture.linesize[2]; | |
250 } | |
251 | |
4687 | 252 dct_offset = dct_linesize_luma << 3; |
253 ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); | |
254 ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]); | |
255 ctx->dsp.idct_put(dest_y + dct_offset, dct_linesize_luma, ctx->blocks[4]); | |
256 ctx->dsp.idct_put(dest_y + dct_offset + 8, dct_linesize_luma, ctx->blocks[5]); | |
257 | |
258 if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { | |
259 dct_offset = dct_linesize_chroma << 3; | |
260 ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); | |
261 ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); | |
262 ctx->dsp.idct_put(dest_u + dct_offset, dct_linesize_chroma, ctx->blocks[6]); | |
263 ctx->dsp.idct_put(dest_v + dct_offset, dct_linesize_chroma, ctx->blocks[7]); | |
264 } | |
265 | |
266 return 0; | |
267 } | |
268 | |
6233 | 269 static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int buf_size) |
4687 | 270 { |
271 int x, y; | |
272 for (y = 0; y < ctx->mb_height; y++) { | |
5463 | 273 ctx->last_dc[0] = |
274 ctx->last_dc[1] = | |
5794
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
275 ctx->last_dc[2] = 1<<(ctx->cid_table->bit_depth+2); // for levels +2^(bitdepth-1) |
4687 | 276 init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3); |
277 for (x = 0; x < ctx->mb_width; x++) { | |
278 //START_TIMER; | |
279 dnxhd_decode_macroblock(ctx, x, y); | |
280 //STOP_TIMER("decode macroblock"); | |
281 } | |
282 } | |
283 return 0; | |
284 } | |
285 | |
286 static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8629
diff
changeset
|
287 AVPacket *avpkt) |
4687 | 288 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8629
diff
changeset
|
289 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8629
diff
changeset
|
290 int buf_size = avpkt->size; |
4687 | 291 DNXHDContext *ctx = avctx->priv_data; |
292 AVFrame *picture = data; | |
5468 | 293 int first_field = 1; |
4687 | 294 |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
295 dprintf(avctx, "frame size %d\n", buf_size); |
4687 | 296 |
5468 | 297 decode_coding_unit: |
298 if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0) | |
4687 | 299 return -1; |
300 | |
11424 | 301 if ((avctx->width || avctx->height) && |
302 (ctx->width != avctx->width || ctx->height != avctx->height)) { | |
303 av_log(avctx, AV_LOG_WARNING, "frame size changed: %dx%d -> %dx%d\n", | |
304 avctx->width, avctx->height, ctx->width, ctx->height); | |
305 first_field = 1; | |
306 } | |
307 | |
4687 | 308 avctx->pix_fmt = PIX_FMT_YUV422P; |
12462
ffb3668ff7af
Use new imgutils.h API names, fix deprecation warnings.
stefano
parents:
12372
diff
changeset
|
309 if (av_image_check_size(ctx->width, ctx->height, 0, avctx)) |
4687 | 310 return -1; |
311 avcodec_set_dimensions(avctx, ctx->width, ctx->height); | |
312 | |
5468 | 313 if (first_field) { |
5469 | 314 if (ctx->picture.data[0]) |
315 avctx->release_buffer(avctx, &ctx->picture); | |
316 if (avctx->get_buffer(avctx, &ctx->picture) < 0) { | |
317 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
318 return -1; | |
319 } | |
5468 | 320 } |
4687 | 321 |
322 dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); | |
323 | |
5468 | 324 if (first_field && ctx->picture.interlaced_frame) { |
325 buf += ctx->cid_table->coding_unit_size; | |
326 buf_size -= ctx->cid_table->coding_unit_size; | |
327 first_field = 0; | |
328 goto decode_coding_unit; | |
329 } | |
330 | |
4687 | 331 *picture = ctx->picture; |
332 *data_size = sizeof(AVPicture); | |
4721 | 333 return buf_size; |
4687 | 334 } |
335 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6448
diff
changeset
|
336 static av_cold int dnxhd_decode_close(AVCodecContext *avctx) |
4687 | 337 { |
338 DNXHDContext *ctx = avctx->priv_data; | |
339 | |
5467 | 340 if (ctx->picture.data[0]) |
4687 | 341 avctx->release_buffer(avctx, &ctx->picture); |
342 free_vlc(&ctx->ac_vlc); | |
343 free_vlc(&ctx->dc_vlc); | |
344 free_vlc(&ctx->run_vlc); | |
345 return 0; | |
346 } | |
347 | |
348 AVCodec dnxhd_decoder = { | |
349 "dnxhd", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
11424
diff
changeset
|
350 AVMEDIA_TYPE_VIDEO, |
4687 | 351 CODEC_ID_DNXHD, |
352 sizeof(DNXHDContext), | |
353 dnxhd_decode_init, | |
354 NULL, | |
355 dnxhd_decode_close, | |
356 dnxhd_decode_frame, | |
357 CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
358 .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), |
4687 | 359 }; |