diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 78a0a300b3..8a1774a758 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -313,7 +313,7 @@ OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o -OBJS-$(CONFIG_PRORES_GPL_DECODER) += proresdec_gpl.o +OBJS-$(CONFIG_PRORES_DECODER) += proresdec.o OBJS-$(CONFIG_PRORES_LGPL_DECODER) += proresdec_lgpl.o proresdsp.o OBJS-$(CONFIG_PTX_DECODER) += ptx.o OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o celp_math.o \ diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 6226cac3ce..bc10f46702 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -172,7 +172,7 @@ void avcodec_register_all(void) REGISTER_DECODER (PICTOR, pictor); REGISTER_ENCDEC (PNG, png); REGISTER_ENCDEC (PPM, ppm); - REGISTER_DECODER (PRORES_GPL, prores_gpl); + REGISTER_DECODER (PRORES, prores); REGISTER_DECODER (PRORES_LGPL, prores_lgpl); REGISTER_DECODER (PTX, ptx); REGISTER_DECODER (QDRAW, qdraw); diff --git a/libavcodec/proresdec_gpl.c b/libavcodec/proresdec.c similarity index 84% rename from libavcodec/proresdec_gpl.c rename to libavcodec/proresdec.c index a97b4f7f36..6f4290253b 100644 --- a/libavcodec/proresdec_gpl.c +++ b/libavcodec/proresdec.c @@ -5,16 +5,16 @@ * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; - * version 2 of the License. + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public + * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -30,33 +30,8 @@ #include "avcodec.h" #include "get_bits.h" -#include "dsputil.h" #include "simple_idct.h" - -typedef struct { - const uint8_t *data; - unsigned mb_x; - unsigned mb_y; - unsigned mb_count; - unsigned data_size; -} SliceContext; - -typedef struct { - AVFrame frame; - DSPContext dsp; - int frame_type; ///< 0 = progressive, 1 = tff, 2 = bff - uint8_t qmat_luma[64]; - uint8_t qmat_chroma[64]; - SliceContext *slices; - int slice_count; ///< number of slices in the current picture - unsigned mb_width; ///< width of the current picture in mb - unsigned mb_height; ///< height of the current picture in mb - uint8_t progressive_scan[64]; - uint8_t interlaced_scan[64]; - const uint8_t *scan; - int first_field; - void (*idct_put)(DCTELEM *, uint8_t *restrict, int); -} ProresContext; +#include "proresdec.h" static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64]) { @@ -65,27 +40,6 @@ static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[ dst[i] = permutation[src[i]]; } -static av_always_inline void put_pixels(const DCTELEM *block, uint8_t *restrict pixels, int stride) -{ - int16_t *p = (int16_t*)pixels; - int i, j; - - stride >>= 1; - for(i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - p[j] = av_clip(block[j], 4, 1019); - } - p += stride; - block += 8; - } -} - -static void idct_put(DCTELEM *block, uint8_t *restrict pixels, int stride) -{ - ff_simple_idct_10(block); - put_pixels(block, pixels, stride); -} - static const uint8_t progressive_scan[64] = { 0, 1, 8, 9, 2, 3, 10, 11, 16, 17, 24, 25, 18, 19, 26, 27, @@ -111,18 +65,22 @@ static const uint8_t interlaced_scan[64] = { static av_cold int decode_init(AVCodecContext *avctx) { ProresContext *ctx = avctx->priv_data; + uint8_t idct_permutation[64]; avctx->bits_per_raw_sample = 10; dsputil_init(&ctx->dsp, avctx); + ff_proresdsp_init(&ctx->prodsp); avctx->coded_frame = &ctx->frame; ctx->frame.type = FF_I_TYPE; ctx->frame.key_frame = 1; - ctx->idct_put = idct_put; - memcpy(ctx->progressive_scan, progressive_scan, sizeof(progressive_scan)); - memcpy(ctx->interlaced_scan, interlaced_scan, sizeof(interlaced_scan)); + ff_init_scantable_permutation(idct_permutation, + ctx->prodsp.idct_permutation_type); + + permute(ctx->progressive_scan, progressive_scan, idct_permutation); + permute(ctx->interlaced_scan, interlaced_scan, idct_permutation); return 0; } @@ -133,7 +91,6 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, int hdr_size, width, height, flags; int version; const uint8_t *ptr; - const uint8_t *scan; hdr_size = AV_RB16(buf); av_dlog(avctx, "header size %d\n", hdr_size); @@ -162,10 +119,8 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, av_dlog(avctx, "frame type %d\n", ctx->frame_type); if (ctx->frame_type == 0) { - scan = progressive_scan; ctx->scan = ctx->progressive_scan; // permuted } else { - scan = interlaced_scan; ctx->scan = ctx->interlaced_scan; // permuted ctx->frame.interlaced_frame = 1; ctx->frame.top_field_first = ctx->frame_type == 1; @@ -178,14 +133,14 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, av_dlog(avctx, "flags %x\n", flags); if (flags & 2) { - permute(ctx->qmat_luma, scan, ptr); + permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr); ptr += 64; } else { memset(ctx->qmat_luma, 4, 64); } if (flags & 1) { - permute(ctx->qmat_chroma, scan, ptr); + permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr); } else { memset(ctx->qmat_chroma, 4, 64); } @@ -331,7 +286,7 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70}; static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out, - int blocks_per_slice, const int *qmat) + int blocks_per_slice) { DCTELEM prev_dc; int code, i, sign; @@ -340,7 +295,7 @@ static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out, DECODE_CODEWORD(code, FIRST_DC_CB); prev_dc = TOSIGNED(code); - out[0] = 4096 + ((prev_dc * qmat[0]) >> 2); + out[0] = prev_dc; out += 64; // dc coeff for the next block @@ -351,7 +306,7 @@ static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out, if(code) sign ^= -(code & 1); else sign = 0; prev_dc += (((code + 1) >> 1) ^ sign) - sign; - out[0] = 4096 + ((prev_dc * qmat[0]) >> 2); + out[0] = prev_dc; } CLOSE_READER(re, gb); } @@ -361,8 +316,7 @@ static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C }; static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb, - DCTELEM *out, int blocks_per_slice, - const int *qmat) + DCTELEM *out, int blocks_per_slice) { ProresContext *ctx = avctx->priv_data; int block_mask, sign; @@ -397,7 +351,7 @@ static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitConte sign = SHOW_SBITS(re, gb, 1); SKIP_BITS(re, gb, 1); - out[((pos & block_mask) << 6) + ctx->scan[i]] = (((level ^ sign) - sign) * qmat[i]) >> 2; + out[((pos & block_mask) << 6) + ctx->scan[i]] = ((level ^ sign) - sign); } CLOSE_READER(re, gb); @@ -406,7 +360,7 @@ static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitConte static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, uint8_t *dst, int dst_stride, const uint8_t *buf, unsigned buf_size, - const int *qmat) + const int16_t *qmat) { ProresContext *ctx = avctx->priv_data; LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]); @@ -419,26 +373,24 @@ static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, init_get_bits(&gb, buf, buf_size << 3); - decode_dc_coeffs(&gb, blocks, blocks_per_slice, qmat); - decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice, qmat); + decode_dc_coeffs(&gb, blocks, blocks_per_slice); + decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice); block = blocks; - for (i = 0; i < slice->mb_count; i++) { - ctx->idct_put(block+(0<<6), dst, dst_stride); - ctx->idct_put(block+(1<<6), dst+16, dst_stride); - ctx->idct_put(block+(2<<6), dst+8*dst_stride, dst_stride); - ctx->idct_put(block+(3<<6), dst+8*dst_stride+16, dst_stride); + ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); + ctx->prodsp.idct_put(dst+16, dst_stride, block+(1<<6), qmat); + ctx->prodsp.idct_put(dst+8*dst_stride, dst_stride, block+(2<<6), qmat); + ctx->prodsp.idct_put(dst+8*dst_stride+16, dst_stride, block+(3<<6), qmat); block += 4*64; dst += 32; } - } static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, uint8_t *dst, int dst_stride, const uint8_t *buf, unsigned buf_size, - const int *qmat, int log2_blocks_per_mb) + const int16_t *qmat, int log2_blocks_per_mb) { ProresContext *ctx = avctx->priv_data; LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]); @@ -451,14 +403,14 @@ static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, init_get_bits(&gb, buf, buf_size << 3); - decode_dc_coeffs(&gb, blocks, blocks_per_slice, qmat); - decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice, qmat); + decode_dc_coeffs(&gb, blocks, blocks_per_slice); + decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice); block = blocks; for (i = 0; i < slice->mb_count; i++) { for (j = 0; j < log2_blocks_per_mb; j++) { - ctx->idct_put(block+(0<<6), dst, dst_stride); - ctx->idct_put(block+(1<<6), dst+8*dst_stride, dst_stride); + ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); + ctx->prodsp.idct_put(dst+8*dst_stride, dst_stride, block+(1<<6), qmat); block += 2*64; dst += 16; } @@ -475,8 +427,8 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int int luma_stride, chroma_stride; int y_data_size, u_data_size, v_data_size; uint8_t *dest_y, *dest_u, *dest_v; - int qmat_luma_scaled[64]; - int qmat_chroma_scaled[64]; + int16_t qmat_luma_scaled[64]; + int16_t qmat_chroma_scaled[64]; int mb_x_shift; //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n", @@ -499,7 +451,7 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int buf += hdr_size; for (i = 0; i < 64; i++) { - qmat_luma_scaled[i] = ctx->qmat_luma[i] * qscale; + qmat_luma_scaled [i] = ctx->qmat_luma [i] * qscale; qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * qscale; } @@ -628,8 +580,8 @@ static av_cold int decode_close(AVCodecContext *avctx) return 0; } -AVCodec ff_prores_gpl_decoder = { - .name = "prores_gpl", +AVCodec ff_prores_decoder = { + .name = "prores", .type = AVMEDIA_TYPE_VIDEO, .id = CODEC_ID_PRORES, .priv_data_size = sizeof(ProresContext), diff --git a/libavcodec/proresdec.h b/libavcodec/proresdec.h new file mode 100644 index 0000000000..b3a81d5044 --- /dev/null +++ b/libavcodec/proresdec.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010-2011 Maxim Poliakovski + * Copyright (c) 2010-2011 Elvis Presley + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * version 2 of the License. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_PRORESDEC_H +#define AVCODEC_PRORESDEC_H + +#include "dsputil.h" +#include "proresdsp.h" + +typedef struct { + const uint8_t *data; + unsigned mb_x; + unsigned mb_y; + unsigned mb_count; + unsigned data_size; +} SliceContext; + +typedef struct { + DSPContext dsp; + ProresDSPContext prodsp; + AVFrame frame; + int frame_type; ///< 0 = progressive, 1 = tff, 2 = bff + uint8_t qmat_luma[64]; + uint8_t qmat_chroma[64]; + SliceContext *slices; + int slice_count; ///< number of slices in the current picture + unsigned mb_width; ///< width of the current picture in mb + unsigned mb_height; ///< height of the current picture in mb + uint8_t progressive_scan[64]; + uint8_t interlaced_scan[64]; + const uint8_t *scan; + int first_field; +} ProresContext; + +#endif /* AVCODEC_PRORESDEC_H */ diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index d031f6505b..3ae63ececb 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -36,6 +36,8 @@ MMX-OBJS-$(CONFIG_GPL) += x86/idct_mmx.o MMX-OBJS-$(CONFIG_LPC) += x86/lpc_mmx.o YASM-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp.o MMX-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp-init.o +YASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o +MMX-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp-init.o MMX-OBJS-$(CONFIG_DWT) += x86/snowdsp_mmx.o MMX-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_mmx.o YASM-OBJS-$(CONFIG_VP3_DECODER) += x86/vp3dsp.o