/*
* MPEG - 1 / 2 encoder
* Copyright ( c ) 2000 , 2001 Fabrice Bellard
* Copyright ( c ) 2002 - 2004 Michael Niedermayer < michaelni @ 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
*/
/**
* @ file
* MPEG - 1 / 2 encoder
*/
# include <stdint.h>
# include "config.h"
# include "libavutil/attributes.h"
# include "libavutil/avassert.h"
# include "libavutil/log.h"
# include "libavutil/opt.h"
# include "libavutil/thread.h"
# include "libavutil/timecode.h"
# include "libavutil/stereo3d.h"
# include "avcodec.h"
# include "bytestream.h"
# include "mathops.h"
# include "mpeg12.h"
# include "mpeg12data.h"
# include "mpegutils.h"
# include "mpegvideo.h"
# include "profiles.h"
# if CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER
static const uint8_t svcd_scan_offset_placeholder [ ] = {
0x10 , 0x0E , 0x00 , 0x80 , 0x81 , 0x00 , 0x80 ,
0x81 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
} ;
static uint8_t mv_penalty [ MAX_FCODE + 1 ] [ MAX_DMV * 2 + 1 ] ;
static uint8_t fcode_tab [ MAX_MV * 2 + 1 ] ;
static uint8_t uni_mpeg1_ac_vlc_len [ 64 * 64 * 2 ] ;
static uint8_t uni_mpeg2_ac_vlc_len [ 64 * 64 * 2 ] ;
/* simple include everything table for dc, first byte is bits
* number next 3 are code */
static uint32_t mpeg1_lum_dc_uni [ 512 ] ;
static uint32_t mpeg1_chr_dc_uni [ 512 ] ;
# define A53_MAX_CC_COUNT 0x1f
# endif /* CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER */
av_cold void ff_mpeg1_init_uni_ac_vlc ( const RLTable * rl , uint8_t * uni_ac_vlc_len )
{
int i ;
for ( i = 0 ; i < 128 ; i + + ) {
int level = i - 64 ;
int run ;
if ( ! level )
continue ;
for ( run = 0 ; run < 64 ; run + + ) {
int len , code ;
int alevel = FFABS ( level ) ;
if ( alevel > rl - > max_level [ 0 ] [ run ] )
code = 111 ; /* rl->n */
else
code = rl - > index_run [ 0 ] [ run ] + alevel - 1 ;
if ( code < 111 ) { /* rl->n */
/* length of VLC and sign */
len = rl - > table_vlc [ code ] [ 1 ] + 1 ;
} else {
len = rl - > table_vlc [ 111 /* rl->n */ ] [ 1 ] + 6 ;
if ( alevel < 128 )
len + = 8 ;
else
len + = 16 ;
}
uni_ac_vlc_len [ UNI_AC_ENC_INDEX ( run , i ) ] = len ;
}
}
}
# if CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER
static int find_frame_rate_index ( MpegEncContext * s )
{
int i ;
AVRational bestq = ( AVRational ) { 0 , 0 } ;
AVRational ext ;
AVRational target = av_inv_q ( s - > avctx - > time_base ) ;
for ( i = 1 ; i < 14 ; i + + ) {
if ( s - > avctx - > strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL & &
i > = 9 )
break ;
for ( ext . num = 1 ; ext . num < = 4 ; ext . num + + ) {
for ( ext . den = 1 ; ext . den < = 32 ; ext . den + + ) {
AVRational q = av_mul_q ( ext , ff_mpeg12_frame_rate_tab [ i ] ) ;
if ( s - > codec_id ! = AV_CODEC_ID_MPEG2VIDEO & & ( ext . den ! = 1 | | ext . num ! = 1 ) )
continue ;
if ( av_gcd ( ext . den , ext . num ) ! = 1 )
continue ;
if ( bestq . num = = 0
| | av_nearer_q ( target , bestq , q ) < 0
| | ext . num = = 1 & & ext . den = = 1 & & av_nearer_q ( target , bestq , q ) = = 0 ) {
bestq = q ;
s - > frame_rate_index = i ;
s - > mpeg2_frame_rate_ext . num = ext . num ;
s - > mpeg2_frame_rate_ext . den = ext . den ;
}
}
}
}
if ( av_cmp_q ( target , bestq ) )
return - 1 ;
else
return 0 ;
}
static av_cold int encode_init ( AVCodecContext * avctx )
{
int ret ;
MpegEncContext * s = avctx - > priv_data ;
if ( ( ret = ff_mpv_encode_init ( avctx ) ) < 0 )
return ret ;
if ( find_frame_rate_index ( s ) < 0 ) {
if ( s - > strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL ) {
av_log ( avctx , AV_LOG_ERROR , " MPEG-1/2 does not support %d/%d fps \n " ,
avctx - > time_base . den , avctx - > time_base . num ) ;
return AVERROR ( EINVAL ) ;
} else {
av_log ( avctx , AV_LOG_INFO ,
" MPEG-1/2 does not support %d/%d fps, there may be AV sync issues \n " ,
avctx - > time_base . den , avctx - > time_base . num ) ;
}
}
if ( avctx - > profile = = FF_PROFILE_UNKNOWN ) {
if ( avctx - > level ! = FF_LEVEL_UNKNOWN ) {
av_log ( avctx , AV_LOG_ERROR , " Set profile and level \n " ) ;
return AVERROR ( EINVAL ) ;
}
/* Main or 4:2:2 */
avctx - > profile = s - > chroma_format = = CHROMA_420 ? FF_PROFILE_MPEG2_MAIN : FF_PROFILE_MPEG2_422 ;
}
if ( avctx - > level = = FF_LEVEL_UNKNOWN ) {
if ( avctx - > profile = = FF_PROFILE_MPEG2_422 ) { /* 4:2:2 */
if ( avctx - > width < = 720 & & avctx - > height < = 608 )
avctx - > level = 5 ; /* Main */
else
avctx - > level = 2 ; /* High */
} else {
if ( avctx - > profile ! = FF_PROFILE_MPEG2_HIGH & & s - > chroma_format ! = CHROMA_420 ) {
av_log ( avctx , AV_LOG_ERROR ,
" Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling \n " ) ;
return AVERROR ( EINVAL ) ;
}
if ( avctx - > width < = 720 & & avctx - > height < = 576 )
avctx - > level = 8 ; /* Main */
else if ( avctx - > width < = 1440 )
avctx - > level = 6 ; /* High 1440 */
else
avctx - > level = 4 ; /* High */
}
}
if ( ( avctx - > width & 0xFFF ) = = 0 & & ( avctx - > height & 0xFFF ) = = 1 ) {
av_log ( avctx , AV_LOG_ERROR , " Width / Height is invalid for MPEG2 \n " ) ;
return AVERROR ( EINVAL ) ;
}
if ( s - > strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL ) {
if ( ( avctx - > width & 0xFFF ) = = 0 | | ( avctx - > height & 0xFFF ) = = 0 ) {
av_log ( avctx , AV_LOG_ERROR , " Width or Height are not allowed to be multiples of 4096 \n "
" add '-strict %d' if you want to use them anyway. \n " , FF_COMPLIANCE_UNOFFICIAL ) ;
return AVERROR ( EINVAL ) ;
}
}
s - > drop_frame_timecode = s - > drop_frame_timecode | | ! ! ( avctx - > flags2 & AV_CODEC_FLAG2_DROP_FRAME_TIMECODE ) ;
if ( s - > drop_frame_timecode )
s - > tc . flags | = AV_TIMECODE_FLAG_DROPFRAME ;
if ( s - > drop_frame_timecode & & s - > frame_rate_index ! = 4 ) {
av_log ( avctx , AV_LOG_ERROR ,
" Drop frame time code only allowed with 1001/30000 fps \n " ) ;
return AVERROR ( EINVAL ) ;
}
# if FF_API_PRIVATE_OPT
FF_DISABLE_DEPRECATION_WARNINGS
if ( avctx - > timecode_frame_start )
s - > timecode_frame_start = avctx - > timecode_frame_start ;
FF_ENABLE_DEPRECATION_WARNINGS
# endif
if ( s - > tc_opt_str ) {
AVRational rate = ff_mpeg12_frame_rate_tab [ s - > frame_rate_index ] ;
int ret = av_timecode_init_from_string ( & s - > tc , rate , s - > tc_opt_str , s ) ;
if ( ret < 0 )
return ret ;
s - > drop_frame_timecode = ! ! ( s - > tc . flags & AV_TIMECODE_FLAG_DROPFRAME ) ;
s - > timecode_frame_start = s - > tc . start ;
} else {
s - > timecode_frame_start = 0 ; // default is -1
}
return 0 ;
}
static void put_header ( MpegEncContext * s , int header )
{
align_put_bits ( & s - > pb ) ;
put_bits ( & s - > pb , 16 , header > > 16 ) ;
put_sbits ( & s - > pb , 16 , header ) ;
}
/* put sequence header if needed */
static void mpeg1_encode_sequence_header ( MpegEncContext * s )
{
unsigned int vbv_buffer_size , fps , v ;
int i , constraint_parameter_flag ;
uint64_t time_code ;
int64_t best_aspect_error = INT64_MAX ;
AVRational aspect_ratio = s - > avctx - > sample_aspect_ratio ;
if ( aspect_ratio . num = = 0 | | aspect_ratio . den = = 0 )
aspect_ratio = ( AVRational ) { 1 , 1 } ; // pixel aspect 1.1 (VGA)
if ( s - > current_picture . f - > key_frame ) {
AVRational framerate = ff_mpeg12_frame_rate_tab [ s - > frame_rate_index ] ;
/* MPEG-1 header repeated every GOP */
put_header ( s , SEQ_START_CODE ) ;
put_sbits ( & s - > pb , 12 , s - > width & 0xFFF ) ;
put_sbits ( & s - > pb , 12 , s - > height & 0xFFF ) ;
for ( i = 1 ; i < 15 ; i + + ) {
int64_t error = aspect_ratio . num * ( 1LL < < 32 ) / aspect_ratio . den ;
if ( s - > codec_id = = AV_CODEC_ID_MPEG1VIDEO | | i < = 1 )
error - = ( 1LL < < 32 ) / ff_mpeg1_aspect [ i ] ;
else
error - = ( 1LL < < 32 ) * ff_mpeg2_aspect [ i ] . num * s - > height / s - > width / ff_mpeg2_aspect [ i ] . den ;
error = FFABS ( error ) ;
if ( error - 2 < = best_aspect_error ) {
best_aspect_error = error ;
s - > aspect_ratio_info = i ;
}
}
put_bits ( & s - > pb , 4 , s - > aspect_ratio_info ) ;
put_bits ( & s - > pb , 4 , s - > frame_rate_index ) ;
if ( s - > avctx - > rc_max_rate ) {
v = ( s - > avctx - > rc_max_rate + 399 ) / 400 ;
if ( v > 0x3ffff & & s - > codec_id = = AV_CODEC_ID_MPEG1VIDEO )
v = 0x3ffff ;
} else {
v = 0x3FFFF ;
}
if ( s - > avctx - > rc_buffer_size )
vbv_buffer_size = s - > avctx - > rc_buffer_size ;
else
/* VBV calculation: Scaled so that a VCD has the proper
* VBV size of 40 kilobytes */
vbv_buffer_size = ( ( 20 * s - > bit_rate ) / ( 1151929 / 2 ) ) * 8 * 1024 ;
vbv_buffer_size = ( vbv_buffer_size + 16383 ) / 16384 ;
put_sbits ( & s - > pb , 18 , v ) ;
put_bits ( & s - > pb , 1 , 1 ) ; // marker
put_sbits ( & s - > pb , 10 , vbv_buffer_size ) ;
constraint_parameter_flag =
s - > width < = 768 & &
s - > height < = 576 & &
s - > mb_width * s - > mb_height < = 396 & &
s - > mb_width * s - > mb_height * framerate . num < = 396 * 25 * framerate . den & &
framerate . num < = framerate . den * 30 & &
s - > avctx - > me_range & &
s - > avctx - > me_range < 128 & &
vbv_buffer_size < = 20 & &
v < = 1856000 / 400 & &
s - > codec_id = = AV_CODEC_ID_MPEG1VIDEO ;
put_bits ( & s - > pb , 1 , constraint_parameter_flag ) ;
ff_write_quant_matrix ( & s - > pb , s - > avctx - > intra_matrix ) ;
ff_write_quant_matrix ( & s - > pb , s - > avctx - > inter_matrix ) ;
if ( s - > codec_id = = AV_CODEC_ID_MPEG2VIDEO ) {
AVFrameSideData * side_data ;
int width = s - > width ;
int height = s - > height ;
int use_seq_disp_ext ;
put_header ( s , EXT_START_CODE ) ;
put_bits ( & s - > pb , 4 , 1 ) ; // seq ext
put_bits ( & s - > pb , 1 , s - > avctx - > profile = = FF_PROFILE_MPEG2_422 ) ; // escx 1 for 4:2:2 profile
put_bits ( & s - > pb , 3 , s - > avctx - > profile ) ; // profile
put_bits ( & s - > pb , 4 , s - > avctx - > level ) ; // level
put_bits ( & s - > pb , 1 , s - > progressive_sequence ) ;
put_bits ( & s - > pb , 2 , s - > chroma_format ) ;
put_bits ( & s - > pb , 2 , s - > width > > 12 ) ;
put_bits ( & s - > pb , 2 , s - > height > > 12 ) ;
put_bits ( & s - > pb , 12 , v > > 18 ) ; // bitrate ext
put_bits ( & s - > pb , 1 , 1 ) ; // marker
put_bits ( & s - > pb , 8 , vbv_buffer_size > > 10 ) ; // vbv buffer ext
put_bits ( & s - > pb , 1 , s - > low_delay ) ;
put_bits ( & s - > pb , 2 , s - > mpeg2_frame_rate_ext . num - 1 ) ; // frame_rate_ext_n
put_bits ( & s - > pb , 5 , s - > mpeg2_frame_rate_ext . den - 1 ) ; // frame_rate_ext_d
side_data = av_frame_get_side_data ( s - > current_picture_ptr - > f , AV_FRAME_DATA_PANSCAN ) ;
if ( side_data ) {
AVPanScan * pan_scan = ( AVPanScan * ) side_data - > data ;
if ( pan_scan - > width & & pan_scan - > height ) {
width = pan_scan - > width > > 4 ;
height = pan_scan - > height > > 4 ;
}
}
use_seq_disp_ext = ( width ! = s - > width | |
height ! = s - > height | |
s - > avctx - > color_primaries ! = AVCOL_PRI_UNSPECIFIED | |
s - > avctx - > color_trc ! = AVCOL_TRC_UNSPECIFIED | |
s - > avctx - > colorspace ! = AVCOL_SPC_UNSPECIFIED | |
s - > video_format ! = VIDEO_FORMAT_UNSPECIFIED ) ;
if ( s - > seq_disp_ext = = 1 | | ( s - > seq_disp_ext = = - 1 & & use_seq_disp_ext ) ) {
put_header ( s , EXT_START_CODE ) ;
put_bits ( & s - > pb , 4 , 2 ) ; // sequence display extension
put_bits ( & s - > pb , 3 , s - > video_format ) ; // video_format
put_bits ( & s - > pb , 1 , 1 ) ; // colour_description
put_bits ( & s - > pb , 8 , s - > avctx - > color_primaries ) ; // colour_primaries
put_bits ( & s - > pb , 8 , s - > avctx - > color_trc ) ; // transfer_characteristics
put_bits ( & s - > pb , 8 , s - > avctx - > colorspace ) ; // matrix_coefficients
put_bits ( & s - > pb , 14 , width ) ; // display_horizontal_size
put_bits ( & s - > pb , 1 , 1 ) ; // marker_bit
put_bits ( & s - > pb , 14 , height ) ; // display_vertical_size
put_bits ( & s - > pb , 3 , 0 ) ; // remaining 3 bits are zero padding
}
}
put_header ( s , GOP_START_CODE ) ;
put_bits ( & s - > pb , 1 , s - > drop_frame_timecode ) ; // drop frame flag
/* time code: we must convert from the real frame rate to a
* fake MPEG frame rate in case of low frame rate */
fps = ( framerate . num + framerate . den / 2 ) / framerate . den ;
time_code = s - > current_picture_ptr - > f - > coded_picture_number +
s - > timecode_frame_start ;
s - > gop_picture_number = s - > current_picture_ptr - > f - > coded_picture_number ;
av_assert0 ( s - > drop_frame_timecode = = ! ! ( s - > tc . flags & AV_TIMECODE_FLAG_DROPFRAME ) ) ;
if ( s - > drop_frame_timecode )
time_code = av_timecode_adjust_ntsc_framenum2 ( time_code , fps ) ;
put_bits ( & s - > pb , 5 , ( uint32_t ) ( ( time_code / ( fps * 3600 ) ) % 24 ) ) ;
put_bits ( & s - > pb , 6 , ( uint32_t ) ( ( time_code / ( fps * 60 ) ) % 60 ) ) ;
put_bits ( & s - > pb , 1 , 1 ) ;
put_bits ( & s - > pb , 6 , ( uint32_t ) ( ( time_code / fps ) % 60 ) ) ;
put_bits ( & s - > pb , 6 , ( uint32_t ) ( ( time_code % fps ) ) ) ;
put_bits ( & s - > pb , 1 , ! ! ( s - > avctx - > flags & AV_CODEC_FLAG_CLOSED_GOP ) | | s - > intra_only | | ! s - > gop_picture_number ) ;
put_bits ( & s - > pb , 1 , 0 ) ; // broken link
}
}
static inline void encode_mb_skip_run ( MpegEncContext * s , int run )
{
while ( run > = 33 ) {
put_bits ( & s - > pb , 11 , 0x008 ) ;
run - = 33 ;
}
put_bits ( & s - > pb , ff_mpeg12_mbAddrIncrTable [ run ] [ 1 ] ,
ff_mpeg12_mbAddrIncrTable [ run ] [ 0 ] ) ;
}
static av_always_inline void put_qscale ( MpegEncContext * s )
{
put_bits ( & s - > pb , 5 , s - > qscale ) ;
}
void ff_mpeg1_encode_slice_header ( MpegEncContext * s )
{
if ( s - > codec_id = = AV_CODEC_ID_MPEG2VIDEO & & s - > height > 2800 ) {
put_header ( s , SLICE_MIN_START_CODE + ( s - > mb_y & 127 ) ) ;
/* slice_vertical_position_extension */
put_bits ( & s - > pb , 3 , s - > mb_y > > 7 ) ;
} else {
put_header ( s , SLICE_MIN_START_CODE + s - > mb_y ) ;
}
put_qscale ( s ) ;
/* slice extra information */
put_bits ( & s - > pb , 1 , 0 ) ;
}
void ff_mpeg1_encode_picture_header ( MpegEncContext * s , int picture_number )
{
AVFrameSideData * side_data ;
mpeg1_encode_sequence_header ( s ) ;
/* MPEG-1 picture header */
put_header ( s , PICTURE_START_CODE ) ;
/* temporal reference */
// RAL: s->picture_number instead of s->fake_picture_number
put_bits ( & s - > pb , 10 ,
( s - > picture_number - s - > gop_picture_number ) & 0x3ff ) ;
put_bits ( & s - > pb , 3 , s - > pict_type ) ;
s - > vbv_delay_ptr = s - > pb . buf + put_bits_count ( & s - > pb ) / 8 ;
put_bits ( & s - > pb , 16 , 0xFFFF ) ; /* vbv_delay */
// RAL: Forward f_code also needed for B-frames
if ( s - > pict_type = = AV_PICTURE_TYPE_P | |
s - > pict_type = = AV_PICTURE_TYPE_B ) {
put_bits ( & s - > pb , 1 , 0 ) ; /* half pel coordinates */
if ( s - > codec_id = = AV_CODEC_ID_MPEG1VIDEO )
put_bits ( & s - > pb , 3 , s - > f_code ) ; /* forward_f_code */
else
put_bits ( & s - > pb , 3 , 7 ) ; /* forward_f_code */
}
// RAL: Backward f_code necessary for B-frames
if ( s - > pict_type = = AV_PICTURE_TYPE_B ) {
put_bits ( & s - > pb , 1 , 0 ) ; /* half pel coordinates */
if ( s - > codec_id = = AV_CODEC_ID_MPEG1VIDEO )
put_bits ( & s - > pb , 3 , s - > b_code ) ; /* backward_f_code */
else
put_bits ( & s - > pb , 3 , 7 ) ; /* backward_f_code */
}
put_bits ( & s - > pb , 1 , 0 ) ; /* extra bit picture */
s - > frame_pred_frame_dct = 1 ;
if ( s - > codec_id = = AV_CODEC_ID_MPEG2VIDEO ) {
put_header ( s , EXT_START_CODE ) ;
put_bits ( & s - > pb , 4 , 8 ) ; /* pic ext */
if ( s - > pict_type = = AV_PICTURE_TYPE_P | |
s - > pict_type = = AV_PICTURE_TYPE_B ) {
put_bits ( & s - > pb , 4 , s - > f_code ) ;
put_bits ( & s - > pb , 4 , s - > f_code ) ;
} else {
put_bits ( & s - > pb , 8 , 255 ) ;
}
if ( s - > pict_type = = AV_PICTURE_TYPE_B ) {
put_bits ( & s - > pb , 4 , s - > b_code ) ;
put_bits ( & s - > pb , 4 , s - > b_code ) ;
} else {
put_bits ( & s - > pb , 8 , 255 ) ;
}
put_bits ( & s - > pb , 2 , s - > intra_dc_precision ) ;
av_assert0 ( s - > picture_structure = = PICT_FRAME ) ;
put_bits ( & s - > pb , 2 , s - > picture_structure ) ;
if ( s - > progressive_sequence )
put_bits ( & s - > pb , 1 , 0 ) ; /* no repeat */
else
put_bits ( & s - > pb , 1 , s - > current_picture_ptr - > f - > top_field_first ) ;
/* XXX: optimize the generation of this flag with entropy measures */
s - > frame_pred_frame_dct = s - > progressive_sequence ;
put_bits ( & s - > pb , 1 , s - > frame_pred_frame_dct ) ;
put_bits ( & s - > pb , 1 , s - > concealment_motion_vectors ) ;
put_bits ( & s - > pb , 1 , s - > q_scale_type ) ;
put_bits ( & s - > pb , 1 , s - > intra_vlc_format ) ;
put_bits ( & s - > pb , 1 , s - > alternate_scan ) ;
put_bits ( & s - > pb , 1 , s - > repeat_first_field ) ;
s - > progressive_frame = s - > progressive_sequence ;
/* chroma_420_type */
put_bits ( & s - > pb , 1 , s - > chroma_format = =
CHROMA_420 ? s - > progressive_frame : 0 ) ;
put_bits ( & s - > pb , 1 , s - > progressive_frame ) ;
put_bits ( & s - > pb , 1 , 0 ) ; /* composite_display_flag */
}
if ( s - > scan_offset ) {
int i ;
put_header ( s , USER_START_CODE ) ;
for ( i = 0 ; i < sizeof ( svcd_scan_offset_placeholder ) ; i + + )
put_bits ( & s - > pb , 8 , svcd_scan_offset_placeholder [ i ] ) ;
}
side_data = av_frame_get_side_data ( s - > current_picture_ptr - > f ,
AV_FRAME_DATA_STEREO3D ) ;
if ( side_data ) {
AVStereo3D * stereo = ( AVStereo3D * ) side_data - > data ;
uint8_t fpa_type ;
switch ( stereo - > type ) {
case AV_STEREO3D_SIDEBYSIDE :
fpa_type = 0x03 ;
break ;
case AV_STEREO3D_TOPBOTTOM :
fpa_type = 0x04 ;
break ;
case AV_STEREO3D_2D :
fpa_type = 0x08 ;
break ;
case AV_STEREO3D_SIDEBYSIDE_QUINCUNX :
fpa_type = 0x23 ;
break ;
default :
fpa_type = 0 ;
break ;
}
if ( fpa_type ! = 0 ) {
put_header ( s , USER_START_CODE ) ;
put_bits ( & s - > pb , 8 , ' J ' ) ; // S3D_video_format_signaling_identifier
put_bits ( & s - > pb , 8 , ' P ' ) ;
put_bits ( & s - > pb , 8 , ' 3 ' ) ;
put_bits ( & s - > pb , 8 , ' D ' ) ;
put_bits ( & s - > pb , 8 , 0x03 ) ; // S3D_video_format_length
put_bits ( & s - > pb , 1 , 1 ) ; // reserved_bit
put_bits ( & s - > pb , 7 , fpa_type ) ; // S3D_video_format_type
put_bits ( & s - > pb , 8 , 0x04 ) ; // reserved_data[0]
put_bits ( & s - > pb , 8 , 0xFF ) ; // reserved_data[1]
}
}
if ( s - > codec_id = = AV_CODEC_ID_MPEG2VIDEO & & s - > a53_cc ) {
side_data = av_frame_get_side_data ( s - > current_picture_ptr - > f ,
AV_FRAME_DATA_A53_CC ) ;
if ( side_data ) {
if ( side_data - > size < = A53_MAX_CC_COUNT * 3 & & side_data - > size % 3 = = 0 ) {
int i = 0 ;
put_header ( s , USER_START_CODE ) ;
put_bits ( & s - > pb , 8 , ' G ' ) ; // user_identifier
put_bits ( & s - > pb , 8 , ' A ' ) ;
put_bits ( & s - > pb , 8 , ' 9 ' ) ;
put_bits ( & s - > pb , 8 , ' 4 ' ) ;
put_bits ( & s - > pb , 8 , 3 ) ; // user_data_type_code
put_bits ( & s - > pb , 8 ,
( side_data - > size / 3 & A53_MAX_CC_COUNT ) | 0x40 ) ; // flags, cc_count
put_bits ( & s - > pb , 8 , 0xff ) ; // em_data
for ( i = 0 ; i < side_data - > size ; i + + )
put_bits ( & s - > pb , 8 , side_data - > data [ i ] ) ;
put_bits ( & s - > pb , 8 , 0xff ) ; // marker_bits
} else {
av_log ( s - > avctx , AV_LOG_WARNING ,
" Warning Closed Caption size (%d) can not exceed 93 bytes "
" and must be a multiple of 3 \n " , side_data - > size ) ;
}
}
}
s - > mb_y = 0 ;
ff_mpeg1_encode_slice_header ( s ) ;
}
static inline void put_mb_modes ( MpegEncContext * s , int n , int bits ,
int has_mv , int field_motion )
{
put_bits ( & s - > pb , n , bits ) ;
if ( ! s - > frame_pred_frame_dct ) {
if ( has_mv )
/* motion_type: frame/field */
put_bits ( & s - > pb , 2 , 2 - field_motion ) ;
put_bits ( & s - > pb , 1 , s - > interlaced_dct ) ;
}
}
// RAL: Parameter added: f_or_b_code
static void mpeg1_encode_motion ( MpegEncContext * s , int val , int f_or_b_code )
{
if ( val = = 0 ) {
/* zero vector */
put_bits ( & s - > pb ,
ff_mpeg12_mbMotionVectorTable [ 0 ] [ 1 ] ,
ff_mpeg12_mbMotionVectorTable [ 0 ] [ 0 ] ) ;
} else {
int code , sign , bits ;
int bit_size = f_or_b_code - 1 ;
int range = 1 < < bit_size ;
/* modulo encoding */
val = sign_extend ( val , 5 + bit_size ) ;
if ( val > = 0 ) {
val - - ;
code = ( val > > bit_size ) + 1 ;
bits = val & ( range - 1 ) ;
sign = 0 ;
} else {
val = - val ;
val - - ;
code = ( val > > bit_size ) + 1 ;
bits = val & ( range - 1 ) ;
sign = 1 ;
}
av_assert2 ( code > 0 & & code < = 16 ) ;
put_bits ( & s - > pb ,
ff_mpeg12_mbMotionVectorTable [ code ] [ 1 ] ,
ff_mpeg12_mbMotionVectorTable [ code ] [ 0 ] ) ;
put_bits ( & s - > pb , 1 , sign ) ;
if ( bit_size > 0 )
put_bits ( & s - > pb , bit_size , bits ) ;
}
}
static inline void encode_dc ( MpegEncContext * s , int diff , int component )
{
unsigned int diff_u = diff + 255 ;
if ( diff_u > = 511 ) {
int index ;
if ( diff < 0 ) {
index = av_log2_16bit ( - 2 * diff ) ;
diff - - ;
} else {
index = av_log2_16bit ( 2 * diff ) ;
}
if ( component = = 0 )
put_bits ( & s - > pb ,
ff_mpeg12_vlc_dc_lum_bits [ index ] + index ,
( ff_mpeg12_vlc_dc_lum_code [ index ] < < index ) +
av_mod_uintp2 ( diff , index ) ) ;
else
put_bits ( & s - > pb ,
ff_mpeg12_vlc_dc_chroma_bits [ index ] + index ,
( ff_mpeg12_vlc_dc_chroma_code [ index ] < < index ) +
av_mod_uintp2 ( diff , index ) ) ;
} else {
if ( component = = 0 )
put_bits ( & s - > pb ,
mpeg1_lum_dc_uni [ diff + 255 ] & 0xFF ,
mpeg1_lum_dc_uni [ diff + 255 ] > > 8 ) ;
else
put_bits ( & s - > pb ,
mpeg1_chr_dc_uni [ diff + 255 ] & 0xFF ,
mpeg1_chr_dc_uni [ diff + 255 ] > > 8 ) ;
}
}
static void mpeg1_encode_block ( MpegEncContext * s , int16_t * block , int n )
{
int alevel , level , last_non_zero , dc , diff , i , j , run , last_index , sign ;
int code , component ;
const uint16_t ( * table_vlc ) [ 2 ] = ff_rl_mpeg1 . table_vlc ;
last_index = s - > block_last_index [ n ] ;
/* DC coef */
if ( s - > mb_intra ) {
component = ( n < = 3 ? 0 : ( n & 1 ) + 1 ) ;
dc = block [ 0 ] ; /* overflow is impossible */
diff = dc - s - > last_dc [ component ] ;
encode_dc ( s , diff , component ) ;
s - > last_dc [ component ] = dc ;
i = 1 ;
if ( s - > intra_vlc_format )
table_vlc = ff_rl_mpeg2 . table_vlc ;
} else {
/* encode the first coefficient: needs to be done here because
* it is handled slightly differently */
level = block [ 0 ] ;
if ( abs ( level ) = = 1 ) {
code = ( ( uint32_t ) level > > 31 ) ; /* the sign bit */
put_bits ( & s - > pb , 2 , code | 0x02 ) ;
i = 1 ;
} else {
i = 0 ;
last_non_zero = - 1 ;
goto next_coef ;
}
}
/* now quantify & encode AC coefs */
last_non_zero = i - 1 ;
for ( ; i < = last_index ; i + + ) {
j = s - > intra_scantable . permutated [ i ] ;
level = block [ j ] ;
next_coef :
/* encode using VLC */
if ( level ! = 0 ) {
run = i - last_non_zero - 1 ;
alevel = level ;
MASK_ABS ( sign , alevel ) ;
sign & = 1 ;
if ( alevel < = ff_rl_mpeg1 . max_level [ 0 ] [ run ] ) {
code = ff_rl_mpeg1 . index_run [ 0 ] [ run ] + alevel - 1 ;
/* store the VLC & sign at once */
put_bits ( & s - > pb , table_vlc [ code ] [ 1 ] + 1 ,
( table_vlc [ code ] [ 0 ] < < 1 ) + sign ) ;
} else {
/* escape seems to be pretty rare <5% so I do not optimize it */
put_bits ( & s - > pb , table_vlc [ 111 ] [ 1 ] , table_vlc [ 111 ] [ 0 ] ) ;
/* escape: only clip in this case */
put_bits ( & s - > pb , 6 , run ) ;
if ( s - > codec_id = = AV_CODEC_ID_MPEG1VIDEO ) {
if ( alevel < 128 ) {
put_sbits ( & s - > pb , 8 , level ) ;
} else {
if ( level < 0 )
put_bits ( & s - > pb , 16 , 0x8001 + level + 255 ) ;
else
put_sbits ( & s - > pb , 16 , level ) ;
}
} else {
put_sbits ( & s - > pb , 12 , level ) ;
}
}
last_non_zero = i ;
}
}
/* end of block */
put_bits ( & s - > pb , table_vlc [ 112 ] [ 1 ] , table_vlc [ 112 ] [ 0 ] ) ;
}
static av_always_inline void mpeg1_encode_mb_internal ( MpegEncContext * s ,
int16_t block [ 8 ] [ 64 ] ,
int motion_x , int motion_y ,
int mb_block_count )
{
int i , cbp ;
const int mb_x = s - > mb_x ;
const int mb_y = s - > mb_y ;
const int first_mb = mb_x = = s - > resync_mb_x & & mb_y = = s - > resync_mb_y ;
/* compute cbp */
cbp = 0 ;
for ( i = 0 ; i < mb_block_count ; i + + )
if ( s - > block_last_index [ i ] > = 0 )
cbp | = 1 < < ( mb_block_count - 1 - i ) ;
if ( cbp = = 0 & & ! first_mb & & s - > mv_type = = MV_TYPE_16X16 & &
( mb_x ! = s - > mb_width - 1 | |
( mb_y ! = s - > end_mb_y - 1 & & s - > codec_id = = AV_CODEC_ID_MPEG1VIDEO ) ) & &
( ( s - > pict_type = = AV_PICTURE_TYPE_P & & ( motion_x | motion_y ) = = 0 ) | |
( s - > pict_type = = AV_PICTURE_TYPE_B & & s - > mv_dir = = s - > last_mv_dir & &
( ( ( s - > mv_dir & MV_DIR_FORWARD )
? ( ( s - > mv [ 0 ] [ 0 ] [ 0 ] - s - > last_mv [ 0 ] [ 0 ] [ 0 ] ) |
( s - > mv [ 0 ] [ 0 ] [ 1 ] - s - > last_mv [ 0 ] [ 0 ] [ 1 ] ) ) : 0 ) |
( ( s - > mv_dir & MV_DIR_BACKWARD )
? ( ( s - > mv [ 1 ] [ 0 ] [ 0 ] - s - > last_mv [ 1 ] [ 0 ] [ 0 ] ) |
( s - > mv [ 1 ] [ 0 ] [ 1 ] - s - > last_mv [ 1 ] [ 0 ] [ 1 ] ) ) : 0 ) ) = = 0 ) ) ) {
s - > mb_skip_run + + ;
s - > qscale - = s - > dquant ;
s - > skip_count + + ;
s - > misc_bits + + ;
s - > last_bits + + ;
if ( s - > pict_type = = AV_PICTURE_TYPE_P ) {
s - > last_mv [ 0 ] [ 0 ] [ 0 ] =
s - > last_mv [ 0 ] [ 0 ] [ 1 ] =
s - > last_mv [ 0 ] [ 1 ] [ 0 ] =
s - > last_mv [ 0 ] [ 1 ] [ 1 ] = 0 ;
}
} else {
if ( first_mb ) {
av_assert0 ( s - > mb_skip_run = = 0 ) ;
encode_mb_skip_run ( s , s - > mb_x ) ;
} else {
encode_mb_skip_run ( s , s - > mb_skip_run ) ;
}
if ( s - > pict_type = = AV_PICTURE_TYPE_I ) {
if ( s - > dquant & & cbp ) {
/* macroblock_type: macroblock_quant = 1 */
put_mb_modes ( s , 2 , 1 , 0 , 0 ) ;
put_qscale ( s ) ;
} else {
/* macroblock_type: macroblock_quant = 0 */
put_mb_modes ( s , 1 , 1 , 0 , 0 ) ;
s - > qscale - = s - > dquant ;
}
s - > misc_bits + = get_bits_diff ( s ) ;
s - > i_count + + ;
} else if ( s - > mb_intra ) {
if ( s - > dquant & & cbp ) {
put_mb_modes ( s , 6 , 0x01 , 0 , 0 ) ;
put_qscale ( s ) ;
} else {
put_mb_modes ( s , 5 , 0x03 , 0 , 0 ) ;
s - > qscale - = s - > dquant ;
}
s - > misc_bits + = get_bits_diff ( s ) ;
s - > i_count + + ;
memset ( s - > last_mv , 0 , sizeof ( s - > last_mv ) ) ;
} else if ( s - > pict_type = = AV_PICTURE_TYPE_P ) {
if ( s - > mv_type = = MV_TYPE_16X16 ) {
if ( cbp ! = 0 ) {
if ( ( motion_x | motion_y ) = = 0 ) {
if ( s - > dquant ) {
/* macroblock_pattern & quant */
put_mb_modes ( s , 5 , 1 , 0 , 0 ) ;
put_qscale ( s ) ;
} else {
/* macroblock_pattern only */
put_mb_modes ( s , 2 , 1 , 0 , 0 ) ;
}
s - > misc_bits + = get_bits_diff ( s ) ;
} else {
if ( s - > dquant ) {
put_mb_modes ( s , 5 , 2 , 1 , 0 ) ; /* motion + cbp */
put_qscale ( s ) ;
} else {
put_mb_modes ( s , 1 , 1 , 1 , 0 ) ; /* motion + cbp */
}
s - > misc_bits + = get_bits_diff ( s ) ;
// RAL: f_code parameter added
mpeg1_encode_motion ( s ,
motion_x - s - > last_mv [ 0 ] [ 0 ] [ 0 ] ,
s - > f_code ) ;
// RAL: f_code parameter added
mpeg1_encode_motion ( s ,
motion_y - s - > last_mv [ 0 ] [ 0 ] [ 1 ] ,
s - > f_code ) ;
s - > mv_bits + = get_bits_diff ( s ) ;
}
} else {
put_bits ( & s - > pb , 3 , 1 ) ; /* motion only */
if ( ! s - > frame_pred_frame_dct )
put_bits ( & s - > pb , 2 , 2 ) ; /* motion_type: frame */
s - > misc_bits + = get_bits_diff ( s ) ;
// RAL: f_code parameter added
mpeg1_encode_motion ( s ,
motion_x - s - > last_mv [ 0 ] [ 0 ] [ 0 ] ,
s - > f_code ) ;
// RAL: f_code parameter added
mpeg1_encode_motion ( s ,
motion_y - s - > last_mv [ 0 ] [ 0 ] [ 1 ] ,
s - > f_code ) ;
s - > qscale - = s - > dquant ;
s - > mv_bits + = get_bits_diff ( s ) ;
}
s - > last_mv [ 0 ] [ 1 ] [ 0 ] = s - > last_mv [ 0 ] [ 0 ] [ 0 ] = motion_x ;
s - > last_mv [ 0 ] [ 1 ] [ 1 ] = s - > last_mv [ 0 ] [ 0 ] [ 1 ] = motion_y ;
} else {
av_assert2 ( ! s - > frame_pred_frame_dct & & s - > mv_type = = MV_TYPE_FIELD ) ;
if ( cbp ) {
if ( s - > dquant ) {
put_mb_modes ( s , 5 , 2 , 1 , 1 ) ; /* motion + cbp */
put_qscale ( s ) ;
} else {
put_mb_modes ( s , 1 , 1 , 1 , 1 ) ; /* motion + cbp */
}
} else {
put_bits ( & s - > pb , 3 , 1 ) ; /* motion only */
put_bits ( & s - > pb , 2 , 1 ) ; /* motion_type: field */
s - > qscale - = s - > dquant ;
}
s - > misc_bits + = get_bits_diff ( s ) ;
for ( i = 0 ; i < 2 ; i + + ) {
put_bits ( & s - > pb , 1 , s - > field_select [ 0 ] [ i ] ) ;
mpeg1_encode_motion ( s ,
s - > mv [ 0 ] [ i ] [ 0 ] - s - > last_mv [ 0 ] [ i ] [ 0 ] ,
s - > f_code ) ;
mpeg1_encode_motion ( s ,
s - > mv [ 0 ] [ i ] [ 1 ] - ( s - > last_mv [ 0 ] [ i ] [ 1 ] > > 1 ) ,
s - > f_code ) ;
s - > last_mv [ 0 ] [ i ] [ 0 ] = s - > mv [ 0 ] [ i ] [ 0 ] ;
s - > last_mv [ 0 ] [ i ] [ 1 ] = 2 * s - > mv [ 0 ] [ i ] [ 1 ] ;
}
s - > mv_bits + = get_bits_diff ( s ) ;
}
if ( cbp ) {
if ( s - > chroma_y_shift ) {
put_bits ( & s - > pb ,
ff_mpeg12_mbPatTable [ cbp ] [ 1 ] ,
ff_mpeg12_mbPatTable [ cbp ] [ 0 ] ) ;
} else {
put_bits ( & s - > pb ,
ff_mpeg12_mbPatTable [ cbp > > 2 ] [ 1 ] ,
ff_mpeg12_mbPatTable [ cbp > > 2 ] [ 0 ] ) ;
put_sbits ( & s - > pb , 2 , cbp ) ;
}
}
s - > f_count + + ;
} else {
if ( s - > mv_type = = MV_TYPE_16X16 ) {
if ( cbp ) { // With coded bloc pattern
if ( s - > dquant ) {
if ( s - > mv_dir = = MV_DIR_FORWARD )
put_mb_modes ( s , 6 , 3 , 1 , 0 ) ;
else
put_mb_modes ( s , 8 - s - > mv_dir , 2 , 1 , 0 ) ;
put_qscale ( s ) ;
} else {
put_mb_modes ( s , 5 - s - > mv_dir , 3 , 1 , 0 ) ;
}
} else { // No coded bloc pattern
put_bits ( & s - > pb , 5 - s - > mv_dir , 2 ) ;
if ( ! s - > frame_pred_frame_dct )
put_bits ( & s - > pb , 2 , 2 ) ; /* motion_type: frame */
s - > qscale - = s - > dquant ;
}
s - > misc_bits + = get_bits_diff ( s ) ;
if ( s - > mv_dir & MV_DIR_FORWARD ) {
mpeg1_encode_motion ( s ,
s - > mv [ 0 ] [ 0 ] [ 0 ] - s - > last_mv [ 0 ] [ 0 ] [ 0 ] ,
s - > f_code ) ;
mpeg1_encode_motion ( s ,
s - > mv [ 0 ] [ 0 ] [ 1 ] - s - > last_mv [ 0 ] [ 0 ] [ 1 ] ,
s - > f_code ) ;
s - > last_mv [ 0 ] [ 0 ] [ 0 ] =
s - > last_mv [ 0 ] [ 1 ] [ 0 ] = s - > mv [ 0 ] [ 0 ] [ 0 ] ;
s - > last_mv [ 0 ] [ 0 ] [ 1 ] =
s - > last_mv [ 0 ] [ 1 ] [ 1 ] = s - > mv [ 0 ] [ 0 ] [ 1 ] ;
s - > f_count + + ;
}
if ( s - > mv_dir & MV_DIR_BACKWARD ) {
mpeg1_encode_motion ( s ,
s - > mv [ 1 ] [ 0 ] [ 0 ] - s - > last_mv [ 1 ] [ 0 ] [ 0 ] ,
s - > b_code ) ;
mpeg1_encode_motion ( s ,
s - > mv [ 1 ] [ 0 ] [ 1 ] - s - > last_mv [ 1 ] [ 0 ] [ 1 ] ,
s - > b_code ) ;
s - > last_mv [ 1 ] [ 0 ] [ 0 ] =
s - > last_mv [ 1 ] [ 1 ] [ 0 ] = s - > mv [ 1 ] [ 0 ] [ 0 ] ;
s - > last_mv [ 1 ] [ 0 ] [ 1 ] =
s - > last_mv [ 1 ] [ 1 ] [ 1 ] = s - > mv [ 1 ] [ 0 ] [ 1 ] ;
s - > b_count + + ;
}
} else {
av_assert2 ( s - > mv_type = = MV_TYPE_FIELD ) ;
av_assert2 ( ! s - > frame_pred_frame_dct ) ;
if ( cbp ) { // With coded bloc pattern
if ( s - > dquant ) {
if ( s - > mv_dir = = MV_DIR_FORWARD )
put_mb_modes ( s , 6 , 3 , 1 , 1 ) ;
else
put_mb_modes ( s , 8 - s - > mv_dir , 2 , 1 , 1 ) ;
put_qscale ( s ) ;
} else {
put_mb_modes ( s , 5 - s - > mv_dir , 3 , 1 , 1 ) ;
}
} else { // No coded bloc pattern
put_bits ( & s - > pb , 5 - s - > mv_dir , 2 ) ;
put_bits ( & s - > pb , 2 , 1 ) ; /* motion_type: field */
s - > qscale - = s - > dquant ;
}
s - > misc_bits + = get_bits_diff ( s ) ;
if ( s - > mv_dir & MV_DIR_FORWARD ) {
for ( i = 0 ; i < 2 ; i + + ) {
put_bits ( & s - > pb , 1 , s - > field_select [ 0 ] [ i ] ) ;
mpeg1_encode_motion ( s ,
s - > mv [ 0 ] [ i ] [ 0 ] - s - > last_mv [ 0 ] [ i ] [ 0 ] ,
s - > f_code ) ;
mpeg1_encode_motion ( s ,
s - > mv [ 0 ] [ i ] [ 1 ] - ( s - > last_mv [ 0 ] [ i ] [ 1 ] > > 1 ) ,
s - > f_code ) ;
s - > last_mv [ 0 ] [ i ] [ 0 ] = s - > mv [ 0 ] [ i ] [ 0 ] ;
s - > last_mv [ 0 ] [ i ] [ 1 ] = s - > mv [ 0 ] [ i ] [ 1 ] * 2 ;
}
s - > f_count + + ;
}
if ( s - > mv_dir & MV_DIR_BACKWARD ) {
for ( i = 0 ; i < 2 ; i + + ) {
put_bits ( & s - > pb , 1 , s - > field_select [ 1 ] [ i ] ) ;
mpeg1_encode_motion ( s ,
s - > mv [ 1 ] [ i ] [ 0 ] - s - > last_mv [ 1 ] [ i ] [ 0 ] ,
s - > b_code ) ;
mpeg1_encode_motion ( s ,
s - > mv [ 1 ] [ i ] [ 1 ] - ( s - > last_mv [ 1 ] [ i ] [ 1 ] > > 1 ) ,
s - > b_code ) ;
s - > last_mv [ 1 ] [ i ] [ 0 ] = s - > mv [ 1 ] [ i ] [ 0 ] ;
s - > last_mv [ 1 ] [ i ] [ 1 ] = s - > mv [ 1 ] [ i ] [ 1 ] * 2 ;
}
s - > b_count + + ;
}
}
s - > mv_bits + = get_bits_diff ( s ) ;
if ( cbp ) {
if ( s - > chroma_y_shift ) {
put_bits ( & s - > pb ,
ff_mpeg12_mbPatTable [ cbp ] [ 1 ] ,
ff_mpeg12_mbPatTable [ cbp ] [ 0 ] ) ;
} else {
put_bits ( & s - > pb ,
ff_mpeg12_mbPatTable [ cbp > > 2 ] [ 1 ] ,
ff_mpeg12_mbPatTable [ cbp > > 2 ] [ 0 ] ) ;
put_sbits ( & s - > pb , 2 , cbp ) ;
}
}
}
for ( i = 0 ; i < mb_block_count ; i + + )
if ( cbp & ( 1 < < ( mb_block_count - 1 - i ) ) )
mpeg1_encode_block ( s , block [ i ] , i ) ;
s - > mb_skip_run = 0 ;
if ( s - > mb_intra )
s - > i_tex_bits + = get_bits_diff ( s ) ;
else
s - > p_tex_bits + = get_bits_diff ( s ) ;
}
}
void ff_mpeg1_encode_mb ( MpegEncContext * s , int16_t block [ 8 ] [ 64 ] ,
int motion_x , int motion_y )
{
if ( s - > chroma_format = = CHROMA_420 )
mpeg1_encode_mb_internal ( s , block , motion_x , motion_y , 6 ) ;
else
mpeg1_encode_mb_internal ( s , block , motion_x , motion_y , 8 ) ;
}
static av_cold void mpeg12_encode_init_static ( void )
{
static uint8_t mpeg12_static_rl_table_store [ 2 ] [ 2 ] [ 2 * MAX_RUN + MAX_LEVEL + 3 ] ;
ff_rl_init ( & ff_rl_mpeg1 , mpeg12_static_rl_table_store [ 0 ] ) ;
ff_rl_init ( & ff_rl_mpeg2 , mpeg12_static_rl_table_store [ 1 ] ) ;
ff_mpeg1_init_uni_ac_vlc ( & ff_rl_mpeg1 , uni_mpeg1_ac_vlc_len ) ;
ff_mpeg1_init_uni_ac_vlc ( & ff_rl_mpeg2 , uni_mpeg2_ac_vlc_len ) ;
/* build unified dc encoding tables */
for ( int i = - 255 ; i < 256 ; i + + ) {
int adiff , index ;
int bits , code ;
int diff = i ;
adiff = FFABS ( diff ) ;
if ( diff < 0 )
diff - - ;
index = av_log2 ( 2 * adiff ) ;
bits = ff_mpeg12_vlc_dc_lum_bits [ index ] + index ;
code = ( ff_mpeg12_vlc_dc_lum_code [ index ] < < index ) +
av_mod_uintp2 ( diff , index ) ;
mpeg1_lum_dc_uni [ i + 255 ] = bits + ( code < < 8 ) ;
bits = ff_mpeg12_vlc_dc_chroma_bits [ index ] + index ;
code = ( ff_mpeg12_vlc_dc_chroma_code [ index ] < < index ) +
av_mod_uintp2 ( diff , index ) ;
mpeg1_chr_dc_uni [ i + 255 ] = bits + ( code < < 8 ) ;
}
for ( int f_code = 1 ; f_code < = MAX_FCODE ; f_code + + )
for ( int mv = - MAX_DMV ; mv < = MAX_DMV ; mv + + ) {
int len ;
if ( mv = = 0 ) {
len = ff_mpeg12_mbMotionVectorTable [ 0 ] [ 1 ] ;
} else {
int val , bit_size , code ;
bit_size = f_code - 1 ;
val = mv ;
if ( val < 0 )
val = - val ;
val - - ;
code = ( val > > bit_size ) + 1 ;
if ( code < 17 )
len = ff_mpeg12_mbMotionVectorTable [ code ] [ 1 ] +
1 + bit_size ;
else
len = ff_mpeg12_mbMotionVectorTable [ 16 ] [ 1 ] +
2 + bit_size ;
}
mv_penalty [ f_code ] [ mv + MAX_DMV ] = len ;
}
for ( int f_code = MAX_FCODE ; f_code > 0 ; f_code - - )
for ( int mv = - ( 8 < < f_code ) ; mv < ( 8 < < f_code ) ; mv + + )
fcode_tab [ mv + MAX_MV ] = f_code ;
}
av_cold void ff_mpeg1_encode_init ( MpegEncContext * s )
{
static AVOnce init_static_once = AV_ONCE_INIT ;
ff_mpeg12_common_init ( s ) ;
s - > me . mv_penalty = mv_penalty ;
s - > fcode_tab = fcode_tab ;
if ( s - > codec_id = = AV_CODEC_ID_MPEG1VIDEO ) {
s - > min_qcoeff = - 255 ;
s - > max_qcoeff = 255 ;
} else {
s - > min_qcoeff = - 2047 ;
s - > max_qcoeff = 2047 ;
}
if ( s - > intra_vlc_format ) {
s - > intra_ac_vlc_length =
s - > intra_ac_vlc_last_length = uni_mpeg2_ac_vlc_len ;
} else {
s - > intra_ac_vlc_length =
s - > intra_ac_vlc_last_length = uni_mpeg1_ac_vlc_len ;
}
s - > inter_ac_vlc_length =
s - > inter_ac_vlc_last_length = uni_mpeg1_ac_vlc_len ;
ff_thread_once ( & init_static_once , mpeg12_encode_init_static ) ;
}
# define OFFSET(x) offsetof(MpegEncContext, x)
# define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
# define COMMON_OPTS \
{ " gop_timecode " , " MPEG GOP Timecode in hh:mm:ss[:;.]ff format. Overrides timecode_frame_start. " , \
OFFSET ( tc_opt_str ) , AV_OPT_TYPE_STRING , { . str = NULL } , 0 , 0 , VE } , \
{ " drop_frame_timecode " , " Timecode is in drop frame format. " , \
OFFSET ( drop_frame_timecode ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , VE } , \
{ " scan_offset " , " Reserve space for SVCD scan offset user data. " , \
OFFSET ( scan_offset ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , VE } , \
{ " timecode_frame_start " , " GOP timecode frame start number, in non-drop-frame format " , \
OFFSET ( timecode_frame_start ) , AV_OPT_TYPE_INT64 , { . i64 = - 1 } , - 1 , INT64_MAX , VE } , \
static const AVOption mpeg1_options [ ] = {
COMMON_OPTS
FF_MPV_COMMON_OPTS
{ NULL } ,
} ;
static const AVOption mpeg2_options [ ] = {
COMMON_OPTS
{ " intra_vlc " , " Use MPEG-2 intra VLC table. " ,
OFFSET ( intra_vlc_format ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , VE } ,
{ " non_linear_quant " , " Use nonlinear quantizer. " , OFFSET ( q_scale_type ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , VE } ,
{ " alternate_scan " , " Enable alternate scantable. " , OFFSET ( alternate_scan ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , VE } ,
{ " seq_disp_ext " , " Write sequence_display_extension blocks. " , OFFSET ( seq_disp_ext ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , 1 , VE , " seq_disp_ext " } ,
{ " auto " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = - 1 } , 0 , 0 , VE , " seq_disp_ext " } ,
{ " never " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = 0 } , 0 , 0 , VE , " seq_disp_ext " } ,
{ " always " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = 1 } , 0 , 0 , VE , " seq_disp_ext " } ,
{ " video_format " , " Video_format in the sequence_display_extension indicating the source of the video. " , OFFSET ( video_format ) , AV_OPT_TYPE_INT , { . i64 = VIDEO_FORMAT_UNSPECIFIED } , 0 , 7 , VE , " video_format " } ,
{ " component " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = VIDEO_FORMAT_COMPONENT } , 0 , 0 , VE , " video_format " } ,
{ " pal " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = VIDEO_FORMAT_PAL } , 0 , 0 , VE , " video_format " } ,
{ " ntsc " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = VIDEO_FORMAT_NTSC } , 0 , 0 , VE , " video_format " } ,
{ " secam " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = VIDEO_FORMAT_SECAM } , 0 , 0 , VE , " video_format " } ,
{ " mac " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = VIDEO_FORMAT_MAC } , 0 , 0 , VE , " video_format " } ,
{ " unspecified " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = VIDEO_FORMAT_UNSPECIFIED } , 0 , 0 , VE , " video_format " } ,
# define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, { .i64 = value }, 0, 0, VE, "avctx.level"
{ LEVEL ( " high " , 4 ) } ,
{ LEVEL ( " high1440 " , 6 ) } ,
{ LEVEL ( " main " , 8 ) } ,
{ LEVEL ( " low " , 10 ) } ,
# undef LEVEL
FF_MPV_COMMON_OPTS
FF_MPEG2_PROFILE_OPTS
{ NULL } ,
} ;
# define mpeg12_class(x) \
static const AVClass mpeg # # x # # _class = { \
. class_name = " mpeg " # x " video encoder " , \
. item_name = av_default_item_name , \
. option = mpeg # # x # # _options , \
. version = LIBAVUTIL_VERSION_INT , \
} ;
mpeg12_class ( 1 )
mpeg12_class ( 2 )
AVCodec ff_mpeg1video_encoder = {
. name = " mpeg1video " ,
. long_name = NULL_IF_CONFIG_SMALL ( " MPEG-1 video " ) ,
. type = AVMEDIA_TYPE_VIDEO ,
. id = AV_CODEC_ID_MPEG1VIDEO ,
. priv_data_size = sizeof ( MpegEncContext ) ,
. init = encode_init ,
. encode2 = ff_mpv_encode_picture ,
. close = ff_mpv_encode_end ,
. supported_framerates = ff_mpeg12_frame_rate_tab + 1 ,
. pix_fmts = ( const enum AVPixelFormat [ ] ) { AV_PIX_FMT_YUV420P ,
AV_PIX_FMT_NONE } ,
. capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS ,
. caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP ,
. priv_class = & mpeg1_class ,
} ;
AVCodec ff_mpeg2video_encoder = {
. name = " mpeg2video " ,
. long_name = NULL_IF_CONFIG_SMALL ( " MPEG-2 video " ) ,
. type = AVMEDIA_TYPE_VIDEO ,
. id = AV_CODEC_ID_MPEG2VIDEO ,
. priv_data_size = sizeof ( MpegEncContext ) ,
. init = encode_init ,
. encode2 = ff_mpv_encode_picture ,
. close = ff_mpv_encode_end ,
. supported_framerates = ff_mpeg2_frame_rate_tab ,
. pix_fmts = ( const enum AVPixelFormat [ ] ) { AV_PIX_FMT_YUV420P ,
AV_PIX_FMT_YUV422P ,
AV_PIX_FMT_NONE } ,
. capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS ,
. caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP ,
. priv_class = & mpeg2_class ,
} ;
# endif /* CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER */