| @@ -41,10 +41,11 @@ typedef struct DNXHDContext { · 40 unmodified lines |
| 41 | 41 | VLC ac_vlc, dc_vlc, run_vlc; |
| 42 | 42 | int last_dc[3]; |
| 43 | 43 | DSPContext dsp; |
| 44 | | − DECLARE_ALIGNED(16, int16_t, blocks)[8][64]; |
| 44 | + DECLARE_ALIGNED(16, int16_t, blocks)[12][64]; |
| 45 | 45 | ScanTable scantable; |
| 46 | 46 | const CIDEntry *cid_table; |
| 47 | 47 | int bit_depth; // 8, 10 or 0 if not initialized at all. |
| 48 | + int is_444; |
| 48 | 49 | void (*decode_dct_block)(struct DNXHDContext *ctx, int16_t *block, |
| 49 | 50 | int n, int qscale); |
| 50 | 51 | } DNXHDContext; |
| @@ -54,6 +55,7 @@ typedef struct DNXHDContext { · 3 unmodified lines |
| 54 | 55 | |
| 55 | 56 | static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, int16_t *block, int n, int qscale); |
| 56 | 57 | static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block, int n, int qscale); |
| 58 | +static void dnxhd_decode_dct_block_10_444(DNXHDContext *ctx, int16_t *block, int n, int qscale); |
| 57 | 59 | |
| 58 | 60 | static av_cold int dnxhd_decode_init(AVCodecContext *avctx) |
| 59 | 61 | { |
| @@ -97,13 +99,14 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) · 37 unmodified lines |
| 97 | 99 | static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, |
| 98 | 100 | const uint8_t *buf, int buf_size, int first_field) |
| 99 | 101 | { |
| 100 | | − static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; |
| 102 | + static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; |
| 103 | + static const uint8_t header_prefix444[] = { 0x00, 0x00, 0x02, 0x80, 0x02 }; |
| 101 | 104 | int i, cid, ret; |
| 102 | 105 | |
| 103 | 106 | if (buf_size < 0x280) |
| 104 | 107 | return AVERROR_INVALIDDATA; |
| 105 | 108 | |
| 106 | | − if (memcmp(buf, header_prefix, 5)) { |
| 109 | + if (memcmp(buf, header_prefix, 5) && memcmp(buf, header_prefix444, 5)) { |
| 107 | 110 | av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); |
| 108 | 111 | return AVERROR_INVALIDDATA; |
| 109 | 112 | } |
| @@ -119,7 +122,17 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, · 9 unmodified lines |
| 119 | 122 | |
| 120 | 123 | av_dlog(ctx->avctx, "width %d, height %d\n", ctx->width, ctx->height); |
| 121 | 124 | |
| 122 | | − if (buf[0x21] & 0x40) { |
| 125 | + ctx->is_444 = 0; |
| 126 | + if (buf[0x4] == 0x2) { |
| 127 | + ctx->avctx->pix_fmt = AV_PIX_FMT_YUV444P10; |
| 128 | + ctx->avctx->bits_per_raw_sample = 10; |
| 129 | + if (ctx->bit_depth != 10) { |
| 130 | + ff_dsputil_init(&ctx->dsp, ctx->avctx); |
| 131 | + ctx->bit_depth = 10; |
| 132 | + ctx->decode_dct_block = dnxhd_decode_dct_block_10_444; |
| 133 | + } |
| 134 | + ctx->is_444 = 1; |
| 135 | + } else if (buf[0x21] & 0x40) { |
| 123 | 136 | ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; |
| 124 | 137 | ctx->avctx->bits_per_raw_sample = 10; |
| 125 | 138 | if (ctx->bit_depth != 10) { |
| @@ -186,12 +199,21 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx, · 60 unmodified lines |
| 186 | 199 | const uint8_t *weight_matrix; |
| 187 | 200 | OPEN_READER(bs, &ctx->gb); |
| 188 | 201 | |
| 189 | | − if (n&2) { |
| 190 | | − component = 1 + (n&1); |
| 191 | | − weight_matrix = ctx->cid_table->chroma_weight; |
| 202 | + if (!ctx->is_444) { |
| 203 | + if (n&2) { |
| 204 | + component = 1 + (n&1); |
| 205 | + weight_matrix = ctx->cid_table->chroma_weight; |
| 206 | + } else { |
| 207 | + component = 0; |
| 208 | + weight_matrix = ctx->cid_table->luma_weight; |
| 209 | + } |
| 192 | 210 | } else { |
| 193 | | − component = 0; |
| 194 | | − weight_matrix = ctx->cid_table->luma_weight; |
| 211 | + component = (n >> 1) % 3; |
| 212 | + if (component) { |
| 213 | + weight_matrix = ctx->cid_table->chroma_weight; |
| 214 | + } else { |
| 215 | + weight_matrix = ctx->cid_table->luma_weight; |
| 216 | + } |
| 195 | 217 | } |
| 196 | 218 | |
| 197 | 219 | UPDATE_CACHE(bs, &ctx->gb); |
| @@ -257,6 +279,12 @@ static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block, · 59 unmodified lines |
| 257 | 279 | dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 8, 4); |
| 258 | 280 | } |
| 259 | 281 | |
| 282 | +static void dnxhd_decode_dct_block_10_444(DNXHDContext *ctx, int16_t *block, |
| 283 | + int n, int qscale) |
| 284 | +{ |
| 285 | + dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 32, 6); |
| 286 | +} |
| 287 | + |
| 260 | 288 | static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int y) |
| 261 | 289 | { |
| 262 | 290 | int shift1 = ctx->bit_depth == 10; |
| @@ -273,6 +301,12 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int · 10 unmodified lines |
| 273 | 301 | ctx->dsp.clear_block(ctx->blocks[i]); |
| 274 | 302 | ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale); |
| 275 | 303 | } |
| 304 | + if (ctx->is_444) { |
| 305 | + for (; i < 12; i++) { |
| 306 | + ctx->dsp.clear_block(ctx->blocks[i]); |
| 307 | + ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale); |
| 308 | + } |
| 309 | + } |
| 276 | 310 | |
| 277 | 311 | if (frame->interlaced_frame) { |
| 278 | 312 | dct_linesize_luma <<= 1; |
| @@ -280,8 +314,8 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int · 1 unmodified line |
| 280 | 314 | } |
| 281 | 315 | |
| 282 | 316 | dest_y = frame->data[0] + ((y * dct_linesize_luma) << 4) + (x << (4 + shift1)); |
| 283 | | − dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); |
| 284 | | − dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); |
| 317 | + dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444)); |
| 318 | + dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444)); |
| 285 | 319 | |
| 286 | 320 | if (ctx->cur_field) { |
| 287 | 321 | dest_y += frame->linesize[0]; |
| @@ -291,17 +325,36 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int · 3 unmodified lines |
| 291 | 325 | |
| 292 | 326 | dct_y_offset = dct_linesize_luma << 3; |
| 293 | 327 | dct_x_offset = 8 << shift1; |
| 294 | | − ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); |
| 295 | | − ctx->dsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, ctx->blocks[1]); |
| 296 | | − ctx->dsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, ctx->blocks[4]); |
| 297 | | − ctx->dsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[5]); |
| 298 | | − |
| 299 | | − if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { |
| 300 | | − dct_y_offset = dct_linesize_chroma << 3; |
| 301 | | − ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); |
| 302 | | − ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); |
| 303 | | − ctx->dsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[6]); |
| 304 | | − ctx->dsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, ctx->blocks[7]); |
| 328 | + if (!ctx->is_444) { |
| 329 | + ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); |
| 330 | + ctx->dsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, ctx->blocks[1]); |
| 331 | + ctx->dsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, ctx->blocks[4]); |
| 332 | + ctx->dsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[5]); |
| 333 | + |
| 334 | + if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { |
| 335 | + dct_y_offset = dct_linesize_chroma << 3; |
| 336 | + ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); |
| 337 | + ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); |
| 338 | + ctx->dsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[6]); |
| 339 | + ctx->dsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, ctx->blocks[7]); |
| 340 | + } |
| 341 | + } else { |
| 342 | + ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); |
| 343 | + ctx->dsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, ctx->blocks[1]); |
| 344 | + ctx->dsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, ctx->blocks[6]); |
| 345 | + ctx->dsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[7]); |
| 346 | + |
| 347 | + if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { |
| 348 | + dct_y_offset = dct_linesize_chroma << 3; |
| 349 | + ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); |
| 350 | + ctx->dsp.idct_put(dest_u + dct_x_offset, dct_linesize_chroma, ctx->blocks[3]); |
| 351 | + ctx->dsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[8]); |
| 352 | + ctx->dsp.idct_put(dest_u + dct_y_offset + dct_x_offset, dct_linesize_chroma, ctx->blocks[9]); |
| 353 | + ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[4]); |
| 354 | + ctx->dsp.idct_put(dest_v + dct_x_offset, dct_linesize_chroma, ctx->blocks[5]); |
| 355 | + ctx->dsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, ctx->blocks[10]); |
| 356 | + ctx->dsp.idct_put(dest_v + dct_y_offset + dct_x_offset, dct_linesize_chroma, ctx->blocks[11]); |
| 357 | + } |
| 305 | 358 | } |
| 306 | 359 | |
| 307 | 360 | return 0; |