1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * MSMPEG4 encoder backend 3cabdff1aSopenharmony_ci * Copyright (c) 2001 Fabrice Bellard 4cabdff1aSopenharmony_ci * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * This file is part of FFmpeg. 9cabdff1aSopenharmony_ci * 10cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 11cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 12cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 13cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 14cabdff1aSopenharmony_ci * 15cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 16cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 17cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18cabdff1aSopenharmony_ci * Lesser General Public License for more details. 19cabdff1aSopenharmony_ci * 20cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 21cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 22cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23cabdff1aSopenharmony_ci */ 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci/** 26cabdff1aSopenharmony_ci * @file 27cabdff1aSopenharmony_ci * MSMPEG4 encoder backend 28cabdff1aSopenharmony_ci */ 29cabdff1aSopenharmony_ci 30cabdff1aSopenharmony_ci#include <stdint.h> 31cabdff1aSopenharmony_ci#include <string.h> 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 34cabdff1aSopenharmony_ci#include "libavutil/avutil.h" 35cabdff1aSopenharmony_ci#include "libavutil/thread.h" 36cabdff1aSopenharmony_ci#include "codec_internal.h" 37cabdff1aSopenharmony_ci#include "mpegvideo.h" 38cabdff1aSopenharmony_ci#include "mpegvideoenc.h" 39cabdff1aSopenharmony_ci#include "h263.h" 40cabdff1aSopenharmony_ci#include "h263data.h" 41cabdff1aSopenharmony_ci#include "mpeg4video.h" 42cabdff1aSopenharmony_ci#include "msmpeg4.h" 43cabdff1aSopenharmony_ci#include "msmpeg4data.h" 44cabdff1aSopenharmony_ci#include "msmpeg4enc.h" 45cabdff1aSopenharmony_ci#include "put_bits.h" 46cabdff1aSopenharmony_ci#include "rl.h" 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_cistatic uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2]; 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_ci/* build the table which associate a (x,y) motion vector to a vlc */ 51cabdff1aSopenharmony_cistatic av_cold void init_mv_table(MVTable *tab, uint16_t table_mv_index[4096]) 52cabdff1aSopenharmony_ci{ 53cabdff1aSopenharmony_ci int i, x, y; 54cabdff1aSopenharmony_ci 55cabdff1aSopenharmony_ci tab->table_mv_index = table_mv_index; 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci /* mark all entries as not used */ 58cabdff1aSopenharmony_ci for(i=0;i<4096;i++) 59cabdff1aSopenharmony_ci tab->table_mv_index[i] = MSMPEG4_MV_TABLES_NB_ELEMS; 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci for (i = 0; i < MSMPEG4_MV_TABLES_NB_ELEMS; i++) { 62cabdff1aSopenharmony_ci x = tab->table_mvx[i]; 63cabdff1aSopenharmony_ci y = tab->table_mvy[i]; 64cabdff1aSopenharmony_ci tab->table_mv_index[(x << 6) | y] = i; 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci} 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_civoid ff_msmpeg4_code012(PutBitContext *pb, int n) 69cabdff1aSopenharmony_ci{ 70cabdff1aSopenharmony_ci if (n == 0) { 71cabdff1aSopenharmony_ci put_bits(pb, 1, 0); 72cabdff1aSopenharmony_ci } else { 73cabdff1aSopenharmony_ci put_bits(pb, 1, 1); 74cabdff1aSopenharmony_ci put_bits(pb, 1, (n >= 2)); 75cabdff1aSopenharmony_ci } 76cabdff1aSopenharmony_ci} 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_cistatic int get_size_of_code(const RLTable *rl, int last, int run, 79cabdff1aSopenharmony_ci int level, int intra) 80cabdff1aSopenharmony_ci{ 81cabdff1aSopenharmony_ci int size=0; 82cabdff1aSopenharmony_ci int code; 83cabdff1aSopenharmony_ci int run_diff= intra ? 0 : 1; 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci code = get_rl_index(rl, last, run, level); 86cabdff1aSopenharmony_ci size+= rl->table_vlc[code][1]; 87cabdff1aSopenharmony_ci if (code == rl->n) { 88cabdff1aSopenharmony_ci int level1, run1; 89cabdff1aSopenharmony_ci 90cabdff1aSopenharmony_ci level1 = level - rl->max_level[last][run]; 91cabdff1aSopenharmony_ci if (level1 < 1) 92cabdff1aSopenharmony_ci goto esc2; 93cabdff1aSopenharmony_ci code = get_rl_index(rl, last, run, level1); 94cabdff1aSopenharmony_ci if (code == rl->n) { 95cabdff1aSopenharmony_ci esc2: 96cabdff1aSopenharmony_ci size++; 97cabdff1aSopenharmony_ci if (level > MAX_LEVEL) 98cabdff1aSopenharmony_ci goto esc3; 99cabdff1aSopenharmony_ci run1 = run - rl->max_run[last][level] - run_diff; 100cabdff1aSopenharmony_ci if (run1 < 0) 101cabdff1aSopenharmony_ci goto esc3; 102cabdff1aSopenharmony_ci code = get_rl_index(rl, last, run1, level); 103cabdff1aSopenharmony_ci if (code == rl->n) { 104cabdff1aSopenharmony_ci esc3: 105cabdff1aSopenharmony_ci /* third escape */ 106cabdff1aSopenharmony_ci size+=1+1+6+8; 107cabdff1aSopenharmony_ci } else { 108cabdff1aSopenharmony_ci /* second escape */ 109cabdff1aSopenharmony_ci size+= 1+1+ rl->table_vlc[code][1]; 110cabdff1aSopenharmony_ci } 111cabdff1aSopenharmony_ci } else { 112cabdff1aSopenharmony_ci /* first escape */ 113cabdff1aSopenharmony_ci size+= 1+1+ rl->table_vlc[code][1]; 114cabdff1aSopenharmony_ci } 115cabdff1aSopenharmony_ci } else { 116cabdff1aSopenharmony_ci size++; 117cabdff1aSopenharmony_ci } 118cabdff1aSopenharmony_ci return size; 119cabdff1aSopenharmony_ci} 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_cistatic av_cold void msmpeg4_encode_init_static(void) 122cabdff1aSopenharmony_ci{ 123cabdff1aSopenharmony_ci static uint16_t mv_index_tables[2][4096]; 124cabdff1aSopenharmony_ci init_mv_table(&ff_mv_tables[0], mv_index_tables[0]); 125cabdff1aSopenharmony_ci init_mv_table(&ff_mv_tables[1], mv_index_tables[1]); 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci for (int i = 0; i < NB_RL_TABLES; i++) { 128cabdff1aSopenharmony_ci for (int level = 1; level <= MAX_LEVEL; level++) { 129cabdff1aSopenharmony_ci for (int run = 0; run <= MAX_RUN; run++) { 130cabdff1aSopenharmony_ci for (int last = 0; last < 2; last++) { 131cabdff1aSopenharmony_ci rl_length[i][level][run][last] = get_size_of_code(&ff_rl_table[i], last, run, level, 0); 132cabdff1aSopenharmony_ci } 133cabdff1aSopenharmony_ci } 134cabdff1aSopenharmony_ci } 135cabdff1aSopenharmony_ci } 136cabdff1aSopenharmony_ci} 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ciav_cold void ff_msmpeg4_encode_init(MpegEncContext *s) 139cabdff1aSopenharmony_ci{ 140cabdff1aSopenharmony_ci static AVOnce init_static_once = AV_ONCE_INIT; 141cabdff1aSopenharmony_ci 142cabdff1aSopenharmony_ci ff_msmpeg4_common_init(s); 143cabdff1aSopenharmony_ci if (s->msmpeg4_version >= 4) { 144cabdff1aSopenharmony_ci s->min_qcoeff = -255; 145cabdff1aSopenharmony_ci s->max_qcoeff = 255; 146cabdff1aSopenharmony_ci } 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci /* init various encoding tables */ 149cabdff1aSopenharmony_ci ff_thread_once(&init_static_once, msmpeg4_encode_init_static); 150cabdff1aSopenharmony_ci} 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_cistatic void find_best_tables(MSMPEG4EncContext *ms) 153cabdff1aSopenharmony_ci{ 154cabdff1aSopenharmony_ci MpegEncContext *const s = &ms->s; 155cabdff1aSopenharmony_ci int i; 156cabdff1aSopenharmony_ci int best = 0, best_size = INT_MAX; 157cabdff1aSopenharmony_ci int chroma_best = 0, best_chroma_size = INT_MAX; 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci for(i=0; i<3; i++){ 160cabdff1aSopenharmony_ci int level; 161cabdff1aSopenharmony_ci int chroma_size=0; 162cabdff1aSopenharmony_ci int size=0; 163cabdff1aSopenharmony_ci 164cabdff1aSopenharmony_ci if(i>0){// ;) 165cabdff1aSopenharmony_ci size++; 166cabdff1aSopenharmony_ci chroma_size++; 167cabdff1aSopenharmony_ci } 168cabdff1aSopenharmony_ci for(level=0; level<=MAX_LEVEL; level++){ 169cabdff1aSopenharmony_ci int run; 170cabdff1aSopenharmony_ci for(run=0; run<=MAX_RUN; run++){ 171cabdff1aSopenharmony_ci int last; 172cabdff1aSopenharmony_ci const int last_size= size + chroma_size; 173cabdff1aSopenharmony_ci for(last=0; last<2; last++){ 174cabdff1aSopenharmony_ci int inter_count = ms->ac_stats[0][0][level][run][last] + ms->ac_stats[0][1][level][run][last]; 175cabdff1aSopenharmony_ci int intra_luma_count = ms->ac_stats[1][0][level][run][last]; 176cabdff1aSopenharmony_ci int intra_chroma_count= ms->ac_stats[1][1][level][run][last]; 177cabdff1aSopenharmony_ci 178cabdff1aSopenharmony_ci if(s->pict_type==AV_PICTURE_TYPE_I){ 179cabdff1aSopenharmony_ci size += intra_luma_count *rl_length[i ][level][run][last]; 180cabdff1aSopenharmony_ci chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last]; 181cabdff1aSopenharmony_ci }else{ 182cabdff1aSopenharmony_ci size+= intra_luma_count *rl_length[i ][level][run][last] 183cabdff1aSopenharmony_ci +intra_chroma_count*rl_length[i+3][level][run][last] 184cabdff1aSopenharmony_ci +inter_count *rl_length[i+3][level][run][last]; 185cabdff1aSopenharmony_ci } 186cabdff1aSopenharmony_ci } 187cabdff1aSopenharmony_ci if(last_size == size+chroma_size) break; 188cabdff1aSopenharmony_ci } 189cabdff1aSopenharmony_ci } 190cabdff1aSopenharmony_ci if(size<best_size){ 191cabdff1aSopenharmony_ci best_size= size; 192cabdff1aSopenharmony_ci best= i; 193cabdff1aSopenharmony_ci } 194cabdff1aSopenharmony_ci if(chroma_size<best_chroma_size){ 195cabdff1aSopenharmony_ci best_chroma_size= chroma_size; 196cabdff1aSopenharmony_ci chroma_best= i; 197cabdff1aSopenharmony_ci } 198cabdff1aSopenharmony_ci } 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci if(s->pict_type==AV_PICTURE_TYPE_P) chroma_best= best; 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci memset(ms->ac_stats, 0, sizeof(ms->ac_stats)); 203cabdff1aSopenharmony_ci 204cabdff1aSopenharmony_ci s->rl_table_index = best; 205cabdff1aSopenharmony_ci s->rl_chroma_table_index= chroma_best; 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci if(s->pict_type != s->last_non_b_pict_type){ 208cabdff1aSopenharmony_ci s->rl_table_index= 2; 209cabdff1aSopenharmony_ci if(s->pict_type==AV_PICTURE_TYPE_I) 210cabdff1aSopenharmony_ci s->rl_chroma_table_index= 1; 211cabdff1aSopenharmony_ci else 212cabdff1aSopenharmony_ci s->rl_chroma_table_index= 2; 213cabdff1aSopenharmony_ci } 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci} 216cabdff1aSopenharmony_ci 217cabdff1aSopenharmony_ci/* write MSMPEG4 compatible frame header */ 218cabdff1aSopenharmony_civoid ff_msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) 219cabdff1aSopenharmony_ci{ 220cabdff1aSopenharmony_ci MSMPEG4EncContext *const ms = (MSMPEG4EncContext*)s; 221cabdff1aSopenharmony_ci 222cabdff1aSopenharmony_ci find_best_tables(ms); 223cabdff1aSopenharmony_ci 224cabdff1aSopenharmony_ci align_put_bits(&s->pb); 225cabdff1aSopenharmony_ci put_bits(&s->pb, 2, s->pict_type - 1); 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_ci put_bits(&s->pb, 5, s->qscale); 228cabdff1aSopenharmony_ci if(s->msmpeg4_version<=2){ 229cabdff1aSopenharmony_ci s->rl_table_index = 2; 230cabdff1aSopenharmony_ci s->rl_chroma_table_index = 2; 231cabdff1aSopenharmony_ci } 232cabdff1aSopenharmony_ci 233cabdff1aSopenharmony_ci s->dc_table_index = 1; 234cabdff1aSopenharmony_ci s->mv_table_index = 1; /* only if P-frame */ 235cabdff1aSopenharmony_ci s->use_skip_mb_code = 1; /* only if P-frame */ 236cabdff1aSopenharmony_ci s->per_mb_rl_table = 0; 237cabdff1aSopenharmony_ci if(s->msmpeg4_version==4) 238cabdff1aSopenharmony_ci s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE && s->pict_type==AV_PICTURE_TYPE_P); 239cabdff1aSopenharmony_ci ff_dlog(s, "%d %"PRId64" %d %d %d\n", s->pict_type, s->bit_rate, 240cabdff1aSopenharmony_ci s->inter_intra_pred, s->width, s->height); 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_I) { 243cabdff1aSopenharmony_ci s->slice_height= s->mb_height/1; 244cabdff1aSopenharmony_ci put_bits(&s->pb, 5, 0x16 + s->mb_height/s->slice_height); 245cabdff1aSopenharmony_ci 246cabdff1aSopenharmony_ci if(s->msmpeg4_version==4){ 247cabdff1aSopenharmony_ci ff_msmpeg4_encode_ext_header(s); 248cabdff1aSopenharmony_ci if(s->bit_rate>MBAC_BITRATE) 249cabdff1aSopenharmony_ci put_bits(&s->pb, 1, s->per_mb_rl_table); 250cabdff1aSopenharmony_ci } 251cabdff1aSopenharmony_ci 252cabdff1aSopenharmony_ci if(s->msmpeg4_version>2){ 253cabdff1aSopenharmony_ci if(!s->per_mb_rl_table){ 254cabdff1aSopenharmony_ci ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index); 255cabdff1aSopenharmony_ci ff_msmpeg4_code012(&s->pb, s->rl_table_index); 256cabdff1aSopenharmony_ci } 257cabdff1aSopenharmony_ci 258cabdff1aSopenharmony_ci put_bits(&s->pb, 1, s->dc_table_index); 259cabdff1aSopenharmony_ci } 260cabdff1aSopenharmony_ci } else { 261cabdff1aSopenharmony_ci put_bits(&s->pb, 1, s->use_skip_mb_code); 262cabdff1aSopenharmony_ci 263cabdff1aSopenharmony_ci if(s->msmpeg4_version==4 && s->bit_rate>MBAC_BITRATE) 264cabdff1aSopenharmony_ci put_bits(&s->pb, 1, s->per_mb_rl_table); 265cabdff1aSopenharmony_ci 266cabdff1aSopenharmony_ci if(s->msmpeg4_version>2){ 267cabdff1aSopenharmony_ci if(!s->per_mb_rl_table) 268cabdff1aSopenharmony_ci ff_msmpeg4_code012(&s->pb, s->rl_table_index); 269cabdff1aSopenharmony_ci 270cabdff1aSopenharmony_ci put_bits(&s->pb, 1, s->dc_table_index); 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci put_bits(&s->pb, 1, s->mv_table_index); 273cabdff1aSopenharmony_ci } 274cabdff1aSopenharmony_ci } 275cabdff1aSopenharmony_ci 276cabdff1aSopenharmony_ci s->esc3_level_length= 0; 277cabdff1aSopenharmony_ci s->esc3_run_length= 0; 278cabdff1aSopenharmony_ci} 279cabdff1aSopenharmony_ci 280cabdff1aSopenharmony_civoid ff_msmpeg4_encode_ext_header(MpegEncContext * s) 281cabdff1aSopenharmony_ci{ 282cabdff1aSopenharmony_ci unsigned fps = s->avctx->time_base.den / s->avctx->time_base.num / FFMAX(s->avctx->ticks_per_frame, 1); 283cabdff1aSopenharmony_ci put_bits(&s->pb, 5, FFMIN(fps, 31)); //yes 29.97 -> 29 284cabdff1aSopenharmony_ci 285cabdff1aSopenharmony_ci put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047)); 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci if(s->msmpeg4_version>=3) 288cabdff1aSopenharmony_ci put_bits(&s->pb, 1, s->flipflop_rounding); 289cabdff1aSopenharmony_ci else 290cabdff1aSopenharmony_ci av_assert0(s->flipflop_rounding==0); 291cabdff1aSopenharmony_ci} 292cabdff1aSopenharmony_ci 293cabdff1aSopenharmony_civoid ff_msmpeg4_encode_motion(MpegEncContext * s, 294cabdff1aSopenharmony_ci int mx, int my) 295cabdff1aSopenharmony_ci{ 296cabdff1aSopenharmony_ci int code; 297cabdff1aSopenharmony_ci MVTable *mv; 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_ci /* modulo encoding */ 300cabdff1aSopenharmony_ci /* WARNING : you cannot reach all the MVs even with the modulo 301cabdff1aSopenharmony_ci encoding. This is a somewhat strange compromise they took !!! */ 302cabdff1aSopenharmony_ci if (mx <= -64) 303cabdff1aSopenharmony_ci mx += 64; 304cabdff1aSopenharmony_ci else if (mx >= 64) 305cabdff1aSopenharmony_ci mx -= 64; 306cabdff1aSopenharmony_ci if (my <= -64) 307cabdff1aSopenharmony_ci my += 64; 308cabdff1aSopenharmony_ci else if (my >= 64) 309cabdff1aSopenharmony_ci my -= 64; 310cabdff1aSopenharmony_ci 311cabdff1aSopenharmony_ci mx += 32; 312cabdff1aSopenharmony_ci my += 32; 313cabdff1aSopenharmony_ci mv = &ff_mv_tables[s->mv_table_index]; 314cabdff1aSopenharmony_ci 315cabdff1aSopenharmony_ci code = mv->table_mv_index[(mx << 6) | my]; 316cabdff1aSopenharmony_ci put_bits(&s->pb, 317cabdff1aSopenharmony_ci mv->table_mv_bits[code], 318cabdff1aSopenharmony_ci mv->table_mv_code[code]); 319cabdff1aSopenharmony_ci if (code == MSMPEG4_MV_TABLES_NB_ELEMS) { 320cabdff1aSopenharmony_ci /* escape : code literally */ 321cabdff1aSopenharmony_ci put_bits(&s->pb, 6, mx); 322cabdff1aSopenharmony_ci put_bits(&s->pb, 6, my); 323cabdff1aSopenharmony_ci } 324cabdff1aSopenharmony_ci} 325cabdff1aSopenharmony_ci 326cabdff1aSopenharmony_civoid ff_msmpeg4_handle_slices(MpegEncContext *s){ 327cabdff1aSopenharmony_ci if (s->mb_x == 0) { 328cabdff1aSopenharmony_ci if (s->slice_height && (s->mb_y % s->slice_height) == 0) { 329cabdff1aSopenharmony_ci if(s->msmpeg4_version < 4){ 330cabdff1aSopenharmony_ci ff_mpeg4_clean_buffers(s); 331cabdff1aSopenharmony_ci } 332cabdff1aSopenharmony_ci s->first_slice_line = 1; 333cabdff1aSopenharmony_ci } else { 334cabdff1aSopenharmony_ci s->first_slice_line = 0; 335cabdff1aSopenharmony_ci } 336cabdff1aSopenharmony_ci } 337cabdff1aSopenharmony_ci} 338cabdff1aSopenharmony_ci 339cabdff1aSopenharmony_cistatic void msmpeg4v2_encode_motion(MpegEncContext * s, int val) 340cabdff1aSopenharmony_ci{ 341cabdff1aSopenharmony_ci int range, bit_size, sign, code, bits; 342cabdff1aSopenharmony_ci 343cabdff1aSopenharmony_ci if (val == 0) { 344cabdff1aSopenharmony_ci /* zero vector */ 345cabdff1aSopenharmony_ci code = 0; 346cabdff1aSopenharmony_ci put_bits(&s->pb, ff_mvtab[code][1], ff_mvtab[code][0]); 347cabdff1aSopenharmony_ci } else { 348cabdff1aSopenharmony_ci bit_size = s->f_code - 1; 349cabdff1aSopenharmony_ci range = 1 << bit_size; 350cabdff1aSopenharmony_ci if (val <= -64) 351cabdff1aSopenharmony_ci val += 64; 352cabdff1aSopenharmony_ci else if (val >= 64) 353cabdff1aSopenharmony_ci val -= 64; 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_ci if (val >= 0) { 356cabdff1aSopenharmony_ci sign = 0; 357cabdff1aSopenharmony_ci } else { 358cabdff1aSopenharmony_ci val = -val; 359cabdff1aSopenharmony_ci sign = 1; 360cabdff1aSopenharmony_ci } 361cabdff1aSopenharmony_ci val--; 362cabdff1aSopenharmony_ci code = (val >> bit_size) + 1; 363cabdff1aSopenharmony_ci bits = val & (range - 1); 364cabdff1aSopenharmony_ci 365cabdff1aSopenharmony_ci put_bits(&s->pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign); 366cabdff1aSopenharmony_ci if (bit_size > 0) { 367cabdff1aSopenharmony_ci put_bits(&s->pb, bit_size, bits); 368cabdff1aSopenharmony_ci } 369cabdff1aSopenharmony_ci } 370cabdff1aSopenharmony_ci} 371cabdff1aSopenharmony_ci 372cabdff1aSopenharmony_civoid ff_msmpeg4_encode_mb(MpegEncContext * s, 373cabdff1aSopenharmony_ci int16_t block[6][64], 374cabdff1aSopenharmony_ci int motion_x, int motion_y) 375cabdff1aSopenharmony_ci{ 376cabdff1aSopenharmony_ci int cbp, coded_cbp, i; 377cabdff1aSopenharmony_ci int pred_x, pred_y; 378cabdff1aSopenharmony_ci uint8_t *coded_block; 379cabdff1aSopenharmony_ci 380cabdff1aSopenharmony_ci ff_msmpeg4_handle_slices(s); 381cabdff1aSopenharmony_ci 382cabdff1aSopenharmony_ci if (!s->mb_intra) { 383cabdff1aSopenharmony_ci /* compute cbp */ 384cabdff1aSopenharmony_ci cbp = 0; 385cabdff1aSopenharmony_ci for (i = 0; i < 6; i++) { 386cabdff1aSopenharmony_ci if (s->block_last_index[i] >= 0) 387cabdff1aSopenharmony_ci cbp |= 1 << (5 - i); 388cabdff1aSopenharmony_ci } 389cabdff1aSopenharmony_ci if (s->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) { 390cabdff1aSopenharmony_ci /* skip macroblock */ 391cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 1); 392cabdff1aSopenharmony_ci s->last_bits++; 393cabdff1aSopenharmony_ci s->misc_bits++; 394cabdff1aSopenharmony_ci s->skip_count++; 395cabdff1aSopenharmony_ci 396cabdff1aSopenharmony_ci return; 397cabdff1aSopenharmony_ci } 398cabdff1aSopenharmony_ci if (s->use_skip_mb_code) 399cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 0); /* mb coded */ 400cabdff1aSopenharmony_ci 401cabdff1aSopenharmony_ci if(s->msmpeg4_version<=2){ 402cabdff1aSopenharmony_ci put_bits(&s->pb, 403cabdff1aSopenharmony_ci ff_v2_mb_type[cbp&3][1], 404cabdff1aSopenharmony_ci ff_v2_mb_type[cbp&3][0]); 405cabdff1aSopenharmony_ci if((cbp&3) != 3) coded_cbp= cbp ^ 0x3C; 406cabdff1aSopenharmony_ci else coded_cbp= cbp; 407cabdff1aSopenharmony_ci 408cabdff1aSopenharmony_ci put_bits(&s->pb, 409cabdff1aSopenharmony_ci ff_h263_cbpy_tab[coded_cbp>>2][1], 410cabdff1aSopenharmony_ci ff_h263_cbpy_tab[coded_cbp>>2][0]); 411cabdff1aSopenharmony_ci 412cabdff1aSopenharmony_ci s->misc_bits += get_bits_diff(s); 413cabdff1aSopenharmony_ci 414cabdff1aSopenharmony_ci ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); 415cabdff1aSopenharmony_ci msmpeg4v2_encode_motion(s, motion_x - pred_x); 416cabdff1aSopenharmony_ci msmpeg4v2_encode_motion(s, motion_y - pred_y); 417cabdff1aSopenharmony_ci }else{ 418cabdff1aSopenharmony_ci put_bits(&s->pb, 419cabdff1aSopenharmony_ci ff_table_mb_non_intra[cbp + 64][1], 420cabdff1aSopenharmony_ci ff_table_mb_non_intra[cbp + 64][0]); 421cabdff1aSopenharmony_ci 422cabdff1aSopenharmony_ci s->misc_bits += get_bits_diff(s); 423cabdff1aSopenharmony_ci 424cabdff1aSopenharmony_ci /* motion vector */ 425cabdff1aSopenharmony_ci ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); 426cabdff1aSopenharmony_ci ff_msmpeg4_encode_motion(s, motion_x - pred_x, 427cabdff1aSopenharmony_ci motion_y - pred_y); 428cabdff1aSopenharmony_ci } 429cabdff1aSopenharmony_ci 430cabdff1aSopenharmony_ci s->mv_bits += get_bits_diff(s); 431cabdff1aSopenharmony_ci 432cabdff1aSopenharmony_ci for (i = 0; i < 6; i++) { 433cabdff1aSopenharmony_ci ff_msmpeg4_encode_block(s, block[i], i); 434cabdff1aSopenharmony_ci } 435cabdff1aSopenharmony_ci s->p_tex_bits += get_bits_diff(s); 436cabdff1aSopenharmony_ci } else { 437cabdff1aSopenharmony_ci /* compute cbp */ 438cabdff1aSopenharmony_ci cbp = 0; 439cabdff1aSopenharmony_ci coded_cbp = 0; 440cabdff1aSopenharmony_ci for (i = 0; i < 6; i++) { 441cabdff1aSopenharmony_ci int val, pred; 442cabdff1aSopenharmony_ci val = (s->block_last_index[i] >= 1); 443cabdff1aSopenharmony_ci cbp |= val << (5 - i); 444cabdff1aSopenharmony_ci if (i < 4) { 445cabdff1aSopenharmony_ci /* predict value for close blocks only for luma */ 446cabdff1aSopenharmony_ci pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); 447cabdff1aSopenharmony_ci *coded_block = val; 448cabdff1aSopenharmony_ci val = val ^ pred; 449cabdff1aSopenharmony_ci } 450cabdff1aSopenharmony_ci coded_cbp |= val << (5 - i); 451cabdff1aSopenharmony_ci } 452cabdff1aSopenharmony_ci 453cabdff1aSopenharmony_ci if(s->msmpeg4_version<=2){ 454cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_I) { 455cabdff1aSopenharmony_ci put_bits(&s->pb, 456cabdff1aSopenharmony_ci ff_v2_intra_cbpc[cbp&3][1], ff_v2_intra_cbpc[cbp&3][0]); 457cabdff1aSopenharmony_ci } else { 458cabdff1aSopenharmony_ci if (s->use_skip_mb_code) 459cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 0); /* mb coded */ 460cabdff1aSopenharmony_ci put_bits(&s->pb, 461cabdff1aSopenharmony_ci ff_v2_mb_type[(cbp&3) + 4][1], 462cabdff1aSopenharmony_ci ff_v2_mb_type[(cbp&3) + 4][0]); 463cabdff1aSopenharmony_ci } 464cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 0); /* no AC prediction yet */ 465cabdff1aSopenharmony_ci put_bits(&s->pb, 466cabdff1aSopenharmony_ci ff_h263_cbpy_tab[cbp>>2][1], 467cabdff1aSopenharmony_ci ff_h263_cbpy_tab[cbp>>2][0]); 468cabdff1aSopenharmony_ci }else{ 469cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_I) { 470cabdff1aSopenharmony_ci put_bits(&s->pb, 471cabdff1aSopenharmony_ci ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); 472cabdff1aSopenharmony_ci } else { 473cabdff1aSopenharmony_ci if (s->use_skip_mb_code) 474cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 0); /* mb coded */ 475cabdff1aSopenharmony_ci put_bits(&s->pb, 476cabdff1aSopenharmony_ci ff_table_mb_non_intra[cbp][1], 477cabdff1aSopenharmony_ci ff_table_mb_non_intra[cbp][0]); 478cabdff1aSopenharmony_ci } 479cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 0); /* no AC prediction yet */ 480cabdff1aSopenharmony_ci if(s->inter_intra_pred){ 481cabdff1aSopenharmony_ci s->h263_aic_dir=0; 482cabdff1aSopenharmony_ci put_bits(&s->pb, ff_table_inter_intra[s->h263_aic_dir][1], ff_table_inter_intra[s->h263_aic_dir][0]); 483cabdff1aSopenharmony_ci } 484cabdff1aSopenharmony_ci } 485cabdff1aSopenharmony_ci s->misc_bits += get_bits_diff(s); 486cabdff1aSopenharmony_ci 487cabdff1aSopenharmony_ci for (i = 0; i < 6; i++) { 488cabdff1aSopenharmony_ci ff_msmpeg4_encode_block(s, block[i], i); 489cabdff1aSopenharmony_ci } 490cabdff1aSopenharmony_ci s->i_tex_bits += get_bits_diff(s); 491cabdff1aSopenharmony_ci s->i_count++; 492cabdff1aSopenharmony_ci } 493cabdff1aSopenharmony_ci} 494cabdff1aSopenharmony_ci 495cabdff1aSopenharmony_cistatic void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr) 496cabdff1aSopenharmony_ci{ 497cabdff1aSopenharmony_ci int sign, code; 498cabdff1aSopenharmony_ci int pred; 499cabdff1aSopenharmony_ci 500cabdff1aSopenharmony_ci int16_t *dc_val; 501cabdff1aSopenharmony_ci pred = ff_msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); 502cabdff1aSopenharmony_ci 503cabdff1aSopenharmony_ci /* update predictor */ 504cabdff1aSopenharmony_ci if (n < 4) { 505cabdff1aSopenharmony_ci *dc_val = level * s->y_dc_scale; 506cabdff1aSopenharmony_ci } else { 507cabdff1aSopenharmony_ci *dc_val = level * s->c_dc_scale; 508cabdff1aSopenharmony_ci } 509cabdff1aSopenharmony_ci 510cabdff1aSopenharmony_ci /* do the prediction */ 511cabdff1aSopenharmony_ci level -= pred; 512cabdff1aSopenharmony_ci 513cabdff1aSopenharmony_ci if(s->msmpeg4_version<=2){ 514cabdff1aSopenharmony_ci if (n < 4) { 515cabdff1aSopenharmony_ci put_bits(&s->pb, 516cabdff1aSopenharmony_ci ff_v2_dc_lum_table[level + 256][1], 517cabdff1aSopenharmony_ci ff_v2_dc_lum_table[level + 256][0]); 518cabdff1aSopenharmony_ci }else{ 519cabdff1aSopenharmony_ci put_bits(&s->pb, 520cabdff1aSopenharmony_ci ff_v2_dc_chroma_table[level + 256][1], 521cabdff1aSopenharmony_ci ff_v2_dc_chroma_table[level + 256][0]); 522cabdff1aSopenharmony_ci } 523cabdff1aSopenharmony_ci }else{ 524cabdff1aSopenharmony_ci sign = 0; 525cabdff1aSopenharmony_ci if (level < 0) { 526cabdff1aSopenharmony_ci level = -level; 527cabdff1aSopenharmony_ci sign = 1; 528cabdff1aSopenharmony_ci } 529cabdff1aSopenharmony_ci code = level; 530cabdff1aSopenharmony_ci if (code > DC_MAX) 531cabdff1aSopenharmony_ci code = DC_MAX; 532cabdff1aSopenharmony_ci 533cabdff1aSopenharmony_ci if (s->dc_table_index == 0) { 534cabdff1aSopenharmony_ci if (n < 4) { 535cabdff1aSopenharmony_ci put_bits(&s->pb, ff_table0_dc_lum[code][1], ff_table0_dc_lum[code][0]); 536cabdff1aSopenharmony_ci } else { 537cabdff1aSopenharmony_ci put_bits(&s->pb, ff_table0_dc_chroma[code][1], ff_table0_dc_chroma[code][0]); 538cabdff1aSopenharmony_ci } 539cabdff1aSopenharmony_ci } else { 540cabdff1aSopenharmony_ci if (n < 4) { 541cabdff1aSopenharmony_ci put_bits(&s->pb, ff_table1_dc_lum[code][1], ff_table1_dc_lum[code][0]); 542cabdff1aSopenharmony_ci } else { 543cabdff1aSopenharmony_ci put_bits(&s->pb, ff_table1_dc_chroma[code][1], ff_table1_dc_chroma[code][0]); 544cabdff1aSopenharmony_ci } 545cabdff1aSopenharmony_ci } 546cabdff1aSopenharmony_ci 547cabdff1aSopenharmony_ci if (code == DC_MAX) 548cabdff1aSopenharmony_ci put_bits(&s->pb, 8, level); 549cabdff1aSopenharmony_ci 550cabdff1aSopenharmony_ci if (level != 0) { 551cabdff1aSopenharmony_ci put_bits(&s->pb, 1, sign); 552cabdff1aSopenharmony_ci } 553cabdff1aSopenharmony_ci } 554cabdff1aSopenharmony_ci} 555cabdff1aSopenharmony_ci 556cabdff1aSopenharmony_ci/* Encoding of a block; very similar to MPEG-4 except for a different 557cabdff1aSopenharmony_ci * escape coding (same as H.263) and more VLC tables. */ 558cabdff1aSopenharmony_civoid ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n) 559cabdff1aSopenharmony_ci{ 560cabdff1aSopenharmony_ci MSMPEG4EncContext *const ms = (MSMPEG4EncContext*)s; 561cabdff1aSopenharmony_ci int level, run, last, i, j, last_index; 562cabdff1aSopenharmony_ci int last_non_zero, sign, slevel; 563cabdff1aSopenharmony_ci int code, run_diff, dc_pred_dir; 564cabdff1aSopenharmony_ci const RLTable *rl; 565cabdff1aSopenharmony_ci const uint8_t *scantable; 566cabdff1aSopenharmony_ci 567cabdff1aSopenharmony_ci if (s->mb_intra) { 568cabdff1aSopenharmony_ci msmpeg4_encode_dc(s, block[0], n, &dc_pred_dir); 569cabdff1aSopenharmony_ci i = 1; 570cabdff1aSopenharmony_ci if (n < 4) { 571cabdff1aSopenharmony_ci rl = &ff_rl_table[s->rl_table_index]; 572cabdff1aSopenharmony_ci } else { 573cabdff1aSopenharmony_ci rl = &ff_rl_table[3 + s->rl_chroma_table_index]; 574cabdff1aSopenharmony_ci } 575cabdff1aSopenharmony_ci run_diff = s->msmpeg4_version>=4; 576cabdff1aSopenharmony_ci scantable= s->intra_scantable.permutated; 577cabdff1aSopenharmony_ci } else { 578cabdff1aSopenharmony_ci i = 0; 579cabdff1aSopenharmony_ci rl = &ff_rl_table[3 + s->rl_table_index]; 580cabdff1aSopenharmony_ci if(s->msmpeg4_version<=2) 581cabdff1aSopenharmony_ci run_diff = 0; 582cabdff1aSopenharmony_ci else 583cabdff1aSopenharmony_ci run_diff = 1; 584cabdff1aSopenharmony_ci scantable= s->inter_scantable.permutated; 585cabdff1aSopenharmony_ci } 586cabdff1aSopenharmony_ci 587cabdff1aSopenharmony_ci /* recalculate block_last_index for M$ wmv1 */ 588cabdff1aSopenharmony_ci if (s->msmpeg4_version >= 4 && s->block_last_index[n] > 0) { 589cabdff1aSopenharmony_ci for(last_index=63; last_index>=0; last_index--){ 590cabdff1aSopenharmony_ci if(block[scantable[last_index]]) break; 591cabdff1aSopenharmony_ci } 592cabdff1aSopenharmony_ci s->block_last_index[n]= last_index; 593cabdff1aSopenharmony_ci }else 594cabdff1aSopenharmony_ci last_index = s->block_last_index[n]; 595cabdff1aSopenharmony_ci /* AC coefs */ 596cabdff1aSopenharmony_ci last_non_zero = i - 1; 597cabdff1aSopenharmony_ci for (; i <= last_index; i++) { 598cabdff1aSopenharmony_ci j = scantable[i]; 599cabdff1aSopenharmony_ci level = block[j]; 600cabdff1aSopenharmony_ci if (level) { 601cabdff1aSopenharmony_ci run = i - last_non_zero - 1; 602cabdff1aSopenharmony_ci last = (i == last_index); 603cabdff1aSopenharmony_ci sign = 0; 604cabdff1aSopenharmony_ci slevel = level; 605cabdff1aSopenharmony_ci if (level < 0) { 606cabdff1aSopenharmony_ci sign = 1; 607cabdff1aSopenharmony_ci level = -level; 608cabdff1aSopenharmony_ci } 609cabdff1aSopenharmony_ci 610cabdff1aSopenharmony_ci if(level<=MAX_LEVEL && run<=MAX_RUN){ 611cabdff1aSopenharmony_ci ms->ac_stats[s->mb_intra][n>3][level][run][last]++; 612cabdff1aSopenharmony_ci } 613cabdff1aSopenharmony_ci 614cabdff1aSopenharmony_ci ms->ac_stats[s->mb_intra][n > 3][40][63][0]++; //esc3 like 615cabdff1aSopenharmony_ci 616cabdff1aSopenharmony_ci code = get_rl_index(rl, last, run, level); 617cabdff1aSopenharmony_ci put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); 618cabdff1aSopenharmony_ci if (code == rl->n) { 619cabdff1aSopenharmony_ci int level1, run1; 620cabdff1aSopenharmony_ci 621cabdff1aSopenharmony_ci level1 = level - rl->max_level[last][run]; 622cabdff1aSopenharmony_ci if (level1 < 1) 623cabdff1aSopenharmony_ci goto esc2; 624cabdff1aSopenharmony_ci code = get_rl_index(rl, last, run, level1); 625cabdff1aSopenharmony_ci if (code == rl->n) { 626cabdff1aSopenharmony_ci esc2: 627cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 0); 628cabdff1aSopenharmony_ci if (level > MAX_LEVEL) 629cabdff1aSopenharmony_ci goto esc3; 630cabdff1aSopenharmony_ci run1 = run - rl->max_run[last][level] - run_diff; 631cabdff1aSopenharmony_ci if (run1 < 0) 632cabdff1aSopenharmony_ci goto esc3; 633cabdff1aSopenharmony_ci code = get_rl_index(rl, last, run1+1, level); 634cabdff1aSopenharmony_ci if (s->msmpeg4_version == 4 && code == rl->n) 635cabdff1aSopenharmony_ci goto esc3; 636cabdff1aSopenharmony_ci code = get_rl_index(rl, last, run1, level); 637cabdff1aSopenharmony_ci if (code == rl->n) { 638cabdff1aSopenharmony_ci esc3: 639cabdff1aSopenharmony_ci /* third escape */ 640cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 0); 641cabdff1aSopenharmony_ci put_bits(&s->pb, 1, last); 642cabdff1aSopenharmony_ci if(s->msmpeg4_version>=4){ 643cabdff1aSopenharmony_ci if(s->esc3_level_length==0){ 644cabdff1aSopenharmony_ci s->esc3_level_length=8; 645cabdff1aSopenharmony_ci s->esc3_run_length= 6; 646cabdff1aSopenharmony_ci //ESCLVLSZ + ESCRUNSZ 647cabdff1aSopenharmony_ci if(s->qscale<8) 648cabdff1aSopenharmony_ci put_bits(&s->pb, 6, 3); 649cabdff1aSopenharmony_ci else 650cabdff1aSopenharmony_ci put_bits(&s->pb, 8, 3); 651cabdff1aSopenharmony_ci } 652cabdff1aSopenharmony_ci put_bits(&s->pb, s->esc3_run_length, run); 653cabdff1aSopenharmony_ci put_bits(&s->pb, 1, sign); 654cabdff1aSopenharmony_ci put_bits(&s->pb, s->esc3_level_length, level); 655cabdff1aSopenharmony_ci }else{ 656cabdff1aSopenharmony_ci put_bits(&s->pb, 6, run); 657cabdff1aSopenharmony_ci put_sbits(&s->pb, 8, slevel); 658cabdff1aSopenharmony_ci } 659cabdff1aSopenharmony_ci } else { 660cabdff1aSopenharmony_ci /* second escape */ 661cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 1); 662cabdff1aSopenharmony_ci put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); 663cabdff1aSopenharmony_ci put_bits(&s->pb, 1, sign); 664cabdff1aSopenharmony_ci } 665cabdff1aSopenharmony_ci } else { 666cabdff1aSopenharmony_ci /* first escape */ 667cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 1); 668cabdff1aSopenharmony_ci put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); 669cabdff1aSopenharmony_ci put_bits(&s->pb, 1, sign); 670cabdff1aSopenharmony_ci } 671cabdff1aSopenharmony_ci } else { 672cabdff1aSopenharmony_ci put_bits(&s->pb, 1, sign); 673cabdff1aSopenharmony_ci } 674cabdff1aSopenharmony_ci last_non_zero = i; 675cabdff1aSopenharmony_ci } 676cabdff1aSopenharmony_ci } 677cabdff1aSopenharmony_ci} 678cabdff1aSopenharmony_ci 679cabdff1aSopenharmony_ciconst FFCodec ff_msmpeg4v2_encoder = { 680cabdff1aSopenharmony_ci .p.name = "msmpeg4v2", 681cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), 682cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 683cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_MSMPEG4V2, 684cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, 685cabdff1aSopenharmony_ci .p.priv_class = &ff_mpv_enc_class, 686cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 687cabdff1aSopenharmony_ci .priv_data_size = sizeof(MSMPEG4EncContext), 688cabdff1aSopenharmony_ci .init = ff_mpv_encode_init, 689cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), 690cabdff1aSopenharmony_ci .close = ff_mpv_encode_end, 691cabdff1aSopenharmony_ci}; 692cabdff1aSopenharmony_ci 693cabdff1aSopenharmony_ciconst FFCodec ff_msmpeg4v3_encoder = { 694cabdff1aSopenharmony_ci .p.name = "msmpeg4", 695cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), 696cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 697cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_MSMPEG4V3, 698cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, 699cabdff1aSopenharmony_ci .p.priv_class = &ff_mpv_enc_class, 700cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 701cabdff1aSopenharmony_ci .priv_data_size = sizeof(MSMPEG4EncContext), 702cabdff1aSopenharmony_ci .init = ff_mpv_encode_init, 703cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), 704cabdff1aSopenharmony_ci .close = ff_mpv_encode_end, 705cabdff1aSopenharmony_ci}; 706cabdff1aSopenharmony_ci 707cabdff1aSopenharmony_ciconst FFCodec ff_wmv1_encoder = { 708cabdff1aSopenharmony_ci .p.name = "wmv1", 709cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 7"), 710cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 711cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_WMV1, 712cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, 713cabdff1aSopenharmony_ci .p.priv_class = &ff_mpv_enc_class, 714cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 715cabdff1aSopenharmony_ci .priv_data_size = sizeof(MSMPEG4EncContext), 716cabdff1aSopenharmony_ci .init = ff_mpv_encode_init, 717cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), 718cabdff1aSopenharmony_ci .close = ff_mpv_encode_end, 719cabdff1aSopenharmony_ci}; 720