Florian Nouwt: > I applied the few changes you suggested. I moved the shared tables to > h264_cavlc_data.c. Am I supposed to share the actual vlc tables (such > as "static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2];") > which are generated by actimagine_init_static respectively > ff_h264_decode_init_vlc as well? > Yes, please.
> Op ma 15 mrt. 2021 om 16:10 schreef Florian Nouwt <fnou...@gmail.com>: >> >> Signed-off-by: Florian Nouwt <fnou...@gmail.com> >> --- >> Changelog | 1 + >> configure | 1 + >> doc/general_contents.texi | 2 + >> libavcodec/Makefile | 3 +- >> libavcodec/actimagine.c | 1523 ++++++++++++++++++++++++++++++++++ >> libavcodec/allcodecs.c | 1 + >> libavcodec/codec_desc.c | 7 + >> libavcodec/codec_id.h | 1 + >> libavcodec/h264_cavlc.c | 135 +-- >> libavcodec/h264_cavlc_data.c | 140 ++++ >> libavcodec/h264_cavlc_data.h | 33 + >> libavcodec/version.h | 2 +- >> libavformat/riff.c | 2 + >> 13 files changed, 1723 insertions(+), 128 deletions(-) >> create mode 100644 libavcodec/actimagine.c >> create mode 100644 libavcodec/h264_cavlc_data.c >> create mode 100644 libavcodec/h264_cavlc_data.h >> >> diff --git a/Changelog b/Changelog >> index a96e350e09..8807f3dcb3 100644 >> --- a/Changelog >> +++ b/Changelog >> @@ -83,6 +83,7 @@ version <next>: >> - msad video filter >> - gophers protocol >> - RIST protocol via librist >> +- Actimagine VX video decoder >> >> >> version 4.3: >> diff --git a/configure b/configure >> index f0ac719d2d..10a07da95f 100755 >> --- a/configure >> +++ b/configure >> @@ -2662,6 +2662,7 @@ ac3_fixed_decoder_select="ac3_parser ac3dsp bswapdsp >> mdct" >> ac3_encoder_select="ac3dsp audiodsp mdct me_cmp" >> ac3_fixed_encoder_select="ac3dsp audiodsp mdct me_cmp" >> acelp_kelvin_decoder_select="audiodsp" >> +actimagine_decoder_select="bswapdsp golomb" >> adpcm_g722_decoder_select="g722dsp" >> adpcm_g722_encoder_select="g722dsp" >> aic_decoder_select="golomb idctdsp" >> diff --git a/doc/general_contents.texi b/doc/general_contents.texi >> index 33ece6e884..d4261386fc 100644 >> --- a/doc/general_contents.texi >> +++ b/doc/general_contents.texi >> @@ -807,6 +807,8 @@ following image formats are supported: >> @item 8088flex TMV @tab @tab X >> @item A64 multicolor @tab X @tab >> @tab Creates video suitable to be played on a commodore 64 (multicolor >> mode). >> +@item Actimagine VX Video @tab @tab X >> + @tab fourcc: vxs1, VXS1 >> @item Amazing Studio PAF Video @tab @tab X >> @item American Laser Games MM @tab @tab X >> @tab Used in games like Mad Dog McCree. >> diff --git a/libavcodec/Makefile b/libavcodec/Makefile >> index 81cc16471b..1b90c66925 100644 >> --- a/libavcodec/Makefile >> +++ b/libavcodec/Makefile >> @@ -182,6 +182,7 @@ OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o >> ac3enc.o ac3tab.o \ >> OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o >> ac3.o kbdwin.o >> OBJS-$(CONFIG_AC3_MF_ENCODER) += mfenc.o mf_utils.o >> OBJS-$(CONFIG_ACELP_KELVIN_DECODER) += g729dec.o lsp.o celp_math.o >> celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o >> g729postfilter.o >> +OBJS-$(CONFIG_ACTIMAGINE_DECODER) += actimagine.o h264_cavlc_data.o >> OBJS-$(CONFIG_AGM_DECODER) += agm.o >> OBJS-$(CONFIG_AIC_DECODER) += aic.o >> OBJS-$(CONFIG_ALAC_DECODER) += alac.o alac_data.o alacdsp.o >> @@ -367,7 +368,7 @@ OBJS-$(CONFIG_H264_DECODER) += h264dec.o >> h264_cabac.o h264_cavlc.o \ >> h264_direct.o h264_loopfilter.o \ >> h264_mb.o h264_picture.o \ >> h264_refs.o h264_sei.o \ >> - h264_slice.o h264data.o >> + h264_slice.o h264data.o >> h264_cavlc_data.o >> OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o >> OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o >> OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o >> diff --git a/libavcodec/actimagine.c b/libavcodec/actimagine.c >> new file mode 100644 >> index 0000000000..f495426869 >> --- /dev/null >> +++ b/libavcodec/actimagine.c >> @@ -0,0 +1,1523 @@ >> +/* >> + * Actimagine VX Video decoder >> + * Copyright (c) 2021 Florian Nouwt >> + * >> + * This file is part of FFmpeg. >> + * >> + * FFmpeg is free software; you can redistribute it and/or >> + * 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 >> + * Lesser General Public License for more details. >> + * >> + * 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 >> + */ >> + >> +#include <inttypes.h> >> + >> +#include "libavutil/avassert.h" >> +#include "libavutil/thread.h" >> + >> +#include "avcodec.h" >> +#include "bytestream.h" >> +#include "bswapdsp.h" >> +#include "get_bits.h" >> +#include "golomb.h" >> +#include "internal.h" >> +#include "h264_cavlc_data.h" >> + >> +static const uint8_t predict_dc_shift_tab[] = {1, 2, 3, 0, 4}; >> + >> +static const uint8_t zigzag4x4_tab[] = >> +{ >> + 0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, >> + 0x06, 0x03, 0x07, 0x0A, 0x0D, 0x0E, 0x0B, 0x0F >> +}; >> + >> +static const uint8_t quant4x4_tab[][8] = >> +{ >> + { 0x0A, 0x0D, 0x0A, 0x0D, 0x0D, 0x10, 0x0D, 0x10 }, >> + { 0x0B, 0x0E, 0x0B, 0x0E, 0x0E, 0x12, 0x0E, 0x12 }, >> + { 0x0D, 0x10, 0x0D, 0x10, 0x10, 0x14, 0x10, 0x14 }, >> + { 0x0E, 0x12, 0x0E, 0x12, 0x12, 0x17, 0x12, 0x17 }, >> + { 0x10, 0x14, 0x10, 0x14, 0x14, 0x19, 0x14, 0x19 }, >> + { 0x12, 0x17, 0x12, 0x17, 0x17, 0x1D, 0x17, 0x1D } >> +}; >> + >> +static const uint8_t old_mb_mode_remap_tab[] = >> +{ >> + 1, 2, 0, 4, 7, 3, 11, 15, 9, 5, 14, 6, >> + 12, 13, 8, 16, 23, 10, 22, 19, 20, 17, 21, 18 >> +}; >> + >> +static const uint8_t residu_mask_old_tab[] = >> +{ >> + 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x03, 0x05, >> + 0x0A, 0x0C, 0x0F, 0x1F, 0x07, 0x0B, 0x0D, 0x0E, >> + 0x06, 0x09, 0x13, 0x15, 0x1A, 0x1C, 0x11, 0x12, >> + 0x14, 0x18, 0x17, 0x1B, 0x1D, 0x1E, 0x16, 0x19 >> +}; >> + >> +static const uint8_t residu_mask_new_tab[] = >> +{ >> + 0x00, 0x08, 0x04, 0x02, 0x01, 0x1F, 0x0F, 0x0A, >> + 0x05, 0x0C, 0x03, 0x10, 0x0E, 0x0D, 0x0B, 0x07, >> + 0x09, 0x06, 0x1E, 0x1B, 0x1A, 0x1D, 0x17, 0x15, >> + 0x18, 0x12, 0x11, 0x1C, 0x14, 0x13, 0x16, 0x19 >> +}; >> + >> +static const int cavlc_suffix_len_update_tab[] = >> +{ >> + 2, 5, 11, 23, 47, 32768 >> +}; >> + >> +static const uint8_t coeff_token_table_index[17] = >> +{ >> + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3 >> +}; >> + >> +typedef struct MVec { >> + int x, y; >> +} MVec; >> + >> +typedef struct ActimagineContext { >> + AVFrame *cur_frame; >> + AVFrame *ref_frames[3]; >> + int ref_frame_count; >> + >> + int version; >> + int quantizer; >> + int avi; >> + >> + GetBitContext gb; >> + >> + uint8_t *bitstream; >> + int bitstream_size; >> + >> + int qtab[2][4]; >> + >> + uint8_t pred4_cache[5][5]; >> + >> + MVec *vectors; >> + int vectors_stride; >> + >> + uint8_t *total_coeff_y; >> + int total_coeff_y_stride; >> + >> + uint8_t *total_coeff_uv; >> + int total_coeff_uv_stride; >> + >> + BswapDSPContext bdsp; >> +} ActimagineContext; >> + >> +static VLC coeff_token_vlc[4]; >> +static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2]; >> +static const int coeff_token_vlc_tables_size[4]={520,332,280,256}; >> + >> +static VLC total_zeros_vlc[15+1]; >> +static VLC_TYPE total_zeros_vlc_tables[15][512][2]; >> +static const int total_zeros_vlc_tables_size = 512; >> + >> +static VLC run_vlc[6+1]; >> +static VLC_TYPE run_vlc_tables[6][8][2]; >> +static const int run_vlc_tables_size = 8; >> + >> +static VLC run7_vlc; >> +static VLC_TYPE run7_vlc_table[96][2]; >> +static const int run7_vlc_table_size = 96; >> + >> +#define COEFF_TOKEN_VLC_BITS 8 >> +#define TOTAL_ZEROS_VLC_BITS 9 >> +#define RUN_VLC_BITS 3 >> +#define RUN7_VLC_BITS 6 >> + >> +#define PIXEL_REF(s, ref, plane, x, y)\ >> + ((s)->ref_frames[(ref)]->data[(plane)]\ >> + [(y) * (s)->ref_frames[(ref)]->linesize[(plane)] + (x)]) >> + >> +#define PIXEL_CUR(s, plane, x, y)\ >> + ((s)->cur_frame->data[(plane)]\ >> + [(y) * (s)->cur_frame->linesize[(plane)] + (x)]) >> + >> +#define PREDICT2(a,b) (((a) + (b) + 1) >> 1) >> +#define PREDICT3(a,b,c) (((a) + 2 * (b) + (c) + 2) >> 2) >> + >> +#define VX_VERSION_INVALID -1 >> +#define VX_VERSION_OLD 0 >> +#define VX_VERSION_NEW 1 >> + >> +static av_cold void actimagine_init_static(void) >> +{ >> + // all these tables are equal to the ones used for h264 cavlc >> + int offset = 0; >> + for (int i = 0; i < 4; i++) { >> + coeff_token_vlc[i].table = coeff_token_vlc_tables + offset; >> + coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i]; >> + init_vlc(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4 * 17, >> + &ff_h264_cavlc_coeff_token_len [i][0], 1, 1, >> + &ff_h264_cavlc_coeff_token_bits[i][0], 1, 1, >> + INIT_VLC_USE_NEW_STATIC); >> + offset += coeff_token_vlc_tables_size[i]; >> + } >> + /* >> + * This is a one time safety check to make sure that >> + * the packed static coeff_token_vlc table sizes >> + * were initialized correctly. >> + */ >> + av_assert0(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables)); >> + >> + for (int i = 0; i < 15; i++) { >> + total_zeros_vlc[i + 1].table = total_zeros_vlc_tables[i]; >> + total_zeros_vlc[i + 1].table_allocated = >> total_zeros_vlc_tables_size; >> + init_vlc(&total_zeros_vlc[i + 1], >> + TOTAL_ZEROS_VLC_BITS, 16, >> + &ff_h264_cavlc_total_zeros_len [i][0], 1, 1, >> + &ff_h264_cavlc_total_zeros_bits[i][0], 1, 1, >> + INIT_VLC_USE_NEW_STATIC); >> + } >> + >> + for (int i = 0; i < 6; i++) { >> + run_vlc[i + 1].table = run_vlc_tables[i]; >> + run_vlc[i + 1].table_allocated = run_vlc_tables_size; >> + init_vlc(&run_vlc[i + 1], >> + RUN_VLC_BITS, 7, >> + &ff_h264_cavlc_run_len [i][0], 1, 1, >> + &ff_h264_cavlc_run_bits[i][0], 1, 1, >> + INIT_VLC_USE_NEW_STATIC); >> + } >> + >> + run7_vlc.table = run7_vlc_table, >> + run7_vlc.table_allocated = run7_vlc_table_size; >> + init_vlc(&run7_vlc, RUN7_VLC_BITS, 16, >> + &ff_h264_cavlc_run_len [6][0], 1, 1, >> + &ff_h264_cavlc_run_bits[6][0], 1, 1, >> + INIT_VLC_USE_NEW_STATIC); >> +} >> + >> +static int setup_qtables(AVCodecContext *avctx, int quantizer) >> +{ >> + int qx, qy; >> + ActimagineContext *s = avctx->priv_data; >> + >> + if (quantizer < 12 || quantizer > 161) >> + return AVERROR_INVALIDDATA; >> + >> + s->quantizer = quantizer; >> + >> + qx = quantizer % 6; >> + qy = quantizer / 6; >> + >> + for (int i = 0; i < 2; i++) >> + for (int j = 0; j < 4; j++) >> + s->qtab[i][j] = quant4x4_tab[qx][4 * i + j] << qy; >> + >> + return 0; >> +} >> + >> +static av_cold int actimagine_init(AVCodecContext *avctx) >> +{ >> + int vectors_size; >> + int total_coeff_y_size; >> + int total_coeff_uv_size; >> + static AVOnce init_static_once = AV_ONCE_INIT; >> + ActimagineContext *s = avctx->priv_data; >> + >> + if (avctx->width & 15 || avctx->height & 15) { >> + av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + >> + ff_bswapdsp_init(&s->bdsp); >> + >> + avctx->pix_fmt = AV_PIX_FMT_YUV420P; >> + avctx->color_range = AVCOL_RANGE_JPEG; >> + avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; >> + // the color space of this video format is not supported currently >> + // it is a yuv approximation that can be converted back to rgb using >> bitshifts >> + // r = y + (v << 1) >> + // g = y - (u >> 1) - v >> + // b = y + (u << 1) >> + avctx->colorspace = AVCOL_SPC_NB; >> + >> + // predict4 cache >> + for (int i = 0; i < 5; i++) >> + for (int j = 0; j < 5; j++) >> + s->pred4_cache[i][j] = 9; >> + >> + // motion vector cache >> + s->vectors_stride = (avctx->width >> 4) + 2; >> + vectors_size = ((avctx->height >> 4) + 1) * s->vectors_stride; >> + s->vectors = av_calloc(vectors_size, sizeof(MVec)); >> + if (!s->vectors) >> + return AVERROR(ENOMEM); >> + >> + // total dct coefficient cache for luma >> + s->total_coeff_y_stride = (avctx->width >> 2) + 1; >> + total_coeff_y_size = ((avctx->height >> 2) + 1) * >> s->total_coeff_y_stride; >> + s->total_coeff_y = av_mallocz(total_coeff_y_size); >> + if (!s->total_coeff_y) >> + return AVERROR(ENOMEM); >> + >> + // total dct coefficient cache for chroma >> + s->total_coeff_uv_stride = (avctx->width >> 3) + 1; >> + total_coeff_uv_size = ((avctx->height >> 3) + 1) * >> s->total_coeff_uv_stride; >> + s->total_coeff_uv = av_mallocz(total_coeff_uv_size); >> + if (!s->total_coeff_uv) >> + return AVERROR(ENOMEM); >> + >> + s->ref_frame_count = 0; >> + for (int i = 0; i < 3; i++) { >> + s->ref_frames[i] = av_frame_alloc(); >> + if (!s->ref_frames[i]) >> + return AVERROR(ENOMEM); >> + } >> + s->cur_frame = av_frame_alloc(); >> + if (!s->cur_frame) >> + return AVERROR(ENOMEM); >> + >> + s->version = VX_VERSION_INVALID; >> + s->quantizer = -1; >> + s->avi = 0; >> + >> + // when the source is an avi file, the quantizer is stored in the >> extradata >> + if (avctx->extradata_size == 4) >> + if (!setup_qtables(avctx, AV_RL32(avctx->extradata))) >> + s->avi = 1; >> + >> + ff_thread_once(&init_static_once, actimagine_init_static); >> + >> + return 0; >> +} >> + >> +static void clear_total_coeff(AVCodecContext *avctx, int x, int y, int w, >> int h) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + >> + // luma >> + uint8_t *total_coeff = &s->total_coeff_y[ >> + ((y >> 2) + 1) * s->total_coeff_y_stride + (x >> 2) + 1]; >> + >> + for (int y2 = 0; y2 < (h >> 2); y2++) >> + for (int x2 = 0; x2 < (w >> 2); x2++) >> + total_coeff[y2 * s->total_coeff_y_stride + x2] = 0; >> + >> + // chroma >> + total_coeff = &s->total_coeff_uv[ >> + ((y >> 3) + 1) * s->total_coeff_uv_stride + (x >> 3) + 1]; >> + >> + for (int y2 = 0; y2 < (h >> 3); y2++) >> + for (int x2 = 0; x2 < (w >> 3); x2++) >> + total_coeff[y2 * s->total_coeff_uv_stride + x2] = 0; >> +} >> + >> +static void predict_plane_intern(AVCodecContext *avctx, int x, int y, >> + int w, int h, int plane) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + if (w == 1 && h == 1) >> + return; >> + if (w == 1 && h != 1) { >> + uint8_t top = PIXEL_CUR(s, plane, x, y - 1); >> + uint8_t bottom = PIXEL_CUR(s, plane, x, y + h - 1); >> + PIXEL_CUR(s, plane, x, y + (h >> 1) - 1) = (top + bottom) >> 1; >> + predict_plane_intern(avctx, x, y, 1, h >> 1, plane); >> + predict_plane_intern(avctx, x, y + (h >> 1), 1, h >> 1, plane); >> + } else if (w != 1 && h == 1) { >> + uint8_t left = PIXEL_CUR(s, plane, x - 1, y); >> + uint8_t right = PIXEL_CUR(s, plane, x + w - 1, y); >> + PIXEL_CUR(s, plane, x + (w >> 1) - 1, y) = (left + right) >> 1; >> + predict_plane_intern(avctx, x, y, w >> 1, 1, plane); >> + predict_plane_intern(avctx, x + (w >> 1), y, w >> 1, 1, plane); >> + } else { >> + uint8_t bottom_left = PIXEL_CUR(s, plane, x - 1, y + h - 1); >> + uint8_t top_right = PIXEL_CUR(s, plane, x + w - 1, y - 1); >> + uint8_t bottom_right = PIXEL_CUR(s, plane, x + w - 1, y + h - 1); >> + uint8_t bottom_center = (bottom_left + bottom_right) >> 1; >> + uint8_t center_right = (top_right + bottom_right) >> 1; >> + PIXEL_CUR(s, plane, x + (w >> 1) - 1, y + h - 1) = bottom_center; >> + PIXEL_CUR(s, plane, x + w - 1, y + (h >> 1) - 1) = center_right; >> + if ((w == 4 || w == 16) ^ (h == 4 || h == 16)) { >> + uint8_t center_left = PIXEL_CUR(s, plane, x - 1, y + (h >> 1) - >> 1); >> + PIXEL_CUR(s, plane, x + (w >> 1) - 1, y + (h >> 1) - 1) >> + = (center_left + center_right) >> 1; >> + } else { >> + uint8_t top_center = PIXEL_CUR(s, plane, x + (w >> 1) - 1, y - >> 1); >> + PIXEL_CUR(s, plane, x + (w >> 1) - 1, y + (h >> 1) - 1) >> + = (top_center + bottom_center) >> 1; >> + } >> + predict_plane_intern(avctx, x, y, w >> 1, h >> 1, plane); >> + predict_plane_intern(avctx, x + (w >> 1), y, w >> 1, h >> 1, plane); >> + predict_plane_intern(avctx, x, y + (h >> 1), w >> 1, h >> 1, plane); >> + predict_plane_intern(avctx, x + (w >> 1), y + (h >> 1), w >> 1, h >> >> 1, >> + plane); >> + } >> +} >> + >> +static void predict_plane(AVCodecContext *avctx, int x, int y, int w, int h, >> + int plane, int param) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + uint8_t bottom_left = PIXEL_CUR(s, plane, x - 1, y + h - 1); >> + uint8_t top_right = PIXEL_CUR(s, plane, x + w - 1, y - 1); >> + PIXEL_CUR(s, plane, x + w - 1, y + h - 1) >> + = ((bottom_left + top_right + 1) >> 1) + param; >> + predict_plane_intern(avctx, x, y, w, h, plane); >> +} >> + >> +static int predict_mb_plane(AVCodecContext *avctx, int x, int y, int w, int >> h) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + // y >> + int param = get_se_golomb(gb); >> + if (param < -(1 << 16) || param >= (1 << 16)) { >> + av_log(avctx, AV_LOG_ERROR, "invalid plane param\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + predict_plane(avctx, x, y, w, h, 0, param << 1); >> + >> + // u >> + param = get_se_golomb(gb); >> + if (param < -(1 << 16) || param >= (1 << 16)) { >> + av_log(avctx, AV_LOG_ERROR, "invalid plane param\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + predict_plane(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1, param << 1); >> + >> + // v >> + param = get_se_golomb(gb); >> + if (param < -(1 << 16) || param >= (1 << 16)) { >> + av_log(avctx, AV_LOG_ERROR, "invalid plane param\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + predict_plane(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2, param << 1); >> + >> + return 0; >> +} >> + >> +static void predict_horizontal(AVCodecContext *avctx, int x, int y, >> + int w, int h, int plane) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + for (int y2 = 0; y2 < h; y2++) { >> + uint8_t pixel = PIXEL_CUR(s, plane, x - 1, y + y2); >> + for (int x2 = 0; x2 < w; x2++) >> + PIXEL_CUR(s, plane, x + x2, y + y2) = pixel; >> + } >> +} >> + >> +static void predict_vertical(AVCodecContext *avctx, int x, int y, >> + int w, int h, int plane) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + for (int y2 = 0; y2 < h; y2++) >> + for (int x2 = 0; x2 < w; x2++) >> + PIXEL_CUR(s, plane, x + x2, y + y2) >> + = PIXEL_CUR(s, plane, x + x2, y - 1); >> +} >> + >> +static void predict_dc(AVCodecContext *avctx, int x, int y, int w, int h, >> + int plane) >> +{ >> + uint8_t dc; >> + ActimagineContext *s = avctx->priv_data; >> + if (x != 0 && y != 0) { >> + int sum_h, sum_v; >> + sum_h = w >> 1; >> + for (int x2 = 0; x2 < w; x2++) >> + sum_h += PIXEL_CUR(s, plane, x + x2, y - 1); >> + sum_h >>= predict_dc_shift_tab[w >> 2]; >> + >> + sum_v = h >> 1; >> + for (int y2 = 0; y2 < h; y2++) >> + sum_v += PIXEL_CUR(s, plane, x - 1, y + y2); >> + sum_v >>= predict_dc_shift_tab[h >> 2]; >> + >> + dc = (sum_h + sum_v + 1) >> 1; >> + } else if (x == 0 && y != 0) { >> + int sum = w >> 1; >> + for (int x2 = 0; x2 < w; x2++) >> + sum += PIXEL_CUR(s, plane, x + x2, y - 1); >> + dc = sum >> predict_dc_shift_tab[w >> 2]; >> + } else if (x != 0 && y == 0) { >> + int sum = h >> 1; >> + for (int y2 = 0; y2 < h; y2++) >> + sum += PIXEL_CUR(s, plane, x - 1, y + y2); >> + dc = sum >> predict_dc_shift_tab[h >> 2]; >> + } else >> + dc = 128; >> + >> + for (int y2 = 0; y2 < h; y2++) >> + for (int x2 = 0; x2 < w; x2++) >> + PIXEL_CUR(s, plane, x + x2, y + y2) = dc; >> +} >> + >> +static int predict_notile_uv(AVCodecContext *avctx, int x, int y, int w, >> int h) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + int mode_uv = get_ue_golomb_31(gb); >> + switch (mode_uv) { >> + case 0:// dc >> + predict_dc(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1); >> + predict_dc(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2); >> + break; >> + case 1:// horizontal >> + predict_horizontal(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1); >> + predict_horizontal(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2); >> + break; >> + case 2:// vertical >> + predict_vertical(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1); >> + predict_vertical(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2); >> + break; >> + case 3:// plane >> + predict_plane(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1, 0); >> + predict_plane(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2, 0); >> + break; >> + default: >> + av_log(avctx, AV_LOG_ERROR, "invalid predict notile uv mode\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + return 0; >> +} >> + >> +static int predict_notile(AVCodecContext *avctx, int x, int y, int w, int h) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + int mode_y = get_ue_golomb_31(gb); >> + switch (mode_y) { >> + case 0:// vertical >> + predict_vertical(avctx, x, y, w, h, 0); >> + break; >> + case 1:// horizontal >> + predict_horizontal(avctx, x, y, w, h, 0); >> + break; >> + case 2:// dc >> + predict_dc(avctx, x, y, w, h, 0); >> + break; >> + case 3:// plane >> + predict_plane(avctx, x, y, w, h, 0, 0); >> + break; >> + default: >> + av_log(avctx, AV_LOG_ERROR, "invalid predict notile y mode\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + return predict_notile_uv(avctx, x, y, w, h); >> +} >> + >> +// slightly different from the common dc prediction method >> +static void predict4_dc(AVCodecContext *avctx, int x, int y) >> +{ >> + uint8_t dc; >> + ActimagineContext *s = avctx->priv_data; >> + if (x == 0 && y == 0) >> + dc = 128; >> + else { >> + int sum = 0; >> + int shift = 1; >> + >> + if (x != 0) { >> + shift++; >> + for (int y2 = 0; y2 < 4; y2++) >> + sum += PIXEL_CUR(s, 0, x - 1, y + y2); >> + sum += 2; >> + } >> + >> + if (y != 0) { >> + shift++; >> + for (int x2 = 0; x2 < 4; x2++) >> + sum += PIXEL_CUR(s, 0, x + x2, y - 1); >> + sum += 2; >> + } >> + >> + dc = sum >> shift; >> + } >> + >> + for (int y2 = 0; y2 < 4; y2++) >> + for (int x2 = 0; x2 < 4; x2++) >> + PIXEL_CUR(s, 0, x + x2, y + y2) = dc; >> +} >> + >> +static void predict4_diagonal_down_left(AVCodecContext *avctx, int x, int y) >> +{ >> + uint8_t val; >> + ActimagineContext *s = avctx->priv_data; >> + >> + uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1); >> + uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1); >> + uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1); >> + uint8_t d = PIXEL_CUR(s, 0, x + 3, y - 1); >> + uint8_t e = PIXEL_CUR(s, 0, x + 4, y - 1); >> + uint8_t f = PIXEL_CUR(s, 0, x + 5, y - 1); >> + uint8_t g = PIXEL_CUR(s, 0, x + 6, y - 1); >> + uint8_t h = PIXEL_CUR(s, 0, x + 7, y - 1); >> + >> + PIXEL_CUR(s, 0, x, y) = PREDICT3(a, b, c); >> + >> + val = PREDICT3(b, c, d); >> + PIXEL_CUR(s, 0, x + 1, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 0, y + 1) = val; >> + >> + val = PREDICT3(c, d, e); >> + PIXEL_CUR(s, 0, x + 2, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 0, y + 2) = val; >> + >> + val = PREDICT3(d, e, f); >> + PIXEL_CUR(s, 0, x + 3, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 2) = val; >> + PIXEL_CUR(s, 0, x + 0, y + 3) = val; >> + >> + val = PREDICT3(e, f, g); >> + PIXEL_CUR(s, 0, x + 3, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 2) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 3) = val; >> + >> + val = PREDICT3(f, g, h); >> + PIXEL_CUR(s, 0, x + 3, y + 2) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 3) = val; >> + >> + PIXEL_CUR(s, 0, x + 3, y + 3) = PREDICT3(g, h, h); >> +} >> + >> +static void predict4_diagonal_down_right(AVCodecContext *avctx, int x, int >> y) >> +{ >> + uint8_t val; >> + ActimagineContext *s = avctx->priv_data; >> + >> + uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1); >> + uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1); >> + uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1); >> + uint8_t d = PIXEL_CUR(s, 0, x + 3, y - 1); >> + >> + uint8_t i = PIXEL_CUR(s, 0, x - 1, y + 0); >> + uint8_t j = PIXEL_CUR(s, 0, x - 1, y + 1); >> + uint8_t k = PIXEL_CUR(s, 0, x - 1, y + 2); >> + uint8_t l = PIXEL_CUR(s, 0, x - 1, y + 3); >> + >> + uint8_t m = PIXEL_CUR(s, 0, x - 1, y - 1); >> + >> + PIXEL_CUR(s, 0, x + 0, y + 3) = PREDICT3(j, k, l); >> + >> + val = PREDICT3(i, j, k); >> + PIXEL_CUR(s, 0, x + 0, y + 2) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 3) = val; >> + >> + val = PREDICT3(m, i, j); >> + PIXEL_CUR(s, 0, x + 0, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 2) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 3) = val; >> + >> + val = PREDICT3(i, m, a); >> + PIXEL_CUR(s, 0, x + 0, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 2) = val; >> + PIXEL_CUR(s, 0, x + 3, y + 3) = val; >> + >> + val = PREDICT3(m, a, b); >> + PIXEL_CUR(s, 0, x + 1, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 3, y + 2) = val; >> + >> + val = PREDICT3(a, b, c); >> + PIXEL_CUR(s, 0, x + 2, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 3, y + 1) = val; >> + >> + PIXEL_CUR(s, 0, x + 3, y + 0) = PREDICT3(b, c, d); >> +} >> + >> +static void predict4_vertical_right(AVCodecContext *avctx, int x, int y) >> +{ >> + uint8_t val; >> + ActimagineContext *s = avctx->priv_data; >> + >> + uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1); >> + uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1); >> + uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1); >> + uint8_t d = PIXEL_CUR(s, 0, x + 3, y - 1); >> + >> + uint8_t i = PIXEL_CUR(s, 0, x - 1, y + 0); >> + uint8_t j = PIXEL_CUR(s, 0, x - 1, y + 1); >> + uint8_t k = PIXEL_CUR(s, 0, x - 1, y + 2); >> + >> + uint8_t m = PIXEL_CUR(s, 0, x - 1, y - 1); >> + >> + PIXEL_CUR(s, 0, x + 0, y + 3) = PREDICT3(i, j, k); >> + PIXEL_CUR(s, 0, x + 0, y + 2) = PREDICT3(m, i, j); >> + >> + val = PREDICT3(a, m, i); >> + PIXEL_CUR(s, 0, x + 0, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 3) = val; >> + >> + val = PREDICT2(a, m); >> + PIXEL_CUR(s, 0, x + 0, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 2) = val; >> + >> + val = PREDICT3(b, a, m); >> + PIXEL_CUR(s, 0, x + 1, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 3) = val; >> + >> + val = PREDICT2(b, a); >> + PIXEL_CUR(s, 0, x + 1, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 2) = val; >> + >> + val = PREDICT3(c, b, a); >> + PIXEL_CUR(s, 0, x + 2, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 3, y + 3) = val; >> + >> + val = PREDICT2(c, b); >> + PIXEL_CUR(s, 0, x + 2, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 3, y + 2) = val; >> + >> + PIXEL_CUR(s, 0, x + 3, y + 1) = PREDICT3(d, c, b); >> + PIXEL_CUR(s, 0, x + 3, y + 0) = PREDICT2(d, c); >> +} >> + >> +static void predict4_horizontal_down(AVCodecContext *avctx, int x, int y) >> +{ >> + uint8_t val; >> + ActimagineContext *s = avctx->priv_data; >> + >> + uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1); >> + uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1); >> + uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1); >> + >> + uint8_t i = PIXEL_CUR(s, 0, x - 1, y + 0); >> + uint8_t j = PIXEL_CUR(s, 0, x - 1, y + 1); >> + uint8_t k = PIXEL_CUR(s, 0, x - 1, y + 2); >> + uint8_t l = PIXEL_CUR(s, 0, x - 1, y + 3); >> + >> + uint8_t m = PIXEL_CUR(s, 0, x - 1, y - 1); >> + >> + PIXEL_CUR(s, 0, x + 0, y + 3) = PREDICT2(k, l); >> + PIXEL_CUR(s, 0, x + 1, y + 3) = PREDICT3(j, k, l); >> + >> + val = PREDICT2(j, k); >> + PIXEL_CUR(s, 0, x + 0, y + 2) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 3) = val; >> + >> + val = PREDICT3(i, j, k); >> + PIXEL_CUR(s, 0, x + 1, y + 2) = val; >> + PIXEL_CUR(s, 0, x + 3, y + 3) = val; >> + >> + val = PREDICT2(i, j); >> + PIXEL_CUR(s, 0, x + 0, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 2) = val; >> + >> + val = PREDICT3(m, i, j); >> + PIXEL_CUR(s, 0, x + 1, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 3, y + 2) = val; >> + >> + val = PREDICT2(i, m); >> + PIXEL_CUR(s, 0, x + 0, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 1) = val; >> + >> + val = PREDICT3(i, m, a); >> + PIXEL_CUR(s, 0, x + 1, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 3, y + 1) = val; >> + >> + PIXEL_CUR(s, 0, x + 2, y + 0) = PREDICT3(m, a, b); >> + PIXEL_CUR(s, 0, x + 3, y + 0) = PREDICT3(a, b, c); >> +} >> + >> +static void predict4_vertical_left(AVCodecContext *avctx, int x, int y) >> +{ >> + uint8_t val; >> + ActimagineContext *s = avctx->priv_data; >> + >> + uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1); >> + uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1); >> + uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1); >> + uint8_t d = PIXEL_CUR(s, 0, x + 3, y - 1); >> + uint8_t e = PIXEL_CUR(s, 0, x + 4, y - 1); >> + uint8_t f = PIXEL_CUR(s, 0, x + 5, y - 1); >> + uint8_t g = PIXEL_CUR(s, 0, x + 6, y - 1); >> + >> + PIXEL_CUR(s, 0, x + 3, y + 3) = PREDICT3(e, f, g); >> + PIXEL_CUR(s, 0, x + 3, y + 2) = PREDICT2(e, f); >> + >> + val = PREDICT3(d, e, f); >> + PIXEL_CUR(s, 0, x + 3, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 3) = val; >> + >> + val = PREDICT2(d, e); >> + PIXEL_CUR(s, 0, x + 3, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 2, y + 2) = val; >> + >> + val = PREDICT3(c, d, e); >> + PIXEL_CUR(s, 0, x + 2, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 3) = val; >> + >> + val = PREDICT2(c, d); >> + PIXEL_CUR(s, 0, x + 2, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 1, y + 2) = val; >> + >> + val = PREDICT3(b, c, d); >> + PIXEL_CUR(s, 0, x + 1, y + 1) = val; >> + PIXEL_CUR(s, 0, x + 0, y + 3) = val; >> + >> + val = PREDICT2(b, c); >> + PIXEL_CUR(s, 0, x + 1, y + 0) = val; >> + PIXEL_CUR(s, 0, x + 0, y + 2) = val; >> + >> + PIXEL_CUR(s, 0, x + 0, y + 1) = PREDICT3(a, b, c); >> + PIXEL_CUR(s, 0, x + 0, y + 0) = PREDICT2(a, b); >> +} >> + >> +static void predict4_horizontal_up(AVCodecContext *avctx, int x, int y) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + >> + uint8_t i = PIXEL_CUR(s, 0, x - 1, y + 0); >> + uint8_t j = PIXEL_CUR(s, 0, x - 1, y + 1); >> + uint8_t k = PIXEL_CUR(s, 0, x - 1, y + 2); >> + uint8_t l = PIXEL_CUR(s, 0, x - 1, y + 3); >> + >> + PIXEL_CUR(s, 0, x + 0, y + 0) = PREDICT2(i, j); >> + PIXEL_CUR(s, 0, x + 1, y + 0) = PREDICT3(i, j, k); >> + PIXEL_CUR(s, 0, x + 2, y + 0) = PREDICT2(j, k); >> + PIXEL_CUR(s, 0, x + 3, y + 0) = PREDICT3(j, k, l); >> + >> + PIXEL_CUR(s, 0, x + 0, y + 1) = PREDICT2(j, k); >> + PIXEL_CUR(s, 0, x + 1, y + 1) = PREDICT3(j, k, l); >> + PIXEL_CUR(s, 0, x + 2, y + 1) = PREDICT2(k, l); >> + PIXEL_CUR(s, 0, x + 3, y + 1) = PREDICT3(k, l, l); >> + >> + PIXEL_CUR(s, 0, x + 0, y + 2) = PREDICT2(k, l); >> + PIXEL_CUR(s, 0, x + 1, y + 2) = PREDICT3(k, l, l); >> + PIXEL_CUR(s, 0, x + 2, y + 2) = l; >> + PIXEL_CUR(s, 0, x + 3, y + 2) = l; >> + >> + PIXEL_CUR(s, 0, x + 0, y + 3) = l; >> + PIXEL_CUR(s, 0, x + 1, y + 3) = l; >> + PIXEL_CUR(s, 0, x + 2, y + 3) = l; >> + PIXEL_CUR(s, 0, x + 3, y + 3) = l; >> +} >> + >> +static int predict4(AVCodecContext *avctx, int x, int y, int w, int h) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + for (int y2 = 0; y2 < h >> 2; y2++) { >> + for (int x2 = 0; x2 < w >> 2; x2++) { >> + uint8_t mode = FFMIN(s->pred4_cache[1 + y2 - 1][1 + x2], >> + s->pred4_cache[1 + y2][1 + x2 - 1]); >> + if (mode == 9)// if invalid predict dc >> + mode = 2; >> + >> + if (!get_bits1(gb)) { >> + uint8_t val = get_bits(gb, 3); >> + if (val >= mode) >> + val++; >> + mode = val; >> + } >> + >> + s->pred4_cache[1 + y2][1 + x2] = mode; >> + >> + switch (mode) { >> + case 0:// vertical >> + predict_vertical(avctx, x + x2 * 4, y + y2 * 4, 4, 4, 0); >> + break; >> + case 1:// horizontal >> + predict_horizontal(avctx, x + x2 * 4, y + y2 * 4, 4, 4, 0); >> + break; >> + case 2:// dc >> + predict4_dc(avctx, x + x2 * 4, y + y2 * 4); >> + break; >> + case 3:// diagonal-down-left >> + predict4_diagonal_down_left(avctx, x + x2 * 4, y + y2 * 4); >> + break; >> + case 4:// diagonal-down-right >> + predict4_diagonal_down_right(avctx, x + x2 * 4, y + y2 * 4); >> + break; >> + case 5:// vertical-right >> + predict4_vertical_right(avctx, x + x2 * 4, y + y2 * 4); >> + break; >> + case 6:// horizontal-down >> + predict4_horizontal_down(avctx, x + x2 * 4, y + y2 * 4); >> + break; >> + case 7:// vertical-left >> + predict4_vertical_left(avctx, x + x2 * 4, y + y2 * 4); >> + break; >> + case 8:// horizontal-up >> + predict4_horizontal_up(avctx, x + x2 * 4, y + y2 * 4); >> + break; >> + default: >> + av_log(avctx, AV_LOG_ERROR, "invalid predict4 mode\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + } >> + } >> + return predict_notile_uv(avctx, x, y, w, h); >> +} >> + >> +static void decode_dct(AVCodecContext *avctx, int x, int y, int plane, >> + const int* level) >> +{ >> + int a, b, c, d, e, f; >> + int dct[16]; >> + int tmp[16]; >> + ActimagineContext *s = avctx->priv_data; >> + >> + // dezigzag >> + for (int i = 0; i < 16; i++) >> + dct[zigzag4x4_tab[i]] = level[i]; >> + >> + // dequantize >> + for (int i = 0; i < 2; i++) { >> + for (int j = 0; j < 4; j++) { >> + dct[4 * j + i] *= s->qtab[i][j]; >> + dct[4 * j + i + 2] *= s->qtab[i][j]; >> + } >> + } >> + >> + dct[0] += 32;// rounding >> + >> + for (int i = 0; i < 4; i++) { >> + a = dct[i * 4 + 0]; >> + b = dct[i * 4 + 1]; >> + c = dct[i * 4 + 2]; >> + d = dct[i * 4 + 3]; >> + a += c; >> + c = a - c * 2; >> + e = (b >> 1) - d; >> + f = b + (d >> 1); >> + tmp[ 0 + i] = a + f; >> + tmp[ 4 + i] = c + e; >> + tmp[ 8 + i] = c - e; >> + tmp[12 + i] = a - f; >> + } >> + >> + for (int i = 0; i < 4; i++) { >> + a = tmp[i * 4 + 0]; >> + b = tmp[i * 4 + 1]; >> + c = tmp[i * 4 + 2]; >> + d = tmp[i * 4 + 3]; >> + a += c; >> + c = a - c * 2; >> + e = (b >> 1) - d; >> + f = b + (d >> 1); >> + PIXEL_CUR(s, plane, x + 0, y + i) >> + = av_clip_uint8(PIXEL_CUR(s, plane, x + 0, y + i) + ((a + f) >> >> 6)); >> + PIXEL_CUR(s, plane, x + 1, y + i) >> + = av_clip_uint8(PIXEL_CUR(s, plane, x + 1, y + i) + ((c + e) >> >> 6)); >> + PIXEL_CUR(s, plane, x + 2, y + i) >> + = av_clip_uint8(PIXEL_CUR(s, plane, x + 2, y + i) + ((c - e) >> >> 6)); >> + PIXEL_CUR(s, plane, x + 3, y + i) >> + = av_clip_uint8(PIXEL_CUR(s, plane, x + 3, y + i) + ((a - f) >> >> 6)); >> + } >> +} >> + >> +static void decode_residu_cavlc(AVCodecContext *avctx, int x, int y, int >> plane, >> + int nc, uint8_t *out_total_coeff) >> +{ >> + int level[16]; >> + int coeff_token, total_coeff, trailing_ones, i, zeros_left, >> suffix_length; >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + >> + coeff_token = get_vlc2(gb, >> coeff_token_vlc[coeff_token_table_index[nc]].table, >> + COEFF_TOKEN_VLC_BITS, 2); >> + trailing_ones = coeff_token & 3; >> + total_coeff = coeff_token >> 2; >> + >> + *out_total_coeff = total_coeff; >> + if (total_coeff == 0) >> + return; >> + >> + av_assert2(total_coeff <= 16); >> + >> + i = 15; >> + if (total_coeff != 16) { >> + int trailing_zeros; >> + zeros_left = get_vlc2(gb, total_zeros_vlc[total_coeff].table, >> + TOTAL_ZEROS_VLC_BITS, 1); >> + trailing_zeros = 16 - (total_coeff + zeros_left); >> + while(trailing_zeros-- > 0) >> + level[i--] = 0; >> + } else >> + zeros_left = 0; >> + >> + suffix_length = 0; >> + while (1) { >> + int level_suffix, level_code, run_before; >> + if (trailing_ones > 0) { >> + trailing_ones--; >> + level[i--] = get_bits1(gb) ? -1 : 1; >> + } else { >> + int level_prefix = 0; >> + while (!get_bits1(gb)) >> + level_prefix++; >> + >> + if (level_prefix == 15) >> + level_suffix = get_bits(gb, 11); >> + else >> + level_suffix = suffix_length == 0 ? 0 : get_bits(gb, >> suffix_length); >> + >> + level_code = level_suffix + (level_prefix << suffix_length); >> + >> + if (level_code > cavlc_suffix_len_update_tab[suffix_length]) >> + suffix_length++; >> + >> + level_code++; >> + if (get_bits1(gb)) >> + level_code = -level_code; >> + level[i--] = level_code; >> + } >> + >> + if (--total_coeff == 0) >> + break; >> + >> + if (zeros_left == 0) >> + continue; >> + >> + if(zeros_left < 7) >> + run_before = get_vlc2(gb, run_vlc[zeros_left].table, >> RUN_VLC_BITS, 1); >> + else >> + run_before = get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); >> + zeros_left -= run_before; >> + while(run_before-- > 0) >> + level[i--] = 0; >> + } >> + >> + while(zeros_left-- > 0) >> + level[i--] = 0; >> + >> + decode_dct(avctx, x, y, plane, level); >> +} >> + >> +static int decode_residu_blocks(AVCodecContext *avctx, int x, int y, >> + int w, int h) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + uint8_t *total_coeff_y = &s->total_coeff_y[ >> + ((y >> 2) + 1) * s->total_coeff_y_stride + (x >> 2) + 1]; >> + uint8_t *total_coeff_uv = &s->total_coeff_uv[ >> + ((y >> 3) + 1) * s->total_coeff_uv_stride + (x >> 3) + 1]; >> + for (int y2 = 0; y2 < h >> 3; y2++) { >> + for (int x2 = 0; x2 < w >> 3; x2++) { >> + uint8_t residu_mask; >> + int code = get_ue_golomb_31(gb); >> + if (code > 0x1F) { >> + av_log(avctx, AV_LOG_ERROR, "invalid residu mask code\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + if (s->version == VX_VERSION_OLD) >> + residu_mask = residu_mask_old_tab[code]; >> + else >> + residu_mask = residu_mask_new_tab[code]; >> + >> + if (residu_mask & 1) { >> + int nc = (total_coeff_y[-1] + >> + total_coeff_y[-s->total_coeff_y_stride] + 1) >> 1; >> + decode_residu_cavlc(avctx, x + x2 * 8, y + y2 * 8, 0, nc, >> + &total_coeff_y[0]); >> + } else >> + total_coeff_y[0] = 0; >> + >> + if (residu_mask & 2) { >> + int nc = (total_coeff_y[0] + >> + total_coeff_y[-s->total_coeff_y_stride + 1] + 1) >> >> 1; >> + decode_residu_cavlc(avctx, x + x2 * 8 + 4, y + y2 * 8, 0, >> nc, >> + &total_coeff_y[1]); >> + } else >> + total_coeff_y[1] = 0; >> + >> + if (residu_mask & 4) { >> + int nc = (total_coeff_y[s->total_coeff_y_stride - 1] + >> + total_coeff_y[0] + 1) >> 1; >> + decode_residu_cavlc(avctx, x + x2 * 8, y + y2 * 8 + 4, 0, >> nc, >> + >> &total_coeff_y[s->total_coeff_y_stride]); >> + } else >> + total_coeff_y[s->total_coeff_y_stride] = 0; >> + >> + if (residu_mask & 8) { >> + int nc = (total_coeff_y[s->total_coeff_y_stride] + >> + total_coeff_y[1] + 1) >> 1; >> + decode_residu_cavlc( >> + avctx, x + x2 * 8 + 4, y + y2 * 8 + 4, 0, nc, >> + &total_coeff_y[s->total_coeff_y_stride + 1]); >> + } else >> + total_coeff_y[s->total_coeff_y_stride + 1] = 0; >> + >> + if (residu_mask & 16) { >> + uint8_t total_coeff_u, total_coeff_v; >> + int nc = (total_coeff_uv[-1] + >> + total_coeff_uv[-s->total_coeff_uv_stride] + 1) >> >> 1; >> + decode_residu_cavlc(avctx, (x + x2 * 8) >> 1, (y + y2 * 8) >> >> 1, >> + 1, nc, &total_coeff_u); >> + decode_residu_cavlc(avctx, (x + x2 * 8) >> 1, (y + y2 * 8) >> >> 1, >> + 2, nc, &total_coeff_v); >> + total_coeff_uv[0] = (total_coeff_u + total_coeff_v + 1) >> >> 1; >> + } else >> + total_coeff_uv[0] = 0; >> + >> + total_coeff_y += 2; >> + total_coeff_uv++; >> + } >> + total_coeff_y += (s->total_coeff_y_stride << 1) - (w >> 2); >> + total_coeff_uv += s->total_coeff_uv_stride - (w >> 3); >> + } >> + return 0; >> +} >> + >> +static int predict_inter(AVCodecContext *avctx, int x, int y, int w, int h, >> + const MVec *predVec, int has_delta, int ref_frame) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + MVec vec = *predVec; >> + >> + if (ref_frame >= s->ref_frame_count) { >> + av_log(avctx, AV_LOG_ERROR, "reference to unavailable frame\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + >> + s->cur_frame->pict_type = AV_PICTURE_TYPE_P; >> + s->cur_frame->key_frame = 0; >> + >> + if (has_delta) { >> + vec.x += (unsigned)get_se_golomb(gb); >> + vec.y += (unsigned)get_se_golomb(gb); >> + } >> + >> + if (vec.x >= INT_MAX || vec.y >= INT_MAX) >> + return AVERROR_INVALIDDATA; >> + >> + s->vectors[(1 + (y >> 4)) * s->vectors_stride + 1 + (x >> 4)] = vec; >> + >> + if (x + vec.x < 0 || x + vec.x + w > avctx->width || >> + y + vec.y < 0 || y + vec.y + h > avctx->height) { >> + av_log(avctx, AV_LOG_ERROR, "motion vector out of bounds\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + >> + // luma >> + for (int y2 = 0; y2 < h; y2++) >> + for (int x2 = 0; x2 < w; x2++) >> + PIXEL_CUR(s, 0, x + x2, y + y2) >> + = PIXEL_REF(s, ref_frame, 0, x + x2 + vec.x, y + y2 + >> vec.y); >> + >> + // chroma >> + for (int y2 = 0; y2 < (h >> 1); y2++) { >> + for (int x2 = 0; x2 < (w >> 1); x2++) { >> + // u >> + PIXEL_CUR(s, 1, (x >> 1) + x2, (y >> 1) + y2) >> + = PIXEL_REF(s, ref_frame, 1, (x >> 1) + x2 + (vec.x >> 1), >> + (y >> 1) + y2 + (vec.y >> 1)); >> + // v >> + PIXEL_CUR(s, 2, (x >> 1) + x2, (y >> 1) + y2) >> + = PIXEL_REF(s, ref_frame, 2, (x >> 1) + x2 + (vec.x >> 1), >> + (y >> 1) + y2 + (vec.y >> 1)); >> + } >> + } >> + >> + return 0; >> +} >> + >> +static int predict_inter_dc(AVCodecContext *avctx, int x, int y, int w, int >> h) >> +{ >> + int dx, dy, dc_y, dc_u, dc_v; >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + >> + if (s->ref_frame_count == 0) { >> + av_log(avctx, AV_LOG_ERROR, "reference to unavailable frame\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + >> + dx = get_se_golomb(gb); >> + dy = get_se_golomb(gb); >> + >> + if (x + dx < 0 || x + dx + w > avctx->width || >> + y + dy < 0 || y + dy + h > avctx->height) { >> + av_log(avctx, AV_LOG_ERROR, "motion vector out of bounds\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + >> + dc_y = get_se_golomb(gb); >> + if (dc_y < -(1<<16) || dc_y >= (1 << 16)) { >> + av_log(avctx, AV_LOG_ERROR, "invalid dc offset\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + dc_y <<= 1; >> + >> + dc_u = get_se_golomb(gb); >> + if (dc_u < -(1<<16) || dc_u >= (1 << 16)) { >> + av_log(avctx, AV_LOG_ERROR, "invalid dc offset\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + dc_u <<= 1; >> + >> + dc_v = get_se_golomb(gb); >> + if (dc_v < -(1<<16) || dc_v >= (1 << 16)) { >> + av_log(avctx, AV_LOG_ERROR, "invalid dc offset\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + dc_v <<= 1; >> + >> + s->cur_frame->pict_type = AV_PICTURE_TYPE_P; >> + s->cur_frame->key_frame = 0; >> + >> + // luma >> + for (int y2 = 0; y2 < h; y2++) >> + for (int x2 = 0; x2 < w; x2++) >> + PIXEL_CUR(s, 0, x + x2, y + y2) = av_clip_uint8( >> + PIXEL_REF(s, 0, 0, x + x2 + dx, y + y2 + dy) + dc_y); >> + >> + // chroma >> + for (int y2 = 0; y2 < (h >> 1); y2++) { >> + for (int x2 = 0; x2 < (w >> 1); x2++) { >> + PIXEL_CUR(s, 1, (x >> 1) + x2, (y >> 1) + y2) = av_clip_uint8( >> + PIXEL_REF(s, 0, 1, (x >> 1) + x2 + (dx >> 1), >> + (y >> 1) + y2 + (dy >> 1)) + dc_u); >> + PIXEL_CUR(s, 2, (x >> 1) + x2, (y >> 1) + y2) = av_clip_uint8( >> + PIXEL_REF(s, 0, 2, (x >> 1) + x2 + (dx >> 1), >> + (y >> 1) + y2 + (dy >> 1)) + dc_v); >> + } >> + } >> + >> + return 0; >> +} >> + >> +static int decode_mb(AVCodecContext *avctx, int x, int y, int w, int h, >> + const MVec *predVec) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + int ret = 0; >> + >> + int mode = get_ue_golomb_31(gb); >> + if (s->version == VX_VERSION_OLD) >> + mode = old_mb_mode_remap_tab[mode]; >> + >> + switch (mode) { >> + case 0:// v-split, no residu >> + if (w == 2) { >> + av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + if ((ret = decode_mb(avctx, x, y, w >> 1, h, predVec)) < 0) >> + return ret; >> + if ((ret = decode_mb(avctx, x + (w >> 1), y, w >> 1, h, predVec)) < >> 0) >> + return ret; >> + if (w == 8 && (h == 8 || h == 16)) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 1:// no delta, no residu, ref 0 >> + if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, 0)) < 0) >> + return ret; >> + if ((w == 8 || w == 16) && (h == 8 || h == 16)) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 2:// h-split, no residu >> + if (h == 2) { >> + av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + if ((ret = decode_mb(avctx, x, y, w, h >> 1, predVec)) < 0) >> + return ret; >> + if ((ret = decode_mb(avctx, x, y + (h >> 1), w, h >> 1, predVec)) < >> 0) >> + return ret; >> + if ((w == 8 || w == 16) && h == 8) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 3:// unpredicted delta ref0 + dc offset, no residu >> + if ((ret = predict_inter_dc(avctx, x, y, w, h)) < 0) >> + return ret; >> + if ((w == 8 || w == 16) && (h == 8 || h == 16)) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 4:// delta, no residu, ref 0 >> + case 5:// delta, no residu, ref 1 >> + case 6:// delta, no residu, ref 2 >> + if ((ret = predict_inter(avctx, x, y, w, h, predVec, 1, mode - 4)) >> < 0) >> + return ret; >> + if ((w == 8 || w == 16) && (h == 8 || h == 16)) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 7:// plane, no residu >> + if ((ret = predict_mb_plane(avctx, x, y, w, h)) < 0) >> + return ret; >> + if ((w == 8 || w == 16) && (h == 8 || h == 16)) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 8:// v-split, residu >> + if (w == 2) { >> + av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + if ((ret = decode_mb(avctx, x, y, w >> 1, h, predVec)) < 0) >> + return ret; >> + if ((ret = decode_mb(avctx, x + (w >> 1), y, w >> 1, h, predVec)) < >> 0) >> + return ret; >> + if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0) >> + return ret; >> + break; >> + case 9:// no delta, no residu, ref 1 >> + if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, 1)) < 0) >> + return ret; >> + if ((w == 8 || w == 16) && (h == 8 || h == 16)) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 10:// unpredicted delta ref0 + dc offset, residu >> + if ((ret = predict_inter_dc(avctx, x, y, w, h)) < 0) >> + return ret; >> + if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0) >> + return ret; >> + break; >> + case 11:// predict notile, no residu >> + if ((ret = predict_notile(avctx, x, y, w, h)) < 0) >> + return ret; >> + if ((w == 8 || w == 16) && (h == 8 || h == 16)) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 12:// no delta, residu, ref 0 >> + if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, 0)) < 0) >> + return ret; >> + if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0) >> + return ret; >> + break; >> + case 13:// h-split, residu >> + if (h == 2) { >> + av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + if ((ret = decode_mb(avctx, x, y, w, h >> 1, predVec)) < 0) >> + return ret; >> + if ((ret = decode_mb(avctx, x, y + (h >> 1), w, h >> 1, predVec)) < >> 0) >> + return ret; >> + if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0) >> + return ret; >> + break; >> + case 14:// no delta, no residu, ref 2 >> + if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, 2)) < 0) >> + return ret; >> + if ((w == 8 || w == 16) && (h == 8 || h == 16)) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 15:// predict4, no residu >> + if ((ret = predict4(avctx, x, y, w, h)) < 0) >> + return ret; >> + if ((w == 8 || w == 16) && (h == 8 || h == 16)) >> + clear_total_coeff(avctx, x, y, w, h); >> + break; >> + case 16:// delta, residu, ref 0 >> + case 17:// delta, residu, ref 1 >> + case 18:// delta, residu, ref 2 >> + if ((ret = predict_inter(avctx, x, y, w, h, predVec, 1, mode - 16)) >> < 0) >> + return ret; >> + if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0) >> + return ret; >> + break; >> + case 19:// predict4, residu >> + if ((ret = predict4(avctx, x, y, w, h)) < 0) >> + return ret; >> + if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0) >> + return ret; >> + break; >> + case 20:// no delta, residu, ref 1 >> + case 21:// no delta, residu, ref 2 >> + if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, mode - 20 + >> 1)) < 0) >> + return ret; >> + if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0) >> + return ret; >> + break; >> + case 22:// predict notile, residu >> + if ((ret = predict_notile(avctx, x, y, w, h)) < 0) >> + return ret; >> + if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0) >> + return ret; >> + break; >> + case 23:// plane, residu >> + if ((ret = predict_mb_plane(avctx, x, y, w, h)) < 0) >> + return ret; >> + if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0) >> + return ret; >> + break; >> + default: >> + av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + return 0; >> +} >> + >> +static int detect_format(AVCodecContext *avctx) >> +{ >> + // assume the new format, if any incorrect decisions are made for the >> + // first macroblock of a keyframe (ref, non-dc prediction) then it must >> be >> + // the old format >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + int w = 16; >> + int h = 16; >> + while (1) { >> + int mode = get_ue_golomb_31(gb); >> + if (mode == 0 || mode == 8) { // v-split >> + if (w == 2) // too many splits >> + return VX_VERSION_OLD; >> + w >>= 1; >> + continue; >> + } else if (mode == 2 || mode == 13) { // h-split >> + if (h == 2) // too many splits >> + return VX_VERSION_OLD; >> + h >>= 1; >> + continue; >> + } else if (mode == 11 || mode == 22) { // predict notile >> + if (get_ue_golomb_31(gb) != 2) // mode_y != dc >> + return VX_VERSION_OLD; >> + if (get_ue_golomb_31(gb) != 0) // mode_uv != dc >> + return VX_VERSION_OLD; >> + break; //we should have enough evidence now >> + } else if (mode == 15 || mode == 19) { // predict4 >> + // initial prediction is always dc >> + // we don't expect that prediction to be wrong >> + if (!get_bits1(gb)) >> + return VX_VERSION_OLD; >> + break; //we should have enough evidence now >> + } else // inter prediction, plane or any other value >> + return VX_VERSION_OLD; >> + } >> + return VX_VERSION_NEW; >> +} >> + >> +static int actimagine_decode(AVCodecContext *avctx, void *data, >> + int *got_frame, AVPacket *pkt) >> +{ >> + MVec *vectors; >> + int ret; >> + ActimagineContext *s = avctx->priv_data; >> + GetBitContext *gb = &s->gb; >> + AVFrame *frame = s->cur_frame; >> + >> + // in avi files the frames start with a 32 bit number that seems to >> + // indicate the total number of bits >> + int offset = s->avi ? 4 : 0; >> + >> + av_fast_padded_malloc(&s->bitstream, &s->bitstream_size, >> + pkt->size); >> + >> + if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0) >> + return ret; >> + >> + s->bdsp.bswap16_buf((uint16_t *)s->bitstream, (uint16_t *)pkt->data, >> + (pkt->size + 1) >> 1); >> + >> + ret = init_get_bits8(gb, s->bitstream + offset, >> + FFALIGN(pkt->size - offset, 2)); >> + if (ret < 0) >> + return ret; >> + >> + // determine the bitstream version if this was not done yet >> + if (s->version == VX_VERSION_INVALID) { >> + if (s->ref_frame_count != 0) { >> + av_log(avctx, AV_LOG_ERROR, "can't determine version on p >> frame\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + s->version = detect_format(avctx); >> + >> + // reinit bitreader >> + ret = init_get_bits8(gb, s->bitstream + offset, >> + FFALIGN(pkt->size - offset, 2)); >> + if (ret < 0) >> + return ret; >> + } >> + >> + vectors = s->vectors + s->vectors_stride + 1; >> + >> + frame->pict_type = AV_PICTURE_TYPE_I; >> + frame->key_frame = 1; >> + >> + if (s->quantizer == -1) { >> + av_log(avctx, AV_LOG_ERROR, "no quantizer setup\n"); >> + return AVERROR_INVALIDDATA; >> + } >> + >> + for (int y = 0; y < avctx->height; y += 16) { >> + MVec *vec_cur = vectors; >> + for (int x = 0; x < avctx->width; x += 16) { >> + MVec predVec; >> + vec_cur[0].x = 0; >> + vec_cur[0].y = 0; >> + predVec.x = mid_pred(vec_cur[-1].x, >> vec_cur[-s->vectors_stride].x, >> + vec_cur[-s->vectors_stride + 1].x); >> + predVec.y = mid_pred(vec_cur[-1].y, >> vec_cur[-s->vectors_stride].y, >> + vec_cur[-s->vectors_stride + 1].y); >> + if ((ret = decode_mb(avctx, x, y, 16, 16, &predVec)) < 0) >> + return ret; >> + vec_cur++; >> + } >> + vectors += s->vectors_stride; >> + } >> + >> + if (s->ref_frame_count == 3) >> + av_frame_unref(s->ref_frames[2]); >> + >> + s->cur_frame = s->ref_frames[2]; >> + s->ref_frames[2] = s->ref_frames[1]; >> + s->ref_frames[1] = s->ref_frames[0]; >> + s->ref_frames[0] = frame; >> + >> + if (s->ref_frame_count < 3) >> + s->ref_frame_count++; >> + >> + if ((ret = av_frame_ref(data, frame)) < 0) >> + return ret; >> + *got_frame = 1; >> + >> + return 0; >> +} >> + >> +static void actimagine_flush(AVCodecContext *avctx) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + >> + for (int i = 0; i < 3; i++) >> + av_frame_unref(s->ref_frames[i]); >> + >> + s->ref_frame_count = 0; >> +} >> + >> +static av_cold int actimagine_close(AVCodecContext *avctx) >> +{ >> + ActimagineContext *s = avctx->priv_data; >> + >> + av_freep(&s->vectors); >> + s->vectors_stride = 0; >> + av_freep(&s->total_coeff_y); >> + s->total_coeff_y_stride = 0; >> + av_freep(&s->total_coeff_uv); >> + s->total_coeff_uv_stride = 0; >> + >> + av_freep(&s->bitstream); >> + s->bitstream_size = 0; >> + >> + for (int i = 0; i < 3; i++) >> + av_frame_free(&s->ref_frames[i]); >> + av_frame_free(&s->cur_frame); >> + >> + return 0; >> +} >> + >> +AVCodec ff_actimagine_decoder = { >> + .name = "actimagine", >> + .long_name = NULL_IF_CONFIG_SMALL("Actimagine VX Video"), >> + .type = AVMEDIA_TYPE_VIDEO, >> + .id = AV_CODEC_ID_ACTIMAGINE, >> + .priv_data_size = sizeof(ActimagineContext), >> + .init = actimagine_init, >> + .decode = actimagine_decode, >> + .flush = actimagine_flush, >> + .close = actimagine_close, >> + .capabilities = AV_CODEC_CAP_DR1, >> + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | >> FF_CODEC_CAP_INIT_CLEANUP, >> +}; >> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c >> index 2e9a3581de..10809f3492 100644 >> --- a/libavcodec/allcodecs.c >> +++ b/libavcodec/allcodecs.c >> @@ -32,6 +32,7 @@ >> extern AVCodec ff_a64multi_encoder; >> extern AVCodec ff_a64multi5_encoder; >> extern AVCodec ff_aasc_decoder; >> +extern AVCodec ff_actimagine_decoder; >> extern AVCodec ff_aic_decoder; >> extern AVCodec ff_alias_pix_encoder; >> extern AVCodec ff_alias_pix_decoder; >> diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c >> index 17f8a14044..65d96c21af 100644 >> --- a/libavcodec/codec_desc.c >> +++ b/libavcodec/codec_desc.c >> @@ -1856,6 +1856,13 @@ static const AVCodecDescriptor codec_descriptors[] = { >> .long_name = NULL_IF_CONFIG_SMALL("Digital Pictures SGA Video"), >> .props = AV_CODEC_PROP_LOSSY, >> }, >> + { >> + .id = AV_CODEC_ID_ACTIMAGINE, >> + .type = AVMEDIA_TYPE_VIDEO, >> + .name = "actimagine", >> + .long_name = NULL_IF_CONFIG_SMALL("Actimagine VX Video"), >> + .props = AV_CODEC_PROP_LOSSY, >> + }, >> >> /* various PCM "codecs" */ >> { >> diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h >> index ab7bc68ee2..a4b3f3955d 100644 >> --- a/libavcodec/codec_id.h >> +++ b/libavcodec/codec_id.h >> @@ -307,6 +307,7 @@ enum AVCodecID { >> AV_CODEC_ID_CRI, >> AV_CODEC_ID_SIMBIOSIS_IMX, >> AV_CODEC_ID_SGA_VIDEO, >> + AV_CODEC_ID_ACTIMAGINE, >> >> /* various PCM "codecs" */ >> AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the >> start of audio codecs >> diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c >> index 9f5f692331..642fb2659d 100644 >> --- a/libavcodec/h264_cavlc.c >> +++ b/libavcodec/h264_cavlc.c >> @@ -36,6 +36,7 @@ >> #include "golomb.h" >> #include "mpegutils.h" >> #include "libavutil/avassert.h" >> +#include "h264_cavlc_data.h" >> >> >> static const uint8_t golomb_to_inter_cbp_gray[16]={ >> @@ -86,104 +87,6 @@ static const uint8_t chroma422_dc_coeff_token_bits[4*9]={ >> 7, 5, 4, 4, >> }; >> >> -static const uint8_t coeff_token_len[4][4*17]={ >> -{ >> - 1, 0, 0, 0, >> - 6, 2, 0, 0, 8, 6, 3, 0, 9, 8, 7, 5, 10, 9, 8, 6, >> - 11,10, 9, 7, 13,11,10, 8, 13,13,11, 9, 13,13,13,10, >> - 14,14,13,11, 14,14,14,13, 15,15,14,14, 15,15,15,14, >> - 16,15,15,15, 16,16,16,15, 16,16,16,16, 16,16,16,16, >> -}, >> -{ >> - 2, 0, 0, 0, >> - 6, 2, 0, 0, 6, 5, 3, 0, 7, 6, 6, 4, 8, 6, 6, 4, >> - 8, 7, 7, 5, 9, 8, 8, 6, 11, 9, 9, 6, 11,11,11, 7, >> - 12,11,11, 9, 12,12,12,11, 12,12,12,11, 13,13,13,12, >> - 13,13,13,13, 13,14,13,13, 14,14,14,13, 14,14,14,14, >> -}, >> -{ >> - 4, 0, 0, 0, >> - 6, 4, 0, 0, 6, 5, 4, 0, 6, 5, 5, 4, 7, 5, 5, 4, >> - 7, 5, 5, 4, 7, 6, 6, 4, 7, 6, 6, 4, 8, 7, 7, 5, >> - 8, 8, 7, 6, 9, 8, 8, 7, 9, 9, 8, 8, 9, 9, 9, 8, >> - 10, 9, 9, 9, 10,10,10,10, 10,10,10,10, 10,10,10,10, >> -}, >> -{ >> - 6, 0, 0, 0, >> - 6, 6, 0, 0, 6, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, >> - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, >> - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, >> - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, >> -} >> -}; >> - >> -static const uint8_t coeff_token_bits[4][4*17]={ >> -{ >> - 1, 0, 0, 0, >> - 5, 1, 0, 0, 7, 4, 1, 0, 7, 6, 5, 3, 7, 6, 5, 3, >> - 7, 6, 5, 4, 15, 6, 5, 4, 11,14, 5, 4, 8,10,13, 4, >> - 15,14, 9, 4, 11,10,13,12, 15,14, 9,12, 11,10,13, 8, >> - 15, 1, 9,12, 11,14,13, 8, 7,10, 9,12, 4, 6, 5, 8, >> -}, >> -{ >> - 3, 0, 0, 0, >> - 11, 2, 0, 0, 7, 7, 3, 0, 7,10, 9, 5, 7, 6, 5, 4, >> - 4, 6, 5, 6, 7, 6, 5, 8, 15, 6, 5, 4, 11,14,13, 4, >> - 15,10, 9, 4, 11,14,13,12, 8,10, 9, 8, 15,14,13,12, >> - 11,10, 9,12, 7,11, 6, 8, 9, 8,10, 1, 7, 6, 5, 4, >> -}, >> -{ >> - 15, 0, 0, 0, >> - 15,14, 0, 0, 11,15,13, 0, 8,12,14,12, 15,10,11,11, >> - 11, 8, 9,10, 9,14,13, 9, 8,10, 9, 8, 15,14,13,13, >> - 11,14,10,12, 15,10,13,12, 11,14, 9,12, 8,10,13, 8, >> - 13, 7, 9,12, 9,12,11,10, 5, 8, 7, 6, 1, 4, 3, 2, >> -}, >> -{ >> - 3, 0, 0, 0, >> - 0, 1, 0, 0, 4, 5, 6, 0, 8, 9,10,11, 12,13,14,15, >> - 16,17,18,19, 20,21,22,23, 24,25,26,27, 28,29,30,31, >> - 32,33,34,35, 36,37,38,39, 40,41,42,43, 44,45,46,47, >> - 48,49,50,51, 52,53,54,55, 56,57,58,59, 60,61,62,63, >> -} >> -}; >> - >> -static const uint8_t total_zeros_len[16][16]= { >> - {1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9}, >> - {3,3,3,3,3,4,4,4,4,5,5,6,6,6,6}, >> - {4,3,3,3,4,4,3,3,4,5,5,6,5,6}, >> - {5,3,4,4,3,3,3,4,3,4,5,5,5}, >> - {4,4,4,3,3,3,3,3,4,5,4,5}, >> - {6,5,3,3,3,3,3,3,4,3,6}, >> - {6,5,3,3,3,2,3,4,3,6}, >> - {6,4,5,3,2,2,3,3,6}, >> - {6,6,4,2,2,3,2,5}, >> - {5,5,3,2,2,2,4}, >> - {4,4,3,3,1,3}, >> - {4,4,2,1,3}, >> - {3,3,1,2}, >> - {2,2,1}, >> - {1,1}, >> -}; >> - >> -static const uint8_t total_zeros_bits[16][16]= { >> - {1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1}, >> - {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0}, >> - {5,7,6,5,4,3,4,3,2,3,2,1,1,0}, >> - {3,7,5,4,6,5,4,3,3,2,2,1,0}, >> - {5,4,3,7,6,5,4,3,2,1,1,0}, >> - {1,1,7,6,5,4,3,2,1,1,0}, >> - {1,1,5,4,3,3,2,1,1,0}, >> - {1,1,1,3,3,2,2,1,0}, >> - {1,0,1,3,2,1,1,1}, >> - {1,0,1,3,2,1,1}, >> - {0,1,1,2,1,3}, >> - {0,1,1,1,1}, >> - {0,1,1,1}, >> - {0,1,1}, >> - {0,1}, >> -}; >> - >> static const uint8_t chroma_dc_total_zeros_len[3][4]= { >> { 1, 2, 3, 3,}, >> { 1, 2, 2, 0,}, >> @@ -216,26 +119,6 @@ static const uint8_t >> chroma422_dc_total_zeros_bits[7][8]= { >> { 0, 1 }, >> }; >> >> -static const uint8_t run_len[7][16]={ >> - {1,1}, >> - {1,2,2}, >> - {2,2,2,2}, >> - {2,2,2,3,3}, >> - {2,2,3,3,3,3}, >> - {2,3,3,3,3,3,3}, >> - {3,3,3,3,3,3,3,4,5,6,7,8,9,10,11}, >> -}; >> - >> -static const uint8_t run_bits[7][16]={ >> - {1,0}, >> - {1,1,0}, >> - {3,2,1,0}, >> - {3,2,1,1,0}, >> - {3,2,3,2,1,0}, >> - {3,0,1,3,2,5,4}, >> - {7,6,5,4,3,2,1,1,1,1,1,1,1,1,1}, >> -}; >> - >> static VLC coeff_token_vlc[4]; >> static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2]; >> static const int coeff_token_vlc_tables_size[4]={520,332,280,256}; >> @@ -347,8 +230,8 @@ av_cold void ff_h264_decode_init_vlc(void) >> coeff_token_vlc[i].table = coeff_token_vlc_tables + offset; >> coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i]; >> init_vlc(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4*17, >> - &coeff_token_len [i][0], 1, 1, >> - &coeff_token_bits[i][0], 1, 1, >> + &ff_h264_cavlc_coeff_token_len [i][0], 1, 1, >> + &ff_h264_cavlc_coeff_token_bits[i][0], 1, 1, >> INIT_VLC_USE_NEW_STATIC); >> offset += coeff_token_vlc_tables_size[i]; >> } >> @@ -384,8 +267,8 @@ av_cold void ff_h264_decode_init_vlc(void) >> total_zeros_vlc[i + 1].table_allocated = >> total_zeros_vlc_tables_size; >> init_vlc(&total_zeros_vlc[i + 1], >> TOTAL_ZEROS_VLC_BITS, 16, >> - &total_zeros_len [i][0], 1, 1, >> - &total_zeros_bits[i][0], 1, 1, >> + &ff_h264_cavlc_total_zeros_len [i][0], 1, 1, >> + &ff_h264_cavlc_total_zeros_bits[i][0], 1, 1, >> INIT_VLC_USE_NEW_STATIC); >> } >> >> @@ -394,15 +277,15 @@ av_cold void ff_h264_decode_init_vlc(void) >> run_vlc[i + 1].table_allocated = run_vlc_tables_size; >> init_vlc(&run_vlc[i + 1], >> RUN_VLC_BITS, 7, >> - &run_len [i][0], 1, 1, >> - &run_bits[i][0], 1, 1, >> + &ff_h264_cavlc_run_len [i][0], 1, 1, >> + &ff_h264_cavlc_run_bits[i][0], 1, 1, >> INIT_VLC_USE_NEW_STATIC); >> } >> run7_vlc.table = run7_vlc_table; >> run7_vlc.table_allocated = run7_vlc_table_size; >> init_vlc(&run7_vlc, RUN7_VLC_BITS, 16, >> - &run_len [6][0], 1, 1, >> - &run_bits[6][0], 1, 1, >> + &ff_h264_cavlc_run_len [6][0], 1, 1, >> + &ff_h264_cavlc_run_bits[6][0], 1, 1, >> INIT_VLC_USE_NEW_STATIC); >> >> init_cavlc_level_tab(); >> diff --git a/libavcodec/h264_cavlc_data.c b/libavcodec/h264_cavlc_data.c >> new file mode 100644 >> index 0000000000..d18ab1954c >> --- /dev/null >> +++ b/libavcodec/h264_cavlc_data.c >> @@ -0,0 +1,140 @@ >> +/* >> + * H.264 cavlc tables >> + * Copyright (c) 2003 Michael Niedermayer <michae...@gmx.at> >> + * >> + * This file is part of FFmpeg. >> + * >> + * FFmpeg is free software; you can redistribute it and/or >> + * 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 >> + * Lesser General Public License for more details. >> + * >> + * 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 >> + */ >> + >> +#include "h264_cavlc_data.h" >> + >> +const uint8_t ff_h264_cavlc_coeff_token_len[4][4*17]={ >> +{ >> + 1, 0, 0, 0, >> + 6, 2, 0, 0, 8, 6, 3, 0, 9, 8, 7, 5, 10, 9, 8, 6, >> + 11,10, 9, 7, 13,11,10, 8, 13,13,11, 9, 13,13,13,10, >> + 14,14,13,11, 14,14,14,13, 15,15,14,14, 15,15,15,14, >> + 16,15,15,15, 16,16,16,15, 16,16,16,16, 16,16,16,16, >> +}, >> +{ >> + 2, 0, 0, 0, >> + 6, 2, 0, 0, 6, 5, 3, 0, 7, 6, 6, 4, 8, 6, 6, 4, >> + 8, 7, 7, 5, 9, 8, 8, 6, 11, 9, 9, 6, 11,11,11, 7, >> + 12,11,11, 9, 12,12,12,11, 12,12,12,11, 13,13,13,12, >> + 13,13,13,13, 13,14,13,13, 14,14,14,13, 14,14,14,14, >> +}, >> +{ >> + 4, 0, 0, 0, >> + 6, 4, 0, 0, 6, 5, 4, 0, 6, 5, 5, 4, 7, 5, 5, 4, >> + 7, 5, 5, 4, 7, 6, 6, 4, 7, 6, 6, 4, 8, 7, 7, 5, >> + 8, 8, 7, 6, 9, 8, 8, 7, 9, 9, 8, 8, 9, 9, 9, 8, >> + 10, 9, 9, 9, 10,10,10,10, 10,10,10,10, 10,10,10,10, >> +}, >> +{ >> + 6, 0, 0, 0, >> + 6, 6, 0, 0, 6, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, >> + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, >> + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, >> + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, >> +} >> +}; >> + >> +const uint8_t ff_h264_cavlc_coeff_token_bits[4][4*17]={ >> +{ >> + 1, 0, 0, 0, >> + 5, 1, 0, 0, 7, 4, 1, 0, 7, 6, 5, 3, 7, 6, 5, 3, >> + 7, 6, 5, 4, 15, 6, 5, 4, 11,14, 5, 4, 8,10,13, 4, >> + 15,14, 9, 4, 11,10,13,12, 15,14, 9,12, 11,10,13, 8, >> + 15, 1, 9,12, 11,14,13, 8, 7,10, 9,12, 4, 6, 5, 8, >> +}, >> +{ >> + 3, 0, 0, 0, >> + 11, 2, 0, 0, 7, 7, 3, 0, 7,10, 9, 5, 7, 6, 5, 4, >> + 4, 6, 5, 6, 7, 6, 5, 8, 15, 6, 5, 4, 11,14,13, 4, >> + 15,10, 9, 4, 11,14,13,12, 8,10, 9, 8, 15,14,13,12, >> + 11,10, 9,12, 7,11, 6, 8, 9, 8,10, 1, 7, 6, 5, 4, >> +}, >> +{ >> + 15, 0, 0, 0, >> + 15,14, 0, 0, 11,15,13, 0, 8,12,14,12, 15,10,11,11, >> + 11, 8, 9,10, 9,14,13, 9, 8,10, 9, 8, 15,14,13,13, >> + 11,14,10,12, 15,10,13,12, 11,14, 9,12, 8,10,13, 8, >> + 13, 7, 9,12, 9,12,11,10, 5, 8, 7, 6, 1, 4, 3, 2, >> +}, >> +{ >> + 3, 0, 0, 0, >> + 0, 1, 0, 0, 4, 5, 6, 0, 8, 9,10,11, 12,13,14,15, >> + 16,17,18,19, 20,21,22,23, 24,25,26,27, 28,29,30,31, >> + 32,33,34,35, 36,37,38,39, 40,41,42,43, 44,45,46,47, >> + 48,49,50,51, 52,53,54,55, 56,57,58,59, 60,61,62,63, >> +} >> +}; >> + >> +const uint8_t ff_h264_cavlc_total_zeros_len[16][16]= { >> + {1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9}, >> + {3,3,3,3,3,4,4,4,4,5,5,6,6,6,6}, >> + {4,3,3,3,4,4,3,3,4,5,5,6,5,6}, >> + {5,3,4,4,3,3,3,4,3,4,5,5,5}, >> + {4,4,4,3,3,3,3,3,4,5,4,5}, >> + {6,5,3,3,3,3,3,3,4,3,6}, >> + {6,5,3,3,3,2,3,4,3,6}, >> + {6,4,5,3,2,2,3,3,6}, >> + {6,6,4,2,2,3,2,5}, >> + {5,5,3,2,2,2,4}, >> + {4,4,3,3,1,3}, >> + {4,4,2,1,3}, >> + {3,3,1,2}, >> + {2,2,1}, >> + {1,1}, >> +}; >> + >> +const uint8_t ff_h264_cavlc_total_zeros_bits[16][16]= { >> + {1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1}, >> + {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0}, >> + {5,7,6,5,4,3,4,3,2,3,2,1,1,0}, >> + {3,7,5,4,6,5,4,3,3,2,2,1,0}, >> + {5,4,3,7,6,5,4,3,2,1,1,0}, >> + {1,1,7,6,5,4,3,2,1,1,0}, >> + {1,1,5,4,3,3,2,1,1,0}, >> + {1,1,1,3,3,2,2,1,0}, >> + {1,0,1,3,2,1,1,1}, >> + {1,0,1,3,2,1,1}, >> + {0,1,1,2,1,3}, >> + {0,1,1,1,1}, >> + {0,1,1,1}, >> + {0,1,1}, >> + {0,1}, >> +}; >> + >> +const uint8_t ff_h264_cavlc_run_len[7][16]={ >> + {1,1}, >> + {1,2,2}, >> + {2,2,2,2}, >> + {2,2,2,3,3}, >> + {2,2,3,3,3,3}, >> + {2,3,3,3,3,3,3}, >> + {3,3,3,3,3,3,3,4,5,6,7,8,9,10,11}, >> +}; >> + >> +const uint8_t ff_h264_cavlc_run_bits[7][16]={ >> + {1,0}, >> + {1,1,0}, >> + {3,2,1,0}, >> + {3,2,1,1,0}, >> + {3,2,3,2,1,0}, >> + {3,0,1,3,2,5,4}, >> + {7,6,5,4,3,2,1,1,1,1,1,1,1,1,1}, >> +}; >> diff --git a/libavcodec/h264_cavlc_data.h b/libavcodec/h264_cavlc_data.h >> new file mode 100644 >> index 0000000000..f20453fa26 >> --- /dev/null >> +++ b/libavcodec/h264_cavlc_data.h >> @@ -0,0 +1,33 @@ >> +/* >> + * This file is part of FFmpeg. >> + * >> + * FFmpeg is free software; you can redistribute it and/or >> + * 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 >> + * Lesser General Public License for more details. >> + * >> + * 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 >> + */ >> + >> +#ifndef AVCODEC_H264_CAVLC_DATA_H >> +#define AVCODEC_H264_CAVLC_DATA_H >> + >> +#include <stdint.h> >> + >> +extern const uint8_t ff_h264_cavlc_coeff_token_len[4][4*17]; >> +extern const uint8_t ff_h264_cavlc_coeff_token_bits[4][4*17]; >> + >> +extern const uint8_t ff_h264_cavlc_total_zeros_len[16][16]; >> +extern const uint8_t ff_h264_cavlc_total_zeros_bits[16][16]; >> + >> +extern const uint8_t ff_h264_cavlc_run_len[7][16]; >> +extern const uint8_t ff_h264_cavlc_run_bits[7][16]; >> + >> +#endif /* AVCODEC_H264_CAVLC_DATA_H */ >> diff --git a/libavcodec/version.h b/libavcodec/version.h >> index 4299ad4239..f992e1b36e 100644 >> --- a/libavcodec/version.h >> +++ b/libavcodec/version.h >> @@ -28,7 +28,7 @@ >> #include "libavutil/version.h" >> >> #define LIBAVCODEC_VERSION_MAJOR 58 >> -#define LIBAVCODEC_VERSION_MINOR 131 >> +#define LIBAVCODEC_VERSION_MINOR 132 >> #define LIBAVCODEC_VERSION_MICRO 100 >> >> #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ >> diff --git a/libavformat/riff.c b/libavformat/riff.c >> index 270ff7c024..5d5cfe16b0 100644 >> --- a/libavformat/riff.c >> +++ b/libavformat/riff.c >> @@ -496,6 +496,8 @@ const AVCodecTag ff_codec_bmp_tags[] = { >> { AV_CODEC_ID_MVHA, MKTAG('M', 'V', 'H', 'A') }, >> { AV_CODEC_ID_MV30, MKTAG('M', 'V', '3', '0') }, >> { AV_CODEC_ID_NOTCHLC, MKTAG('n', 'l', 'c', '1') }, >> + { AV_CODEC_ID_ACTIMAGINE, MKTAG('V', 'X', 'S', '1') }, >> + { AV_CODEC_ID_ACTIMAGINE, MKTAG('v', 'x', 's', '1') }, >> { AV_CODEC_ID_NONE, 0 } >> }; >> >> -- >> 2.17.1 >> > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".