diff options
author | James Almer <jamrial@gmail.com> | 2017-10-17 20:26:00 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2017-10-17 20:28:59 -0300 |
commit | 6007f7d4665e970714c2962c0ddb7de910d9da0c (patch) | |
tree | 199d6b22ab0f54964528cd45dc892f8da5ab8ac2 /libavcodec/cfhd.c | |
parent | 8f2cc2f1e9ef7611cbba43fe96f331271b4844fd (diff) | |
parent | 5f794aa1653aa04c1da7397e9ccacad947fadf5f (diff) | |
download | ffmpeg-6007f7d4665e970714c2962c0ddb7de910d9da0c.tar.gz |
Merge commit '5f794aa1653aa04c1da7397e9ccacad947fadf5f'
* commit '5f794aa1653aa04c1da7397e9ccacad947fadf5f':
Add Cineform HD Decoder
See 3485332bf99602910fe8830b0230d02fc653135d.
Some cosmetics are merged. The refactoring is not merged at the
request of Kieran Kunhya.
Merged-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec/cfhd.c')
-rw-r--r-- | libavcodec/cfhd.c | 138 |
1 files changed, 82 insertions, 56 deletions
diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index 5ea8f24821..5646ee8271 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -20,24 +20,39 @@ /** * @file - * CFHD Video Decoder + * Cineform HD video decoder */ +#include "libavutil/attributes.h" #include "libavutil/buffer.h" #include "libavutil/common.h" -#include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" +#include "libavutil/intreadwrite.h" #include "libavutil/opt.h" #include "avcodec.h" -#include "internal.h" #include "bytestream.h" +#include "get_bits.h" +#include "internal.h" #include "thread.h" #include "cfhd.h" -#define SUBBAND_COUNT 10 +enum CFHDParam { + ChannelCount = 12, + SubbandCount = 14, + ImageWidth = 20, + ImageHeight = 21, + LowpassPrecision = 35, + SubbandNumber = 48, + Quantization = 53, + ChannelNumber = 62, + BitsPerComponent = 101, + ChannelWidth = 104, + ChannelHeight = 105, + PrescaleShift = 109, +}; -static av_cold int cfhd_decode_init(AVCodecContext *avctx) +static av_cold int cfhd_init(AVCodecContext *avctx) { CFHDContext *s = avctx->priv_data; @@ -60,7 +75,7 @@ static void init_frame_defaults(CFHDContext *s) s->coded_height = 0; s->bpc = 10; s->channel_cnt = 4; - s->subband_cnt = 10; + s->subband_cnt = SUBBAND_COUNT; s->channel_num = 0; s->lowpass_precision = 16; s->quantisation = 1; @@ -74,15 +89,18 @@ static void init_frame_defaults(CFHDContext *s) static inline int dequant_and_decompand(int level, int quantisation) { int64_t abslevel = abs(level); - return (abslevel + ((768 * abslevel * abslevel * abslevel) / (255 * 255 * 255))) * FFSIGN(level) * quantisation; + return (abslevel + ((768 * abslevel * abslevel * abslevel) / (255 * 255 * 255))) * + FFSIGN(level) * quantisation; } -static inline void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, ptrdiff_t low_stride, - int16_t *high, ptrdiff_t high_stride, int len, uint8_t clip) +static inline void filter(int16_t *output, ptrdiff_t out_stride, + int16_t *low, ptrdiff_t low_stride, + int16_t *high, ptrdiff_t high_stride, + int len, int clip) { int16_t tmp; - int i; + for (i = 0; i < len; i++) { if (i == 0) { tmp = (11*low[0*low_stride] - 4*low[1*low_stride] + low[2*low_stride] + 4) >> 3; @@ -118,28 +136,30 @@ static inline void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, p } } -static void horiz_filter(int16_t *output, int16_t *low, int16_t *high, int width) +static void horiz_filter(int16_t *output, int16_t *low, int16_t *high, + int width) { filter(output, 1, low, 1, high, 1, width, 0); } -static void horiz_filter_clip(int16_t *output, int16_t *low, int16_t *high, int width, uint8_t clip) +static void horiz_filter_clip(int16_t *output, int16_t *low, int16_t *high, + int width, int clip) { filter(output, 1, low, 1, high, 1, width, clip); } -static void vert_filter(int16_t *output, int out_stride, int16_t *low, int low_stride, - int16_t *high, int high_stride, int len) +static void vert_filter(int16_t *output, ptrdiff_t out_stride, + int16_t *low, ptrdiff_t low_stride, + int16_t *high, ptrdiff_t high_stride, int len) { filter(output, out_stride, low, low_stride, high, high_stride, len, 0); } -static void free_buffers(AVCodecContext *avctx) +static void free_buffers(CFHDContext *s) { - CFHDContext *s = avctx->priv_data; int i, j; - for (i = 0; i < 4; i++) { + for (i = 0; i < FF_ARRAY_ELEMS(s->plane); i++) { av_freep(&s->plane[i].idwt_buf); av_freep(&s->plane[i].idwt_tmp); @@ -156,37 +176,43 @@ static void free_buffers(AVCodecContext *avctx) static int alloc_buffers(AVCodecContext *avctx) { CFHDContext *s = avctx->priv_data; - int i, j, k, ret, planes; + int i, j, ret, planes; + int chroma_x_shift, chroma_y_shift; + unsigned k; if ((ret = ff_set_dimensions(avctx, s->coded_width, s->coded_height)) < 0) return ret; avctx->pix_fmt = s->coded_format; - avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift); - planes = av_pix_fmt_count_planes(avctx->pix_fmt); + if ((ret = av_pix_fmt_get_chroma_sub_sample(s->coded_format, + &chroma_x_shift, + &chroma_y_shift)) < 0) + return ret; + planes = av_pix_fmt_count_planes(s->coded_format); for (i = 0; i < planes; i++) { - int width = i ? avctx->width >> s->chroma_x_shift : avctx->width; - int height = i ? avctx->height >> s->chroma_y_shift : avctx->height; - int stride = FFALIGN(width / 8, 8) * 8; int w8, h8, w4, h4, w2, h2; - height = FFALIGN(height / 8, 2) * 8; - s->plane[i].width = width; + int width = i ? avctx->width >> chroma_x_shift : avctx->width; + int height = i ? avctx->height >> chroma_y_shift : avctx->height; + ptrdiff_t stride = FFALIGN(width / 8, 8) * 8; + height = FFALIGN(height / 8, 2) * 8; + s->plane[i].width = width; s->plane[i].height = height; s->plane[i].stride = stride; - w8 = FFALIGN(s->plane[i].width / 8, 8); + w8 = FFALIGN(s->plane[i].width / 8, 8); h8 = FFALIGN(s->plane[i].height / 8, 2); w4 = w8 * 2; h4 = h8 * 2; w2 = w4 * 2; h2 = h4 * 2; - s->plane[i].idwt_buf = av_mallocz_array(height * stride, sizeof(*s->plane[i].idwt_buf)); - s->plane[i].idwt_tmp = av_malloc_array(height * stride, sizeof(*s->plane[i].idwt_tmp)); - if (!s->plane[i].idwt_buf || !s->plane[i].idwt_tmp) { + s->plane[i].idwt_buf = + av_mallocz_array(height * stride, sizeof(*s->plane[i].idwt_buf)); + s->plane[i].idwt_tmp = + av_malloc_array(height * stride, sizeof(*s->plane[i].idwt_tmp)); + if (!s->plane[i].idwt_buf || !s->plane[i].idwt_tmp) return AVERROR(ENOMEM); - } s->plane[i].subband[0] = s->plane[i].idwt_buf; s->plane[i].subband[1] = s->plane[i].idwt_buf + 2 * w8 * h8; @@ -200,7 +226,7 @@ static int alloc_buffers(AVCodecContext *avctx) s->plane[i].subband[9] = s->plane[i].idwt_buf + 3 * w2 * h2; for (j = 0; j < DWT_LEVELS; j++) { - for(k = 0; k < 4; k++) { + for (k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { s->plane[i].band[j][k].a_width = w8 << j; s->plane[i].band[j][k].a_height = h8 << j; } @@ -209,10 +235,10 @@ static int alloc_buffers(AVCodecContext *avctx) /* ll2 and ll1 commented out because they are done in-place */ s->plane[i].l_h[0] = s->plane[i].idwt_tmp; s->plane[i].l_h[1] = s->plane[i].idwt_tmp + 2 * w8 * h8; - //s->plane[i].l_h[2] = ll2; + // s->plane[i].l_h[2] = ll2; s->plane[i].l_h[3] = s->plane[i].idwt_tmp; s->plane[i].l_h[4] = s->plane[i].idwt_tmp + 2 * w4 * h4; - //s->plane[i].l_h[5] = ll1; + // s->plane[i].l_h[5] = ll1; s->plane[i].l_h[6] = s->plane[i].idwt_tmp; s->plane[i].l_h[7] = s->plane[i].idwt_tmp + 2 * w2 * h2; } @@ -250,10 +276,10 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, uint16_t data = bytestream2_get_be16(&gb); if (abs_tag8 >= 0x60 && abs_tag8 <= 0x6f) { av_log(avctx, AV_LOG_DEBUG, "large len %x\n", ((tagu & 0xff) << 16) | data); - } else if (tag == 20) { + } else if (tag == ImageWidth) { av_log(avctx, AV_LOG_DEBUG, "Width %"PRIu16"\n", data); s->coded_width = data; - } else if (tag == 21) { + } else if (tag == ImageHeight) { av_log(avctx, AV_LOG_DEBUG, "Height %"PRIu16"\n", data); s->coded_height = data; } else if (tag == 101) { @@ -264,7 +290,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, break; } s->bpc = data; - } else if (tag == 12) { + } else if (tag == ChannelCount) { av_log(avctx, AV_LOG_DEBUG, "Channel Count: %"PRIu16"\n", data); s->channel_cnt = data; if (data > 4) { @@ -272,14 +298,14 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, ret = AVERROR_PATCHWELCOME; break; } - } else if (tag == 14) { + } else if (tag == SubbandCount) { av_log(avctx, AV_LOG_DEBUG, "Subband Count: %"PRIu16"\n", data); if (data != SUBBAND_COUNT) { av_log(avctx, AV_LOG_ERROR, "Subband Count of %"PRIu16" is unsupported\n", data); ret = AVERROR_PATCHWELCOME; break; } - } else if (tag == 62) { + } else if (tag == ChannelNumber) { s->channel_num = data; av_log(avctx, AV_LOG_DEBUG, "Channel number %"PRIu16"\n", data); if (s->channel_num >= planes) { @@ -288,7 +314,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, break; } init_plane_defaults(s); - } else if (tag == 48) { + } else if (tag == SubbandNumber) { if (s->subband_num != 0 && data == 1) // hack s->level++; av_log(avctx, AV_LOG_DEBUG, "Subband number %"PRIu16"\n", data); @@ -311,12 +337,12 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, ret = AVERROR(EINVAL); break; } - } else if (tag == 35) + } else if (tag == LowpassPrecision) av_log(avctx, AV_LOG_DEBUG, "Lowpass precision bits: %"PRIu16"\n", data); - else if (tag == 53) { + else if (tag == Quantization) { s->quantisation = data; av_log(avctx, AV_LOG_DEBUG, "Quantisation: %"PRIu16"\n", data); - } else if (tag == 109) { + } else if (tag == PrescaleShift) { s->prescale_shift[0] = (data >> 0) & 0x7; s->prescale_shift[1] = (data >> 3) & 0x7; s->prescale_shift[2] = (data >> 6) & 0x7; @@ -437,9 +463,9 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, s->coded_format != AV_PIX_FMT_NONE) { if (s->a_width != s->coded_width || s->a_height != s->coded_height || s->a_format != s->coded_format) { - free_buffers(avctx); + free_buffers(s); if ((ret = alloc_buffers(avctx)) < 0) { - free_buffers(avctx); + free_buffers(s); return ret; } } @@ -775,11 +801,11 @@ end: return avpkt->size; } -static av_cold int cfhd_close_decoder(AVCodecContext *avctx) +static av_cold int cfhd_close(AVCodecContext *avctx) { CFHDContext *s = avctx->priv_data; - free_buffers(avctx); + free_buffers(s); if (!avctx->internal->is_copy) { ff_free_vlc(&s->vlc_9); @@ -790,14 +816,14 @@ static av_cold int cfhd_close_decoder(AVCodecContext *avctx) } AVCodec ff_cfhd_decoder = { - .name = "cfhd", - .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"), - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_CFHD, - .priv_data_size = sizeof(CFHDContext), - .init = cfhd_decode_init, - .close = cfhd_close_decoder, - .decode = cfhd_decode, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, + .name = "cfhd", + .long_name = NULL_IF_CONFIG_SMALL("Cineform HD"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_CFHD, + .priv_data_size = sizeof(CFHDContext), + .init = cfhd_init, + .close = cfhd_close, + .decode = cfhd_decode, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; |