X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=libavcodec%2Fffv1.c;h=bde577c55b2bd2a1e6f2e698345f7043684f53b6;hb=5b423887f4dcf2b200689e472b9e239a1cf86a6b;hp=ee5419cd3f8a13865fd54caa46552664014a02ee;hpb=2029f312e8c13b25d322d69961b42db2e66f616a;p=ffmpeg diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index ee5419cd3f8..bde577c55b2 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -18,23 +18,26 @@ * 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 - * */ /** - * @file ffv1.c + * @file libavcodec/ffv1.c * FF Video Codec 1 (an experimental lossless codec) */ #include "avcodec.h" -#include "bitstream.h" +#include "get_bits.h" +#include "put_bits.h" #include "dsputil.h" #include "rangecoder.h" #include "golomb.h" +#include "mathops.h" #define MAX_PLANES 4 #define CONTEXT_SIZE 32 +extern const uint8_t ff_log2_run[32]; + static const int8_t quant3[256]={ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -53,6 +56,26 @@ static const int8_t quant3[256]={ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, }; + +static const int8_t quant5_10bit[256]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +-1,-1,-1,-1,-1,-1,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0, +}; + static const int8_t quant5[256]={ 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -107,6 +130,25 @@ static const int8_t quant9[256]={ -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1, }; +static const int8_t quant9_10bit[256]={ + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3, +-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, +-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-1,-1,-1,-1,-1,-1,-1,-1,-0,-0,-0,-0, +}; + static const int8_t quant11[256]={ 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, @@ -144,12 +186,6 @@ static const int8_t quant13[256]={ -4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1, }; -static const uint8_t log2_run[32]={ - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, - 8, 9,10,11,12,13,14,15, -}; - typedef struct VlcState{ int16_t drift; uint16_t error_sum; @@ -176,7 +212,7 @@ typedef struct FFV1Context{ int picture_number; AVFrame picture; int plane_count; - int ac; ///< 1-> CABAC 0-> golomb rice + int ac; ///< 1=range coder <-> 0=golomb rice PlaneContext plane[MAX_PLANES]; int16_t quant_table[5][256]; int run_index; @@ -220,55 +256,71 @@ static inline int get_context(FFV1Context *f, int_fast16_t *src, int_fast16_t *l return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF]; } -static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){ +static inline void put_symbol_inline(RangeCoder *c, uint8_t *state, int v, int is_signed){ int i; if(v){ const int a= FFABS(v); const int e= av_log2(a); put_rac(c, state+0, 0); + if(e<=9){ + for(i=0; i=0; i--){ + put_rac(c, state+22+i, (a>>i)&1); //22..31 + } - for(i=0; i=0; i--){ - put_rac(c, state+22+i, (a>>i)&1); //22..31 - } + for(i=e-1; i>=0; i--){ + put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31 + } - if(is_signed) - put_rac(c, state+11 + e, v < 0); //11..21 + if(is_signed) + put_rac(c, state+11 + 10, v < 0); //11..21 + } }else{ put_rac(c, state+0, 1); } } -static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){ +static void av_noinline put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){ + put_symbol_inline(c, state, v, is_signed); +} + +static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, int is_signed){ if(get_rac(c, state+0)) return 0; else{ int i, e, a; e= 0; - while(get_rac(c, state+1 + e)){ //1..10 + while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10 e++; } - assert(e<=9); a= 1; for(i=e-1; i>=0; i--){ - a += a + get_rac(c, state+22 + i); //22..31 + a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31 } - if(is_signed && get_rac(c, state+11 + e)) //11..21 - return -a; - else - return a; + e= -(is_signed && get_rac(c, state+11 + FFMIN(e, 10))); //11..21 + return (a^e)-e; } } +static int av_noinline get_symbol(RangeCoder *c, uint8_t *state, int is_signed){ + return get_symbol_inline(c, state, is_signed); +} + static inline void update_vlc_state(VlcState * const state, const int v){ int drift= state->drift; int count= state->count; @@ -355,7 +407,7 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int return ret; } -#ifdef CONFIG_ENCODERS +#if CONFIG_FFV1_ENCODER static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){ PlaneContext * const p= &s->plane[plane_index]; RangeCoder * const c= &s->c; @@ -390,20 +442,20 @@ static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], in diff= fold(diff, bits); if(s->ac){ - put_symbol(c, p->state[context], diff, 1); + put_symbol_inline(c, p->state[context], diff, 1); }else{ if(context == 0) run_mode=1; if(run_mode){ if(diff){ - while(run_count >= 1<= 1<pb, 1, 1); } - put_bits(&s->pb, 1 + log2_run[run_index], run_count); + put_bits(&s->pb, 1 + ff_log2_run[run_index], run_count); if(run_index) run_index--; run_count=0; run_mode=0; @@ -420,8 +472,8 @@ static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], in } } if(run_mode){ - while(run_count >= 1<= 1<pb, 1, 1); } @@ -449,10 +501,17 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, sample[0][-1]= sample[1][0 ]; sample[1][ w]= sample[1][w-1]; //{START_TIMER - for(x=0; xavctx->bits_per_raw_sample<=8){ + for(x=0; x> (16 - s->avctx->bits_per_raw_sample); + } + encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); } - encode_line(s, w, sample, plane_index, 8); //STOP_TIMER("encode line")} } } @@ -521,6 +580,8 @@ static void write_header(FFV1Context *f){ put_symbol(c, state, f->version, 0); put_symbol(c, state, f->avctx->coder_type, 0); put_symbol(c, state, f->colorspace, 0); //YUV cs type + if(f->version>0) + put_symbol(c, state, f->avctx->bits_per_raw_sample, 0); put_rac(c, state, 1); //chroma planes put_symbol(c, state, f->chroma_h_shift, 0); put_symbol(c, state, f->chroma_v_shift, 0); @@ -529,27 +590,26 @@ static void write_header(FFV1Context *f){ for(i=0; i<5; i++) write_quant_table(c, f->quant_table[i]); } -#endif /* CONFIG_ENCODERS */ +#endif /* CONFIG_FFV1_ENCODER */ -static int common_init(AVCodecContext *avctx){ +static av_cold int common_init(AVCodecContext *avctx){ FFV1Context *s = avctx->priv_data; - int width, height; s->avctx= avctx; s->flags= avctx->flags; dsputil_init(&s->dsp, avctx); - width= s->width= avctx->width; - height= s->height= avctx->height; + s->width = avctx->width; + s->height= avctx->height; - assert(width && height); + assert(s->width && s->height); return 0; } -#ifdef CONFIG_ENCODERS -static int encode_init(AVCodecContext *avctx) +#if CONFIG_FFV1_ENCODER +static av_cold int encode_init(AVCodecContext *avctx) { FFV1Context *s = avctx->priv_data; int i; @@ -561,16 +621,30 @@ static int encode_init(AVCodecContext *avctx) s->plane_count=2; for(i=0; i<256; i++){ - s->quant_table[0][i]= quant11[i]; - s->quant_table[1][i]= 11*quant11[i]; - if(avctx->context_model==0){ - s->quant_table[2][i]= 11*11*quant11[i]; - s->quant_table[3][i]= - s->quant_table[4][i]=0; + if(avctx->bits_per_raw_sample <=8){ + s->quant_table[0][i]= quant11[i]; + s->quant_table[1][i]= 11*quant11[i]; + if(avctx->context_model==0){ + s->quant_table[2][i]= 11*11*quant11[i]; + s->quant_table[3][i]= + s->quant_table[4][i]=0; + }else{ + s->quant_table[2][i]= 11*11*quant5 [i]; + s->quant_table[3][i]= 5*11*11*quant5 [i]; + s->quant_table[4][i]= 5*5*11*11*quant5 [i]; + } }else{ - s->quant_table[2][i]= 11*11*quant5 [i]; - s->quant_table[3][i]= 5*11*11*quant5 [i]; - s->quant_table[4][i]= 5*5*11*11*quant5 [i]; + s->quant_table[0][i]= quant9_10bit[i]; + s->quant_table[1][i]= 11*quant9_10bit[i]; + if(avctx->context_model==0){ + s->quant_table[2][i]= 11*11*quant9_10bit[i]; + s->quant_table[3][i]= + s->quant_table[4][i]=0; + }else{ + s->quant_table[2][i]= 11*11*quant5_10bit[i]; + s->quant_table[3][i]= 5*11*11*quant5_10bit[i]; + s->quant_table[4][i]= 5*5*11*11*quant5_10bit[i]; + } } } @@ -592,6 +666,19 @@ static int encode_init(AVCodecContext *avctx) avctx->coded_frame= &s->picture; switch(avctx->pix_fmt){ + case PIX_FMT_YUV444P16: + case PIX_FMT_YUV422P16: + case PIX_FMT_YUV420P16: + if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ + av_log(avctx, AV_LOG_ERROR, "More than 8 bit per component is still experimental and no gurantee is yet made for future compatibility\n" + "Use vstrict=-2 / -strict -2 to use it anyway.\n"); + return -1; + } + if(avctx->bits_per_raw_sample <=8){ + av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n"); + return -1; + } + s->version= 1; case PIX_FMT_YUV444P: case PIX_FMT_YUV422P: case PIX_FMT_YUV420P: @@ -612,7 +699,7 @@ static int encode_init(AVCodecContext *avctx) return 0; } -#endif /* CONFIG_ENCODERS */ +#endif /* CONFIG_FFV1_ENCODER */ static void clear_state(FFV1Context *f){ @@ -637,7 +724,7 @@ static void clear_state(FFV1Context *f){ } } -#ifdef CONFIG_ENCODERS +#if CONFIG_FFV1_ENCODER static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ FFV1Context *f = avctx->priv_data; RangeCoder * const c= &f->c; @@ -649,7 +736,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, uint8_t keystate=128; ff_init_range_encoder(c, buf, buf_size); -// ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); *p = *pict; @@ -693,9 +779,9 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, return used_count + (put_bits_count(&f->pb)+7)/8; } } -#endif /* CONFIG_ENCODERS */ +#endif /* CONFIG_FFV1_ENCODER */ -static int common_end(AVCodecContext *avctx){ +static av_cold int common_end(AVCodecContext *avctx){ FFV1Context *s = avctx->priv_data; int i; @@ -703,12 +789,13 @@ static int common_end(AVCodecContext *avctx){ PlaneContext *p= &s->plane[i]; av_freep(&p->state); + av_freep(&p->vlc_state); } return 0; } -static inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){ +static av_always_inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){ PlaneContext * const p= &s->plane[plane_index]; RangeCoder * const c= &s->c; int x; @@ -728,17 +815,17 @@ static inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], i if(s->ac){ - diff= get_symbol(c, p->state[context], 1); + diff= get_symbol_inline(c, p->state[context], 1); }else{ if(context == 0 && run_mode==0) run_mode=1; if(run_mode){ if(run_count==0 && run_mode==1){ if(get_bits1(&s->gb)){ - run_count = 1<gb, log2_run[run_index]); + if(ff_log2_run[run_index]) run_count = get_bits(&s->gb, ff_log2_run[run_index]); else run_count=0; if(run_index) run_index--; run_mode=2; @@ -768,7 +855,9 @@ static inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], i static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ int x, y; int_fast16_t sample_buffer[2][w+6]; - int_fast16_t *sample[2]= {sample_buffer[0]+3, sample_buffer[1]+3}; + int_fast16_t *sample[2]; + sample[0]=sample_buffer[0]+3; + sample[1]=sample_buffer[1]+3; s->run_index=0; @@ -784,9 +873,16 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, sample[0][ w]= sample[0][w-1]; //{START_TIMER - decode_line(s, w, sample, plane_index, 8); - for(x=0; xavctx->bits_per_raw_sample <= 8){ + decode_line(s, w, sample, plane_index, 8); + for(x=0; xavctx->bits_per_raw_sample); + for(x=0; xavctx->bits_per_raw_sample); + } } //STOP_TIMER("decode-line")} } @@ -795,10 +891,11 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ int x, y, p; int_fast16_t sample_buffer[3][2][w+6]; - int_fast16_t *sample[3][2]= { - {sample_buffer[0][0]+3, sample_buffer[0][1]+3}, - {sample_buffer[1][0]+3, sample_buffer[1][1]+3}, - {sample_buffer[2][0]+3, sample_buffer[2][1]+3}}; + int_fast16_t *sample[3][2]; + for(x=0; x<3; x++){ + sample[x][0] = sample_buffer[x][0]+3; + sample[x][1] = sample_buffer[x][1]+3; + } s->run_index=0; @@ -872,6 +969,8 @@ static int read_header(FFV1Context *f){ f->version= get_symbol(c, state, 0); f->ac= f->avctx->coder_type= get_symbol(c, state, 0); f->colorspace= get_symbol(c, state, 0); //YUV cs type + if(f->version>0) + f->avctx->bits_per_raw_sample= get_symbol(c, state, 0); get_rac(c, state); //no chroma = false f->chroma_h_shift= get_symbol(c, state, 0); f->chroma_v_shift= get_symbol(c, state, 0); @@ -879,15 +978,26 @@ static int read_header(FFV1Context *f){ f->plane_count= 2; if(f->colorspace==0){ - switch(16*f->chroma_h_shift + f->chroma_v_shift){ - case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break; - case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break; - case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break; - case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break; - case 0x22: f->avctx->pix_fmt= PIX_FMT_YUV410P; break; - default: - av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); - return -1; + if(f->avctx->bits_per_raw_sample<=8){ + switch(16*f->chroma_h_shift + f->chroma_v_shift){ + case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break; + case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break; + case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break; + case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break; + case 0x22: f->avctx->pix_fmt= PIX_FMT_YUV410P; break; + default: + av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); + return -1; + } + }else{ + switch(16*f->chroma_h_shift + f->chroma_v_shift){ + case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break; + case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break; + case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P16; break; + default: + av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); + return -1; + } } }else if(f->colorspace==1){ if(f->chroma_h_shift || f->chroma_v_shift){ @@ -927,7 +1037,7 @@ static int read_header(FFV1Context *f){ return 0; } -static int decode_init(AVCodecContext *avctx) +static av_cold int decode_init(AVCodecContext *avctx) { // FFV1Context *s = avctx->priv_data; @@ -936,7 +1046,9 @@ static int decode_init(AVCodecContext *avctx) return 0; } -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){ +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; FFV1Context *f = avctx->priv_data; RangeCoder * const c= &f->c; const int width= f->width; @@ -1022,10 +1134,11 @@ AVCodec ffv1_decoder = { common_end, decode_frame, CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, - NULL + NULL, + .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), }; -#ifdef CONFIG_ENCODERS +#if CONFIG_FFV1_ENCODER AVCodec ffv1_encoder = { "ffv1", CODEC_TYPE_VIDEO, @@ -1034,6 +1147,7 @@ AVCodec ffv1_encoder = { encode_init, encode_frame, common_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, -1}, + .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_NONE}, + .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), }; #endif