Mercurial > libavcodec.hg
annotate dnxhddec.c @ 5876:731ee5ad6bde libavcodec
Correct assignment of interlaced_frame; was being set on output frames,
in display order, based on decoding information in decoding order. Now
set properly, immediately upon completion of decode.
Based on original patch from Reinhard Nissl, rnisssl % gmx , de
Original Thread: [FFmpeg-devel] H.264 + PAFF: BBC HD recording shows
extreme interlacing artefacts, Thu, 01 Nov 2007 22:43:09
author | heydowns |
---|---|
date | Mon, 05 Nov 2007 18:16:42 +0000 |
parents | 8b6fe123be88 |
children | 0b967440e270 |
rev | line source |
---|---|
4687 | 1 /* |
2 * VC3/DNxHD decoder. | |
3 * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>. | |
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 #include "mpegvideo.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; | |
43 DECLARE_ALIGNED_16(DCTELEM, blocks[8][64]); | |
44 DECLARE_ALIGNED_8(ScanTable, scantable); | |
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 |
51 static int dnxhd_decode_init(AVCodecContext *avctx) | |
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 | |
5468 | 87 static int dnxhd_decode_header(DNXHDContext *ctx, 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; |
5468 | 102 ctx->picture.top_field_first = first_field && ctx->cur_field == 1; |
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 | |
130 if (ctx->mb_height > 68) { | |
131 av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big\n"); | |
132 return -1; | |
133 } | |
134 | |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
135 dprintf(ctx->avctx, "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height); |
4687 | 136 for (i = 0; i < ctx->mb_height; i++) { |
137 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
|
138 dprintf(ctx->avctx, "mb scan index %d\n", ctx->mb_scan_index[i]); |
4687 | 139 if (buf_size < ctx->mb_scan_index[i] + 0x280) { |
140 av_log(ctx->avctx, AV_LOG_ERROR, "invalid mb scan index\n"); | |
141 return -1; | |
142 } | |
143 } | |
144 | |
145 return 0; | |
146 } | |
147 | |
148 static int dnxhd_decode_dc(DNXHDContext *ctx) | |
149 { | |
150 int len; | |
151 | |
152 len = get_vlc2(&ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1); | |
153 return len ? get_xbits(&ctx->gb, len) : 0; | |
154 } | |
155 | |
156 static void dnxhd_decode_dct_block(DNXHDContext *ctx, DCTELEM *block, int n, int qscale) | |
157 { | |
158 int i, j, index, index2; | |
159 int level, component, sign; | |
160 const uint8_t *weigth_matrix; | |
161 | |
162 if (n&2) { | |
163 component = 1 + (n&1); | |
5795 | 164 weigth_matrix = ctx->cid_table->chroma_weight; |
4687 | 165 } else { |
166 component = 0; | |
5795 | 167 weigth_matrix = ctx->cid_table->luma_weight; |
4687 | 168 } |
169 | |
170 ctx->last_dc[component] += dnxhd_decode_dc(ctx); | |
171 block[0] = ctx->last_dc[component]; | |
172 //av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]); | |
173 for (i = 1; ; i++) { | |
174 index = get_vlc2(&ctx->gb, ctx->ac_vlc.table, DNXHD_VLC_BITS, 2); | |
175 //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index); | |
5466 | 176 level = ctx->cid_table->ac_level[index]; |
4687 | 177 if (!level) { /* EOB */ |
178 //av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n"); | |
179 return; | |
180 } | |
181 sign = get_sbits(&ctx->gb, 1); | |
182 | |
5466 | 183 if (ctx->cid_table->ac_index_flag[index]) { |
184 level += get_bits(&ctx->gb, ctx->cid_table->index_bits)<<6; | |
4687 | 185 } |
186 | |
5466 | 187 if (ctx->cid_table->ac_run_flag[index]) { |
4687 | 188 index2 = get_vlc2(&ctx->gb, ctx->run_vlc.table, DNXHD_VLC_BITS, 2); |
5466 | 189 i += ctx->cid_table->run[index2]; |
4687 | 190 } |
191 | |
5792 | 192 if (i > 63) { |
193 av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i); | |
194 return; | |
195 } | |
196 | |
4687 | 197 j = ctx->scantable.permutated[i]; |
198 //av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j); | |
199 //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weigth %d\n", level, weigth_matrix[i]); | |
200 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
|
201 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
|
202 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
|
203 level += 8; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
204 level >>= 4; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
205 } else { |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
206 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
|
207 level += 32; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
208 level >>= 6; |
8412118b41d3
preliminary 10 bit depth decoding support, still miss generic api to export picture, working on it
bcoudurier
parents:
5793
diff
changeset
|
209 } |
4687 | 210 //av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level); |
5793 | 211 block[j] = (level^sign) - sign; |
4687 | 212 } |
213 } | |
214 | |
215 static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) | |
216 { | |
217 int dct_linesize_luma = ctx->picture.linesize[0]; | |
218 int dct_linesize_chroma = ctx->picture.linesize[1]; | |
219 uint8_t *dest_y, *dest_u, *dest_v; | |
220 int dct_offset; | |
221 int qscale, i; | |
222 | |
223 ctx->dsp.clear_blocks(ctx->blocks[0]); | |
224 ctx->dsp.clear_blocks(ctx->blocks[2]); // FIXME change clear blocks to take block amount | |
225 | |
226 qscale = get_bits(&ctx->gb, 11); | |
227 skip_bits1(&ctx->gb); | |
228 //av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale); | |
229 | |
230 for (i = 0; i < 8; i++) { | |
231 dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale); | |
232 } | |
5468 | 233 |
234 if (ctx->picture.interlaced_frame) { | |
235 dct_linesize_luma <<= 1; | |
236 dct_linesize_chroma <<= 1; | |
237 } | |
238 | |
4687 | 239 dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4); |
240 dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3); | |
241 dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3); | |
242 | |
5468 | 243 if (ctx->cur_field) { |
244 dest_y += ctx->picture.linesize[0]; | |
245 dest_u += ctx->picture.linesize[1]; | |
246 dest_v += ctx->picture.linesize[2]; | |
247 } | |
248 | |
4687 | 249 dct_offset = dct_linesize_luma << 3; |
250 ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); | |
251 ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]); | |
252 ctx->dsp.idct_put(dest_y + dct_offset, dct_linesize_luma, ctx->blocks[4]); | |
253 ctx->dsp.idct_put(dest_y + dct_offset + 8, dct_linesize_luma, ctx->blocks[5]); | |
254 | |
255 if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { | |
256 dct_offset = dct_linesize_chroma << 3; | |
257 ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); | |
258 ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); | |
259 ctx->dsp.idct_put(dest_u + dct_offset, dct_linesize_chroma, ctx->blocks[6]); | |
260 ctx->dsp.idct_put(dest_v + dct_offset, dct_linesize_chroma, ctx->blocks[7]); | |
261 } | |
262 | |
263 return 0; | |
264 } | |
265 | |
266 static int dnxhd_decode_macroblocks(DNXHDContext *ctx, uint8_t *buf, int buf_size) | |
267 { | |
268 int x, y; | |
269 for (y = 0; y < ctx->mb_height; y++) { | |
5463 | 270 ctx->last_dc[0] = |
271 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
|
272 ctx->last_dc[2] = 1<<(ctx->cid_table->bit_depth+2); // for levels +2^(bitdepth-1) |
4687 | 273 init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3); |
274 for (x = 0; x < ctx->mb_width; x++) { | |
275 //START_TIMER; | |
276 dnxhd_decode_macroblock(ctx, x, y); | |
277 //STOP_TIMER("decode macroblock"); | |
278 } | |
279 } | |
280 return 0; | |
281 } | |
282 | |
283 static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | |
284 uint8_t *buf, int buf_size) | |
285 { | |
286 DNXHDContext *ctx = avctx->priv_data; | |
287 AVFrame *picture = data; | |
5468 | 288 int first_field = 1; |
4687 | 289 |
4688
1cefcd7da878
10l, fix debug, dprintf does not have log level
bcoudurier
parents:
4687
diff
changeset
|
290 dprintf(avctx, "frame size %d\n", buf_size); |
4687 | 291 |
5468 | 292 decode_coding_unit: |
293 if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0) | |
4687 | 294 return -1; |
295 | |
296 avctx->pix_fmt = PIX_FMT_YUV422P; | |
297 if (avcodec_check_dimensions(avctx, ctx->width, ctx->height)) | |
298 return -1; | |
299 avcodec_set_dimensions(avctx, ctx->width, ctx->height); | |
300 | |
5468 | 301 if (first_field) { |
5469 | 302 if (ctx->picture.data[0]) |
303 avctx->release_buffer(avctx, &ctx->picture); | |
304 if (avctx->get_buffer(avctx, &ctx->picture) < 0) { | |
305 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
306 return -1; | |
307 } | |
5468 | 308 } |
4687 | 309 |
310 dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); | |
311 | |
5468 | 312 if (first_field && ctx->picture.interlaced_frame) { |
313 buf += ctx->cid_table->coding_unit_size; | |
314 buf_size -= ctx->cid_table->coding_unit_size; | |
315 first_field = 0; | |
316 goto decode_coding_unit; | |
317 } | |
318 | |
4687 | 319 *picture = ctx->picture; |
320 *data_size = sizeof(AVPicture); | |
4721 | 321 return buf_size; |
4687 | 322 } |
323 | |
324 static int dnxhd_decode_close(AVCodecContext *avctx) | |
325 { | |
326 DNXHDContext *ctx = avctx->priv_data; | |
327 | |
5467 | 328 if (ctx->picture.data[0]) |
4687 | 329 avctx->release_buffer(avctx, &ctx->picture); |
330 free_vlc(&ctx->ac_vlc); | |
331 free_vlc(&ctx->dc_vlc); | |
332 free_vlc(&ctx->run_vlc); | |
333 return 0; | |
334 } | |
335 | |
336 AVCodec dnxhd_decoder = { | |
337 "dnxhd", | |
338 CODEC_TYPE_VIDEO, | |
339 CODEC_ID_DNXHD, | |
340 sizeof(DNXHDContext), | |
341 dnxhd_decode_init, | |
342 NULL, | |
343 dnxhd_decode_close, | |
344 dnxhd_decode_frame, | |
345 CODEC_CAP_DR1, | |
346 }; |