On Fri, May 17, 2013 at 08:56:04PM +0200, Anton Khirnov wrote: > > On Fri, 17 May 2013 19:43:36 +0200, Kostya Shishkov > <[email protected]> wrote: > > --- > > Maybe I'll work on encoder support as well. > > --- > > libavcodec/proresdec.c | 112 > > ++++++++++++++++++++++++++++++++++++++++++++---- > > 1 file changed, 103 insertions(+), 9 deletions(-) > > > > diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c > > index c42e444..0d1eb7a 100644 > > --- a/libavcodec/proresdec.c > > +++ b/libavcodec/proresdec.c > > @@ -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); > > + > > This construct is quite unshapely and could be prettiefied. > E.g. the third parameter shares a lot of stuff with a_data_size. > The fifth parameter could be declared a temp variable.
Would you agree to this patch as is and the latter patch for prettifying it? _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
