ffmpeg | branch: master | James Almer <jamr...@gmail.com> | Mon Oct 30 15:46:23 2017 -0300| [269ed71e93a4eb96cbdf3720311708fb613999d1] | committer: James Almer
Merge commit '189157c3fc8eeb691e3684b09d971eb5ddb47d5b' * commit '189157c3fc8eeb691e3684b09d971eb5ddb47d5b': Add ClearVideo decoder See a63496cc882428aefafc85d2f60e0908b020bffe Merged-by: James Almer <jamr...@gmail.com> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=269ed71e93a4eb96cbdf3720311708fb613999d1 --- doc/general.texi | 1 + libavcodec/clearvideo.c | 56 ++++++++++++++++++++++++++----------------------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/doc/general.texi b/doc/general.texi index 56f315d67b..9e6ae13435 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -365,6 +365,7 @@ library: @item Interplay MVE @tab @tab X @tab Format used in various Interplay computer games. @item Iterated Systems ClearVideo @tab @tab X + @tab I-frames only @item IV8 @tab @tab X @tab A format generated by IndigoVision 8000 video server. @item IVF (On2) @tab X @tab X diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c index 067942a131..2c06b79fd5 100644 --- a/libavcodec/clearvideo.c +++ b/libavcodec/clearvideo.c @@ -25,10 +25,10 @@ */ #include "avcodec.h" +#include "bytestream.h" +#include "get_bits.h" #include "idctdsp.h" #include "internal.h" -#include "get_bits.h" -#include "bytestream.h" #define NUM_DC_CODES 127 #define NUM_AC_CODES 103 @@ -129,6 +129,7 @@ typedef struct CLVContext { int luma_dc_quant, chroma_dc_quant, ac_quant; DECLARE_ALIGNED(16, int16_t, block)[64]; int top_dc[3], left_dc[4]; + int iframes_warning; } CLVContext; static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac, @@ -179,12 +180,12 @@ static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac, } #define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP) \ - const int t0 = OP( 2841 * blk[1 * step] + 565 * blk[7 * step]); \ - const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \ - const int t2 = OP( 1609 * blk[5 * step] + 2408 * blk[3 * step]); \ - const int t3 = OP( 2408 * blk[5 * step] - 1609 * blk[3 * step]); \ - const int t4 = OP( 1108 * blk[2 * step] - 2676 * blk[6 * step]); \ - const int t5 = OP( 2676 * blk[2 * step] + 1108 * blk[6 * step]); \ + const int t0 = OP(2841 * blk[1 * step] + 565 * blk[7 * step]); \ + const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \ + const int t2 = OP(1609 * blk[5 * step] + 2408 * blk[3 * step]); \ + const int t3 = OP(2408 * blk[5 * step] - 1609 * blk[3 * step]); \ + const int t4 = OP(1108 * blk[2 * step] - 2676 * blk[6 * step]); \ + const int t5 = OP(2676 * blk[2 * step] + 1108 * blk[6 * step]); \ const int t6 = ((blk[0 * step] + blk[4 * step]) * (1 << dshift)) + bias; \ const int t7 = ((blk[0 * step] - blk[4 * step]) * (1 << dshift)) + bias; \ const int t8 = t0 + t2; \ @@ -225,9 +226,7 @@ static void clv_dct(int16_t *block) static int decode_mb(CLVContext *c, int x, int y) { - int i; - int has_ac[6]; - int off; + int i, has_ac[6], off; for (i = 0; i < 6; i++) has_ac[i] = get_bits1(&c->gb); @@ -247,7 +246,8 @@ static int decode_mb(CLVContext *c, int x, int y) clv_dct(c->block); if (i == 2) off += c->pic->linesize[0] * 8; - c->idsp.put_pixels_clamped(c->block, c->pic->data[0] + off + (i & 1) * 8, + c->idsp.put_pixels_clamped(c->block, + c->pic->data[0] + off + (i & 1) * 8, c->pic->linesize[0]); } @@ -279,12 +279,11 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, CLVContext *c = avctx->priv_data; GetByteContext gb; uint32_t frame_type; - int i, j; - int ret; + int i, j, ret; int mb_ret = 0; bytestream2_init(&gb, buf, buf_size); - if (avctx->codec_tag == MKTAG('C','L','V','1')) { + if (avctx->codec_tag == MKTAG('C', 'L', 'V', '1')) { int skip = bytestream2_get_byte(&gb); bytestream2_skip(&gb, (skip + 1) * 8); } @@ -301,7 +300,8 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, return ret; c->pic->key_frame = frame_type & 0x20 ? 1 : 0; - c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I + : AV_PICTURE_TYPE_P; bytestream2_get_be32(&gb); // frame size; c->ac_quant = bytestream2_get_byte(&gb); @@ -309,7 +309,7 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, c->chroma_dc_quant = 32; if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb), - (buf_size - bytestream2_tell(&gb)))) < 0) + buf_size - bytestream2_tell(&gb))) < 0) return ret; for (i = 0; i < 3; i++) @@ -330,6 +330,10 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, *got_frame = 1; } else { + if (!c->iframes_warning) + avpriv_report_missing_feature(avctx, "Non-I-frames in Clearvideo"); + c->iframes_warning = 1; + return AVERROR_PATCHWELCOME; } return mb_ret < 0 ? mb_ret : buf_size; @@ -337,20 +341,19 @@ static int clv_decode_frame(AVCodecContext *avctx, void *data, static av_cold int clv_decode_init(AVCodecContext *avctx) { - CLVContext * const c = avctx->priv_data; + CLVContext *const c = avctx->priv_data; int ret; - c->avctx = avctx; - avctx->pix_fmt = AV_PIX_FMT_YUV420P; - c->pic = av_frame_alloc(); + c->avctx = avctx; + c->mb_width = FFALIGN(avctx->width, 16) >> 4; + c->mb_height = FFALIGN(avctx->height, 16) >> 4; + c->iframes_warning = 0; + c->pic = av_frame_alloc(); if (!c->pic) return AVERROR(ENOMEM); - c->mb_width = FFALIGN(avctx->width, 16) >> 4; - c->mb_height = FFALIGN(avctx->height, 16) >> 4; - ff_idctdsp_init(&c->idsp, avctx); ret = init_vlc(&c->dc_vlc, 9, NUM_DC_CODES, clv_dc_bits, 1, 1, @@ -373,7 +376,7 @@ static av_cold int clv_decode_init(AVCodecContext *avctx) static av_cold int clv_decode_end(AVCodecContext *avctx) { - CLVContext * const c = avctx->priv_data; + CLVContext *const c = avctx->priv_data; av_frame_free(&c->pic); @@ -385,6 +388,7 @@ static av_cold int clv_decode_end(AVCodecContext *avctx) AVCodec ff_clearvideo_decoder = { .name = "clearvideo", + .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_CLEARVIDEO, .priv_data_size = sizeof(CLVContext), @@ -392,5 +396,5 @@ AVCodec ff_clearvideo_decoder = { .close = clv_decode_end, .decode = clv_decode_frame, .capabilities = AV_CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"), + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, }; ====================================================================== diff --cc doc/general.texi index 56f315d67b,905e2d1810..9e6ae13435 --- a/doc/general.texi +++ b/doc/general.texi @@@ -364,7 -334,6 +364,8 @@@ library @item iLBC @tab X @tab X @item Interplay MVE @tab @tab X @tab Format used in various Interplay computer games. +@item Iterated Systems ClearVideo @tab @tab X ++ @tab I-frames only @item IV8 @tab @tab X @tab A format generated by IndigoVision 8000 video server. @item IVF (On2) @tab X @tab X diff --cc libavcodec/clearvideo.c index 067942a131,a0ce686385..2c06b79fd5 --- a/libavcodec/clearvideo.c +++ b/libavcodec/clearvideo.c @@@ -179,18 -180,18 +180,18 @@@ static inline int decode_block(CLVConte } #define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP) \ - const int t0 = OP( 2841 * blk[1 * step] + 565 * blk[7 * step]); \ - const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \ - const int t2 = OP( 1609 * blk[5 * step] + 2408 * blk[3 * step]); \ - const int t3 = OP( 2408 * blk[5 * step] - 1609 * blk[3 * step]); \ - const int t4 = OP( 1108 * blk[2 * step] - 2676 * blk[6 * step]); \ - const int t5 = OP( 2676 * blk[2 * step] + 1108 * blk[6 * step]); \ + const int t0 = OP(2841 * blk[1 * step] + 565 * blk[7 * step]); \ + const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \ + const int t2 = OP(1609 * blk[5 * step] + 2408 * blk[3 * step]); \ + const int t3 = OP(2408 * blk[5 * step] - 1609 * blk[3 * step]); \ + const int t4 = OP(1108 * blk[2 * step] - 2676 * blk[6 * step]); \ + const int t5 = OP(2676 * blk[2 * step] + 1108 * blk[6 * step]); \ - const int t6 = ((blk[0 * step] + blk[4 * step]) << dshift) + bias; \ - const int t7 = ((blk[0 * step] - blk[4 * step]) << dshift) + bias; \ + const int t6 = ((blk[0 * step] + blk[4 * step]) * (1 << dshift)) + bias; \ + const int t7 = ((blk[0 * step] - blk[4 * step]) * (1 << dshift)) + bias; \ const int t8 = t0 + t2; \ const int t9 = t0 - t2; \ - const int tA = 181 * (t9 + (t1 - t3)) + 0x80 >> 8; \ - const int tB = 181 * (t9 - (t1 - t3)) + 0x80 >> 8; \ + const int tA = (int)(181U * (t9 + (t1 - t3)) + 0x80) >> 8; \ + const int tB = (int)(181U * (t9 - (t1 - t3)) + 0x80) >> 8; \ const int tC = t1 + t3; \ \ blk[0 * step] = (t6 + t5 + t8) >> shift; \ @@@ -279,30 -279,23 +279,30 @@@ static int clv_decode_frame(AVCodecCont CLVContext *c = avctx->priv_data; GetByteContext gb; uint32_t frame_type; - int i, j; - int ret; + int i, j, ret; + int mb_ret = 0; bytestream2_init(&gb, buf, buf_size); - if (avctx->codec_tag == MKTAG('C','L','V','1')) { + if (avctx->codec_tag == MKTAG('C', 'L', 'V', '1')) { int skip = bytestream2_get_byte(&gb); bytestream2_skip(&gb, (skip + 1) * 8); } frame_type = bytestream2_get_byte(&gb); - if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) - return ret; - - c->pic->key_frame = frame_type & 0x20 ? 1 : 0; - c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I - : AV_PICTURE_TYPE_P; if (frame_type & 0x2) { + if (buf_size < c->mb_width * c->mb_height) { + av_log(avctx, AV_LOG_ERROR, "Packet too small\n"); + return AVERROR_INVALIDDATA; + } + + if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) + return ret; + + c->pic->key_frame = frame_type & 0x20 ? 1 : 0; - c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; ++ c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I ++ : AV_PICTURE_TYPE_P; + bytestream2_get_be32(&gb); // frame size; c->ac_quant = bytestream2_get_byte(&gb); c->luma_dc_quant = 32; @@@ -319,20 -312,22 +319,24 @@@ for (j = 0; j < c->mb_height; j++) { for (i = 0; i < c->mb_width; i++) { - ret |= decode_mb(c, i, j); + ret = decode_mb(c, i, j); + if (ret < 0) + mb_ret = ret; } } + + if ((ret = av_frame_ref(data, c->pic)) < 0) + return ret; + + *got_frame = 1; } else { + if (!c->iframes_warning) + avpriv_report_missing_feature(avctx, "Non-I-frames in Clearvideo"); + c->iframes_warning = 1; + return AVERROR_PATCHWELCOME; } - if ((ret = av_frame_ref(data, c->pic)) < 0) - return ret; - - *got_frame = 1; - - return ret < 0 ? ret : buf_size; + return mb_ret < 0 ? mb_ret : buf_size; } static av_cold int clv_decode_init(AVCodecContext *avctx) _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog