Mercurial > libavcodec.hg
annotate dnxhddec.c @ 9830:bd0879f752e6 libavcodec
Express the H.264 parser dependency on the golomb code in configure instead of
in the Makefile as it is done for all other parts that depend on golomb.
author | diego |
---|---|
date | Tue, 09 Jun 2009 20:29:52 +0000 |
parents | 0dce4fe6e6f3 |
children | beb616cf1885 |
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 | |
25 #include "avcodec.h" | |
9428 | 26 #include "get_bits.h" |
4687 | 27 #include "dnxhddata.h" |
28 #include "dsputil.h" | |
29 | |
30 typedef struct { | |
31 AVCodecContext *avctx; | |
32 AVFrame picture; | |
33 GetBitContext gb; | |
34 int cid; ///< compression id | |
35 unsigned int width, height; | |
36 unsigned int mb_width, mb_height; | |
37 uint32_t mb_scan_index[68]; /* max for 1080p */ | |
38 int cur_field; ///< current interlaced field | |
39 VLC ac_vlc, dc_vlc, run_vlc; | |
40 int last_dc[3]; | |
41 DSPContext dsp; | |
42 DECLARE_ALIGNED_16(DCTELEM, blocks[8][64]); | |
43 DECLARE_ALIGNED_8(ScanTable, scantable); | |
44 const CIDEntry *cid_table; | |
45 } DNXHDContext; | |
46 | |
47 #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
|
48 #define DNXHD_DC_VLC_BITS 7 |
4687 | 49 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6448
diff
changeset
|
50 static av_cold int dnxhd_decode_init(AVCodecContext *avctx) |
4687 | 51 { |
52 DNXHDContext *ctx = avctx->priv_data; | |
53 | |
54 ctx->avctx = avctx; | |
55 dsputil_init(&ctx->dsp, avctx); | |
56 avctx->coded_frame = &ctx->picture; | |
57 ctx->picture.type = FF_I_TYPE; | |
58 return 0; | |
59 } | |
60 | |
61 static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) | |
62 { | |
63 if (!ctx->cid_table) { | |
64 int index; | |
65 | |
5473 | 66 if ((index = ff_dnxhd_get_cid_table(cid)) < 0) { |
4687 | 67 av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %d\n", cid); |
68 return -1; | |
69 } | |
5473 | 70 ctx->cid_table = &ff_dnxhd_cid_table[index]; |
4687 | 71 init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257, |
5465 | 72 ctx->cid_table->ac_bits, 1, 1, |
73 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
|
74 init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, ctx->cid_table->bit_depth+4, |
5465 | 75 ctx->cid_table->dc_bits, 1, 1, |
76 ctx->cid_table->dc_codes, 1, 1, 0); | |
4687 | 77 init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62, |
5465 | 78 ctx->cid_table->run_bits, 1, 1, |
79 ctx->cid_table->run_codes, 2, 2, 0); | |
4687 | 80 |
81 ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct); | |
82 } | |
83 return 0; | |
84 } | |
85 | |
6233 | 86 static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field) |
4687 | 87 { |
88 static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; | |
89 int i; | |
90 | |
91 if (buf_size < 0x280) | |
92 return -1; | |
93 | |
94 if (memcmp(buf, header_prefix, 5)) { | |
95 av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); | |
96 return -1; | |
97 } | |
5468 | 98 if (buf[5] & 2) { /* interlaced */ |
99 ctx->cur_field = buf[5] & 1; | |
4687 | 100 ctx->picture.interlaced_frame = 1; |
6212 | 101 ctx->picture.top_field_first = first_field ^ ctx->cur_field; |
5468 | 102 av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field); |
4687 | 103 } |
104 | |
105 ctx->height = AV_RB16(buf + 0x18); | |
106 ctx->width = AV_RB16(buf + 0x1a); | |
107 | |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
108 dprintf(ctx->avctx, "width %d, heigth %d\n", ctx->width, ctx->height); |
4687 | 109 |
5791 | 110 if (buf[0x21] & 0x40) { |
4687 | 111 av_log(ctx->avctx, AV_LOG_ERROR, "10 bit per component\n"); |
112 return -1; | |
113 } | |
114 | |
115 ctx->cid = AV_RB32(buf + 0x28); | |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
116 dprintf(ctx->avctx, "compression id %d\n", ctx->cid); |
4687 | 117 |
118 if (dnxhd_init_vlc(ctx, ctx->cid) < 0) | |
119 return -1; | |
120 | |
5464 | 121 if (buf_size < ctx->cid_table->coding_unit_size) { |
4687 | 122 av_log(ctx->avctx, AV_LOG_ERROR, "incorrect frame size\n"); |
123 return -1; | |
124 } | |
125 | |
126 ctx->mb_width = ctx->width>>4; | |
127 ctx->mb_height = buf[0x16d]; | |
128 | |
129 if (ctx->mb_height > 68) { | |
130 av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big\n"); | |
131 return -1; | |
132 } | |
133 | |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
134 dprintf(ctx->avctx, "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height); |
4687 | 135 for (i = 0; i < ctx->mb_height; i++) { |
136 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
|
137 dprintf(ctx->avctx, "mb scan index %d\n", ctx->mb_scan_index[i]); |
4687 | 138 if (buf_size < ctx->mb_scan_index[i] + 0x280) { |
139 av_log(ctx->avctx, AV_LOG_ERROR, "invalid mb scan index\n"); | |
140 return -1; | |
141 } | |
142 } | |
143 | |
144 return 0; | |
145 } | |
146 | |
147 static int dnxhd_decode_dc(DNXHDContext *ctx) | |
148 { | |
149 int len; | |
150 | |
151 len = get_vlc2(&ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1); | |
152 return len ? get_xbits(&ctx->gb, len) : 0; | |
153 } | |
154 | |
155 static void dnxhd_decode_dct_block(DNXHDContext *ctx, DCTELEM *block, int n, int qscale) | |
156 { | |
157 int i, j, index, index2; | |
158 int level, component, sign; | |
159 const uint8_t *weigth_matrix; | |
160 | |
161 if (n&2) { | |
162 component = 1 + (n&1); | |
5795 | 163 weigth_matrix = ctx->cid_table->chroma_weight; |
4687 | 164 } else { |
165 component = 0; | |
5795 | 166 weigth_matrix = ctx->cid_table->luma_weight; |
4687 | 167 } |
168 | |
169 ctx->last_dc[component] += dnxhd_decode_dc(ctx); | |
170 block[0] = ctx->last_dc[component]; | |
171 //av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]); | |
172 for (i = 1; ; i++) { | |
173 index = get_vlc2(&ctx->gb, ctx->ac_vlc.table, DNXHD_VLC_BITS, 2); | |
174 //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index); | |
5466 | 175 level = ctx->cid_table->ac_level[index]; |
4687 | 176 if (!level) { /* EOB */ |
177 //av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n"); | |
178 return; | |
179 } | |
180 sign = get_sbits(&ctx->gb, 1); | |
181 | |
5466 | 182 if (ctx->cid_table->ac_index_flag[index]) { |
183 level += get_bits(&ctx->gb, ctx->cid_table->index_bits)<<6; | |
4687 | 184 } |
185 | |
5466 | 186 if (ctx->cid_table->ac_run_flag[index]) { |
4687 | 187 index2 = get_vlc2(&ctx->gb, ctx->run_vlc.table, DNXHD_VLC_BITS, 2); |
5466 | 188 i += ctx->cid_table->run[index2]; |
4687 | 189 } |
190 | |
5792 | 191 if (i > 63) { |
192 av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i); | |
193 return; | |
194 } | |
195 | |
4687 | 196 j = ctx->scantable.permutated[i]; |
197 //av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j); | |
198 //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weigth %d\n", level, weigth_matrix[i]); | |
199 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
|
200 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
|
201 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
|
202 level += 8; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
203 level >>= 4; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
204 } else { |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
205 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
|
206 level += 32; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
207 level >>= 6; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
208 } |
4687 | 209 //av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level); |
5793 | 210 block[j] = (level^sign) - sign; |
4687 | 211 } |
212 } | |
213 | |
214 static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) | |
215 { | |
216 int dct_linesize_luma = ctx->picture.linesize[0]; | |
217 int dct_linesize_chroma = ctx->picture.linesize[1]; | |
218 uint8_t *dest_y, *dest_u, *dest_v; | |
219 int dct_offset; | |
220 int qscale, i; | |
221 | |
222 qscale = get_bits(&ctx->gb, 11); | |
223 skip_bits1(&ctx->gb); | |
224 //av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale); | |
225 | |
226 for (i = 0; i < 8; i++) { | |
8291 | 227 ctx->dsp.clear_block(ctx->blocks[i]); |
4687 | 228 dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale); |
229 } | |
5468 | 230 |
231 if (ctx->picture.interlaced_frame) { | |
232 dct_linesize_luma <<= 1; | |
233 dct_linesize_chroma <<= 1; | |
234 } | |
235 | |
4687 | 236 dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4); |
237 dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3); | |
238 dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3); | |
239 | |
5468 | 240 if (ctx->cur_field) { |
241 dest_y += ctx->picture.linesize[0]; | |
242 dest_u += ctx->picture.linesize[1]; | |
243 dest_v += ctx->picture.linesize[2]; | |
244 } | |
245 | |
4687 | 246 dct_offset = dct_linesize_luma << 3; |
247 ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); | |
248 ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]); | |
249 ctx->dsp.idct_put(dest_y + dct_offset, dct_linesize_luma, ctx->blocks[4]); | |
250 ctx->dsp.idct_put(dest_y + dct_offset + 8, dct_linesize_luma, ctx->blocks[5]); | |
251 | |
252 if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { | |
253 dct_offset = dct_linesize_chroma << 3; | |
254 ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); | |
255 ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); | |
256 ctx->dsp.idct_put(dest_u + dct_offset, dct_linesize_chroma, ctx->blocks[6]); | |
257 ctx->dsp.idct_put(dest_v + dct_offset, dct_linesize_chroma, ctx->blocks[7]); | |
258 } | |
259 | |
260 return 0; | |
261 } | |
262 | |
6233 | 263 static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int buf_size) |
4687 | 264 { |
265 int x, y; | |
266 for (y = 0; y < ctx->mb_height; y++) { | |
5463 | 267 ctx->last_dc[0] = |
268 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
|
269 ctx->last_dc[2] = 1<<(ctx->cid_table->bit_depth+2); // for levels +2^(bitdepth-1) |
4687 | 270 init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3); |
271 for (x = 0; x < ctx->mb_width; x++) { | |
272 //START_TIMER; | |
273 dnxhd_decode_macroblock(ctx, x, y); | |
274 //STOP_TIMER("decode macroblock"); | |
275 } | |
276 } | |
277 return 0; | |
278 } | |
279 | |
280 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
|
281 AVPacket *avpkt) |
4687 | 282 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8629
diff
changeset
|
283 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8629
diff
changeset
|
284 int buf_size = avpkt->size; |
4687 | 285 DNXHDContext *ctx = avctx->priv_data; |
286 AVFrame *picture = data; | |
5468 | 287 int first_field = 1; |
4687 | 288 |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
289 dprintf(avctx, "frame size %d\n", buf_size); |
4687 | 290 |
5468 | 291 decode_coding_unit: |
292 if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0) | |
4687 | 293 return -1; |
294 | |
295 avctx->pix_fmt = PIX_FMT_YUV422P; | |
296 if (avcodec_check_dimensions(avctx, ctx->width, ctx->height)) | |
297 return -1; | |
298 avcodec_set_dimensions(avctx, ctx->width, ctx->height); | |
299 | |
5468 | 300 if (first_field) { |
5469 | 301 if (ctx->picture.data[0]) |
302 avctx->release_buffer(avctx, &ctx->picture); | |
303 if (avctx->get_buffer(avctx, &ctx->picture) < 0) { | |
304 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
305 return -1; | |
306 } | |
5468 | 307 } |
4687 | 308 |
309 dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); | |
310 | |
5468 | 311 if (first_field && ctx->picture.interlaced_frame) { |
312 buf += ctx->cid_table->coding_unit_size; | |
313 buf_size -= ctx->cid_table->coding_unit_size; | |
314 first_field = 0; | |
315 goto decode_coding_unit; | |
316 } | |
317 | |
4687 | 318 *picture = ctx->picture; |
319 *data_size = sizeof(AVPicture); | |
4721 | 320 return buf_size; |
4687 | 321 } |
322 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6448
diff
changeset
|
323 static av_cold int dnxhd_decode_close(AVCodecContext *avctx) |
4687 | 324 { |
325 DNXHDContext *ctx = avctx->priv_data; | |
326 | |
5467 | 327 if (ctx->picture.data[0]) |
4687 | 328 avctx->release_buffer(avctx, &ctx->picture); |
329 free_vlc(&ctx->ac_vlc); | |
330 free_vlc(&ctx->dc_vlc); | |
331 free_vlc(&ctx->run_vlc); | |
332 return 0; | |
333 } | |
334 | |
335 AVCodec dnxhd_decoder = { | |
336 "dnxhd", | |
337 CODEC_TYPE_VIDEO, | |
338 CODEC_ID_DNXHD, | |
339 sizeof(DNXHDContext), | |
340 dnxhd_decode_init, | |
341 NULL, | |
342 dnxhd_decode_close, | |
343 dnxhd_decode_frame, | |
344 CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
345 .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), |
4687 | 346 }; |