|
|
|
@ -134,12 +134,21 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, |
|
|
|
|
ctx->chroma_factor = (buf[12] >> 6) & 3; |
|
|
|
|
ctx->mb_chroma_factor = ctx->chroma_factor + 2; |
|
|
|
|
ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1; |
|
|
|
|
ctx->alpha_info = buf[17] & 0xf; |
|
|
|
|
|
|
|
|
|
if (ctx->alpha_info > 2) { |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch (ctx->chroma_factor) { |
|
|
|
|
case 2: |
|
|
|
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P10; |
|
|
|
|
avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA422P10 |
|
|
|
|
: AV_PIX_FMT_YUV422P10; |
|
|
|
|
break; |
|
|
|
|
case 3: |
|
|
|
|
avctx->pix_fmt = AV_PIX_FMT_YUV444P10; |
|
|
|
|
avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA444P10 |
|
|
|
|
: AV_PIX_FMT_YUV444P10; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, |
|
|
|
@ -168,10 +177,6 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, |
|
|
|
|
avctx->color_trc = buf[15]; |
|
|
|
|
avctx->colorspace = buf[16]; |
|
|
|
|
|
|
|
|
|
ctx->alpha_info = buf[17] & 0xf; |
|
|
|
|
if (ctx->alpha_info) |
|
|
|
|
avpriv_report_missing_feature(avctx, "Alpha channel"); |
|
|
|
|
|
|
|
|
|
ctx->qmat_changed = 0; |
|
|
|
|
ptr = buf + 20; |
|
|
|
|
flags = buf[19]; |
|
|
|
@ -466,6 +471,78 @@ static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs, |
|
|
|
|
const int num_bits) |
|
|
|
|
{ |
|
|
|
|
const int mask = (1 << num_bits) - 1; |
|
|
|
|
int i, idx, val, alpha_val; |
|
|
|
|
|
|
|
|
|
idx = 0; |
|
|
|
|
alpha_val = mask; |
|
|
|
|
do { |
|
|
|
|
do { |
|
|
|
|
if (get_bits1(gb)) |
|
|
|
|
val = get_bits(gb, num_bits); |
|
|
|
|
else { |
|
|
|
|
int sign; |
|
|
|
|
val = get_bits(gb, num_bits == 16 ? 7 : 4); |
|
|
|
|
sign = val & 1; |
|
|
|
|
val = (val + 2) >> 1; |
|
|
|
|
if (sign) |
|
|
|
|
val = -val; |
|
|
|
|
} |
|
|
|
|
alpha_val = (alpha_val + val) & mask; |
|
|
|
|
if (num_bits == 16) |
|
|
|
|
dst[idx++] = alpha_val >> 6; |
|
|
|
|
else |
|
|
|
|
dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); |
|
|
|
|
if (idx == num_coeffs - 1) |
|
|
|
|
break; |
|
|
|
|
} while (get_bits1(gb)); |
|
|
|
|
val = get_bits(gb, 4); |
|
|
|
|
if (!val) |
|
|
|
|
val = get_bits(gb, 11); |
|
|
|
|
if (idx + val > num_coeffs) |
|
|
|
|
val = num_coeffs - idx; |
|
|
|
|
if (num_bits == 16) |
|
|
|
|
for (i = 0; i < val; i++) |
|
|
|
|
dst[idx++] = alpha_val >> 6; |
|
|
|
|
else |
|
|
|
|
for (i = 0; i < val; i++) |
|
|
|
|
dst[idx++] = (alpha_val << 2) | (alpha_val >> 6); |
|
|
|
|
} while (idx < num_coeffs); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Decode alpha slice plane. |
|
|
|
|
*/ |
|
|
|
|
static void decode_alpha_plane(ProresContext *ctx, ProresThreadData *td, |
|
|
|
|
const uint8_t *buf, int data_size, |
|
|
|
|
uint16_t *out_ptr, int linesize, |
|
|
|
|
int mbs_per_slice) |
|
|
|
|
{ |
|
|
|
|
GetBitContext gb; |
|
|
|
|
int i; |
|
|
|
|
uint16_t *block_ptr; |
|
|
|
|
|
|
|
|
|
memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks)); |
|
|
|
|
|
|
|
|
|
init_get_bits(&gb, buf, data_size << 3); |
|
|
|
|
|
|
|
|
|
if (ctx->alpha_info == 2) |
|
|
|
|
unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 16); |
|
|
|
|
else |
|
|
|
|
unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 8); |
|
|
|
|
|
|
|
|
|
block_ptr = td->blocks; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < 16; i++) { |
|
|
|
|
memcpy(out_ptr, block_ptr, 16 * mbs_per_slice * sizeof(*out_ptr)); |
|
|
|
|
out_ptr += linesize >> 1; |
|
|
|
|
block_ptr += 16 * mbs_per_slice; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int decode_slice(AVCodecContext *avctx, void *tdata) |
|
|
|
|
{ |
|
|
|
|
ProresThreadData *td = tdata; |
|
|
|
@ -476,11 +553,12 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) |
|
|
|
|
int slice_num = td->slice_num; |
|
|
|
|
int mbs_per_slice = td->slice_width; |
|
|
|
|
const uint8_t *buf; |
|
|
|
|
uint8_t *y_data, *u_data, *v_data; |
|
|
|
|
uint8_t *y_data, *u_data, *v_data, *a_data; |
|
|
|
|
AVFrame *pic = ctx->frame; |
|
|
|
|
int i, sf, slice_width_factor; |
|
|
|
|
int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size; |
|
|
|
|
int y_linesize, u_linesize, v_linesize; |
|
|
|
|
int slice_data_size, hdr_size; |
|
|
|
|
int y_data_size, u_data_size, v_data_size, a_data_size; |
|
|
|
|
int y_linesize, u_linesize, v_linesize, a_linesize; |
|
|
|
|
|
|
|
|
|
buf = ctx->slice_data[slice_num].index; |
|
|
|
|
slice_data_size = ctx->slice_data[slice_num + 1].index - buf; |
|
|
|
@ -490,19 +568,23 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) |
|
|
|
|
y_data = pic->data[0]; |
|
|
|
|
u_data = pic->data[1]; |
|
|
|
|
v_data = pic->data[2]; |
|
|
|
|
a_data = pic->data[3]; |
|
|
|
|
y_linesize = pic->linesize[0]; |
|
|
|
|
u_linesize = pic->linesize[1]; |
|
|
|
|
v_linesize = pic->linesize[2]; |
|
|
|
|
a_linesize = pic->linesize[3]; |
|
|
|
|
|
|
|
|
|
if (pic->interlaced_frame) { |
|
|
|
|
if (!(pic_num ^ pic->top_field_first)) { |
|
|
|
|
y_data += y_linesize; |
|
|
|
|
u_data += u_linesize; |
|
|
|
|
v_data += v_linesize; |
|
|
|
|
a_data += a_linesize; |
|
|
|
|
} |
|
|
|
|
y_linesize <<= 1; |
|
|
|
|
u_linesize <<= 1; |
|
|
|
|
v_linesize <<= 1; |
|
|
|
|
a_linesize <<= 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (slice_data_size < 6) { |
|
|
|
@ -516,6 +598,8 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) |
|
|
|
|
u_data_size = AV_RB16(buf + 4); |
|
|
|
|
v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : |
|
|
|
|
slice_data_size - y_data_size - u_data_size - hdr_size; |
|
|
|
|
a_data_size = slice_data_size - y_data_size - u_data_size - |
|
|
|
|
v_data_size - hdr_size; |
|
|
|
|
|
|
|
|
|
if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size || |
|
|
|
|
v_data_size < 0 || hdr_size < 6) { |
|
|
|
@ -560,6 +644,16 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) |
|
|
|
|
slice_width_factor + ctx->chroma_factor - 1, |
|
|
|
|
td->qmat_chroma_scaled, 1); |
|
|
|
|
|
|
|
|
|
/* decode alpha plane if available */ |
|
|
|
|
if (a_data && a_data_size) |
|
|
|
|
decode_alpha_plane(ctx, td, |
|
|
|
|
buf + hdr_size + y_data_size + |
|
|
|
|
u_data_size + v_data_size, |
|
|
|
|
a_data_size, |
|
|
|
|
(uint16_t*) (a_data + (mb_y_pos << 4) * a_linesize + |
|
|
|
|
(mb_x_pos << 5)), a_linesize, |
|
|
|
|
mbs_per_slice); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|