* Duck TrueMotion2 decoder.
*/
+#include <inttypes.h>
+
#include "avcodec.h"
+#include "bitstream.h"
+#include "bswapdsp.h"
#include "bytestream.h"
-#include "get_bits.h"
-#include "dsputil.h"
#include "internal.h"
+#include "vlc.h"
#define TM2_ESCAPE 0x80000000
#define TM2_DELTAS 64
typedef struct TM2Context {
AVCodecContext *avctx;
- AVFrame pic;
+ AVFrame *pic;
- GetBitContext gb;
- DSPContext dsp;
+ BitstreamContext bc;
+ BswapDSPContext bdsp;
/* TM2 streams */
int *tokens[TM2_NUM_STREAMS];
return AVERROR_INVALIDDATA;
}
- if (!get_bits1(&ctx->gb)) { /* literal */
+ if (!bitstream_read_bit(&ctx->bc)) { /* literal */
if (length == 0) {
length = 1;
}
av_log(ctx->avctx, AV_LOG_DEBUG, "Too many literals\n");
return AVERROR_INVALIDDATA;
}
- huff->nums[huff->num] = get_bits_long(&ctx->gb, huff->val_bits);
+ huff->nums[huff->num] = bitstream_read(&ctx->bc, huff->val_bits);
huff->bits[huff->num] = prefix;
huff->lens[huff->num] = length;
huff->num++;
TM2Huff huff;
int res = 0;
- huff.val_bits = get_bits(&ctx->gb, 5);
- huff.max_bits = get_bits(&ctx->gb, 5);
- huff.min_bits = get_bits(&ctx->gb, 5);
- huff.nodes = get_bits_long(&ctx->gb, 17);
+ huff.val_bits = bitstream_read(&ctx->bc, 5);
+ huff.max_bits = bitstream_read(&ctx->bc, 5);
+ huff.min_bits = bitstream_read(&ctx->bc, 5);
+ huff.nodes = bitstream_read(&ctx->bc, 17);
huff.num = 0;
/* check for correct codes parameters */
huff.nums = av_mallocz(huff.max_num * sizeof(int));
huff.bits = av_mallocz(huff.max_num * sizeof(uint32_t));
huff.lens = av_mallocz(huff.max_num * sizeof(int));
+ if (!huff.nums || !huff.bits || !huff.lens) {
+ res = AVERROR(ENOMEM);
+ goto out;
+ }
res = tm2_read_tree(ctx, 0, 0, &huff);
code->bits = huff.max_bits;
code->length = huff.max_num;
code->recode = av_malloc(code->length * sizeof(int));
+ if (!code->recode) {
+ res = AVERROR(ENOMEM);
+ goto out;
+ }
for (i = 0; i < code->length; i++)
code->recode[i] = huff.nums[i];
}
}
+
+out:
/* free allocated memory */
av_free(huff.nums);
av_free(huff.bits);
ff_free_vlc(&code->vlc);
}
-static inline int tm2_get_token(GetBitContext *gb, TM2Codes *code)
+static inline int tm2_get_token(BitstreamContext *bc, TM2Codes *code)
{
int val;
- val = get_vlc2(gb, code->vlc.table, code->bits, 1);
+ val = bitstream_read_vlc(bc, code->vlc.table, code->bits, 1);
return code->recode[val];
}
case TM2_NEW_HEADER_MAGIC:
return 0;
default:
- av_log(ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08X\n", magic);
+ av_log(ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08"PRIX32"\n",
+ magic);
return AVERROR_INVALIDDATA;
}
}
int d, mb;
int i, v;
- d = get_bits(&ctx->gb, 9);
- mb = get_bits(&ctx->gb, 5);
+ d = bitstream_read(&ctx->bc, 9);
+ mb = bitstream_read(&ctx->bc, 5);
if ((d < 1) || (d > TM2_DELTAS) || (mb < 1) || (mb > 32)) {
av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect delta table: %i deltas x %i bits\n", d, mb);
}
for (i = 0; i < d; i++) {
- v = get_bits_long(&ctx->gb, mb);
+ v = bitstream_read(&ctx->bc, mb);
if (v & (1 << (mb - 1)))
ctx->deltas[stream_id][i] = v - (1 << mb);
else
if (len == 0)
return 4;
- if (len >= INT_MAX/4-1 || len < 0 || len > buf_size) {
+ if (len >= INT_MAX / 4 - 1 || len < 0 || skip > buf_size) {
av_log(ctx->avctx, AV_LOG_ERROR, "Error, invalid stream size.\n");
return AVERROR_INVALIDDATA;
}
pos = bytestream2_tell(&gb);
if (skip <= pos)
return AVERROR_INVALIDDATA;
- init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
+ bitstream_init8(&ctx->bc, buf + pos, skip - pos);
if ((ret = tm2_read_deltas(ctx, stream_id)) < 0)
return ret;
- bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
+ bytestream2_skip(&gb, ((bitstream_tell(&ctx->bc) + 31) >> 5) << 2);
}
}
/* skip unused fields */
pos = bytestream2_tell(&gb);
if (skip <= pos)
return AVERROR_INVALIDDATA;
- init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
+ bitstream_init8(&ctx->bc, buf + pos, skip - pos);
if ((ret = tm2_build_huff_table(ctx, &codes)) < 0)
return ret;
- bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
+ bytestream2_skip(&gb, ((bitstream_tell(&ctx->bc) + 31) >> 5) << 2);
toks >>= 1;
/* check if we have sane number of tokens */
pos = bytestream2_tell(&gb);
if (skip <= pos)
return AVERROR_INVALIDDATA;
- init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
+ bitstream_init8(&ctx->bc, buf + pos, skip - pos);
for (i = 0; i < toks; i++) {
- if (get_bits_left(&ctx->gb) <= 0) {
+ if (bitstream_bits_left(&ctx->bc) <= 0) {
av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
return AVERROR_INVALIDDATA;
}
- ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes);
+ ctx->tokens[stream_id][i] = tm2_get_token(&ctx->bc, &codes);
if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) {
av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n",
ctx->tokens[stream_id][i], stream_id, i);
TM2Context * const l = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size & ~3;
- AVFrame * const p = &l->pic;
+ AVFrame * const p = l->pic;
int offset = TM2_HEADER_SIZE;
int i, t, ret;
uint8_t *swbuf;
- swbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ swbuf = av_malloc(buf_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!swbuf) {
av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
return AVERROR(ENOMEM);
return ret;
}
- l->dsp.bswap_buf((uint32_t*)swbuf, (const uint32_t*)buf, buf_size >> 2);
+ l->bdsp.bswap_buf((uint32_t *) swbuf, (const uint32_t *) buf,
+ buf_size >> 2);
if ((ret = tm2_read_header(l, swbuf)) < 0) {
av_free(swbuf);
l->cur = !l->cur;
*got_frame = 1;
- ret = av_frame_ref(data, &l->pic);
+ ret = av_frame_ref(data, l->pic);
av_free(swbuf);
return (ret < 0) ? ret : buf_size;
}
l->avctx = avctx;
- avcodec_get_frame_defaults(&l->pic);
avctx->pix_fmt = AV_PIX_FMT_BGR24;
- ff_dsputil_init(&l->dsp, avctx);
+ l->pic = av_frame_alloc();
+ if (!l->pic)
+ return AVERROR(ENOMEM);
+
+ ff_bswapdsp_init(&l->bdsp);
l->last = av_malloc(4 * sizeof(*l->last) * (w >> 2));
l->clast = av_malloc(4 * sizeof(*l->clast) * (w >> 2));
static av_cold int decode_end(AVCodecContext *avctx)
{
TM2Context * const l = avctx->priv_data;
- AVFrame *pic = &l->pic;
int i;
av_free(l->last);
av_free(l->V2_base);
}
- av_frame_unref(pic);
+ av_frame_free(&l->pic);
return 0;
}
AVCodec ff_truemotion2_decoder = {
.name = "truemotion2",
+ .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_TRUEMOTION2,
.priv_data_size = sizeof(TM2Context),
.init = decode_init,
.close = decode_end,
.decode = decode_frame,
- .capabilities = CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"),
+ .capabilities = AV_CODEC_CAP_DR1,
};