| @@ -41,10 +41,11 @@ typedef struct DNXHDContext { · 40 unmodified lines |
| 41 | VLC ac_vlc, dc_vlc, run_vlc; | 41 | VLC ac_vlc, dc_vlc, run_vlc; |
| 42 | int last_dc[3]; | 42 | int last_dc[3]; |
| 43 | DSPContext dsp; | 43 | DSPContext dsp; |
| 44 | DECLARE_ALIGNED(16, int16_t, blocks)[8][64]; | 44 | DECLARE_ALIGNED(16, int16_t, blocks)[12][64]; |
| 45 | ScanTable scantable; | 45 | ScanTable scantable; |
| 46 | const CIDEntry *cid_table; | 46 | const CIDEntry *cid_table; |
| 47 | int bit_depth; // 8, 10 or 0 if not initialized at all. | 47 | int bit_depth; // 8, 10 or 0 if not initialized at all. |
| | 48 | int is_444; |
| 48 | void (*decode_dct_block)(struct DNXHDContext *ctx, int16_t *block, | 49 | void (*decode_dct_block)(struct DNXHDContext *ctx, int16_t *block, |
| 49 | int n, int qscale); | 50 | int n, int qscale); |
| 50 | } DNXHDContext; | 51 | } DNXHDContext; |
| @@ -54,6 +55,7 @@ typedef struct DNXHDContext { · 3 unmodified lines |
| 54 | | 55 | |
| 55 | static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, int16_t *block, int n, int qscale); | 56 | static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, int16_t *block, int n, int qscale); |
| 56 | static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block, int n, int qscale); | 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 | static av_cold int dnxhd_decode_init(AVCodecContext *avctx) | 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 | static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, | 99 | static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, |
| 98 | const uint8_t *buf, int buf_size, int first_field) | 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 | int i, cid, ret; | 104 | int i, cid, ret; |
| 102 | | 105 | |
| 103 | if (buf_size < 0x280) | 106 | if (buf_size < 0x280) |
| 104 | return AVERROR_INVALIDDATA; | 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 | av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); | 110 | av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); |
| 108 | return AVERROR_INVALIDDATA; | 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 | av_dlog(ctx->avctx, "width %d, height %d\n", ctx->width, ctx->height); | 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 | ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; | 136 | ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; |
| 124 | ctx->avctx->bits_per_raw_sample = 10; | 137 | ctx->avctx->bits_per_raw_sample = 10; |
| 125 | if (ctx->bit_depth != 10) { | 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 | const uint8_t *weight_matrix; | 199 | const uint8_t *weight_matrix; |
| 187 | OPEN_READER(bs, &ctx->gb); | 200 | OPEN_READER(bs, &ctx->gb); |
| 188 | | 201 | |
| 189 | if (n&2) { | 202 | if (!ctx->is_444) { |
| 190 | component = 1 + (n&1); | 203 | if (n&2) { |
| 191 | weight_matrix = ctx->cid_table->chroma_weight; | 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 | } else { | 210 | } else { |
| 193 | component = 0; | 211 | component = (n >> 1) % 3; |
| 194 | weight_matrix = ctx->cid_table->luma_weight; | 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 | UPDATE_CACHE(bs, &ctx->gb); | 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 | dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 8, 4); | 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 | static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int y) | 288 | static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int y) |
| 261 | { | 289 | { |
| 262 | int shift1 = ctx->bit_depth == 10; | 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 | ctx->dsp.clear_block(ctx->blocks[i]); | 301 | ctx->dsp.clear_block(ctx->blocks[i]); |
| 274 | ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale); | 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 | if (frame->interlaced_frame) { | 311 | if (frame->interlaced_frame) { |
| 278 | dct_linesize_luma <<= 1; | 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 | dest_y = frame->data[0] + ((y * dct_linesize_luma) << 4) + (x << (4 + shift1)); | 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)); | 317 | dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444)); |
| 284 | dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); | 318 | dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444)); |
| 285 | | 319 | |
| 286 | if (ctx->cur_field) { | 320 | if (ctx->cur_field) { |
| 287 | dest_y += frame->linesize[0]; | 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 | dct_y_offset = dct_linesize_luma << 3; | 326 | dct_y_offset = dct_linesize_luma << 3; |
| 293 | dct_x_offset = 8 << shift1; | 327 | dct_x_offset = 8 << shift1; |
| 294 | ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); | 328 | if (!ctx->is_444) { |
| 295 | ctx->dsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, ctx->blocks[1]); | 329 | ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); |
| 296 | ctx->dsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, ctx->blocks[4]); | 330 | ctx->dsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, ctx->blocks[1]); |
| 297 | ctx->dsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[5]); | 331 | ctx->dsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, ctx->blocks[4]); |
| 298 | | 332 | ctx->dsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[5]); |
| 299 | if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { | 333 | |
| 300 | dct_y_offset = dct_linesize_chroma << 3; | 334 | if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { |
| 301 | ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); | 335 | dct_y_offset = dct_linesize_chroma << 3; |
| 302 | ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); | 336 | ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); |
| 303 | ctx->dsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[6]); | 337 | ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); |
| 304 | ctx->dsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, ctx->blocks[7]); | 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 | return 0; | 360 | return 0; |