Mercurial > libavcodec.hg
annotate dnxhddec.c @ 8991:ca768cb2bfb6 libavcodec
Use last decoded SPS as current SPS in order to parse picture timing SEI
correctly. This works around an apparent H.264 standard deficiency.
Patch by Ivan Schreter, schreter gmx net
author | cehoyos |
---|---|
date | Fri, 20 Feb 2009 16:20:01 +0000 |
parents | 04423b2f6e0b |
children | 54bc8a2727b0 |
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" | |
26 #include "bitstream.h" | |
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, | |
6233 | 281 const uint8_t *buf, int buf_size) |
4687 | 282 { |
283 DNXHDContext *ctx = avctx->priv_data; | |
284 AVFrame *picture = data; | |
5468 | 285 int first_field = 1; |
4687 | 286 |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
287 dprintf(avctx, "frame size %d\n", buf_size); |
4687 | 288 |
5468 | 289 decode_coding_unit: |
290 if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0) | |
4687 | 291 return -1; |
292 | |
293 avctx->pix_fmt = PIX_FMT_YUV422P; | |
294 if (avcodec_check_dimensions(avctx, ctx->width, ctx->height)) | |
295 return -1; | |
296 avcodec_set_dimensions(avctx, ctx->width, ctx->height); | |
297 | |
5468 | 298 if (first_field) { |
5469 | 299 if (ctx->picture.data[0]) |
300 avctx->release_buffer(avctx, &ctx->picture); | |
301 if (avctx->get_buffer(avctx, &ctx->picture) < 0) { | |
302 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
303 return -1; | |
304 } | |
5468 | 305 } |
4687 | 306 |
307 dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); | |
308 | |
5468 | 309 if (first_field && ctx->picture.interlaced_frame) { |
310 buf += ctx->cid_table->coding_unit_size; | |
311 buf_size -= ctx->cid_table->coding_unit_size; | |
312 first_field = 0; | |
313 goto decode_coding_unit; | |
314 } | |
315 | |
4687 | 316 *picture = ctx->picture; |
317 *data_size = sizeof(AVPicture); | |
4721 | 318 return buf_size; |
4687 | 319 } |
320 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6448
diff
changeset
|
321 static av_cold int dnxhd_decode_close(AVCodecContext *avctx) |
4687 | 322 { |
323 DNXHDContext *ctx = avctx->priv_data; | |
324 | |
5467 | 325 if (ctx->picture.data[0]) |
4687 | 326 avctx->release_buffer(avctx, &ctx->picture); |
327 free_vlc(&ctx->ac_vlc); | |
328 free_vlc(&ctx->dc_vlc); | |
329 free_vlc(&ctx->run_vlc); | |
330 return 0; | |
331 } | |
332 | |
333 AVCodec dnxhd_decoder = { | |
334 "dnxhd", | |
335 CODEC_TYPE_VIDEO, | |
336 CODEC_ID_DNXHD, | |
337 sizeof(DNXHDContext), | |
338 dnxhd_decode_init, | |
339 NULL, | |
340 dnxhd_decode_close, | |
341 dnxhd_decode_frame, | |
342 CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
343 .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), |
4687 | 344 }; |