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