Commit 51290068 authored by Michael Niedermayer's avatar Michael Niedermayer

Merge commit 'e95018b6'

* commit 'e95018b6':
  dnxhd: Support DNx444

Conflicts:
	Changelog
	libavcodec/dnxhddata.c
	libavcodec/dnxhddec.c
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents d84f1a60 e95018b6
...@@ -25,6 +25,7 @@ version <next> ...@@ -25,6 +25,7 @@ version <next>
- Use metadata_header_padding to control padding in ID3 tags (currently used in - Use metadata_header_padding to control padding in ID3 tags (currently used in
MP3, AIFF, and OMA files), FLAC header, and the AVI "junk" block. MP3, AIFF, and OMA files), FLAC header, and the AVI "junk" block.
- Mirillis FIC video decoder - Mirillis FIC video decoder
- Support DNx444
version 2.1: version 2.1:
......
...@@ -222,6 +222,17 @@ static const uint8_t dnxhd_1252_chroma_weight[] = { ...@@ -222,6 +222,17 @@ static const uint8_t dnxhd_1252_chroma_weight[] = {
114, 128, 125, 129, 134, 125, 116, 116, 114, 128, 125, 129, 134, 125, 116, 116,
}; };
static const uint8_t dnxhd_1256_chroma_weight[] = {
0, 32, 32, 32, 32, 32, 32, 33,
32, 32, 32, 32, 32, 32, 32, 34,
32, 32, 32, 32, 32, 32, 33, 37,
32, 32, 32, 32, 32, 32, 36, 39,
32, 32, 32, 32, 32, 34, 39, 44,
32, 37, 32, 32, 35, 40, 43, 49,
32, 33, 36, 36, 40, 43, 50, 60,
34, 37, 39, 44, 51, 56, 61, 70,
};
static const uint8_t dnxhd_1237_dc_codes[12] = { static const uint8_t dnxhd_1237_dc_codes[12] = {
0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63,
}; };
...@@ -1026,6 +1037,14 @@ const CIDEntry ff_dnxhd_cid_table[] = { ...@@ -1026,6 +1037,14 @@ const CIDEntry ff_dnxhd_cid_table[] = {
dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
{ 36, 36, 45, 75, 90 }, { 36, 36, 45, 75, 90 },
{ { 24000, 1001 }, { 25, 1 }, { 30000, 1001 }, { 50, 1 }, { 60000, 1001 } } }, { { 24000, 1001 }, { 25, 1 }, { 30000, 1001 }, { 50, 1 }, { 60000, 1001 } } },
{ 1256, 1920, 1080, 0, 1835008, 1835008, 6, 10, 4,
dnxhd_1235_luma_weight, dnxhd_1256_chroma_weight,
dnxhd_1235_1241_dc_codes, dnxhd_1235_1241_dc_bits,
dnxhd_1235_1241_ac_codes, dnxhd_1235_1241_ac_bits, dnxhd_1235_1241_ac_level,
dnxhd_1235_1241_ac_flags,
dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1235_1241_run,
{ 350, 390, 440, 730, 880 },
{ { 24000, 1001 }, { 25, 1 }, { 30000, 1001 }, { 50, 1 }, { 60000, 1001 } } },
}; };
int ff_dnxhd_get_cid_table(int cid) int ff_dnxhd_get_cid_table(int cid)
......
...@@ -42,10 +42,11 @@ typedef struct DNXHDContext { ...@@ -42,10 +42,11 @@ typedef struct DNXHDContext {
VLC ac_vlc, dc_vlc, run_vlc; VLC ac_vlc, dc_vlc, run_vlc;
int last_dc[3]; int last_dc[3];
DSPContext dsp; DSPContext dsp;
DECLARE_ALIGNED(16, int16_t, blocks)[8][64]; DECLARE_ALIGNED(16, int16_t, blocks)[12][64];
ScanTable scantable; ScanTable scantable;
const CIDEntry *cid_table; const CIDEntry *cid_table;
int bit_depth; // 8, 10 or 0 if not initialized at all. int bit_depth; // 8, 10 or 0 if not initialized at all.
int is_444;
void (*decode_dct_block)(struct DNXHDContext *ctx, int16_t *block, void (*decode_dct_block)(struct DNXHDContext *ctx, int16_t *block,
int n, int qscale); int n, int qscale);
int last_qscale; int last_qscale;
...@@ -58,6 +59,7 @@ typedef struct DNXHDContext { ...@@ -58,6 +59,7 @@ typedef struct DNXHDContext {
static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, int16_t *block, int n, int qscale); static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, int16_t *block, int n, int qscale);
static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block, int n, int qscale); static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block, int n, int qscale);
static void dnxhd_decode_dct_block_10_444(DNXHDContext *ctx, int16_t *block, int n, int qscale);
static av_cold int dnxhd_decode_init(AVCodecContext *avctx) static av_cold int dnxhd_decode_init(AVCodecContext *avctx)
{ {
...@@ -107,12 +109,13 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, ...@@ -107,12 +109,13 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
const uint8_t *buf, int buf_size, int first_field) const uint8_t *buf, int buf_size, int first_field)
{ {
static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 };
static const uint8_t header_prefix444[] = { 0x00, 0x00, 0x02, 0x80, 0x02 };
int i, cid, ret; int i, cid, ret;
if (buf_size < 0x280) if (buf_size < 0x280)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
if (memcmp(buf, header_prefix, 5)) { if (memcmp(buf, header_prefix, 5) && memcmp(buf, header_prefix444, 5)) {
av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
...@@ -128,7 +131,17 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, ...@@ -128,7 +131,17 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
av_dlog(ctx->avctx, "width %d, height %d\n", ctx->width, ctx->height); av_dlog(ctx->avctx, "width %d, height %d\n", ctx->width, ctx->height);
if (buf[0x21] & 0x40) { ctx->is_444 = 0;
if (buf[0x4] == 0x2) {
ctx->avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
ctx->avctx->bits_per_raw_sample = 10;
if (ctx->bit_depth != 10) {
ff_dsputil_init(&ctx->dsp, ctx->avctx);
ctx->bit_depth = 10;
ctx->decode_dct_block = dnxhd_decode_dct_block_10_444;
}
ctx->is_444 = 1;
} else if (buf[0x21] & 0x40) {
ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
ctx->avctx->bits_per_raw_sample = 10; ctx->avctx->bits_per_raw_sample = 10;
if (ctx->bit_depth != 10) { if (ctx->bit_depth != 10) {
...@@ -199,6 +212,7 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx, ...@@ -199,6 +212,7 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,
const int eob_index = ctx->cid_table->eob_index; const int eob_index = ctx->cid_table->eob_index;
OPEN_READER(bs, &ctx->gb); OPEN_READER(bs, &ctx->gb);
if (!ctx->is_444) {
if (n&2) { if (n&2) {
component = 1 + (n&1); component = 1 + (n&1);
scale = ctx->chroma_scale; scale = ctx->chroma_scale;
...@@ -208,6 +222,16 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx, ...@@ -208,6 +222,16 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,
scale = ctx->luma_scale; scale = ctx->luma_scale;
weight_matrix = ctx->cid_table->luma_weight; weight_matrix = ctx->cid_table->luma_weight;
} }
} else {
component = (n >> 1) % 3;
if (component) {
scale = ctx->chroma_scale;
weight_matrix = ctx->cid_table->chroma_weight;
} else {
scale = ctx->luma_scale;
weight_matrix = ctx->cid_table->luma_weight;
}
}
UPDATE_CACHE(bs, &ctx->gb); UPDATE_CACHE(bs, &ctx->gb);
GET_VLC(len, bs, &ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1); GET_VLC(len, bs, &ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1);
...@@ -278,6 +302,12 @@ static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block, ...@@ -278,6 +302,12 @@ static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block,
dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 8, 4); dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 8, 4);
} }
static void dnxhd_decode_dct_block_10_444(DNXHDContext *ctx, int16_t *block,
int n, int qscale)
{
dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 32, 6);
}
static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int y) static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int y)
{ {
int shift1 = ctx->bit_depth == 10; int shift1 = ctx->bit_depth == 10;
...@@ -302,6 +332,12 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int ...@@ -302,6 +332,12 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int
ctx->dsp.clear_block(ctx->blocks[i]); ctx->dsp.clear_block(ctx->blocks[i]);
ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale); ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale);
} }
if (ctx->is_444) {
for (; i < 12; i++) {
ctx->dsp.clear_block(ctx->blocks[i]);
ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale);
}
}
if (frame->interlaced_frame) { if (frame->interlaced_frame) {
dct_linesize_luma <<= 1; dct_linesize_luma <<= 1;
...@@ -309,8 +345,8 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int ...@@ -309,8 +345,8 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int
} }
dest_y = frame->data[0] + ((y * dct_linesize_luma) << 4) + (x << (4 + shift1)); dest_y = frame->data[0] + ((y * dct_linesize_luma) << 4) + (x << (4 + shift1));
dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444));
dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444));
if (ctx->cur_field) { if (ctx->cur_field) {
dest_y += frame->linesize[0]; dest_y += frame->linesize[0];
...@@ -320,6 +356,7 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int ...@@ -320,6 +356,7 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int
dct_y_offset = dct_linesize_luma << 3; dct_y_offset = dct_linesize_luma << 3;
dct_x_offset = 8 << shift1; dct_x_offset = 8 << shift1;
if (!ctx->is_444) {
ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]);
ctx->dsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, ctx->blocks[1]); ctx->dsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, ctx->blocks[1]);
ctx->dsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, ctx->blocks[4]); ctx->dsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, ctx->blocks[4]);
...@@ -332,6 +369,24 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int ...@@ -332,6 +369,24 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int
ctx->dsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[6]); ctx->dsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[6]);
ctx->dsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, ctx->blocks[7]); ctx->dsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, ctx->blocks[7]);
} }
} else {
ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]);
ctx->dsp.idct_put(dest_y + dct_x_offset, dct_linesize_luma, ctx->blocks[1]);
ctx->dsp.idct_put(dest_y + dct_y_offset, dct_linesize_luma, ctx->blocks[6]);
ctx->dsp.idct_put(dest_y + dct_y_offset + dct_x_offset, dct_linesize_luma, ctx->blocks[7]);
if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) {
dct_y_offset = dct_linesize_chroma << 3;
ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]);
ctx->dsp.idct_put(dest_u + dct_x_offset, dct_linesize_chroma, ctx->blocks[3]);
ctx->dsp.idct_put(dest_u + dct_y_offset, dct_linesize_chroma, ctx->blocks[8]);
ctx->dsp.idct_put(dest_u + dct_y_offset + dct_x_offset, dct_linesize_chroma, ctx->blocks[9]);
ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[4]);
ctx->dsp.idct_put(dest_v + dct_x_offset, dct_linesize_chroma, ctx->blocks[5]);
ctx->dsp.idct_put(dest_v + dct_y_offset, dct_linesize_chroma, ctx->blocks[10]);
ctx->dsp.idct_put(dest_v + dct_y_offset + dct_x_offset, dct_linesize_chroma, ctx->blocks[11]);
}
}
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment