2001-07-22 17:18:56 +03:00
/*
* H263 / MPEG4 backend for ffmpeg encoder and decoder
2002-05-26 01:45:33 +03:00
* Copyright ( c ) 2000 , 2001 Fabrice Bellard .
2001-08-29 02:32:34 +03:00
* H263 + support .
2001-07-22 17:18:56 +03:00
* Copyright ( c ) 2001 Juan J . Sierralta P .
2004-01-10 18:04:55 +02:00
* Copyright ( c ) 2002 - 2004 Michael Niedermayer < michaelni @ gmx . at >
2001-07-22 17:18:56 +03:00
*
2002-05-26 01:45:33 +03:00
* This library 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 of the License , or ( at your option ) any later version .
2001-07-22 17:18:56 +03:00
*
2002-05-26 01:45:33 +03:00
* This library is distributed in the hope that it will be useful ,
2001-07-22 17:18:56 +03:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2002-05-26 01:45:33 +03:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
2001-07-22 17:18:56 +03:00
*
2002-05-26 01:45:33 +03:00
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-01-13 00:43:26 +02:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2002-03-22 04:21:17 +02:00
*
2002-09-12 15:26:09 +03:00
* ac prediction encoding , b - frame support , error resilience , optimizations ,
2005-12-17 20:14:38 +02:00
* qpel decoding , gmc decoding , interlaced decoding ,
2002-09-12 15:26:09 +03:00
* by Michael Niedermayer < michaelni @ gmx . at >
2001-07-22 17:18:56 +03:00
*/
2003-01-27 01:09:12 +02:00
/**
* @ file h263 . c
2003-03-06 13:32:04 +02:00
* h263 / mpeg4 codec .
2003-01-27 01:09:12 +02:00
*/
2005-12-17 20:14:38 +02:00
2002-05-03 21:11:23 +03:00
//#define DEBUG
2003-10-01 01:18:43 +03:00
# include <limits.h>
2001-07-22 17:18:56 +03:00
# include "common.h"
# include "dsputil.h"
# include "avcodec.h"
# include "mpegvideo.h"
# include "h263data.h"
# include "mpeg4data.h"
2002-09-23 17:56:11 +03:00
//#undef NDEBUG
//#include <assert.h>
2002-07-13 18:45:52 +03:00
# define INTRA_MCBPC_VLC_BITS 6
2003-09-27 01:18:25 +03:00
# define INTER_MCBPC_VLC_BITS 7
2002-07-13 18:45:52 +03:00
# define CBPY_VLC_BITS 6
# define MV_VLC_BITS 9
# define DC_VLC_BITS 9
# define SPRITE_TRAJ_VLC_BITS 6
# define MB_TYPE_B_VLC_BITS 4
# define TEX_VLC_BITS 9
2003-12-04 20:34:47 +02:00
# define H263_MBTYPE_B_VLC_BITS 6
# define CBPC_B_VLC_BITS 3
2002-07-13 18:45:52 +03:00
2002-10-31 18:11:03 +02:00
# ifdef CONFIG_ENCODERS
2001-07-22 17:18:56 +03:00
static void h263_encode_block ( MpegEncContext * s , DCTELEM * block ,
2003-07-10 02:10:59 +03:00
int n ) ;
2001-08-29 02:32:34 +03:00
static void h263p_encode_umotion ( MpegEncContext * s , int val ) ;
2002-09-07 03:16:30 +03:00
static inline void mpeg4_encode_block ( MpegEncContext * s , DCTELEM * block ,
2005-12-17 20:14:38 +02:00
int n , int dc , uint8_t * scan_table ,
2002-06-02 15:15:17 +03:00
PutBitContext * dc_pb , PutBitContext * ac_pb ) ;
2006-09-27 22:54:07 +03:00
static int mpeg4_get_block_length ( MpegEncContext * s , DCTELEM * block , int n , int intra_dc ,
uint8_t * scan_table ) ;
2002-10-31 18:11:03 +02:00
# endif
2002-03-13 00:54:25 +02:00
static int h263_decode_motion ( MpegEncContext * s , int pred , int fcode ) ;
2001-08-29 02:32:34 +03:00
static int h263p_decode_umotion ( MpegEncContext * s , int pred ) ;
2001-07-22 17:18:56 +03:00
static int h263_decode_block ( MpegEncContext * s , DCTELEM * block ,
int n , int coded ) ;
2002-06-02 15:15:17 +03:00
static inline int mpeg4_decode_dc ( MpegEncContext * s , int n , int * dir_ptr ) ;
static inline int mpeg4_decode_block ( MpegEncContext * s , DCTELEM * block ,
2003-03-13 01:09:18 +02:00
int n , int coded , int intra , int rvlc ) ;
2003-02-17 01:05:38 +02:00
# ifdef CONFIG_ENCODERS
2006-09-28 01:13:44 +03:00
static int h263_pred_dc ( MpegEncContext * s , int n , int16_t * * dc_val_ptr ) ;
2003-08-26 23:14:28 +03:00
static void mpeg4_encode_visual_object_header ( MpegEncContext * s ) ;
static void mpeg4_encode_vol_header ( MpegEncContext * s , int vo_number , int vol_number ) ;
2003-02-17 01:05:38 +02:00
# endif //CONFIG_ENCODERS
2004-04-02 19:21:55 +03:00
static void mpeg4_decode_sprite_trajectory ( MpegEncContext * s , GetBitContext * gb ) ;
2004-05-05 03:14:22 +03:00
static inline int ff_mpeg4_pred_dc ( MpegEncContext * s , int n , int level , int * dir_ptr , int encoding ) ;
2002-10-13 16:16:04 +03:00
2003-02-17 01:05:38 +02:00
# ifdef CONFIG_ENCODERS
2003-02-11 18:35:48 +02:00
static uint8_t uni_DCtab_lum_len [ 512 ] ;
static uint8_t uni_DCtab_chrom_len [ 512 ] ;
static uint16_t uni_DCtab_lum_bits [ 512 ] ;
static uint16_t uni_DCtab_chrom_bits [ 512 ] ;
2002-10-31 18:11:03 +02:00
2003-03-31 14:13:14 +03:00
static uint8_t ( * mv_penalty ) [ MAX_MV * 2 + 1 ] = NULL ;
2003-02-11 18:35:48 +02:00
static uint8_t fcode_tab [ MAX_MV * 2 + 1 ] ;
static uint8_t umv_fcode_tab [ MAX_MV * 2 + 1 ] ;
2002-03-22 04:21:17 +02:00
2002-12-31 19:23:56 +02:00
static uint32_t uni_mpeg4_intra_rl_bits [ 64 * 64 * 2 * 2 ] ;
static uint8_t uni_mpeg4_intra_rl_len [ 64 * 64 * 2 * 2 ] ;
static uint32_t uni_mpeg4_inter_rl_bits [ 64 * 64 * 2 * 2 ] ;
static uint8_t uni_mpeg4_inter_rl_len [ 64 * 64 * 2 * 2 ] ;
2004-09-24 23:35:59 +03:00
static uint8_t uni_h263_intra_aic_rl_len [ 64 * 64 * 2 * 2 ] ;
static uint8_t uni_h263_inter_rl_len [ 64 * 64 * 2 * 2 ] ;
2002-12-31 19:23:56 +02:00
//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level))
2002-09-07 03:16:30 +03:00
//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64)
2002-12-31 19:23:56 +02:00
# define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level))
2002-09-07 03:16:30 +03:00
/* mpeg4
inter
max level : 24 / 6
max run : 53 / 63
intra
max level : 53 / 16
max run : 29 / 41
*/
2002-10-31 18:11:03 +02:00
# endif
2005-05-05 17:34:47 +03:00
#if 0 //3IV1 is quite rare and it slows things down a tiny bit
2003-05-18 03:07:17 +03:00
# define IS_3IV1 s->avctx->codec_tag == ff_get_fourcc("3IV1")
2005-12-17 20:14:38 +02:00
# else
2003-05-18 03:07:17 +03:00
# define IS_3IV1 0
# endif
2002-03-25 17:36:16 +02:00
2001-07-22 17:18:56 +03:00
int h263_get_picture_format ( int width , int height )
{
int format ;
if ( width = = 128 & & height = = 96 )
2002-05-03 21:11:23 +03:00
format = 1 ;
2001-07-22 17:18:56 +03:00
else if ( width = = 176 & & height = = 144 )
2002-05-03 21:11:23 +03:00
format = 2 ;
2001-07-22 17:18:56 +03:00
else if ( width = = 352 & & height = = 288 )
2002-05-03 21:11:23 +03:00
format = 3 ;
2001-07-22 17:18:56 +03:00
else if ( width = = 704 & & height = = 576 )
2002-05-03 21:11:23 +03:00
format = 4 ;
2001-07-22 17:18:56 +03:00
else if ( width = = 1408 & & height = = 1152 )
2002-05-03 21:11:23 +03:00
format = 5 ;
2001-07-22 17:18:56 +03:00
else
format = 7 ;
return format ;
}
2003-02-17 01:05:38 +02:00
# ifdef CONFIG_ENCODERS
2003-10-20 23:23:46 +03:00
static void aspect_to_info ( MpegEncContext * s , AVRational aspect ) {
2002-11-25 11:23:19 +02:00
int i ;
2003-10-20 23:23:46 +03:00
if ( aspect . num = = 0 ) aspect = ( AVRational ) { 1 , 1 } ;
2002-11-25 11:23:19 +02:00
for ( i = 1 ; i < 6 ; i + + ) {
2003-10-20 23:23:46 +03:00
if ( av_cmp_q ( pixel_aspect [ i ] , aspect ) = = 0 ) {
2002-11-25 11:23:19 +02:00
s - > aspect_ratio_info = i ;
return ;
}
}
2005-12-17 20:14:38 +02:00
2002-11-25 11:23:19 +02:00
s - > aspect_ratio_info = FF_ASPECT_EXTENDED ;
2002-11-20 15:08:04 +02:00
}
2003-07-10 03:15:27 +03:00
void ff_flv_encode_picture_header ( MpegEncContext * s , int picture_number )
2001-07-22 17:18:56 +03:00
{
2003-07-10 03:15:27 +03:00
int format ;
2001-07-22 17:18:56 +03:00
2003-07-10 03:15:27 +03:00
align_put_bits ( & s - > pb ) ;
2002-02-09 18:59:56 +02:00
2003-07-10 02:10:59 +03:00
put_bits ( & s - > pb , 17 , 1 ) ;
put_bits ( & s - > pb , 5 , ( s - > h263_flv - 1 ) ) ; /* 0: h263 escape codes 1: 11-bit escape codes */
2005-05-01 00:43:59 +03:00
put_bits ( & s - > pb , 8 , ( ( ( int64_t ) s - > picture_number * 30 * s - > avctx - > time_base . num ) / //FIXME use timestamp
s - > avctx - > time_base . den ) & 0xff ) ; /* TemporalReference */
2003-07-10 02:10:59 +03:00
if ( s - > width = = 352 & & s - > height = = 288 )
format = 2 ;
else if ( s - > width = = 176 & & s - > height = = 144 )
format = 3 ;
else if ( s - > width = = 128 & & s - > height = = 96 )
format = 4 ;
else if ( s - > width = = 320 & & s - > height = = 240 )
format = 5 ;
else if ( s - > width = = 160 & & s - > height = = 120 )
format = 6 ;
else if ( s - > width < = 255 & & s - > height < = 255 )
format = 0 ; /* use 1 byte width & height */
else
format = 1 ; /* use 2 bytes width & height */
put_bits ( & s - > pb , 3 , format ) ; /* PictureSize */
if ( format = = 0 ) {
put_bits ( & s - > pb , 8 , s - > width ) ;
put_bits ( & s - > pb , 8 , s - > height ) ;
} else if ( format = = 1 ) {
put_bits ( & s - > pb , 16 , s - > width ) ;
put_bits ( & s - > pb , 16 , s - > height ) ;
}
put_bits ( & s - > pb , 2 , s - > pict_type = = P_TYPE ) ; /* PictureType */
2003-07-29 12:58:47 +03:00
put_bits ( & s - > pb , 1 , 1 ) ; /* DeblockingFlag: on */
2003-07-10 02:10:59 +03:00
put_bits ( & s - > pb , 5 , s - > qscale ) ; /* Quantizer */
put_bits ( & s - > pb , 1 , 0 ) ; /* ExtraInformation */
if ( s - > h263_aic ) {
2005-12-17 20:14:38 +02:00
s - > y_dc_scale_table =
2003-11-30 16:35:35 +02:00
s - > c_dc_scale_table = ff_aic_dc_scale_table ;
2003-07-10 02:10:59 +03:00
} else {
s - > y_dc_scale_table =
s - > c_dc_scale_table = ff_mpeg1_dc_scale_table ;
}
2003-07-10 03:15:27 +03:00
}
void h263_encode_picture_header ( MpegEncContext * s , int picture_number )
{
2004-03-11 00:11:49 +02:00
int format , coded_frame_rate , coded_frame_rate_base , i , temp_ref ;
int best_clock_code = 1 ;
int best_divisor = 60 ;
int best_error = INT_MAX ;
2005-12-17 20:14:38 +02:00
2004-03-11 00:11:49 +02:00
if ( s - > h263_plus ) {
for ( i = 0 ; i < 2 ; i + + ) {
int div , error ;
2005-05-01 00:43:59 +03:00
div = ( s - > avctx - > time_base . num * 1800000LL + 500LL * s - > avctx - > time_base . den ) / ( ( 1000LL + i ) * s - > avctx - > time_base . den ) ;
2004-03-11 00:11:49 +02:00
div = clip ( 1 , div , 127 ) ;
2005-05-01 00:43:59 +03:00
error = ABS ( s - > avctx - > time_base . num * 1800000LL - ( 1000LL + i ) * s - > avctx - > time_base . den * div ) ;
2004-03-11 00:11:49 +02:00
if ( error < best_error ) {
best_error = error ;
best_divisor = div ;
best_clock_code = i ;
}
}
}
s - > custom_pcf = best_clock_code ! = 1 | | best_divisor ! = 60 ;
coded_frame_rate = 1800000 ;
coded_frame_rate_base = ( 1000 + best_clock_code ) * best_divisor ;
2003-07-10 03:15:27 +03:00
align_put_bits ( & s - > pb ) ;
2003-07-10 02:10:59 +03:00
2002-02-09 18:59:56 +02:00
/* Update the pointer to last GOB */
2002-02-12 17:43:16 +02:00
s - > ptr_lastgob = pbBufPtr ( & s - > pb ) ;
2002-02-09 18:59:56 +02:00
put_bits ( & s - > pb , 22 , 0x20 ) ; /* PSC */
2005-05-01 00:43:59 +03:00
temp_ref = s - > picture_number * ( int64_t ) coded_frame_rate * s - > avctx - > time_base . num / //FIXME use timestamp
( coded_frame_rate_base * ( int64_t ) s - > avctx - > time_base . den ) ;
2004-03-11 00:11:49 +02:00
put_bits ( & s - > pb , 8 , temp_ref & 0xff ) ; /* TemporalReference */
2001-07-22 17:18:56 +03:00
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 1 ) ; /* marker */
put_bits ( & s - > pb , 1 , 0 ) ; /* h263 id */
put_bits ( & s - > pb , 1 , 0 ) ; /* split screen off */
put_bits ( & s - > pb , 1 , 0 ) ; /* camera off */
put_bits ( & s - > pb , 1 , 0 ) ; /* freeze picture release off */
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
format = h263_get_picture_format ( s - > width , s - > height ) ;
2001-07-22 17:18:56 +03:00
if ( ! s - > h263_plus ) {
/* H.263v1 */
put_bits ( & s - > pb , 3 , format ) ;
put_bits ( & s - > pb , 1 , ( s - > pict_type = = P_TYPE ) ) ;
/* By now UMV IS DISABLED ON H.263v1, since the restrictions
of H .263 v1 UMV implies to check the predicted MV after
calculation of the current MB to see if we ' re on the limits */
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* Unrestricted Motion Vector: off */
put_bits ( & s - > pb , 1 , 0 ) ; /* SAC: off */
put_bits ( & s - > pb , 1 , s - > obmc ) ; /* Advanced Prediction */
put_bits ( & s - > pb , 1 , 0 ) ; /* only I/P frames, no PB frame */
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 5 , s - > qscale ) ;
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* Continuous Presence Multipoint mode: off */
2001-07-22 17:18:56 +03:00
} else {
2004-03-11 00:11:49 +02:00
int ufep = 1 ;
2001-07-22 17:18:56 +03:00
/* H.263v2 */
/* H.263 Plus PTYPE */
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 3 , 7 ) ;
2004-03-11 00:11:49 +02:00
put_bits ( & s - > pb , 3 , ufep ) ; /* Update Full Extended PTYPE */
2001-08-29 02:32:34 +03:00
if ( format = = 7 )
put_bits ( & s - > pb , 3 , 6 ) ; /* Custom Source Format */
else
put_bits ( & s - > pb , 3 , format ) ;
2005-12-17 20:14:38 +02:00
2004-03-11 00:11:49 +02:00
put_bits ( & s - > pb , 1 , s - > custom_pcf ) ;
2003-12-07 03:33:45 +02:00
put_bits ( & s - > pb , 1 , s - > umvplus ) ; /* Unrestricted Motion Vector */
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 1 , 0 ) ; /* SAC: off */
2003-11-28 23:31:20 +02:00
put_bits ( & s - > pb , 1 , s - > obmc ) ; /* Advanced Prediction Mode */
2002-05-02 07:39:45 +03:00
put_bits ( & s - > pb , 1 , s - > h263_aic ) ; /* Advanced Intra Coding */
2003-12-01 17:23:14 +02:00
put_bits ( & s - > pb , 1 , s - > loop_filter ) ; /* Deblocking Filter */
2003-12-07 03:33:45 +02:00
put_bits ( & s - > pb , 1 , s - > h263_slice_structured ) ; /* Slice Structured */
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 1 , 0 ) ; /* Reference Picture Selection: off */
put_bits ( & s - > pb , 1 , 0 ) ; /* Independent Segment Decoding: off */
2003-11-29 10:37:51 +02:00
put_bits ( & s - > pb , 1 , s - > alt_inter_vlc ) ; /* Alternative Inter VLC */
2003-12-01 17:23:14 +02:00
put_bits ( & s - > pb , 1 , s - > modified_quant ) ; /* Modified Quantization: */
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 1 , 1 ) ; /* "1" to prevent start code emulation */
put_bits ( & s - > pb , 3 , 0 ) ; /* Reserved */
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 3 , s - > pict_type = = P_TYPE ) ;
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 1 , 0 ) ; /* Reference Picture Resampling: off */
put_bits ( & s - > pb , 1 , 0 ) ; /* Reduced-Resolution Update: off */
2002-05-02 07:39:45 +03:00
put_bits ( & s - > pb , 1 , s - > no_rounding ) ; /* Rounding Type */
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 2 , 0 ) ; /* Reserved */
put_bits ( & s - > pb , 1 , 1 ) ; /* "1" to prevent start code emulation */
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
/* This should be here if PLUSPTYPE */
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* Continuous Presence Multipoint mode: off */
2005-12-17 20:14:38 +02:00
2005-12-22 03:10:11 +02:00
if ( format = = 7 ) {
2001-08-29 02:32:34 +03:00
/* Custom Picture Format (CPFMT) */
2003-10-20 23:23:46 +03:00
aspect_to_info ( s , s - > avctx - > sample_aspect_ratio ) ;
2002-11-20 15:08:04 +02:00
put_bits ( & s - > pb , 4 , s - > aspect_ratio_info ) ;
2001-08-29 02:32:34 +03:00
put_bits ( & s - > pb , 9 , ( s - > width > > 2 ) - 1 ) ;
put_bits ( & s - > pb , 1 , 1 ) ; /* "1" to prevent start code emulation */
put_bits ( & s - > pb , 9 , ( s - > height > > 2 ) ) ;
2003-10-20 23:23:46 +03:00
if ( s - > aspect_ratio_info = = FF_ASPECT_EXTENDED ) {
put_bits ( & s - > pb , 8 , s - > avctx - > sample_aspect_ratio . num ) ;
put_bits ( & s - > pb , 8 , s - > avctx - > sample_aspect_ratio . den ) ;
2005-12-22 03:10:11 +02:00
}
2001-08-29 02:32:34 +03:00
}
2004-03-11 00:11:49 +02:00
if ( s - > custom_pcf ) {
if ( ufep ) {
put_bits ( & s - > pb , 1 , best_clock_code ) ;
put_bits ( & s - > pb , 7 , best_divisor ) ;
}
put_bits ( & s - > pb , 2 , ( temp_ref > > 8 ) & 3 ) ;
}
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
/* Unlimited Unrestricted Motion Vectors Indicator (UUI) */
2001-08-31 09:21:27 +03:00
if ( s - > umvplus )
2003-02-28 15:07:07 +02:00
// put_bits(&s->pb,1,1); /* Limited according tables of Annex D */
2003-12-01 17:23:14 +02:00
//FIXME check actual requested range
2003-02-28 15:07:07 +02:00
put_bits ( & s - > pb , 2 , 1 ) ; /* unlimited */
2003-12-07 03:33:45 +02:00
if ( s - > h263_slice_structured )
put_bits ( & s - > pb , 2 , 0 ) ; /* no weird submodes */
2003-02-28 15:07:07 +02:00
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 5 , s - > qscale ) ;
}
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* no PEI */
2002-06-18 03:46:02 +03:00
2003-12-09 15:47:08 +02:00
if ( s - > h263_slice_structured ) {
put_bits ( & s - > pb , 1 , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-12-09 15:47:08 +02:00
assert ( s - > mb_x = = 0 & & s - > mb_y = = 0 ) ;
ff_h263_encode_mba ( s ) ;
put_bits ( & s - > pb , 1 , 1 ) ;
}
2002-06-18 03:46:02 +03:00
if ( s - > h263_aic ) {
2005-12-17 20:14:38 +02:00
s - > y_dc_scale_table =
2003-11-30 16:35:35 +02:00
s - > c_dc_scale_table = ff_aic_dc_scale_table ;
2002-06-18 03:46:02 +03:00
} else {
s - > y_dc_scale_table =
s - > c_dc_scale_table = ff_mpeg1_dc_scale_table ;
}
2001-07-22 17:18:56 +03:00
}
2002-10-25 03:08:32 +03:00
/**
* Encodes a group of blocks header .
*/
2003-12-07 03:33:45 +02:00
void h263_encode_gob_header ( MpegEncContext * s , int mb_line )
2001-11-19 04:13:14 +02:00
{
2003-12-07 03:33:45 +02:00
put_bits ( & s - > pb , 17 , 1 ) ; /* GBSC */
if ( s - > h263_slice_structured ) {
put_bits ( & s - > pb , 1 , 1 ) ;
ff_h263_encode_mba ( s ) ;
if ( s - > mb_num > 1583 )
put_bits ( & s - > pb , 1 , 1 ) ;
put_bits ( & s - > pb , 5 , s - > qscale ) ; /* GQUANT */
put_bits ( & s - > pb , 1 , 1 ) ;
put_bits ( & s - > pb , 2 , s - > pict_type = = I_TYPE ) ; /* GFID */
} else {
int gob_number = mb_line / s - > gob_index ;
put_bits ( & s - > pb , 5 , gob_number ) ; /* GN */
put_bits ( & s - > pb , 2 , s - > pict_type = = I_TYPE ) ; /* GFID */
put_bits ( & s - > pb , 5 , s - > qscale ) ; /* GQUANT */
}
2001-11-19 04:13:14 +02:00
}
2002-03-15 06:10:53 +02:00
2003-10-01 18:41:36 +03:00
static inline int get_block_rate ( MpegEncContext * s , DCTELEM block [ 64 ] , int block_last_index , uint8_t scantable [ 64 ] ) {
int last = 0 ;
int j ;
int rate = 0 ;
for ( j = 1 ; j < = block_last_index ; j + + ) {
const int index = scantable [ j ] ;
int level = block [ index ] ;
if ( level ) {
level + = 64 ;
if ( ( level & ( ~ 127 ) ) = = 0 ) {
if ( j < block_last_index ) rate + = s - > intra_ac_vlc_length [ UNI_AC_ENC_INDEX ( j - last - 1 , level ) ] ;
else rate + = s - > intra_ac_vlc_last_length [ UNI_AC_ENC_INDEX ( j - last - 1 , level ) ] ;
} else
rate + = s - > ac_esc_length ;
level - = 64 ;
last = j ;
}
}
2005-12-17 20:14:38 +02:00
2003-10-01 18:41:36 +03:00
return rate ;
}
static inline int decide_ac_pred ( MpegEncContext * s , DCTELEM block [ 6 ] [ 64 ] , int dir [ 6 ] , uint8_t * st [ 6 ] , int zigzag_last_index [ 6 ] )
2002-03-15 06:10:53 +02:00
{
2003-10-01 18:41:36 +03:00
int score = 0 ;
2002-03-15 06:10:53 +02:00
int i , n ;
2002-12-04 12:04:03 +02:00
int8_t * const qscale_table = s - > current_picture . qscale_table ;
2002-03-15 06:10:53 +02:00
2003-10-01 18:41:36 +03:00
memcpy ( zigzag_last_index , s - > block_last_index , sizeof ( int ) * 6 ) ;
2005-12-17 20:14:38 +02:00
2002-03-15 06:10:53 +02:00
for ( n = 0 ; n < 6 ; n + + ) {
2003-02-11 18:35:48 +02:00
int16_t * ac_val , * ac_val1 ;
2005-12-17 20:14:38 +02:00
2003-10-01 18:41:36 +03:00
score - = get_block_rate ( s , block [ n ] , s - > block_last_index [ n ] , s - > intra_scantable . permutated ) ;
2002-03-15 06:10:53 +02:00
2002-03-15 16:57:17 +02:00
ac_val = s - > ac_val [ 0 ] [ 0 ] + s - > block_index [ n ] * 16 ;
2002-03-15 06:10:53 +02:00
ac_val1 = ac_val ;
if ( dir [ n ] ) {
2003-04-10 16:18:38 +03:00
const int xy = s - > mb_x + s - > mb_y * s - > mb_stride - s - > mb_stride ;
2002-09-24 12:15:46 +03:00
/* top prediction */
2002-03-15 16:57:17 +02:00
ac_val - = s - > block_wrap [ n ] * 16 ;
2002-12-04 12:04:03 +02:00
if ( s - > mb_y = = 0 | | s - > qscale = = qscale_table [ xy ] | | n = = 2 | | n = = 3 ) {
2002-09-24 12:15:46 +03:00
/* same qscale */
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
const int level = block [ n ] [ s - > dsp . idct_permutation [ i ] ] ;
2003-10-01 18:41:36 +03:00
block [ n ] [ s - > dsp . idct_permutation [ i ] ] = level - ac_val [ i + 8 ] ;
2003-03-03 16:54:00 +02:00
ac_val1 [ i ] = block [ n ] [ s - > dsp . idct_permutation [ i < < 3 ] ] ;
2002-09-24 12:15:46 +03:00
ac_val1 [ i + 8 ] = level ;
}
} else {
/* different qscale, we must rescale */
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
const int level = block [ n ] [ s - > dsp . idct_permutation [ i ] ] ;
2003-10-01 18:41:36 +03:00
block [ n ] [ s - > dsp . idct_permutation [ i ] ] = level - ROUNDED_DIV ( ac_val [ i + 8 ] * qscale_table [ xy ] , s - > qscale ) ;
2003-03-03 16:54:00 +02:00
ac_val1 [ i ] = block [ n ] [ s - > dsp . idct_permutation [ i < < 3 ] ] ;
2002-09-24 12:15:46 +03:00
ac_val1 [ i + 8 ] = level ;
}
2002-03-15 06:10:53 +02:00
}
2003-10-01 18:41:36 +03:00
st [ n ] = s - > intra_h_scantable . permutated ;
2002-03-15 06:10:53 +02:00
} else {
2003-04-10 16:18:38 +03:00
const int xy = s - > mb_x - 1 + s - > mb_y * s - > mb_stride ;
2002-09-24 12:15:46 +03:00
/* left prediction */
2002-03-15 06:10:53 +02:00
ac_val - = 16 ;
2002-12-04 12:04:03 +02:00
if ( s - > mb_x = = 0 | | s - > qscale = = qscale_table [ xy ] | | n = = 1 | | n = = 3 ) {
2002-09-24 12:15:46 +03:00
/* same qscale */
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
const int level = block [ n ] [ s - > dsp . idct_permutation [ i < < 3 ] ] ;
2003-10-01 18:41:36 +03:00
block [ n ] [ s - > dsp . idct_permutation [ i < < 3 ] ] = level - ac_val [ i ] ;
2002-09-24 12:15:46 +03:00
ac_val1 [ i ] = level ;
2003-03-03 16:54:00 +02:00
ac_val1 [ i + 8 ] = block [ n ] [ s - > dsp . idct_permutation [ i ] ] ;
2002-09-24 12:15:46 +03:00
}
} else {
/* different qscale, we must rescale */
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
const int level = block [ n ] [ s - > dsp . idct_permutation [ i < < 3 ] ] ;
2003-10-01 18:41:36 +03:00
block [ n ] [ s - > dsp . idct_permutation [ i < < 3 ] ] = level - ROUNDED_DIV ( ac_val [ i ] * qscale_table [ xy ] , s - > qscale ) ;
2002-09-24 12:15:46 +03:00
ac_val1 [ i ] = level ;
2003-03-03 16:54:00 +02:00
ac_val1 [ i + 8 ] = block [ n ] [ s - > dsp . idct_permutation [ i ] ] ;
2002-09-24 12:15:46 +03:00
}
2002-03-15 06:10:53 +02:00
}
2003-10-01 18:41:36 +03:00
st [ n ] = s - > intra_v_scantable . permutated ;
2002-03-15 06:10:53 +02:00
}
2003-10-01 18:41:36 +03:00
for ( i = 63 ; i > 0 ; i - - ) //FIXME optimize
if ( block [ n ] [ st [ n ] [ i ] ] ) break ;
s - > block_last_index [ n ] = i ;
score + = get_block_rate ( s , block [ n ] , s - > block_last_index [ n ] , st [ n ] ) ;
2002-03-15 06:10:53 +02:00
}
2003-10-01 18:41:36 +03:00
return score < 0 ;
}
static inline void restore_ac_coeffs ( MpegEncContext * s , DCTELEM block [ 6 ] [ 64 ] , int dir [ 6 ] , uint8_t * st [ 6 ] , int zigzag_last_index [ 6 ] )
{
int i , n ;
memcpy ( s - > block_last_index , zigzag_last_index , sizeof ( int ) * 6 ) ;
for ( n = 0 ; n < 6 ; n + + ) {
int16_t * ac_val = s - > ac_val [ 0 ] [ 0 ] + s - > block_index [ n ] * 16 ;
st [ n ] = s - > intra_scantable . permutated ;
if ( dir [ n ] ) {
/* top prediction */
for ( i = 1 ; i < 8 ; i + + ) {
block [ n ] [ s - > dsp . idct_permutation [ i ] ] = ac_val [ i + 8 ] ;
}
} else {
/* left prediction */
for ( i = 1 ; i < 8 ; i + + ) {
block [ n ] [ s - > dsp . idct_permutation [ i < < 3 ] ] = ac_val [ i ] ;
}
}
}
2002-03-15 06:10:53 +02:00
}
2002-10-13 16:16:04 +03:00
/**
* modify qscale so that encoding is acually possible in h263 ( limit difference to - 2. .2 )
*/
2002-09-24 18:07:44 +03:00
void ff_clean_h263_qscales ( MpegEncContext * s ) {
2002-09-23 17:56:11 +03:00
int i ;
2002-12-04 12:04:03 +02:00
int8_t * const qscale_table = s - > current_picture . qscale_table ;
2005-12-17 20:14:38 +02:00
2002-09-23 17:56:11 +03:00
for ( i = 1 ; i < s - > mb_num ; i + + ) {
2003-04-10 16:18:38 +03:00
if ( qscale_table [ s - > mb_index2xy [ i ] ] - qscale_table [ s - > mb_index2xy [ i - 1 ] ] > 2 )
qscale_table [ s - > mb_index2xy [ i ] ] = qscale_table [ s - > mb_index2xy [ i - 1 ] ] + 2 ;
2002-09-23 17:56:11 +03:00
}
for ( i = s - > mb_num - 2 ; i > = 0 ; i - - ) {
2003-04-10 16:18:38 +03:00
if ( qscale_table [ s - > mb_index2xy [ i ] ] - qscale_table [ s - > mb_index2xy [ i + 1 ] ] > 2 )
qscale_table [ s - > mb_index2xy [ i ] ] = qscale_table [ s - > mb_index2xy [ i + 1 ] ] + 2 ;
2002-09-23 17:56:11 +03:00
}
2004-04-27 00:46:01 +03:00
if ( s - > codec_id ! = CODEC_ID_H263P ) {
for ( i = 1 ; i < s - > mb_num ; i + + ) {
int mb_xy = s - > mb_index2xy [ i ] ;
2005-12-17 20:14:38 +02:00
2004-04-27 00:46:01 +03:00
if ( qscale_table [ mb_xy ] ! = qscale_table [ s - > mb_index2xy [ i - 1 ] ] & & ( s - > mb_type [ mb_xy ] & CANDIDATE_MB_TYPE_INTER4V ) ) {
s - > mb_type [ mb_xy ] & = ~ CANDIDATE_MB_TYPE_INTER4V ;
s - > mb_type [ mb_xy ] | = CANDIDATE_MB_TYPE_INTER ;
}
}
}
2002-09-24 18:07:44 +03:00
}
2002-10-13 16:16:04 +03:00
/**
* modify mb_type & qscale so that encoding is acually possible in mpeg4
*/
2002-09-24 18:07:44 +03:00
void ff_clean_mpeg4_qscales ( MpegEncContext * s ) {
int i ;
2002-12-04 12:04:03 +02:00
int8_t * const qscale_table = s - > current_picture . qscale_table ;
2002-09-24 18:07:44 +03:00
ff_clean_h263_qscales ( s ) ;
2005-12-17 20:14:38 +02:00
2002-09-23 17:56:11 +03:00
if ( s - > pict_type = = B_TYPE ) {
int odd = 0 ;
2005-05-05 17:34:47 +03:00
/* ok, come on, this isn't funny anymore, there's more code for handling this mpeg4 mess than for the actual adaptive quantization */
2005-12-17 20:14:38 +02:00
2002-09-23 17:56:11 +03:00
for ( i = 0 ; i < s - > mb_num ; i + + ) {
2003-04-10 16:18:38 +03:00
int mb_xy = s - > mb_index2xy [ i ] ;
odd + = qscale_table [ mb_xy ] & 1 ;
2002-09-23 17:56:11 +03:00
}
2005-12-17 20:14:38 +02:00
2002-09-23 17:56:11 +03:00
if ( 2 * odd > s - > mb_num ) odd = 1 ;
else odd = 0 ;
2005-12-17 20:14:38 +02:00
2002-09-23 17:56:11 +03:00
for ( i = 0 ; i < s - > mb_num ; i + + ) {
2003-04-10 16:18:38 +03:00
int mb_xy = s - > mb_index2xy [ i ] ;
if ( ( qscale_table [ mb_xy ] & 1 ) ! = odd )
qscale_table [ mb_xy ] + + ;
if ( qscale_table [ mb_xy ] > 31 )
qscale_table [ mb_xy ] = 31 ;
2005-12-17 20:14:38 +02:00
}
2002-09-23 17:56:11 +03:00
for ( i = 1 ; i < s - > mb_num ; i + + ) {
2003-04-10 16:18:38 +03:00
int mb_xy = s - > mb_index2xy [ i ] ;
2003-12-30 18:07:57 +02:00
if ( qscale_table [ mb_xy ] ! = qscale_table [ s - > mb_index2xy [ i - 1 ] ] & & ( s - > mb_type [ mb_xy ] & CANDIDATE_MB_TYPE_DIRECT ) ) {
s - > mb_type [ mb_xy ] & = ~ CANDIDATE_MB_TYPE_DIRECT ;
s - > mb_type [ mb_xy ] | = CANDIDATE_MB_TYPE_BIDIR ;
2002-09-23 17:56:11 +03:00
}
}
}
}
2003-02-17 01:05:38 +02:00
# endif //CONFIG_ENCODERS
2006-04-03 10:52:24 +03:00
2006-04-09 09:53:40 +03:00
# define tab_size ((signed)(sizeof(s->direct_scale_mv[0]) / sizeof(int16_t)))
2006-04-09 09:04:00 +03:00
# define tab_bias (tab_size / 2)
2006-09-30 02:34:42 +03:00
void ff_mpeg4_init_direct_mv ( MpegEncContext * s ) {
2006-04-03 10:52:24 +03:00
int i ;
for ( i = 0 ; i < tab_size ; i + + ) {
s - > direct_scale_mv [ 0 ] [ i ] = ( i - tab_bias ) * s - > pb_time / s - > pp_time ;
s - > direct_scale_mv [ 1 ] [ i ] = ( i - tab_bias ) * ( s - > pb_time - s - > pp_time ) / s - > pp_time ;
}
}
static inline void ff_mpeg4_set_one_direct_mv ( MpegEncContext * s , int mx , int my , int i ) {
int xy = s - > block_index [ i ] ;
uint16_t time_pp = s - > pp_time ;
uint16_t time_pb = s - > pb_time ;
int p_mx , p_my ;
p_mx = s - > next_picture . motion_val [ 0 ] [ xy ] [ 0 ] ;
if ( ( unsigned ) ( p_mx + tab_bias ) < tab_size ) {
s - > mv [ 0 ] [ i ] [ 0 ] = s - > direct_scale_mv [ 0 ] [ p_mx + tab_bias ] + mx ;
s - > mv [ 1 ] [ i ] [ 0 ] = mx ? s - > mv [ 0 ] [ i ] [ 0 ] - p_mx
: s - > direct_scale_mv [ 1 ] [ p_mx + tab_bias ] ;
} else {
s - > mv [ 0 ] [ i ] [ 0 ] = p_mx * time_pb / time_pp + mx ;
s - > mv [ 1 ] [ i ] [ 0 ] = mx ? s - > mv [ 0 ] [ i ] [ 0 ] - p_mx
: p_mx * ( time_pb - time_pp ) / time_pp ;
}
p_my = s - > next_picture . motion_val [ 0 ] [ xy ] [ 1 ] ;
if ( ( unsigned ) ( p_my + tab_bias ) < tab_size ) {
s - > mv [ 0 ] [ i ] [ 1 ] = s - > direct_scale_mv [ 0 ] [ p_my + tab_bias ] + my ;
s - > mv [ 1 ] [ i ] [ 1 ] = my ? s - > mv [ 0 ] [ i ] [ 1 ] - p_my
: s - > direct_scale_mv [ 1 ] [ p_my + tab_bias ] ;
} else {
s - > mv [ 0 ] [ i ] [ 1 ] = p_my * time_pb / time_pp + my ;
s - > mv [ 1 ] [ i ] [ 1 ] = my ? s - > mv [ 0 ] [ i ] [ 1 ] - p_my
: p_my * ( time_pb - time_pp ) / time_pp ;
}
}
2006-04-09 09:04:00 +03:00
# undef tab_size
# undef tab_bias
2003-04-10 16:18:38 +03:00
/**
*
* @ return the mb_type
*/
int ff_mpeg4_set_direct_mv ( MpegEncContext * s , int mx , int my ) {
const int mb_index = s - > mb_x + s - > mb_y * s - > mb_stride ;
2003-12-30 18:07:57 +02:00
const int colocated_mb_type = s - > next_picture . mb_type [ mb_index ] ;
2002-12-28 01:51:46 +02:00
uint16_t time_pp = s - > pp_time ;
uint16_t time_pb = s - > pb_time ;
int i ;
2005-12-17 20:14:38 +02:00
2002-12-28 01:51:46 +02:00
//FIXME avoid divides
2006-04-03 10:52:24 +03:00
// try special case with shifts for 1 and 3 B-frames?
2005-12-17 20:14:38 +02:00
2003-04-10 16:18:38 +03:00
if ( IS_8X8 ( colocated_mb_type ) ) {
2002-12-28 01:51:46 +02:00
s - > mv_type = MV_TYPE_8X8 ;
for ( i = 0 ; i < 4 ; i + + ) {
2006-04-03 10:52:24 +03:00
ff_mpeg4_set_one_direct_mv ( s , mx , my , i ) ;
2002-12-28 01:51:46 +02:00
}
2003-04-10 16:18:38 +03:00
return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1 ;
} else if ( IS_INTERLACED ( colocated_mb_type ) ) {
2002-12-28 01:51:46 +02:00
s - > mv_type = MV_TYPE_FIELD ;
for ( i = 0 ; i < 2 ; i + + ) {
2004-04-19 06:33:23 +03:00
int field_select = s - > next_picture . ref_index [ 0 ] [ s - > block_index [ 2 * i ] ] ;
2006-03-20 03:18:56 +02:00
s - > field_select [ 0 ] [ i ] = field_select ;
s - > field_select [ 1 ] [ i ] = i ;
2002-12-28 01:51:46 +02:00
if ( s - > top_field_first ) {
2004-04-19 06:33:23 +03:00
time_pp = s - > pp_field_time - field_select + i ;
time_pb = s - > pb_field_time - field_select + i ;
2002-12-28 01:51:46 +02:00
} else {
2004-04-19 06:33:23 +03:00
time_pp = s - > pp_field_time + field_select - i ;
time_pb = s - > pb_field_time + field_select - i ;
2002-12-28 01:51:46 +02:00
}
2003-12-30 18:07:57 +02:00
s - > mv [ 0 ] [ i ] [ 0 ] = s - > p_field_mv_table [ i ] [ 0 ] [ mb_index ] [ 0 ] * time_pb / time_pp + mx ;
s - > mv [ 0 ] [ i ] [ 1 ] = s - > p_field_mv_table [ i ] [ 0 ] [ mb_index ] [ 1 ] * time_pb / time_pp + my ;
s - > mv [ 1 ] [ i ] [ 0 ] = mx ? s - > mv [ 0 ] [ i ] [ 0 ] - s - > p_field_mv_table [ i ] [ 0 ] [ mb_index ] [ 0 ]
: s - > p_field_mv_table [ i ] [ 0 ] [ mb_index ] [ 0 ] * ( time_pb - time_pp ) / time_pp ;
2005-12-17 20:14:38 +02:00
s - > mv [ 1 ] [ i ] [ 1 ] = my ? s - > mv [ 0 ] [ i ] [ 1 ] - s - > p_field_mv_table [ i ] [ 0 ] [ mb_index ] [ 1 ]
2003-12-30 18:07:57 +02:00
: s - > p_field_mv_table [ i ] [ 0 ] [ mb_index ] [ 1 ] * ( time_pb - time_pp ) / time_pp ;
2002-12-28 01:51:46 +02:00
}
2003-04-10 16:18:38 +03:00
return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED ;
} else {
2006-04-03 10:52:24 +03:00
ff_mpeg4_set_one_direct_mv ( s , mx , my , 0 ) ;
s - > mv [ 0 ] [ 1 ] [ 0 ] = s - > mv [ 0 ] [ 2 ] [ 0 ] = s - > mv [ 0 ] [ 3 ] [ 0 ] = s - > mv [ 0 ] [ 0 ] [ 0 ] ;
s - > mv [ 0 ] [ 1 ] [ 1 ] = s - > mv [ 0 ] [ 2 ] [ 1 ] = s - > mv [ 0 ] [ 3 ] [ 1 ] = s - > mv [ 0 ] [ 0 ] [ 1 ] ;
s - > mv [ 1 ] [ 1 ] [ 0 ] = s - > mv [ 1 ] [ 2 ] [ 0 ] = s - > mv [ 1 ] [ 3 ] [ 0 ] = s - > mv [ 1 ] [ 0 ] [ 0 ] ;
s - > mv [ 1 ] [ 1 ] [ 1 ] = s - > mv [ 1 ] [ 2 ] [ 1 ] = s - > mv [ 1 ] [ 3 ] [ 1 ] = s - > mv [ 1 ] [ 0 ] [ 1 ] ;
2003-04-10 16:18:38 +03:00
if ( ( s - > avctx - > workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE ) | | ! s - > quarter_sample )
s - > mv_type = MV_TYPE_16X16 ;
else
s - > mv_type = MV_TYPE_8X8 ;
return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1 ; //Note see prev line
2002-12-28 01:51:46 +02:00
}
}
2003-07-29 05:09:12 +03:00
void ff_h263_update_motion_val ( MpegEncContext * s ) {
const int mb_xy = s - > mb_y * s - > mb_stride + s - > mb_x ;
2005-05-05 17:34:47 +03:00
//FIXME a lot of that is only needed for !low_delay
2004-04-16 04:01:45 +03:00
const int wrap = s - > b8_stride ;
2003-07-29 05:09:12 +03:00
const int xy = s - > block_index [ 0 ] ;
2005-12-17 20:14:38 +02:00
s - > current_picture . mbskip_table [ mb_xy ] = s - > mb_skipped ;
2003-07-29 05:09:12 +03:00
if ( s - > mv_type ! = MV_TYPE_8X8 ) {
int motion_x , motion_y ;
if ( s - > mb_intra ) {
motion_x = 0 ;
motion_y = 0 ;
} else if ( s - > mv_type = = MV_TYPE_16X16 ) {
motion_x = s - > mv [ 0 ] [ 0 ] [ 0 ] ;
motion_y = s - > mv [ 0 ] [ 0 ] [ 1 ] ;
} else /*if (s->mv_type == MV_TYPE_FIELD)*/ {
int i ;
motion_x = s - > mv [ 0 ] [ 0 ] [ 0 ] + s - > mv [ 0 ] [ 1 ] [ 0 ] ;
motion_y = s - > mv [ 0 ] [ 0 ] [ 1 ] + s - > mv [ 0 ] [ 1 ] [ 1 ] ;
motion_x = ( motion_x > > 1 ) | ( motion_x & 1 ) ;
for ( i = 0 ; i < 2 ; i + + ) {
2003-12-30 18:07:57 +02:00
s - > p_field_mv_table [ i ] [ 0 ] [ mb_xy ] [ 0 ] = s - > mv [ 0 ] [ i ] [ 0 ] ;
s - > p_field_mv_table [ i ] [ 0 ] [ mb_xy ] [ 1 ] = s - > mv [ 0 ] [ i ] [ 1 ] ;
2003-07-29 05:09:12 +03:00
}
2004-04-19 06:33:23 +03:00
s - > current_picture . ref_index [ 0 ] [ xy ] =
s - > current_picture . ref_index [ 0 ] [ xy + 1 ] = s - > field_select [ 0 ] [ 0 ] ;
s - > current_picture . ref_index [ 0 ] [ xy + wrap ] =
s - > current_picture . ref_index [ 0 ] [ xy + wrap + 1 ] = s - > field_select [ 0 ] [ 1 ] ;
2003-07-29 05:09:12 +03:00
}
2004-04-19 06:33:23 +03:00
2003-07-29 05:09:12 +03:00
/* no update if 8X8 because it has been done during parsing */
2003-12-09 03:49:56 +02:00
s - > current_picture . motion_val [ 0 ] [ xy ] [ 0 ] = motion_x ;
s - > current_picture . motion_val [ 0 ] [ xy ] [ 1 ] = motion_y ;
s - > current_picture . motion_val [ 0 ] [ xy + 1 ] [ 0 ] = motion_x ;
s - > current_picture . motion_val [ 0 ] [ xy + 1 ] [ 1 ] = motion_y ;
s - > current_picture . motion_val [ 0 ] [ xy + wrap ] [ 0 ] = motion_x ;
s - > current_picture . motion_val [ 0 ] [ xy + wrap ] [ 1 ] = motion_y ;
s - > current_picture . motion_val [ 0 ] [ xy + 1 + wrap ] [ 0 ] = motion_x ;
s - > current_picture . motion_val [ 0 ] [ xy + 1 + wrap ] [ 1 ] = motion_y ;
2003-07-29 05:09:12 +03:00
}
if ( s - > encoding ) { //FIXME encoding MUST be cleaned up
2005-12-17 20:14:38 +02:00
if ( s - > mv_type = = MV_TYPE_8X8 )
2003-07-29 05:09:12 +03:00
s - > current_picture . mb_type [ mb_xy ] = MB_TYPE_L0 | MB_TYPE_8x8 ;
2003-11-28 23:31:20 +02:00
else if ( s - > mb_intra )
s - > current_picture . mb_type [ mb_xy ] = MB_TYPE_INTRA ;
2003-07-29 05:09:12 +03:00
else
s - > current_picture . mb_type [ mb_xy ] = MB_TYPE_L0 | MB_TYPE_16x16 ;
}
}
2002-10-31 18:11:03 +02:00
# ifdef CONFIG_ENCODERS
2003-10-01 01:18:43 +03:00
2005-02-06 19:01:07 +02:00
static inline int h263_get_motion_length ( MpegEncContext * s , int val , int f_code ) {
int l , bit_size , code ;
if ( val = = 0 ) {
return mvtab [ 0 ] [ 1 ] ;
} else {
bit_size = f_code - 1 ;
/* modulo encoding */
l = INT_BIT - 6 - bit_size ;
val = ( val < < l ) > > l ;
val - - ;
code = ( val > > bit_size ) + 1 ;
return mvtab [ code ] [ 1 ] + 1 + bit_size ;
}
}
static inline void ff_h263_encode_motion_vector ( MpegEncContext * s , int x , int y , int f_code ) {
if ( s - > flags2 & CODEC_FLAG2_NO_OUTPUT ) {
2005-12-17 20:14:38 +02:00
skip_put_bits ( & s - > pb ,
2005-02-06 19:01:07 +02:00
h263_get_motion_length ( s , x , f_code )
+ h263_get_motion_length ( s , y , f_code ) ) ;
} else {
ff_h263_encode_motion ( s , x , f_code ) ;
ff_h263_encode_motion ( s , y , f_code ) ;
}
}
2003-10-01 01:18:43 +03:00
static inline int get_p_cbp ( MpegEncContext * s ,
DCTELEM block [ 6 ] [ 64 ] ,
int motion_x , int motion_y ) {
int cbp , i ;
if ( s - > flags & CODEC_FLAG_CBP_RD ) {
int best_cbpy_score = INT_MAX ;
int best_cbpc_score = INT_MAX ;
2003-11-03 15:26:22 +02:00
int cbpc = ( - 1 ) , cbpy = ( - 1 ) ;
2003-10-01 01:18:43 +03:00
const int offset = ( s - > mv_type = = MV_TYPE_16X16 ? 0 : 16 ) + ( s - > dquant ? 8 : 0 ) ;
2003-10-07 14:32:40 +03:00
const int lambda = s - > lambda2 > > ( FF_LAMBDA_SHIFT - 6 ) ;
2003-10-01 01:18:43 +03:00
for ( i = 0 ; i < 4 ; i + + ) {
int score = inter_MCBPC_bits [ i + offset ] * lambda ;
if ( i & 1 ) score + = s - > coded_score [ 5 ] ;
if ( i & 2 ) score + = s - > coded_score [ 4 ] ;
if ( score < best_cbpc_score ) {
best_cbpc_score = score ;
cbpc = i ;
}
}
for ( i = 0 ; i < 16 ; i + + ) {
int score = cbpy_tab [ i ^ 0xF ] [ 1 ] * lambda ;
if ( i & 1 ) score + = s - > coded_score [ 3 ] ;
if ( i & 2 ) score + = s - > coded_score [ 2 ] ;
if ( i & 4 ) score + = s - > coded_score [ 1 ] ;
if ( i & 8 ) score + = s - > coded_score [ 0 ] ;
if ( score < best_cbpy_score ) {
best_cbpy_score = score ;
cbpy = i ;
}
}
cbp = cbpc + 4 * cbpy ;
if ( ( motion_x | motion_y | s - > dquant ) = = 0 & & s - > mv_type = = MV_TYPE_16X16 ) {
if ( best_cbpy_score + best_cbpc_score + 2 * lambda > = 0 )
cbp = 0 ;
}
for ( i = 0 ; i < 6 ; i + + ) {
if ( s - > block_last_index [ i ] > = 0 & & ( ( cbp > > ( 5 - i ) ) & 1 ) = = 0 ) {
s - > block_last_index [ i ] = - 1 ;
memset ( s - > block [ i ] , 0 , sizeof ( DCTELEM ) * 64 ) ;
}
}
} else {
cbp = 0 ;
for ( i = 0 ; i < 6 ; i + + ) {
if ( s - > block_last_index [ i ] > = 0 )
cbp | = 1 < < ( 5 - i ) ;
}
}
return cbp ;
}
static inline int get_b_cbp ( MpegEncContext * s , DCTELEM block [ 6 ] [ 64 ] ,
int motion_x , int motion_y , int mb_type ) {
int cbp = 0 , i ;
if ( s - > flags & CODEC_FLAG_CBP_RD ) {
int score = 0 ;
2003-10-07 14:32:40 +03:00
const int lambda = s - > lambda2 > > ( FF_LAMBDA_SHIFT - 6 ) ;
2005-12-17 20:14:38 +02:00
2003-10-01 01:18:43 +03:00
for ( i = 0 ; i < 6 ; i + + ) {
if ( s - > coded_score [ i ] < 0 ) {
score + = s - > coded_score [ i ] ;
cbp | = 1 < < ( 5 - i ) ;
}
}
2005-12-17 20:14:38 +02:00
2003-10-01 01:18:43 +03:00
if ( cbp ) {
int zero_score = - 6 ;
if ( ( motion_x | motion_y | s - > dquant | mb_type ) = = 0 ) {
zero_score - = 4 ; //2*MV + mb_type + cbp bit
}
zero_score * = lambda ;
if ( zero_score < = score ) {
cbp = 0 ;
}
}
for ( i = 0 ; i < 6 ; i + + ) {
if ( s - > block_last_index [ i ] > = 0 & & ( ( cbp > > ( 5 - i ) ) & 1 ) = = 0 ) {
s - > block_last_index [ i ] = - 1 ;
memset ( s - > block [ i ] , 0 , sizeof ( DCTELEM ) * 64 ) ;
}
}
} else {
for ( i = 0 ; i < 6 ; i + + ) {
if ( s - > block_last_index [ i ] > = 0 )
cbp | = 1 < < ( 5 - i ) ;
}
}
return cbp ;
}
2005-12-17 20:14:38 +02:00
static inline void mpeg4_encode_blocks ( MpegEncContext * s , DCTELEM block [ 6 ] [ 64 ] , int intra_dc [ 6 ] ,
2005-02-06 19:01:07 +02:00
uint8_t * * scan_table , PutBitContext * dc_pb , PutBitContext * ac_pb ) {
int i ;
2005-12-17 20:14:38 +02:00
2005-02-06 19:01:07 +02:00
if ( scan_table ) {
if ( s - > flags2 & CODEC_FLAG2_NO_OUTPUT ) {
for ( i = 0 ; i < 6 ; i + + ) {
skip_put_bits ( & s - > pb , mpeg4_get_block_length ( s , block [ i ] , i , intra_dc [ i ] , scan_table [ i ] ) ) ;
}
} else {
/* encode each block */
for ( i = 0 ; i < 6 ; i + + ) {
mpeg4_encode_block ( s , block [ i ] , i , intra_dc [ i ] , scan_table [ i ] , dc_pb , ac_pb ) ;
}
}
} else {
if ( s - > flags2 & CODEC_FLAG2_NO_OUTPUT ) {
for ( i = 0 ; i < 6 ; i + + ) {
skip_put_bits ( & s - > pb , mpeg4_get_block_length ( s , block [ i ] , i , 0 , s - > intra_scantable . permutated ) ) ;
}
} else {
/* encode each block */
for ( i = 0 ; i < 6 ; i + + ) {
mpeg4_encode_block ( s , block [ i ] , i , 0 , s - > intra_scantable . permutated , dc_pb , ac_pb ) ;
}
}
}
}
2002-03-15 06:10:53 +02:00
void mpeg4_encode_mb ( MpegEncContext * s ,
2005-12-22 03:10:11 +02:00
DCTELEM block [ 6 ] [ 64 ] ,
int motion_x , int motion_y )
2002-03-15 06:10:53 +02:00
{
2003-02-10 11:35:32 +02:00
int cbpc , cbpy , pred_x , pred_y ;
2002-06-02 15:15:17 +03:00
PutBitContext * const pb2 = s - > data_partitioning ? & s - > pb2 : & s - > pb ;
PutBitContext * const tex_pb = s - > data_partitioning & & s - > pict_type ! = B_TYPE ? & s - > tex_pb : & s - > pb ;
PutBitContext * const dc_pb = s - > data_partitioning & & s - > pict_type ! = I_TYPE ? & s - > pb2 : & s - > pb ;
const int interleaved_stats = ( s - > flags & CODEC_FLAG_PASS1 ) & & ! s - > data_partitioning ? 1 : 0 ;
2002-09-23 17:56:11 +03:00
const int dquant_code [ 5 ] = { 1 , 0 , 9 , 2 , 3 } ;
2005-12-17 20:14:38 +02:00
2002-03-15 06:10:53 +02:00
// printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
if ( ! s - > mb_intra ) {
2003-10-01 01:18:43 +03:00
int i , cbp ;
2005-12-17 20:14:38 +02:00
2002-04-17 07:32:12 +03:00
if ( s - > pict_type = = B_TYPE ) {
static const int mb_type_table [ 8 ] = { - 1 , 2 , 3 , 1 , - 1 , - 1 , - 1 , 0 } ; /* convert from mv_dir to type */
int mb_type = mb_type_table [ s - > mv_dir ] ;
2003-12-30 18:07:57 +02:00
2002-04-17 07:32:12 +03:00
if ( s - > mb_x = = 0 ) {
2003-12-30 18:07:57 +02:00
for ( i = 0 ; i < 2 ; i + + ) {
2005-12-17 20:14:38 +02:00
s - > last_mv [ i ] [ 0 ] [ 0 ] =
s - > last_mv [ i ] [ 0 ] [ 1 ] =
s - > last_mv [ i ] [ 1 ] [ 0 ] =
2003-12-30 18:07:57 +02:00
s - > last_mv [ i ] [ 1 ] [ 1 ] = 0 ;
}
2002-04-17 07:32:12 +03:00
}
2005-12-17 20:14:38 +02:00
2002-09-23 17:56:11 +03:00
assert ( s - > dquant > = - 2 & & s - > dquant < = 2 ) ;
assert ( ( s - > dquant & 1 ) = = 0 ) ;
assert ( mb_type > = 0 ) ;
2002-04-17 07:32:12 +03:00
2005-04-24 20:21:11 +03:00
/* nothing to do if this MB was skipped in the next P Frame */
2003-04-10 16:18:38 +03:00
if ( s - > next_picture . mbskip_table [ s - > mb_y * s - > mb_stride + s - > mb_x ] ) { //FIXME avoid DCT & ...
2002-04-17 07:32:12 +03:00
s - > skip_count + + ;
2005-12-17 20:14:38 +02:00
s - > mv [ 0 ] [ 0 ] [ 0 ] =
s - > mv [ 0 ] [ 0 ] [ 1 ] =
s - > mv [ 1 ] [ 0 ] [ 0 ] =
2002-04-17 07:32:12 +03:00
s - > mv [ 1 ] [ 0 ] [ 1 ] = 0 ;
2005-05-05 17:34:47 +03:00
s - > mv_dir = MV_DIR_FORWARD ; //doesn't matter
2002-09-23 17:56:11 +03:00
s - > qscale - = s - > dquant ;
2005-04-24 20:21:11 +03:00
// s->mb_skipped=1;
2002-12-04 12:04:03 +02:00
2002-04-17 07:32:12 +03:00
return ;
}
2005-12-17 20:14:38 +02:00
2003-10-01 01:18:43 +03:00
cbp = get_b_cbp ( s , block , motion_x , motion_y , mb_type ) ;
2005-12-17 20:14:38 +02:00
2002-04-17 07:32:12 +03:00
if ( ( cbp | motion_x | motion_y | mb_type ) = = 0 ) {
/* direct MB with MV={0,0} */
2002-09-23 17:56:11 +03:00
assert ( s - > dquant = = 0 ) ;
2005-12-17 20:14:38 +02:00
2002-04-17 07:32:12 +03:00
put_bits ( & s - > pb , 1 , 1 ) ; /* mb not coded modb1=1 */
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
s - > misc_bits + + ;
s - > last_bits + + ;
}
2002-04-17 07:32:12 +03:00
s - > skip_count + + ;
return ;
}
2005-12-17 20:14:38 +02:00
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* mb coded modb1=0 */
2002-04-17 07:32:12 +03:00
put_bits ( & s - > pb , 1 , cbp ? 0 : 1 ) ; /* modb2 */ //FIXME merge
2005-05-05 17:34:47 +03:00
put_bits ( & s - > pb , mb_type + 1 , 1 ) ; // this table is so simple that we don't need it :)
2002-04-17 07:32:12 +03:00
if ( cbp ) put_bits ( & s - > pb , 6 , cbp ) ;
2005-12-17 20:14:38 +02:00
2002-09-23 17:56:11 +03:00
if ( cbp & & mb_type ) {
if ( s - > dquant )
put_bits ( & s - > pb , 2 , ( s - > dquant > > 2 ) + 3 ) ;
else
put_bits ( & s - > pb , 1 , 0 ) ;
} else
s - > qscale - = s - > dquant ;
2005-12-17 20:14:38 +02:00
2002-09-26 03:22:25 +03:00
if ( ! s - > progressive_sequence ) {
if ( cbp )
put_bits ( & s - > pb , 1 , s - > interlaced_dct ) ;
2005-05-05 17:34:47 +03:00
if ( mb_type ) // not direct mode
2003-12-30 18:07:57 +02:00
put_bits ( & s - > pb , 1 , s - > mv_type = = MV_TYPE_FIELD ) ;
2002-09-26 03:22:25 +03:00
}
2002-04-17 07:32:12 +03:00
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
2003-04-02 12:57:34 +03:00
s - > misc_bits + = get_bits_diff ( s ) ;
2002-06-02 15:15:17 +03:00
}
2002-03-28 06:25:35 +02:00
2003-12-30 18:07:57 +02:00
if ( mb_type = = 0 ) {
assert ( s - > mv_dir & MV_DIRECT ) ;
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , motion_x , motion_y , 1 ) ;
2002-09-12 15:26:09 +03:00
s - > b_count + + ;
s - > f_count + + ;
2003-12-30 18:07:57 +02:00
} else {
assert ( mb_type > 0 & & mb_type < 4 ) ;
if ( s - > mv_type ! = MV_TYPE_FIELD ) {
if ( s - > mv_dir & MV_DIR_FORWARD ) {
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , s - > mv [ 0 ] [ 0 ] [ 0 ] - s - > last_mv [ 0 ] [ 0 ] [ 0 ] ,
s - > mv [ 0 ] [ 0 ] [ 1 ] - s - > last_mv [ 0 ] [ 0 ] [ 1 ] , s - > f_code ) ;
2003-12-30 18:07:57 +02:00
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 ) {
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , s - > mv [ 1 ] [ 0 ] [ 0 ] - s - > last_mv [ 1 ] [ 0 ] [ 0 ] ,
s - > mv [ 1 ] [ 0 ] [ 1 ] - s - > last_mv [ 1 ] [ 0 ] [ 1 ] , s - > b_code ) ;
2003-12-30 18:07:57 +02:00
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 {
if ( s - > mv_dir & MV_DIR_FORWARD ) {
put_bits ( & s - > pb , 1 , s - > field_select [ 0 ] [ 0 ] ) ;
put_bits ( & s - > pb , 1 , s - > field_select [ 0 ] [ 1 ] ) ;
}
if ( s - > mv_dir & MV_DIR_BACKWARD ) {
put_bits ( & s - > pb , 1 , s - > field_select [ 1 ] [ 0 ] ) ;
put_bits ( & s - > pb , 1 , s - > field_select [ 1 ] [ 1 ] ) ;
}
if ( s - > mv_dir & MV_DIR_FORWARD ) {
for ( i = 0 ; i < 2 ; i + + ) {
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , s - > mv [ 0 ] [ i ] [ 0 ] - s - > last_mv [ 0 ] [ i ] [ 0 ] ,
s - > mv [ 0 ] [ i ] [ 1 ] - s - > last_mv [ 0 ] [ i ] [ 1 ] / 2 , s - > f_code ) ;
2003-12-30 18:07:57 +02:00
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 + + ) {
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , s - > mv [ 1 ] [ i ] [ 0 ] - s - > last_mv [ 1 ] [ i ] [ 0 ] ,
s - > mv [ 1 ] [ i ] [ 1 ] - s - > last_mv [ 1 ] [ i ] [ 1 ] / 2 , s - > b_code ) ;
2003-12-30 18:07:57 +02:00
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 + + ;
}
}
2002-04-17 07:32:12 +03:00
}
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
2003-04-02 12:57:34 +03:00
s - > mv_bits + = get_bits_diff ( s ) ;
2002-06-02 15:15:17 +03:00
}
2002-03-15 06:10:53 +02:00
2005-02-06 19:01:07 +02:00
mpeg4_encode_blocks ( s , block , NULL , NULL , NULL , & s - > pb ) ;
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
2003-04-02 12:57:34 +03:00
s - > p_tex_bits + = get_bits_diff ( s ) ;
2002-04-17 07:32:12 +03:00
}
2003-12-30 18:07:57 +02:00
2002-04-17 07:32:12 +03:00
} else { /* s->pict_type==B_TYPE */
2003-10-01 01:18:43 +03:00
cbp = get_p_cbp ( s , block , motion_x , motion_y ) ;
2005-12-17 20:14:38 +02:00
2002-09-23 17:56:11 +03:00
if ( ( cbp | motion_x | motion_y | s - > dquant ) = = 0 & & s - > mv_type = = MV_TYPE_16X16 ) {
2005-12-17 20:14:38 +02:00
/* check if the B frames can skip it too, as we must skip it if we skip here
2005-05-05 17:34:47 +03:00
why didn ' t they just compress the skip - mb bits instead of reusing them ? ! */
2002-04-22 02:47:27 +03:00
if ( s - > max_b_frames > 0 ) {
int i ;
2002-05-05 22:03:24 +03:00
int x , y , offset ;
uint8_t * p_pic ;
x = s - > mb_x * 16 ;
y = s - > mb_y * 16 ;
if ( x + 16 > s - > width ) x = s - > width - 16 ;
if ( y + 16 > s - > height ) y = s - > height - 16 ;
offset = x + y * s - > linesize ;
2002-12-04 12:04:03 +02:00
p_pic = s - > new_picture . data [ 0 ] + offset ;
2005-12-17 20:14:38 +02:00
2005-04-24 20:21:11 +03:00
s - > mb_skipped = 1 ;
2002-04-22 02:47:27 +03:00
for ( i = 0 ; i < s - > max_b_frames ; i + + ) {
2002-04-23 00:02:18 +03:00
uint8_t * b_pic ;
int diff ;
2002-12-04 12:04:03 +02:00
Picture * pic = s - > reordered_input_picture [ i + 1 ] ;
2002-04-23 00:02:18 +03:00
2002-12-04 12:04:03 +02:00
if ( pic = = NULL | | pic - > pict_type ! = B_TYPE ) break ;
2002-04-23 00:02:18 +03:00
2006-01-27 15:19:13 +02:00
b_pic = pic - > data [ 0 ] + offset ;
if ( pic - > type ! = FF_BUFFER_TYPE_SHARED )
b_pic + = INPLACE_OFFSET ;
2005-12-22 03:10:11 +02:00
diff = s - > dsp . sad [ 0 ] ( NULL , p_pic , b_pic , s - > linesize , 16 ) ;
2002-05-05 22:03:24 +03:00
if ( diff > s - > qscale * 70 ) { //FIXME check that 70 is optimal
2005-04-24 20:21:11 +03:00
s - > mb_skipped = 0 ;
2002-04-22 02:47:27 +03:00
break ;
}
}
} else
2005-12-17 20:14:38 +02:00
s - > mb_skipped = 1 ;
2002-04-22 02:47:27 +03:00
2005-04-24 20:21:11 +03:00
if ( s - > mb_skipped = = 1 ) {
2002-04-22 02:47:27 +03:00
/* skip macroblock */
put_bits ( & s - > pb , 1 , 1 ) ;
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
s - > misc_bits + + ;
s - > last_bits + + ;
}
2002-04-22 02:47:27 +03:00
s - > skip_count + + ;
2005-12-17 20:14:38 +02:00
2002-04-22 02:47:27 +03:00
return ;
}
2002-04-17 07:32:12 +03:00
}
2002-05-05 22:03:24 +03:00
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* mb coded */
2003-11-28 23:31:20 +02:00
cbpc = cbp & 3 ;
cbpy = cbp > > 2 ;
cbpy ^ = 0xf ;
2002-04-17 07:32:12 +03:00
if ( s - > mv_type = = MV_TYPE_16X16 ) {
2002-09-23 17:56:11 +03:00
if ( s - > dquant ) cbpc + = 8 ;
2002-04-17 07:32:12 +03:00
put_bits ( & s - > pb ,
inter_MCBPC_bits [ cbpc ] ,
inter_MCBPC_code [ cbpc ] ) ;
2002-09-23 17:56:11 +03:00
2002-06-02 15:15:17 +03:00
put_bits ( pb2 , cbpy_tab [ cbpy ] [ 1 ] , cbpy_tab [ cbpy ] [ 0 ] ) ;
2002-09-23 17:56:11 +03:00
if ( s - > dquant )
put_bits ( pb2 , 2 , dquant_code [ s - > dquant + 2 ] ) ;
2002-09-26 03:22:25 +03:00
if ( ! s - > progressive_sequence ) {
if ( cbp )
put_bits ( pb2 , 1 , s - > interlaced_dct ) ;
2003-12-30 18:07:57 +02:00
put_bits ( pb2 , 1 , 0 ) ;
2002-09-26 03:22:25 +03:00
}
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
2003-04-02 12:57:34 +03:00
s - > misc_bits + = get_bits_diff ( s ) ;
2002-06-02 15:15:17 +03:00
}
2002-03-15 06:10:53 +02:00
2002-04-17 07:32:12 +03:00
/* motion vectors: 16x16 mode */
2004-04-16 04:01:45 +03:00
h263_pred_motion ( s , 0 , 0 , & pred_x , & pred_y ) ;
2005-12-17 20:14:38 +02:00
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , motion_x - pred_x ,
motion_y - pred_y , s - > f_code ) ;
2003-12-30 18:07:57 +02:00
} else if ( s - > mv_type = = MV_TYPE_FIELD ) {
if ( s - > dquant ) cbpc + = 8 ;
put_bits ( & s - > pb ,
inter_MCBPC_bits [ cbpc ] ,
inter_MCBPC_code [ cbpc ] ) ;
put_bits ( pb2 , cbpy_tab [ cbpy ] [ 1 ] , cbpy_tab [ cbpy ] [ 0 ] ) ;
if ( s - > dquant )
put_bits ( pb2 , 2 , dquant_code [ s - > dquant + 2 ] ) ;
assert ( ! s - > progressive_sequence ) ;
if ( cbp )
put_bits ( pb2 , 1 , s - > interlaced_dct ) ;
put_bits ( pb2 , 1 , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-12-30 18:07:57 +02:00
if ( interleaved_stats ) {
s - > misc_bits + = get_bits_diff ( s ) ;
}
/* motion vectors: 16x8 interlaced mode */
2004-04-16 04:01:45 +03:00
h263_pred_motion ( s , 0 , 0 , & pred_x , & pred_y ) ;
2003-12-30 18:07:57 +02:00
pred_y / = 2 ;
2005-12-17 20:14:38 +02:00
2003-12-30 18:07:57 +02:00
put_bits ( & s - > pb , 1 , s - > field_select [ 0 ] [ 0 ] ) ;
put_bits ( & s - > pb , 1 , s - > field_select [ 0 ] [ 1 ] ) ;
2005-12-17 20:14:38 +02:00
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , s - > mv [ 0 ] [ 0 ] [ 0 ] - pred_x ,
s - > mv [ 0 ] [ 0 ] [ 1 ] - pred_y , s - > f_code ) ;
ff_h263_encode_motion_vector ( s , s - > mv [ 0 ] [ 1 ] [ 0 ] - pred_x ,
s - > mv [ 0 ] [ 1 ] [ 1 ] - pred_y , s - > f_code ) ;
2002-04-17 07:32:12 +03:00
} else {
2003-12-30 18:07:57 +02:00
assert ( s - > mv_type = = MV_TYPE_8X8 ) ;
2002-04-17 07:32:12 +03:00
put_bits ( & s - > pb ,
2003-11-28 23:31:20 +02:00
inter_MCBPC_bits [ cbpc + 16 ] ,
inter_MCBPC_code [ cbpc + 16 ] ) ;
2002-06-02 15:15:17 +03:00
put_bits ( pb2 , cbpy_tab [ cbpy ] [ 1 ] , cbpy_tab [ cbpy ] [ 0 ] ) ;
2002-04-17 07:32:12 +03:00
2002-10-19 14:03:13 +03:00
if ( ! s - > progressive_sequence ) {
if ( cbp )
put_bits ( pb2 , 1 , s - > interlaced_dct ) ;
}
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
2003-04-02 12:57:34 +03:00
s - > misc_bits + = get_bits_diff ( s ) ;
2002-06-02 15:15:17 +03:00
}
2002-04-17 07:32:12 +03:00
for ( i = 0 ; i < 4 ; i + + ) {
/* motion vectors: 8x8 mode*/
2004-04-16 04:01:45 +03:00
h263_pred_motion ( s , i , 0 , & pred_x , & pred_y ) ;
2002-04-17 07:32:12 +03:00
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , s - > current_picture . motion_val [ 0 ] [ s - > block_index [ i ] ] [ 0 ] - pred_x ,
s - > current_picture . motion_val [ 0 ] [ s - > block_index [ i ] ] [ 1 ] - pred_y , s - > f_code ) ;
2002-04-17 07:32:12 +03:00
}
2002-03-28 06:25:35 +02:00
}
2002-06-02 15:15:17 +03:00
2005-12-17 20:14:38 +02:00
if ( interleaved_stats ) {
2003-04-02 12:57:34 +03:00
s - > mv_bits + = get_bits_diff ( s ) ;
2002-06-02 15:15:17 +03:00
}
2002-03-23 19:43:30 +02:00
2005-02-06 19:01:07 +02:00
mpeg4_encode_blocks ( s , block , NULL , NULL , NULL , tex_pb ) ;
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
2003-04-02 12:57:34 +03:00
s - > p_tex_bits + = get_bits_diff ( s ) ;
2002-04-17 07:32:12 +03:00
}
2002-09-12 15:26:09 +03:00
s - > f_count + + ;
2002-03-15 06:10:53 +02:00
}
} else {
2002-04-17 07:32:12 +03:00
int cbp ;
2005-12-17 20:14:38 +02:00
int dc_diff [ 6 ] ; //dc values with the dc prediction subtracted
2002-03-15 06:10:53 +02:00
int dir [ 6 ] ; //prediction direction
int zigzag_last_index [ 6 ] ;
2005-12-22 03:10:11 +02:00
uint8_t * scan_table [ 6 ] ;
2003-02-10 11:35:32 +02:00
int i ;
2002-03-15 06:10:53 +02:00
for ( i = 0 ; i < 6 ; i + + ) {
2004-05-05 03:14:22 +03:00
dc_diff [ i ] = ff_mpeg4_pred_dc ( s , i , block [ i ] [ 0 ] , & dir [ i ] , 1 ) ;
2002-03-15 06:10:53 +02:00
}
2003-10-01 18:41:36 +03:00
if ( s - > flags & CODEC_FLAG_AC_PRED ) {
s - > ac_pred = decide_ac_pred ( s , block , dir , scan_table , zigzag_last_index ) ;
if ( ! s - > ac_pred )
restore_ac_coeffs ( s , block , dir , scan_table , zigzag_last_index ) ;
2002-03-15 06:10:53 +02:00
} else {
for ( i = 0 ; i < 6 ; i + + )
2002-09-30 01:44:22 +03:00
scan_table [ i ] = s - > intra_scantable . permutated ;
2002-03-15 06:10:53 +02:00
}
/* compute cbp */
cbp = 0 ;
for ( i = 0 ; i < 6 ; i + + ) {
if ( s - > block_last_index [ i ] > = 1 )
cbp | = 1 < < ( 5 - i ) ;
}
cbpc = cbp & 3 ;
if ( s - > pict_type = = I_TYPE ) {
2002-09-23 17:56:11 +03:00
if ( s - > dquant ) cbpc + = 4 ;
2002-03-15 06:10:53 +02:00
put_bits ( & s - > pb ,
intra_MCBPC_bits [ cbpc ] ,
intra_MCBPC_code [ cbpc ] ) ;
} else {
2002-09-23 17:56:11 +03:00
if ( s - > dquant ) cbpc + = 8 ;
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* mb coded */
2002-03-15 06:10:53 +02:00
put_bits ( & s - > pb ,
inter_MCBPC_bits [ cbpc + 4 ] ,
inter_MCBPC_code [ cbpc + 4 ] ) ;
}
2002-06-02 15:15:17 +03:00
put_bits ( pb2 , 1 , s - > ac_pred ) ;
2002-03-15 06:10:53 +02:00
cbpy = cbp > > 2 ;
2002-06-02 15:15:17 +03:00
put_bits ( pb2 , cbpy_tab [ cbpy ] [ 1 ] , cbpy_tab [ cbpy ] [ 0 ] ) ;
2002-09-23 17:56:11 +03:00
if ( s - > dquant )
put_bits ( dc_pb , 2 , dquant_code [ s - > dquant + 2 ] ) ;
2002-03-15 06:10:53 +02:00
2002-09-26 03:22:25 +03:00
if ( ! s - > progressive_sequence ) {
put_bits ( dc_pb , 1 , s - > interlaced_dct ) ;
}
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
2003-04-02 12:57:34 +03:00
s - > misc_bits + = get_bits_diff ( s ) ;
2002-06-02 15:15:17 +03:00
}
2002-03-23 19:43:30 +02:00
2005-02-06 19:01:07 +02:00
mpeg4_encode_blocks ( s , block , dc_diff , scan_table , dc_pb , tex_pb ) ;
2002-03-15 06:10:53 +02:00
2002-06-02 15:15:17 +03:00
if ( interleaved_stats ) {
2003-04-02 12:57:34 +03:00
s - > i_tex_bits + = get_bits_diff ( s ) ;
2002-06-02 15:15:17 +03:00
}
2002-03-23 19:43:30 +02:00
s - > i_count + + ;
2002-03-15 06:10:53 +02:00
/* restore ac coeffs & last_index stuff if we messed them up with the prediction */
2003-10-01 18:41:36 +03:00
if ( s - > ac_pred )
restore_ac_coeffs ( s , block , dir , scan_table , zigzag_last_index ) ;
2002-03-15 06:10:53 +02:00
}
}
2001-07-22 17:18:56 +03:00
void h263_encode_mb ( MpegEncContext * s ,
2005-12-22 03:10:11 +02:00
DCTELEM block [ 6 ] [ 64 ] ,
int motion_x , int motion_y )
2001-07-22 17:18:56 +03:00
{
int cbpc , cbpy , i , cbp , pred_x , pred_y ;
2003-02-11 18:35:48 +02:00
int16_t pred_dc ;
int16_t rec_intradc [ 6 ] ;
2006-09-28 01:13:44 +03:00
int16_t * dc_ptr [ 6 ] ;
2003-07-10 02:10:59 +03:00
const int interleaved_stats = ( s - > flags & CODEC_FLAG_PASS1 ) ;
2002-09-24 18:07:44 +03:00
const int dquant_code [ 5 ] = { 1 , 0 , 9 , 2 , 3 } ;
2005-12-17 20:14:38 +02:00
2002-05-02 07:39:45 +03:00
//printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
2002-04-17 07:32:12 +03:00
if ( ! s - > mb_intra ) {
2002-05-02 07:39:45 +03:00
/* compute cbp */
2003-10-01 01:18:43 +03:00
cbp = get_p_cbp ( s , block , motion_x , motion_y ) ;
2004-02-07 00:34:33 +02:00
if ( ( cbp | motion_x | motion_y | s - > dquant | ( s - > mv_type - MV_TYPE_16X16 ) ) = = 0 ) {
2002-04-17 07:32:12 +03:00
/* skip macroblock */
put_bits ( & s - > pb , 1 , 1 ) ;
2003-07-10 02:10:59 +03:00
if ( interleaved_stats ) {
s - > misc_bits + + ;
s - > last_bits + + ;
}
2004-01-25 01:47:33 +02:00
s - > skip_count + + ;
2002-04-17 07:32:12 +03:00
return ;
}
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* mb coded */
2005-12-17 20:14:38 +02:00
2002-04-17 07:32:12 +03:00
cbpc = cbp & 3 ;
cbpy = cbp > > 2 ;
2003-11-29 10:37:51 +02:00
if ( s - > alt_inter_vlc = = 0 | | cbpc ! = 3 )
cbpy ^ = 0xF ;
if ( s - > dquant ) cbpc + = 8 ;
2003-11-28 23:31:20 +02:00
if ( s - > mv_type = = MV_TYPE_16X16 ) {
put_bits ( & s - > pb ,
inter_MCBPC_bits [ cbpc ] ,
inter_MCBPC_code [ cbpc ] ) ;
2002-04-17 07:32:12 +03:00
2003-11-28 23:31:20 +02:00
put_bits ( & s - > pb , cbpy_tab [ cbpy ] [ 1 ] , cbpy_tab [ cbpy ] [ 0 ] ) ;
if ( s - > dquant )
put_bits ( & s - > pb , 2 , dquant_code [ s - > dquant + 2 ] ) ;
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
if ( interleaved_stats ) {
s - > misc_bits + = get_bits_diff ( s ) ;
}
2003-07-10 02:10:59 +03:00
2003-11-28 23:31:20 +02:00
/* motion vectors: 16x16 mode */
2004-04-16 04:01:45 +03:00
h263_pred_motion ( s , 0 , 0 , & pred_x , & pred_y ) ;
2005-12-17 20:14:38 +02:00
if ( ! s - > umvplus ) {
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , motion_x - pred_x ,
motion_y - pred_y , 1 ) ;
2003-11-28 23:31:20 +02:00
}
else {
h263p_encode_umotion ( s , motion_x - pred_x ) ;
h263p_encode_umotion ( s , motion_y - pred_y ) ;
if ( ( ( motion_x - pred_x ) = = 1 ) & & ( ( motion_y - pred_y ) = = 1 ) )
/* To prevent Start Code emulation */
put_bits ( & s - > pb , 1 , 1 ) ;
}
} else {
put_bits ( & s - > pb ,
inter_MCBPC_bits [ cbpc + 16 ] ,
inter_MCBPC_code [ cbpc + 16 ] ) ;
put_bits ( & s - > pb , cbpy_tab [ cbpy ] [ 1 ] , cbpy_tab [ cbpy ] [ 0 ] ) ;
if ( s - > dquant )
put_bits ( & s - > pb , 2 , dquant_code [ s - > dquant + 2 ] ) ;
if ( interleaved_stats ) {
s - > misc_bits + = get_bits_diff ( s ) ;
}
for ( i = 0 ; i < 4 ; i + + ) {
/* motion vectors: 8x8 mode*/
2004-04-16 04:01:45 +03:00
h263_pred_motion ( s , i , 0 , & pred_x , & pred_y ) ;
2003-11-28 23:31:20 +02:00
2003-12-09 03:49:56 +02:00
motion_x = s - > current_picture . motion_val [ 0 ] [ s - > block_index [ i ] ] [ 0 ] ;
motion_y = s - > current_picture . motion_val [ 0 ] [ s - > block_index [ i ] ] [ 1 ] ;
2005-12-17 20:14:38 +02:00
if ( ! s - > umvplus ) {
2005-02-06 19:01:07 +02:00
ff_h263_encode_motion_vector ( s , motion_x - pred_x ,
motion_y - pred_y , 1 ) ;
2003-11-28 23:31:20 +02:00
}
else {
h263p_encode_umotion ( s , motion_x - pred_x ) ;
h263p_encode_umotion ( s , motion_y - pred_y ) ;
if ( ( ( motion_x - pred_x ) = = 1 ) & & ( ( motion_y - pred_y ) = = 1 ) )
/* To prevent Start Code emulation */
put_bits ( & s - > pb , 1 , 1 ) ;
}
}
2002-04-17 07:32:12 +03:00
}
2003-07-10 02:10:59 +03:00
if ( interleaved_stats ) {
s - > mv_bits + = get_bits_diff ( s ) ;
}
2002-05-02 07:39:45 +03:00
} else {
2003-11-30 16:35:35 +02:00
assert ( s - > mb_intra ) ;
2005-12-17 20:14:38 +02:00
2002-05-02 07:39:45 +03:00
cbp = 0 ;
2003-12-08 19:42:20 +02:00
if ( s - > h263_aic ) {
2002-05-02 07:39:45 +03:00
/* Predict DC */
2003-12-08 19:42:20 +02:00
for ( i = 0 ; i < 6 ; i + + ) {
2003-02-11 18:35:48 +02:00
int16_t level = block [ i ] [ 0 ] ;
2003-12-08 19:42:20 +02:00
int scale ;
2005-12-17 20:14:38 +02:00
2003-12-08 19:42:20 +02:00
if ( i < 4 ) scale = s - > y_dc_scale ;
else scale = s - > c_dc_scale ;
2002-05-02 07:39:45 +03:00
pred_dc = h263_pred_dc ( s , i , & dc_ptr [ i ] ) ;
level - = pred_dc ;
/* Quant */
2003-12-08 19:42:20 +02:00
if ( level > = 0 )
level = ( level + ( scale > > 1 ) ) / scale ;
2002-05-02 07:39:45 +03:00
else
2003-12-08 19:42:20 +02:00
level = ( level - ( scale > > 1 ) ) / scale ;
2005-12-17 20:14:38 +02:00
2002-05-02 07:39:45 +03:00
/* AIC can change CBP */
if ( level = = 0 & & s - > block_last_index [ i ] = = 0 )
s - > block_last_index [ i ] = - 1 ;
2003-12-08 19:42:20 +02:00
if ( ! s - > modified_quant ) {
if ( level < - 127 )
level = - 127 ;
else if ( level > 127 )
level = 127 ;
}
2002-05-02 07:39:45 +03:00
block [ i ] [ 0 ] = level ;
2005-12-17 20:14:38 +02:00
/* Reconstruction */
2003-12-08 19:42:20 +02:00
rec_intradc [ i ] = scale * level + pred_dc ;
2002-05-02 07:39:45 +03:00
/* Oddify */
rec_intradc [ i ] | = 1 ;
//if ((rec_intradc[i] % 2) == 0)
// rec_intradc[i]++;
/* Clipping */
if ( rec_intradc [ i ] < 0 )
rec_intradc [ i ] = 0 ;
else if ( rec_intradc [ i ] > 2047 )
rec_intradc [ i ] = 2047 ;
2005-12-17 20:14:38 +02:00
2002-05-02 07:39:45 +03:00
/* Update AC/DC tables */
* dc_ptr [ i ] = rec_intradc [ i ] ;
2003-12-08 19:42:20 +02:00
if ( s - > block_last_index [ i ] > = 0 )
cbp | = 1 < < ( 5 - i ) ;
}
} else {
for ( i = 0 ; i < 6 ; i + + ) {
/* compute cbp */
if ( s - > block_last_index [ i ] > = 1 )
cbp | = 1 < < ( 5 - i ) ;
2002-05-02 07:39:45 +03:00
}
}
2001-07-22 17:18:56 +03:00
2002-05-02 07:39:45 +03:00
cbpc = cbp & 3 ;
if ( s - > pict_type = = I_TYPE ) {
2002-09-24 18:07:44 +03:00
if ( s - > dquant ) cbpc + = 4 ;
2002-05-02 07:39:45 +03:00
put_bits ( & s - > pb ,
intra_MCBPC_bits [ cbpc ] ,
intra_MCBPC_code [ cbpc ] ) ;
} else {
2002-09-24 18:07:44 +03:00
if ( s - > dquant ) cbpc + = 8 ;
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* mb coded */
2002-05-02 07:39:45 +03:00
put_bits ( & s - > pb ,
inter_MCBPC_bits [ cbpc + 4 ] ,
inter_MCBPC_code [ cbpc + 4 ] ) ;
}
if ( s - > h263_aic ) {
/* XXX: currently, we do not try to use ac prediction */
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* no AC prediction */
2002-05-02 07:39:45 +03:00
}
cbpy = cbp > > 2 ;
put_bits ( & s - > pb , cbpy_tab [ cbpy ] [ 1 ] , cbpy_tab [ cbpy ] [ 0 ] ) ;
2002-09-24 18:07:44 +03:00
if ( s - > dquant )
put_bits ( & s - > pb , 2 , dquant_code [ s - > dquant + 2 ] ) ;
2003-07-10 02:10:59 +03:00
if ( interleaved_stats ) {
s - > misc_bits + = get_bits_diff ( s ) ;
}
2001-07-22 17:18:56 +03:00
}
2002-05-02 07:39:45 +03:00
for ( i = 0 ; i < 6 ; i + + ) {
/* encode each block */
2003-07-10 03:15:27 +03:00
h263_encode_block ( s , block [ i ] , i ) ;
2005-12-17 20:14:38 +02:00
2002-05-02 07:39:45 +03:00
/* Update INTRADC for decoding */
if ( s - > h263_aic & & s - > mb_intra ) {
block [ i ] [ 0 ] = rec_intradc [ i ] ;
2005-12-17 20:14:38 +02:00
2002-05-02 07:39:45 +03:00
}
}
2003-07-10 02:10:59 +03:00
if ( interleaved_stats ) {
if ( ! s - > mb_intra ) {
s - > p_tex_bits + = get_bits_diff ( s ) ;
s - > f_count + + ;
} else {
s - > i_tex_bits + = get_bits_diff ( s ) ;
s - > i_count + + ;
}
}
2002-05-02 07:39:45 +03:00
}
2002-10-31 18:11:03 +02:00
# endif
2002-05-02 07:39:45 +03:00
2003-12-04 20:46:49 +02:00
void ff_h263_loop_filter ( MpegEncContext * s ) {
2003-12-01 17:23:14 +02:00
int qp_c ;
const int linesize = s - > linesize ;
const int uvlinesize = s - > uvlinesize ;
const int xy = s - > mb_y * s - > mb_stride + s - > mb_x ;
uint8_t * dest_y = s - > dest [ 0 ] ;
uint8_t * dest_cb = s - > dest [ 1 ] ;
uint8_t * dest_cr = s - > dest [ 2 ] ;
2005-12-17 20:14:38 +02:00
2003-12-01 17:23:14 +02:00
// if(s->pict_type==B_TYPE && !s->readable) return;
/*
Diag Top
Left Center
*/
if ( ! IS_SKIP ( s - > current_picture . mb_type [ xy ] ) ) {
qp_c = s - > qscale ;
s - > dsp . h263_v_loop_filter ( dest_y + 8 * linesize , linesize , qp_c ) ;
s - > dsp . h263_v_loop_filter ( dest_y + 8 * linesize + 8 , linesize , qp_c ) ;
} else
qp_c = 0 ;
if ( s - > mb_y ) {
int qp_dt , qp_t , qp_tc ;
if ( IS_SKIP ( s - > current_picture . mb_type [ xy - s - > mb_stride ] ) )
qp_t = 0 ;
2005-12-17 20:14:38 +02:00
else
2003-12-01 17:23:14 +02:00
qp_t = s - > current_picture . qscale_table [ xy - s - > mb_stride ] ;
2005-12-17 20:14:38 +02:00
if ( qp_c )
2003-12-01 17:23:14 +02:00
qp_tc = qp_c ;
else
qp_tc = qp_t ;
2005-12-17 20:14:38 +02:00
2003-12-01 17:23:14 +02:00
if ( qp_tc ) {
const int chroma_qp = s - > chroma_qscale_table [ qp_tc ] ;
s - > dsp . h263_v_loop_filter ( dest_y , linesize , qp_tc ) ;
s - > dsp . h263_v_loop_filter ( dest_y + 8 , linesize , qp_tc ) ;
2005-12-17 20:14:38 +02:00
2003-12-01 17:23:14 +02:00
s - > dsp . h263_v_loop_filter ( dest_cb , uvlinesize , chroma_qp ) ;
s - > dsp . h263_v_loop_filter ( dest_cr , uvlinesize , chroma_qp ) ;
}
2005-12-17 20:14:38 +02:00
2003-12-01 17:23:14 +02:00
if ( qp_t )
s - > dsp . h263_h_loop_filter ( dest_y - 8 * linesize + 8 , linesize , qp_t ) ;
2005-12-17 20:14:38 +02:00
2003-12-01 17:23:14 +02:00
if ( s - > mb_x ) {
if ( qp_t | | IS_SKIP ( s - > current_picture . mb_type [ xy - 1 - s - > mb_stride ] ) )
qp_dt = qp_t ;
else
qp_dt = s - > current_picture . qscale_table [ xy - 1 - s - > mb_stride ] ;
2005-12-17 20:14:38 +02:00
2003-12-01 17:23:14 +02:00
if ( qp_dt ) {
const int chroma_qp = s - > chroma_qscale_table [ qp_dt ] ;
s - > dsp . h263_h_loop_filter ( dest_y - 8 * linesize , linesize , qp_dt ) ;
s - > dsp . h263_h_loop_filter ( dest_cb - 8 * uvlinesize , uvlinesize , chroma_qp ) ;
2004-08-19 01:10:39 +03:00
s - > dsp . h263_h_loop_filter ( dest_cr - 8 * uvlinesize , uvlinesize , chroma_qp ) ;
2003-12-01 17:23:14 +02:00
}
}
}
if ( qp_c ) {
s - > dsp . h263_h_loop_filter ( dest_y + 8 , linesize , qp_c ) ;
if ( s - > mb_y + 1 = = s - > mb_height )
s - > dsp . h263_h_loop_filter ( dest_y + 8 * linesize + 8 , linesize , qp_c ) ;
}
2005-12-17 20:14:38 +02:00
2003-12-01 17:23:14 +02:00
if ( s - > mb_x ) {
int qp_lc ;
if ( qp_c | | IS_SKIP ( s - > current_picture . mb_type [ xy - 1 ] ) )
qp_lc = qp_c ;
else
qp_lc = s - > current_picture . qscale_table [ xy - 1 ] ;
2005-12-17 20:14:38 +02:00
2003-12-01 17:23:14 +02:00
if ( qp_lc ) {
s - > dsp . h263_h_loop_filter ( dest_y , linesize , qp_lc ) ;
if ( s - > mb_y + 1 = = s - > mb_height ) {
const int chroma_qp = s - > chroma_qscale_table [ qp_lc ] ;
s - > dsp . h263_h_loop_filter ( dest_y + 8 * linesize , linesize , qp_lc ) ;
s - > dsp . h263_h_loop_filter ( dest_cb , uvlinesize , chroma_qp ) ;
s - > dsp . h263_h_loop_filter ( dest_cr , uvlinesize , chroma_qp ) ;
}
}
}
}
2006-09-27 22:54:07 +03:00
# ifdef CONFIG_ENCODERS
2006-09-28 01:13:44 +03:00
static int h263_pred_dc ( MpegEncContext * s , int n , int16_t * * dc_val_ptr )
2002-05-02 07:39:45 +03:00
{
int x , y , wrap , a , c , pred_dc , scale ;
2006-09-28 01:13:44 +03:00
int16_t * dc_val ;
2002-05-02 07:39:45 +03:00
/* find prediction */
if ( n < 4 ) {
2004-04-16 04:01:45 +03:00
x = 2 * s - > mb_x + ( n & 1 ) ;
y = 2 * s - > mb_y + ( ( n & 2 ) > > 1 ) ;
wrap = s - > b8_stride ;
2002-05-02 07:39:45 +03:00
dc_val = s - > dc_val [ 0 ] ;
scale = s - > y_dc_scale ;
} else {
2004-04-16 04:01:45 +03:00
x = s - > mb_x ;
y = s - > mb_y ;
wrap = s - > mb_stride ;
2002-05-02 07:39:45 +03:00
dc_val = s - > dc_val [ n - 4 + 1 ] ;
scale = s - > c_dc_scale ;
2001-07-22 17:18:56 +03:00
}
2002-05-02 07:39:45 +03:00
/* B C
2005-12-17 20:14:38 +02:00
* A X
2002-05-02 07:39:45 +03:00
*/
a = dc_val [ ( x - 1 ) + ( y ) * wrap ] ;
c = dc_val [ ( x ) + ( y - 1 ) * wrap ] ;
2005-12-17 20:14:38 +02:00
2002-05-02 07:39:45 +03:00
/* No prediction outside GOB boundary */
2004-03-19 00:45:37 +02:00
if ( s - > first_slice_line & & n ! = 3 ) {
if ( n ! = 2 ) c = 1024 ;
if ( n ! = 1 & & s - > mb_x = = s - > resync_mb_x ) a = 1024 ;
}
2002-05-02 07:39:45 +03:00
pred_dc = 1024 ;
/* just DC prediction */
if ( a ! = 1024 & & c ! = 1024 )
pred_dc = ( a + c ) > > 1 ;
else if ( a ! = 1024 )
pred_dc = a ;
else
pred_dc = c ;
2005-12-17 20:14:38 +02:00
2002-05-02 07:39:45 +03:00
/* we assume pred is positive */
//pred_dc = (pred_dc + (scale >> 1)) / scale;
* dc_val_ptr = & dc_val [ x + y * wrap ] ;
return pred_dc ;
2001-07-22 17:18:56 +03:00
}
2006-09-27 22:54:07 +03:00
# endif /* CONFIG_ENCODERS */
2001-07-22 17:18:56 +03:00
2003-02-10 11:35:32 +02:00
static void h263_pred_acdc ( MpegEncContext * s , DCTELEM * block , int n )
2002-02-18 21:33:27 +02:00
{
2002-02-19 21:23:34 +02:00
int x , y , wrap , a , c , pred_dc , scale , i ;
2006-09-28 01:13:44 +03:00
int16_t * dc_val , * ac_val , * ac_val1 ;
2002-02-18 21:33:27 +02:00
/* find prediction */
if ( n < 4 ) {
2004-04-16 04:01:45 +03:00
x = 2 * s - > mb_x + ( n & 1 ) ;
y = 2 * s - > mb_y + ( n > > 1 ) ;
wrap = s - > b8_stride ;
2002-02-18 21:33:27 +02:00
dc_val = s - > dc_val [ 0 ] ;
2002-02-19 21:23:34 +02:00
ac_val = s - > ac_val [ 0 ] [ 0 ] ;
2002-02-18 21:33:27 +02:00
scale = s - > y_dc_scale ;
} else {
2004-04-16 04:01:45 +03:00
x = s - > mb_x ;
y = s - > mb_y ;
wrap = s - > mb_stride ;
2002-02-18 21:33:27 +02:00
dc_val = s - > dc_val [ n - 4 + 1 ] ;
2002-02-19 21:23:34 +02:00
ac_val = s - > ac_val [ n - 4 + 1 ] [ 0 ] ;
2002-02-18 21:33:27 +02:00
scale = s - > c_dc_scale ;
}
2005-12-17 20:14:38 +02:00
2002-02-19 21:23:34 +02:00
ac_val + = ( ( y ) * wrap + ( x ) ) * 16 ;
ac_val1 = ac_val ;
2005-12-17 20:14:38 +02:00
2002-02-18 21:33:27 +02:00
/* B C
2005-12-17 20:14:38 +02:00
* A X
2002-02-18 21:33:27 +02:00
*/
a = dc_val [ ( x - 1 ) + ( y ) * wrap ] ;
c = dc_val [ ( x ) + ( y - 1 ) * wrap ] ;
2005-12-17 20:14:38 +02:00
2002-05-02 07:39:45 +03:00
/* No prediction outside GOB boundary */
2003-11-30 16:35:35 +02:00
if ( s - > first_slice_line & & n ! = 3 ) {
if ( n ! = 2 ) c = 1024 ;
if ( n ! = 1 & & s - > mb_x = = s - > resync_mb_x ) a = 1024 ;
}
2005-12-17 20:14:38 +02:00
2002-02-18 21:33:27 +02:00
if ( s - > ac_pred ) {
2003-11-30 16:35:35 +02:00
pred_dc = 1024 ;
2002-02-18 21:33:27 +02:00
if ( s - > h263_aic_dir ) {
/* left prediction */
2002-02-19 21:23:34 +02:00
if ( a ! = 1024 ) {
ac_val - = 16 ;
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
block [ s - > dsp . idct_permutation [ i < < 3 ] ] + = ac_val [ i ] ;
2002-02-19 21:23:34 +02:00
}
pred_dc = a ;
2002-02-18 21:33:27 +02:00
}
} else {
/* top prediction */
2002-02-19 21:23:34 +02:00
if ( c ! = 1024 ) {
ac_val - = 16 * wrap ;
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
block [ s - > dsp . idct_permutation [ i ] ] + = ac_val [ i + 8 ] ;
2002-02-19 21:23:34 +02:00
}
pred_dc = c ;
2002-02-18 21:33:27 +02:00
}
}
2002-02-19 21:23:34 +02:00
} else {
/* just DC prediction */
if ( a ! = 1024 & & c ! = 1024 )
pred_dc = ( a + c ) > > 1 ;
else if ( a ! = 1024 )
pred_dc = a ;
else
pred_dc = c ;
2002-02-18 21:33:27 +02:00
}
2005-12-17 20:14:38 +02:00
2002-02-19 21:23:34 +02:00
/* we assume pred is positive */
block [ 0 ] = block [ 0 ] * scale + pred_dc ;
2005-12-17 20:14:38 +02:00
2002-02-19 21:23:34 +02:00
if ( block [ 0 ] < 0 )
block [ 0 ] = 0 ;
2005-12-17 20:14:38 +02:00
else
2003-11-30 16:35:35 +02:00
block [ 0 ] | = 1 ;
2005-12-17 20:14:38 +02:00
2002-02-19 21:23:34 +02:00
/* Update AC/DC tables */
dc_val [ ( x ) + ( y ) * wrap ] = block [ 0 ] ;
2005-12-17 20:14:38 +02:00
2002-02-18 21:33:27 +02:00
/* left copy */
for ( i = 1 ; i < 8 ; i + + )
2003-03-03 16:54:00 +02:00
ac_val1 [ i ] = block [ s - > dsp . idct_permutation [ i < < 3 ] ] ;
2002-02-18 21:33:27 +02:00
/* top copy */
for ( i = 1 ; i < 8 ; i + + )
2003-03-03 16:54:00 +02:00
ac_val1 [ 8 + i ] = block [ s - > dsp . idct_permutation [ i ] ] ;
2002-02-18 21:33:27 +02:00
}
2004-04-16 04:01:45 +03:00
int16_t * h263_pred_motion ( MpegEncContext * s , int block , int dir ,
2001-07-22 17:18:56 +03:00
int * px , int * py )
{
2004-04-16 04:01:45 +03:00
int wrap ;
2003-12-04 20:34:47 +02:00
int16_t * A , * B , * C , ( * mot_val ) [ 2 ] ;
static const int off [ 4 ] = { 2 , 1 , 1 , - 1 } ;
wrap = s - > b8_stride ;
2004-04-16 04:01:45 +03:00
mot_val = s - > current_picture . motion_val [ dir ] + s - > block_index [ block ] ;
2003-12-04 20:34:47 +02:00
A = mot_val [ - 1 ] ;
/* special case for first (slice) line */
if ( s - > first_slice_line & & block < 3 ) {
2005-05-05 17:34:47 +03:00
// we can't just change some MVs to simulate that as we need them for the B frames (and ME)
2003-12-04 20:34:47 +02:00
// and if we ever support non rectangular objects than we need to do a few ifs here anyway :(
if ( block = = 0 ) { //most common case
if ( s - > mb_x = = s - > resync_mb_x ) { //rare
* px = * py = 0 ;
} else if ( s - > mb_x + 1 = = s - > resync_mb_x & & s - > h263_pred ) { //rare
C = mot_val [ off [ block ] - wrap ] ;
if ( s - > mb_x = = 0 ) {
* px = C [ 0 ] ;
* py = C [ 1 ] ;
} else {
* px = mid_pred ( A [ 0 ] , 0 , C [ 0 ] ) ;
* py = mid_pred ( A [ 1 ] , 0 , C [ 1 ] ) ;
}
} else {
* px = A [ 0 ] ;
* py = A [ 1 ] ;
}
} else if ( block = = 1 ) {
if ( s - > mb_x + 1 = = s - > resync_mb_x & & s - > h263_pred ) { //rare
C = mot_val [ off [ block ] - wrap ] ;
* px = mid_pred ( A [ 0 ] , 0 , C [ 0 ] ) ;
* py = mid_pred ( A [ 1 ] , 0 , C [ 1 ] ) ;
} else {
* px = A [ 0 ] ;
* py = A [ 1 ] ;
}
} else { /* block==2*/
B = mot_val [ - wrap ] ;
C = mot_val [ off [ block ] - wrap ] ;
if ( s - > mb_x = = s - > resync_mb_x ) //rare
A [ 0 ] = A [ 1 ] = 0 ;
2005-12-17 20:14:38 +02:00
2003-12-04 20:34:47 +02:00
* px = mid_pred ( A [ 0 ] , B [ 0 ] , C [ 0 ] ) ;
* py = mid_pred ( A [ 1 ] , B [ 1 ] , C [ 1 ] ) ;
}
} else {
B = mot_val [ - wrap ] ;
C = mot_val [ off [ block ] - wrap ] ;
* px = mid_pred ( A [ 0 ] , B [ 0 ] , C [ 0 ] ) ;
* py = mid_pred ( A [ 1 ] , B [ 1 ] , C [ 1 ] ) ;
}
return * mot_val ;
}
2002-10-31 18:11:03 +02:00
# ifdef CONFIG_ENCODERS
2004-05-12 05:03:24 +03:00
void ff_h263_encode_motion ( MpegEncContext * s , int val , int f_code )
2001-07-22 17:18:56 +03:00
{
2002-09-27 18:38:54 +03:00
int range , l , bit_size , sign , code , bits ;
2001-07-22 17:18:56 +03:00
if ( val = = 0 ) {
/* zero vector */
code = 0 ;
put_bits ( & s - > pb , mvtab [ code ] [ 1 ] , mvtab [ code ] [ 0 ] ) ;
} else {
2002-04-17 07:32:12 +03:00
bit_size = f_code - 1 ;
2001-07-22 17:18:56 +03:00
range = 1 < < bit_size ;
/* modulo encoding */
2004-06-25 17:11:44 +03:00
l = INT_BIT - 6 - bit_size ;
val = ( val < < l ) > > l ;
2002-09-27 18:38:54 +03:00
sign = val > > 31 ;
val = ( val ^ sign ) - sign ;
sign & = 1 ;
2001-07-22 17:18:56 +03:00
2002-04-07 05:03:32 +03:00
val - - ;
code = ( val > > bit_size ) + 1 ;
bits = val & ( range - 1 ) ;
2001-07-22 17:18:56 +03:00
2005-12-17 20:14:38 +02:00
put_bits ( & s - > pb , mvtab [ code ] [ 1 ] + 1 , ( mvtab [ code ] [ 0 ] < < 1 ) | sign ) ;
2001-07-22 17:18:56 +03:00
if ( bit_size > 0 ) {
put_bits ( & s - > pb , bit_size , bits ) ;
}
}
}
2001-08-29 02:32:34 +03:00
/* Encode MV differences on H.263+ with Unrestricted MV mode */
static void h263p_encode_umotion ( MpegEncContext * s , int val )
{
2005-12-17 20:14:38 +02:00
short sval = 0 ;
2001-08-29 02:32:34 +03:00
short i = 0 ;
short n_bits = 0 ;
short temp_val ;
int code = 0 ;
int tcode ;
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
if ( val = = 0 )
put_bits ( & s - > pb , 1 , 1 ) ;
else if ( val = = 1 )
put_bits ( & s - > pb , 3 , 0 ) ;
else if ( val = = - 1 )
put_bits ( & s - > pb , 3 , 2 ) ;
else {
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
sval = ( ( val < 0 ) ? ( short ) ( - val ) : ( short ) val ) ;
temp_val = sval ;
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
while ( temp_val ! = 0 ) {
temp_val = temp_val > > 1 ;
n_bits + + ;
}
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
i = n_bits - 1 ;
while ( i > 0 ) {
tcode = ( sval & ( 1 < < ( i - 1 ) ) ) > > ( i - 1 ) ;
tcode = ( tcode < < 1 ) | 1 ;
code = ( code < < 2 ) | tcode ;
i - - ;
}
code = ( ( code < < 1 ) | ( val < 0 ) ) < < 1 ;
put_bits ( & s - > pb , ( 2 * n_bits ) + 1 , code ) ;
//printf("\nVal = %d\tCode = %d", sval, code);
}
}
2002-03-22 04:21:17 +02:00
static void init_mv_penalty_and_fcode ( MpegEncContext * s )
{
int f_code ;
int mv ;
2005-12-17 20:14:38 +02:00
2002-10-31 18:11:03 +02:00
if ( mv_penalty = = NULL )
2003-03-31 14:13:14 +03:00
mv_penalty = av_mallocz ( sizeof ( uint8_t ) * ( MAX_FCODE + 1 ) * ( 2 * MAX_MV + 1 ) ) ;
2005-12-17 20:14:38 +02:00
2002-03-22 04:21:17 +02:00
for ( f_code = 1 ; f_code < = MAX_FCODE ; f_code + + ) {
for ( mv = - MAX_MV ; mv < = MAX_MV ; mv + + ) {
int len ;
if ( mv = = 0 ) len = mvtab [ 0 ] [ 1 ] ;
else {
int val , bit_size , range , code ;
2004-03-16 18:57:27 +02:00
bit_size = f_code - 1 ;
2002-03-22 04:21:17 +02:00
range = 1 < < bit_size ;
val = mv ;
2005-12-17 20:14:38 +02:00
if ( val < 0 )
2002-03-22 04:21:17 +02:00
val = - val ;
val - - ;
code = ( val > > bit_size ) + 1 ;
if ( code < 33 ) {
len = mvtab [ code ] [ 1 ] + 1 + bit_size ;
} else {
2005-12-24 05:12:07 +02:00
len = mvtab [ 32 ] [ 1 ] + av_log2 ( code > > 5 ) + 2 + bit_size ;
2002-03-22 04:21:17 +02:00
}
}
mv_penalty [ f_code ] [ mv + MAX_MV ] = len ;
}
}
for ( f_code = MAX_FCODE ; f_code > 0 ; f_code - - ) {
for ( mv = - ( 16 < < f_code ) ; mv < ( 16 < < f_code ) ; mv + + ) {
fcode_tab [ mv + MAX_MV ] = f_code ;
}
}
2002-03-23 22:21:33 +02:00
for ( mv = 0 ; mv < MAX_MV * 2 + 1 ; mv + + ) {
umv_fcode_tab [ mv ] = 1 ;
}
2002-03-22 04:21:17 +02:00
}
2002-10-31 18:11:03 +02:00
# endif
2002-03-22 04:21:17 +02:00
2003-02-17 01:05:38 +02:00
# ifdef CONFIG_ENCODERS
2002-06-03 14:16:11 +03:00
static void init_uni_dc_tab ( void )
2002-03-25 17:36:16 +02:00
{
int level , uni_code , uni_len ;
2002-04-07 05:03:32 +03:00
for ( level = - 256 ; level < 256 ; level + + ) {
2002-03-25 17:36:16 +02:00
int size , v , l ;
/* find number of bits */
size = 0 ;
v = abs ( level ) ;
while ( v ) {
v > > = 1 ;
2005-12-22 03:10:11 +02:00
size + + ;
2002-03-25 17:36:16 +02:00
}
if ( level < 0 )
l = ( - level ) ^ ( ( 1 < < size ) - 1 ) ;
else
l = level ;
/* luminance */
uni_code = DCtab_lum [ size ] [ 0 ] ;
uni_len = DCtab_lum [ size ] [ 1 ] ;
if ( size > 0 ) {
uni_code < < = size ; uni_code | = l ;
uni_len + = size ;
if ( size > 8 ) {
uni_code < < = 1 ; uni_code | = 1 ;
uni_len + + ;
}
}
2003-01-19 19:55:13 +02:00
uni_DCtab_lum_bits [ level + 256 ] = uni_code ;
uni_DCtab_lum_len [ level + 256 ] = uni_len ;
2002-03-25 17:36:16 +02:00
/* chrominance */
uni_code = DCtab_chrom [ size ] [ 0 ] ;
uni_len = DCtab_chrom [ size ] [ 1 ] ;
2005-12-17 20:14:38 +02:00
2002-03-25 17:36:16 +02:00
if ( size > 0 ) {
uni_code < < = size ; uni_code | = l ;
uni_len + = size ;
if ( size > 8 ) {
uni_code < < = 1 ; uni_code | = 1 ;
uni_len + + ;
}
}
2003-01-19 19:55:13 +02:00
uni_DCtab_chrom_bits [ level + 256 ] = uni_code ;
uni_DCtab_chrom_len [ level + 256 ] = uni_len ;
2002-03-25 17:36:16 +02:00
}
}
2003-02-17 01:05:38 +02:00
# endif //CONFIG_ENCODERS
2002-10-31 18:11:03 +02:00
# ifdef CONFIG_ENCODERS
2003-02-11 18:35:48 +02:00
static void init_uni_mpeg4_rl_tab ( RLTable * rl , uint32_t * bits_tab , uint8_t * len_tab ) {
2002-09-07 03:16:30 +03:00
int slevel , run , last ;
2005-12-17 20:14:38 +02:00
2002-09-07 03:16:30 +03:00
assert ( MAX_LEVEL > = 64 ) ;
assert ( MAX_RUN > = 63 ) ;
for ( slevel = - 64 ; slevel < 64 ; slevel + + ) {
if ( slevel = = 0 ) continue ;
for ( run = 0 ; run < 64 ; run + + ) {
for ( last = 0 ; last < = 1 ; last + + ) {
const int index = UNI_MPEG4_ENC_INDEX ( last , run , slevel + 64 ) ;
int level = slevel < 0 ? - slevel : slevel ;
int sign = slevel < 0 ? 1 : 0 ;
int bits , len , code ;
int level1 , run1 ;
2005-12-17 20:14:38 +02:00
2002-09-07 03:16:30 +03:00
len_tab [ index ] = 100 ;
2005-12-17 20:14:38 +02:00
2002-09-07 03:16:30 +03:00
/* ESC0 */
code = get_rl_index ( rl , last , run , level ) ;
bits = rl - > table_vlc [ code ] [ 0 ] ;
len = rl - > table_vlc [ code ] [ 1 ] ;
bits = bits * 2 + sign ; len + + ;
2005-12-17 20:14:38 +02:00
2002-09-07 03:16:30 +03:00
if ( code ! = rl - > n & & len < len_tab [ index ] ) {
bits_tab [ index ] = bits ;
len_tab [ index ] = len ;
}
# if 1
/* ESC1 */
bits = rl - > table_vlc [ rl - > n ] [ 0 ] ;
len = rl - > table_vlc [ rl - > n ] [ 1 ] ;
bits = bits * 2 ; len + + ; //esc1
level1 = level - rl - > max_level [ last ] [ run ] ;
if ( level1 > 0 ) {
code = get_rl_index ( rl , last , run , level1 ) ;
bits < < = rl - > table_vlc [ code ] [ 1 ] ;
len + = rl - > table_vlc [ code ] [ 1 ] ;
bits + = rl - > table_vlc [ code ] [ 0 ] ;
bits = bits * 2 + sign ; len + + ;
2005-12-17 20:14:38 +02:00
2002-09-07 03:16:30 +03:00
if ( code ! = rl - > n & & len < len_tab [ index ] ) {
bits_tab [ index ] = bits ;
len_tab [ index ] = len ;
}
}
2005-12-17 20:14:38 +02:00
# endif
2002-09-07 03:16:30 +03:00
# if 1
/* ESC2 */
bits = rl - > table_vlc [ rl - > n ] [ 0 ] ;
len = rl - > table_vlc [ rl - > n ] [ 1 ] ;
bits = bits * 4 + 2 ; len + = 2 ; //esc2
run1 = run - rl - > max_run [ last ] [ level ] - 1 ;
if ( run1 > = 0 ) {
code = get_rl_index ( rl , last , run1 , level ) ;
bits < < = rl - > table_vlc [ code ] [ 1 ] ;
len + = rl - > table_vlc [ code ] [ 1 ] ;
bits + = rl - > table_vlc [ code ] [ 0 ] ;
bits = bits * 2 + sign ; len + + ;
2005-12-17 20:14:38 +02:00
2002-09-07 03:16:30 +03:00
if ( code ! = rl - > n & & len < len_tab [ index ] ) {
bits_tab [ index ] = bits ;
len_tab [ index ] = len ;
}
}
2005-12-17 20:14:38 +02:00
# endif
/* ESC3 */
2002-09-07 03:16:30 +03:00
bits = rl - > table_vlc [ rl - > n ] [ 0 ] ;
len = rl - > table_vlc [ rl - > n ] [ 1 ] ;
bits = bits * 4 + 3 ; len + = 2 ; //esc3
bits = bits * 2 + last ; len + + ;
bits = bits * 64 + run ; len + = 6 ;
bits = bits * 2 + 1 ; len + + ; //marker
bits = bits * 4096 + ( slevel & 0xfff ) ; len + = 12 ;
bits = bits * 2 + 1 ; len + + ; //marker
2005-12-17 20:14:38 +02:00
2002-09-07 03:16:30 +03:00
if ( len < len_tab [ index ] ) {
bits_tab [ index ] = bits ;
len_tab [ index ] = len ;
}
}
}
}
}
2004-09-24 23:35:59 +03:00
static void init_uni_h263_rl_tab ( RLTable * rl , uint32_t * bits_tab , uint8_t * len_tab ) {
int slevel , run , last ;
2005-12-17 20:14:38 +02:00
2004-09-24 23:35:59 +03:00
assert ( MAX_LEVEL > = 64 ) ;
assert ( MAX_RUN > = 63 ) ;
for ( slevel = - 64 ; slevel < 64 ; slevel + + ) {
if ( slevel = = 0 ) continue ;
for ( run = 0 ; run < 64 ; run + + ) {
for ( last = 0 ; last < = 1 ; last + + ) {
const int index = UNI_MPEG4_ENC_INDEX ( last , run , slevel + 64 ) ;
int level = slevel < 0 ? - slevel : slevel ;
int sign = slevel < 0 ? 1 : 0 ;
int bits , len , code ;
2005-12-17 20:14:38 +02:00
2004-09-24 23:35:59 +03:00
len_tab [ index ] = 100 ;
2005-12-17 20:14:38 +02:00
2004-09-24 23:35:59 +03:00
/* ESC0 */
code = get_rl_index ( rl , last , run , level ) ;
bits = rl - > table_vlc [ code ] [ 0 ] ;
len = rl - > table_vlc [ code ] [ 1 ] ;
bits = bits * 2 + sign ; len + + ;
2005-12-17 20:14:38 +02:00
2004-09-24 23:35:59 +03:00
if ( code ! = rl - > n & & len < len_tab [ index ] ) {
if ( bits_tab ) bits_tab [ index ] = bits ;
len_tab [ index ] = len ;
}
/* ESC */
bits = rl - > table_vlc [ rl - > n ] [ 0 ] ;
len = rl - > table_vlc [ rl - > n ] [ 1 ] ;
bits = bits * 2 + last ; len + + ;
bits = bits * 64 + run ; len + = 6 ;
bits = bits * 256 + ( level & 0xff ) ; len + = 8 ;
2005-12-17 20:14:38 +02:00
2004-09-24 23:35:59 +03:00
if ( len < len_tab [ index ] ) {
if ( bits_tab ) bits_tab [ index ] = bits ;
len_tab [ index ] = len ;
}
}
}
}
}
2002-03-22 04:21:17 +02:00
void h263_encode_init ( MpegEncContext * s )
2001-07-22 17:18:56 +03:00
{
static int done = 0 ;
if ( ! done ) {
done = 1 ;
2002-03-25 17:36:16 +02:00
init_uni_dc_tab ( ) ;
2004-11-27 20:10:06 +02:00
init_rl ( & rl_inter , 1 ) ;
init_rl ( & rl_intra , 1 ) ;
init_rl ( & rl_intra_aic , 1 ) ;
2005-12-17 20:14:38 +02:00
2002-09-07 03:16:30 +03:00
init_uni_mpeg4_rl_tab ( & rl_intra , uni_mpeg4_intra_rl_bits , uni_mpeg4_intra_rl_len ) ;
init_uni_mpeg4_rl_tab ( & rl_inter , uni_mpeg4_inter_rl_bits , uni_mpeg4_inter_rl_len ) ;
2002-03-22 04:21:17 +02:00
2004-09-24 23:35:59 +03:00
init_uni_h263_rl_tab ( & rl_intra_aic , NULL , uni_h263_intra_aic_rl_len ) ;
init_uni_h263_rl_tab ( & rl_inter , NULL , uni_h263_inter_rl_len ) ;
2002-03-22 04:21:17 +02:00
init_mv_penalty_and_fcode ( s ) ;
2001-07-22 17:18:56 +03:00
}
2002-12-28 01:51:46 +02:00
s - > me . mv_penalty = mv_penalty ; //FIXME exact table for msmpeg4 & h263p
2005-12-17 20:14:38 +02:00
2004-09-24 23:35:59 +03:00
s - > intra_ac_vlc_length = s - > inter_ac_vlc_length = uni_h263_inter_rl_len ;
s - > intra_ac_vlc_last_length = s - > inter_ac_vlc_last_length = uni_h263_inter_rl_len + 128 * 64 ;
if ( s - > h263_aic ) {
s - > intra_ac_vlc_length = uni_h263_intra_aic_rl_len ;
s - > intra_ac_vlc_last_length = uni_h263_intra_aic_rl_len + 128 * 64 ;
}
s - > ac_esc_length = 7 + 1 + 6 + 8 ;
2002-03-23 22:21:33 +02:00
// use fcodes >1 only for mpeg4 & h263 & h263p FIXME
2002-04-27 15:30:26 +03:00
switch ( s - > codec_id ) {
case CODEC_ID_MPEG4 :
s - > fcode_tab = fcode_tab ;
s - > min_qcoeff = - 2048 ;
s - > max_qcoeff = 2047 ;
2002-12-31 19:23:56 +02:00
s - > intra_ac_vlc_length = uni_mpeg4_intra_rl_len ;
s - > intra_ac_vlc_last_length = uni_mpeg4_intra_rl_len + 128 * 64 ;
s - > inter_ac_vlc_length = uni_mpeg4_inter_rl_len ;
s - > inter_ac_vlc_last_length = uni_mpeg4_inter_rl_len + 128 * 64 ;
2003-01-19 19:55:13 +02:00
s - > luma_dc_vlc_length = uni_DCtab_lum_len ;
s - > chroma_dc_vlc_length = uni_DCtab_chrom_len ;
2002-12-31 19:23:56 +02:00
s - > ac_esc_length = 7 + 2 + 1 + 6 + 1 + 12 + 1 ;
2004-02-13 19:54:10 +02:00
s - > y_dc_scale_table = ff_mpeg4_y_dc_scale_table ;
s - > c_dc_scale_table = ff_mpeg4_c_dc_scale_table ;
2003-08-26 23:14:28 +03:00
if ( s - > flags & CODEC_FLAG_GLOBAL_HEADER ) {
2003-09-27 03:01:46 +03:00
2003-08-26 23:14:28 +03:00
s - > avctx - > extradata = av_malloc ( 1024 ) ;
2003-10-13 00:25:00 +03:00
init_put_bits ( & s - > pb , s - > avctx - > extradata , 1024 ) ;
2005-12-17 20:14:38 +02:00
2005-03-23 13:39:38 +02:00
if ( ! ( s - > workaround_bugs & FF_BUG_MS ) )
mpeg4_encode_visual_object_header ( s ) ;
2003-08-26 23:14:28 +03:00
mpeg4_encode_vol_header ( s , 0 , 0 ) ;
// ff_mpeg4_stuffing(&s->pb); ?
flush_put_bits ( & s - > pb ) ;
2004-02-06 17:27:31 +02:00
s - > avctx - > extradata_size = ( put_bits_count ( & s - > pb ) + 7 ) > > 3 ;
2003-08-26 23:14:28 +03:00
}
2005-12-17 20:14:38 +02:00
2002-04-27 15:30:26 +03:00
break ;
case CODEC_ID_H263P :
2003-12-08 19:42:20 +02:00
if ( s - > umvplus )
s - > fcode_tab = umv_fcode_tab ;
if ( s - > modified_quant ) {
s - > min_qcoeff = - 2047 ;
s - > max_qcoeff = 2047 ;
} else {
s - > min_qcoeff = - 127 ;
s - > max_qcoeff = 127 ;
}
2002-04-27 15:30:26 +03:00
break ;
2005-12-17 20:14:38 +02:00
//Note for mpeg4 & h263 the dc-scale table will be set per frame as needed later
2003-07-10 02:10:59 +03:00
case CODEC_ID_FLV1 :
if ( s - > h263_flv > 1 ) {
s - > min_qcoeff = - 1023 ;
s - > max_qcoeff = 1023 ;
} else {
s - > min_qcoeff = - 127 ;
s - > max_qcoeff = 127 ;
}
s - > y_dc_scale_table =
s - > c_dc_scale_table = ff_mpeg1_dc_scale_table ;
break ;
2005-05-05 17:34:47 +03:00
default : //nothing needed - default table already set in mpegvideo.c
2003-02-28 15:07:07 +02:00
s - > min_qcoeff = - 127 ;
2002-04-27 15:30:26 +03:00
s - > max_qcoeff = 127 ;
2002-06-18 03:46:02 +03:00
s - > y_dc_scale_table =
s - > c_dc_scale_table = ff_mpeg1_dc_scale_table ;
2002-04-27 15:30:26 +03:00
}
2001-07-22 17:18:56 +03:00
}
2003-01-27 01:09:12 +02:00
/**
* encodes a 8 x8 block .
* @ param block the 8 x8 block
* @ param n block index ( 0 - 3 are luma , 4 - 5 are chroma )
*/
2001-07-22 17:18:56 +03:00
static void h263_encode_block ( MpegEncContext * s , DCTELEM * block , int n )
{
2002-05-02 07:39:45 +03:00
int level , run , last , i , j , last_index , last_non_zero , sign , slevel , code ;
RLTable * rl ;
2001-07-22 17:18:56 +03:00
2002-05-02 07:39:45 +03:00
rl = & rl_inter ;
if ( s - > mb_intra & & ! s - > h263_aic ) {
2002-02-09 18:59:56 +02:00
/* DC coef */
2003-02-28 15:07:07 +02:00
level = block [ 0 ] ;
2001-07-22 17:18:56 +03:00
/* 255 cannot be represented, so we clamp */
if ( level > 254 ) {
level = 254 ;
block [ 0 ] = 254 ;
}
2002-02-09 18:59:56 +02:00
/* 0 cannot be represented also */
2003-02-28 15:07:07 +02:00
else if ( level < 1 ) {
2002-02-09 18:59:56 +02:00
level = 1 ;
block [ 0 ] = 1 ;
}
2003-02-28 18:06:40 +02:00
if ( level = = 128 ) //FIXME check rv10
2003-02-28 15:07:07 +02:00
put_bits ( & s - > pb , 8 , 0xff ) ;
else
2004-01-25 01:47:33 +02:00
put_bits ( & s - > pb , 8 , level ) ;
2003-02-28 15:07:07 +02:00
i = 1 ;
2001-07-22 17:18:56 +03:00
} else {
2003-02-28 15:07:07 +02:00
i = 0 ;
if ( s - > h263_aic & & s - > mb_intra )
rl = & rl_intra_aic ;
2005-12-17 20:14:38 +02:00
2003-11-29 10:37:51 +02:00
if ( s - > alt_inter_vlc & & ! s - > mb_intra ) {
int aic_vlc_bits = 0 ;
int inter_vlc_bits = 0 ;
int wrong_pos = - 1 ;
int aic_code ;
2005-12-17 20:14:38 +02:00
2003-11-29 10:37:51 +02:00
last_index = s - > block_last_index [ n ] ;
last_non_zero = i - 1 ;
for ( ; i < = last_index ; i + + ) {
j = s - > intra_scantable . permutated [ i ] ;
level = block [ j ] ;
if ( level ) {
run = i - last_non_zero - 1 ;
last = ( i = = last_index ) ;
2005-12-17 20:14:38 +02:00
2003-12-08 04:23:22 +02:00
if ( level < 0 ) level = - level ;
2005-12-17 20:14:38 +02:00
2003-11-29 10:37:51 +02:00
code = get_rl_index ( rl , last , run , level ) ;
aic_code = get_rl_index ( & rl_intra_aic , last , run , level ) ;
inter_vlc_bits + = rl - > table_vlc [ code ] [ 1 ] + 1 ;
aic_vlc_bits + = rl_intra_aic . table_vlc [ aic_code ] [ 1 ] + 1 ;
if ( code = = rl - > n ) {
2003-12-08 04:23:22 +02:00
inter_vlc_bits + = 1 + 6 + 8 - 1 ;
2005-12-17 20:14:38 +02:00
}
2003-11-29 10:37:51 +02:00
if ( aic_code = = rl_intra_aic . n ) {
2003-12-08 04:23:22 +02:00
aic_vlc_bits + = 1 + 6 + 8 - 1 ;
2003-11-29 10:37:51 +02:00
wrong_pos + = run + 1 ;
} else
wrong_pos + = wrong_run [ aic_code ] ;
last_non_zero = i ;
2005-12-17 20:14:38 +02:00
}
2003-11-29 10:37:51 +02:00
}
i = 0 ;
if ( aic_vlc_bits < inter_vlc_bits & & wrong_pos > 63 )
rl = & rl_intra_aic ;
}
2001-07-22 17:18:56 +03:00
}
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
/* AC coefs */
last_index = s - > block_last_index [ n ] ;
last_non_zero = i - 1 ;
for ( ; i < = last_index ; i + + ) {
2002-09-30 01:44:22 +03:00
j = s - > intra_scantable . permutated [ i ] ;
2002-05-02 07:39:45 +03:00
level = block [ j ] ;
if ( level ) {
run = i - last_non_zero - 1 ;
last = ( i = = last_index ) ;
sign = 0 ;
slevel = level ;
if ( level < 0 ) {
sign = 1 ;
level = - level ;
}
2001-07-22 17:18:56 +03:00
code = get_rl_index ( rl , last , run , level ) ;
put_bits ( & s - > pb , rl - > table_vlc [ code ] [ 1 ] , rl - > table_vlc [ code ] [ 0 ] ) ;
if ( code = = rl - > n ) {
2003-07-10 03:15:27 +03:00
if ( s - > h263_flv < = 1 ) {
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 1 , last ) ;
put_bits ( & s - > pb , 6 , run ) ;
2005-12-17 20:14:38 +02:00
2003-02-28 15:07:07 +02:00
assert ( slevel ! = 0 ) ;
2005-12-17 20:14:38 +02:00
if ( level < 128 )
2003-02-28 15:07:07 +02:00
put_bits ( & s - > pb , 8 , slevel & 0xff ) ;
else {
put_bits ( & s - > pb , 8 , 128 ) ;
put_bits ( & s - > pb , 5 , slevel & 0x1f ) ;
put_bits ( & s - > pb , 6 , ( slevel > > 5 ) & 0x3f ) ;
}
2003-07-10 03:15:27 +03:00
} else {
2004-01-25 01:47:33 +02:00
if ( level < 64 ) { // 7-bit level
2003-07-10 03:15:27 +03:00
put_bits ( & s - > pb , 1 , 0 ) ;
put_bits ( & s - > pb , 1 , last ) ;
put_bits ( & s - > pb , 6 , run ) ;
put_bits ( & s - > pb , 7 , slevel & 0x7f ) ;
} else {
/* 11-bit level */
put_bits ( & s - > pb , 1 , 1 ) ;
put_bits ( & s - > pb , 1 , last ) ;
put_bits ( & s - > pb , 6 , run ) ;
put_bits ( & s - > pb , 11 , slevel & 0x7ff ) ;
}
}
2003-07-10 02:10:59 +03:00
} else {
put_bits ( & s - > pb , 1 , sign ) ;
}
last_non_zero = i ;
}
}
}
2002-10-31 18:11:03 +02:00
# endif
2001-07-22 17:18:56 +03:00
2003-02-17 01:05:38 +02:00
# ifdef CONFIG_ENCODERS
2001-07-22 17:18:56 +03:00
/***************************************************/
2002-10-13 16:16:04 +03:00
/**
* add mpeg4 stuffing bits ( 01. . .1 )
*/
2002-06-02 15:15:17 +03:00
void ff_mpeg4_stuffing ( PutBitContext * pbc )
2002-03-13 00:54:25 +02:00
{
int length ;
put_bits ( pbc , 1 , 0 ) ;
2004-02-06 17:27:31 +02:00
length = ( - put_bits_count ( pbc ) ) & 7 ;
2002-06-02 15:15:17 +03:00
if ( length ) put_bits ( pbc , length , ( 1 < < length ) - 1 ) ;
2002-03-13 00:54:25 +02:00
}
2002-04-19 06:25:20 +03:00
/* must be called before writing the header */
void ff_set_mpeg4_time ( MpegEncContext * s , int picture_number ) {
int time_div , time_mod ;
2004-02-25 19:35:52 +02:00
assert ( s - > current_picture_ptr - > pts ! = AV_NOPTS_VALUE ) ;
2005-05-01 00:43:59 +03:00
s - > time = s - > current_picture_ptr - > pts * s - > avctx - > time_base . num ;
2004-02-25 04:05:50 +02:00
2005-05-01 00:43:59 +03:00
time_div = s - > time / s - > avctx - > time_base . den ;
time_mod = s - > time % s - > avctx - > time_base . den ;
2002-04-19 06:25:20 +03:00
if ( s - > pict_type = = B_TYPE ) {
2002-09-13 12:45:32 +03:00
s - > pb_time = s - > pp_time - ( s - > last_non_b_time - s - > time ) ;
2004-09-20 16:47:47 +03:00
assert ( s - > pb_time > 0 & & s - > pb_time < s - > pp_time ) ;
2006-04-03 10:52:24 +03:00
ff_mpeg4_init_direct_mv ( s ) ;
2002-04-19 06:25:20 +03:00
} else {
s - > last_time_base = s - > time_base ;
s - > time_base = time_div ;
s - > pp_time = s - > time - s - > last_non_b_time ;
s - > last_non_b_time = s - > time ;
2005-02-06 19:01:07 +02:00
assert ( picture_number = = 0 | | s - > pp_time > 0 ) ;
2002-04-19 06:25:20 +03:00
}
}
2002-12-30 02:28:42 +02:00
static void mpeg4_encode_gop_header ( MpegEncContext * s ) {
int hours , minutes , seconds ;
2004-01-27 15:55:34 +02:00
int64_t time ;
2005-12-17 20:14:38 +02:00
2002-12-30 02:28:42 +02:00
put_bits ( & s - > pb , 16 , 0 ) ;
put_bits ( & s - > pb , 16 , GOP_STARTCODE ) ;
2005-12-17 20:14:38 +02:00
2004-02-25 19:35:52 +02:00
time = s - > current_picture_ptr - > pts ;
if ( s - > reordered_input_picture [ 1 ] )
time = FFMIN ( time , s - > reordered_input_picture [ 1 ] - > pts ) ;
2005-05-01 00:43:59 +03:00
time = time * s - > avctx - > time_base . num ;
2004-01-27 15:55:34 +02:00
2005-05-01 00:43:59 +03:00
seconds = time / s - > avctx - > time_base . den ;
2002-12-30 02:28:42 +02:00
minutes = seconds / 60 ; seconds % = 60 ;
hours = minutes / 60 ; minutes % = 60 ;
hours % = 24 ;
put_bits ( & s - > pb , 5 , hours ) ;
put_bits ( & s - > pb , 6 , minutes ) ;
put_bits ( & s - > pb , 1 , 1 ) ;
put_bits ( & s - > pb , 6 , seconds ) ;
2005-12-17 20:14:38 +02:00
put_bits ( & s - > pb , 1 , ! ! ( s - > flags & CODEC_FLAG_CLOSED_GOP ) ) ;
2002-12-30 02:28:42 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; //broken link == NO
2005-12-17 20:14:38 +02:00
s - > last_time_base = time / s - > avctx - > time_base . den ;
2002-12-30 02:28:42 +02:00
ff_mpeg4_stuffing ( & s - > pb ) ;
}
static void mpeg4_encode_visual_object_header ( MpegEncContext * s ) {
int profile_and_level_indication ;
int vo_ver_id ;
2005-12-17 20:14:38 +02:00
2004-08-13 16:59:28 +03:00
if ( s - > avctx - > profile ! = FF_PROFILE_UNKNOWN ) {
profile_and_level_indication = s - > avctx - > profile < < 4 ;
} else if ( s - > max_b_frames | | s - > quarter_sample ) {
profile_and_level_indication = 0xF0 ; // adv simple
} else {
profile_and_level_indication = 0x00 ; // simple
}
if ( s - > avctx - > level ! = FF_LEVEL_UNKNOWN ) {
profile_and_level_indication | = s - > avctx - > level ;
} else {
profile_and_level_indication | = 1 ; //level 1
}
if ( profile_and_level_indication > > 4 = = 0xF ) {
2002-12-30 02:28:42 +02:00
vo_ver_id = 5 ;
} else {
vo_ver_id = 1 ;
}
2004-08-13 16:59:28 +03:00
2002-12-30 02:28:42 +02:00
//FIXME levels
put_bits ( & s - > pb , 16 , 0 ) ;
put_bits ( & s - > pb , 16 , VOS_STARTCODE ) ;
2003-07-07 23:17:44 +03:00
2002-12-30 02:28:42 +02:00
put_bits ( & s - > pb , 8 , profile_and_level_indication ) ;
2003-07-07 23:17:44 +03:00
2002-12-30 02:28:42 +02:00
put_bits ( & s - > pb , 16 , 0 ) ;
put_bits ( & s - > pb , 16 , VISUAL_OBJ_STARTCODE ) ;
2005-12-17 20:14:38 +02:00
2002-12-30 02:28:42 +02:00
put_bits ( & s - > pb , 1 , 1 ) ;
put_bits ( & s - > pb , 4 , vo_ver_id ) ;
put_bits ( & s - > pb , 3 , 1 ) ; //priority
2005-12-17 20:14:38 +02:00
2002-12-30 02:28:42 +02:00
put_bits ( & s - > pb , 4 , 1 ) ; //visual obj type== video obj
2005-12-17 20:14:38 +02:00
2002-12-30 02:28:42 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; //video signal type == no clue //FIXME
ff_mpeg4_stuffing ( & s - > pb ) ;
}
static void mpeg4_encode_vol_header ( MpegEncContext * s , int vo_number , int vol_number )
2001-07-22 17:18:56 +03:00
{
2002-12-30 02:28:42 +02:00
int vo_ver_id ;
2002-04-22 22:04:28 +03:00
2002-12-30 02:28:42 +02:00
if ( s - > max_b_frames | | s - > quarter_sample ) {
vo_ver_id = 5 ;
2002-12-09 02:06:15 +02:00
s - > vo_type = ADV_SIMPLE_VO_TYPE ;
} else {
2002-12-30 02:28:42 +02:00
vo_ver_id = 1 ;
2002-12-09 02:06:15 +02:00
s - > vo_type = SIMPLE_VO_TYPE ;
}
2002-04-22 22:04:28 +03:00
2002-03-13 14:50:41 +02:00
put_bits ( & s - > pb , 16 , 0 ) ;
2002-12-30 02:28:42 +02:00
put_bits ( & s - > pb , 16 , 0x100 + vo_number ) ; /* video obj */
2002-03-13 14:50:41 +02:00
put_bits ( & s - > pb , 16 , 0 ) ;
2002-12-30 02:28:42 +02:00
put_bits ( & s - > pb , 16 , 0x120 + vol_number ) ; /* video obj layer */
2002-03-13 14:50:41 +02:00
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* random access vol */
put_bits ( & s - > pb , 8 , s - > vo_type ) ; /* video obj type indication */
2005-03-23 13:39:38 +02:00
if ( s - > workaround_bugs & FF_BUG_MS ) {
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* is obj layer id= no */
2005-03-23 13:39:38 +02:00
} else {
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 1 ) ; /* is obj layer id= yes */
put_bits ( & s - > pb , 4 , vo_ver_id ) ; /* is obj layer ver id */
put_bits ( & s - > pb , 3 , 1 ) ; /* is obj layer priority */
2005-03-23 13:39:38 +02:00
}
2005-12-17 20:14:38 +02:00
2003-10-20 23:23:46 +03:00
aspect_to_info ( s , s - > avctx - > sample_aspect_ratio ) ;
2002-11-20 15:08:04 +02:00
put_bits ( & s - > pb , 4 , s - > aspect_ratio_info ) ; /* aspect ratio info */
2003-10-20 23:23:46 +03:00
if ( s - > aspect_ratio_info = = FF_ASPECT_EXTENDED ) {
put_bits ( & s - > pb , 8 , s - > avctx - > sample_aspect_ratio . num ) ;
put_bits ( & s - > pb , 8 , s - > avctx - > sample_aspect_ratio . den ) ;
2002-09-13 22:31:32 +03:00
}
2002-04-22 22:04:28 +03:00
2005-03-23 13:39:38 +02:00
if ( s - > workaround_bugs & FF_BUG_MS ) { //
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* vol control parameters= no @@@ */
2005-03-23 13:39:38 +02:00
} else {
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 1 ) ; /* vol control parameters= yes */
put_bits ( & s - > pb , 2 , 1 ) ; /* chroma format YUV 420/YV12 */
2005-03-23 13:39:38 +02:00
put_bits ( & s - > pb , 1 , s - > low_delay ) ;
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* vbv parameters= no */
2005-03-23 13:39:38 +02:00
}
2002-04-22 22:04:28 +03:00
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 2 , RECT_SHAPE ) ; /* vol shape= rectangle */
put_bits ( & s - > pb , 1 , 1 ) ; /* marker bit */
2005-12-17 20:14:38 +02:00
2005-05-01 00:43:59 +03:00
put_bits ( & s - > pb , 16 , s - > avctx - > time_base . den ) ;
2002-03-13 14:50:41 +02:00
if ( s - > time_increment_bits < 1 )
s - > time_increment_bits = 1 ;
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 1 ) ; /* marker bit */
put_bits ( & s - > pb , 1 , 0 ) ; /* fixed vop rate=no */
put_bits ( & s - > pb , 1 , 1 ) ; /* marker bit */
put_bits ( & s - > pb , 13 , s - > width ) ; /* vol width */
put_bits ( & s - > pb , 1 , 1 ) ; /* marker bit */
put_bits ( & s - > pb , 13 , s - > height ) ; /* vol height */
put_bits ( & s - > pb , 1 , 1 ) ; /* marker bit */
2002-09-26 03:22:25 +03:00
put_bits ( & s - > pb , 1 , s - > progressive_sequence ? 0 : 1 ) ;
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 1 ) ; /* obmc disable */
2002-03-13 14:50:41 +02:00
if ( vo_ver_id = = 1 ) {
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , s - > vol_sprite_usage ) ; /* sprite enable */
2002-12-30 02:28:42 +02:00
} else {
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 2 , s - > vol_sprite_usage ) ; /* sprite enable */
2002-03-13 14:50:41 +02:00
}
2005-12-17 20:14:38 +02:00
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* not 8 bit == false */
put_bits ( & s - > pb , 1 , s - > mpeg_quant ) ; /* quant type= (0=h263 style)*/
2003-08-23 01:18:08 +03:00
if ( s - > mpeg_quant ) {
ff_write_quant_matrix ( & s - > pb , s - > avctx - > intra_matrix ) ;
ff_write_quant_matrix ( & s - > pb , s - > avctx - > inter_matrix ) ;
}
2002-08-07 02:51:15 +03:00
2002-03-13 14:50:41 +02:00
if ( vo_ver_id ! = 1 )
2002-12-28 01:51:46 +02:00
put_bits ( & s - > pb , 1 , s - > quarter_sample ) ;
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 1 ) ; /* complexity estimation disable */
2002-06-02 15:15:17 +03:00
s - > resync_marker = s - > rtp_mode ;
put_bits ( & s - > pb , 1 , s - > resync_marker ? 0 : 1 ) ; /* resync marker disable */
put_bits ( & s - > pb , 1 , s - > data_partitioning ? 1 : 0 ) ;
if ( s - > data_partitioning ) {
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* no rvlc */
2002-06-02 15:15:17 +03:00
}
2002-03-13 14:50:41 +02:00
if ( vo_ver_id ! = 1 ) {
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* newpred */
put_bits ( & s - > pb , 1 , 0 ) ; /* reduced res vop */
2002-03-13 14:50:41 +02:00
}
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 0 ) ; /* scalability */
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
ff_mpeg4_stuffing ( & s - > pb ) ;
2002-03-13 21:26:38 +02:00
2002-09-15 01:07:35 +03:00
/* user data */
2003-03-03 16:54:00 +02:00
if ( ! ( s - > flags & CODEC_FLAG_BITEXACT ) ) {
2002-09-15 01:07:35 +03:00
put_bits ( & s - > pb , 16 , 0 ) ;
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 16 , 0x1B2 ) ; /* user_data */
ff_put_string ( & s - > pb , LIBAVCODEC_IDENT , 0 ) ;
2002-09-15 01:07:35 +03:00
}
2002-03-13 14:50:41 +02:00
}
/* write mpeg4 VOP header */
void mpeg4_encode_picture_header ( MpegEncContext * s , int picture_number )
{
2002-04-17 07:32:12 +03:00
int time_incr ;
int time_div , time_mod ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( s - > pict_type = = I_TYPE ) {
2003-01-04 01:21:52 +02:00
if ( ! ( s - > flags & CODEC_FLAG_GLOBAL_HEADER ) ) {
2005-05-08 23:15:42 +03:00
if ( s - > strict_std_compliance < FF_COMPLIANCE_VERY_STRICT ) //HACK, the reference sw is buggy
2003-07-07 23:17:44 +03:00
mpeg4_encode_visual_object_header ( s ) ;
2005-05-08 23:15:42 +03:00
if ( s - > strict_std_compliance < FF_COMPLIANCE_VERY_STRICT | | picture_number = = 0 ) //HACK, the reference sw is buggy
2003-07-07 23:17:44 +03:00
mpeg4_encode_vol_header ( s , 0 , 0 ) ;
2002-12-30 02:28:42 +02:00
}
2005-03-23 13:39:38 +02:00
if ( ! ( s - > workaround_bugs & FF_BUG_MS ) )
mpeg4_encode_gop_header ( s ) ;
2002-06-02 15:15:17 +03:00
}
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
s - > partitioned_frame = s - > data_partitioning & & s - > pict_type ! = B_TYPE ;
2005-05-01 00:43:59 +03:00
//printf("num:%d rate:%d base:%d\n", s->picture_number, s->time_base.den, FRAME_RATE_BASE);
2005-12-17 20:14:38 +02:00
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 16 , 0 ) ; /* vop header */
put_bits ( & s - > pb , 16 , VOP_STARTCODE ) ; /* vop header */
put_bits ( & s - > pb , 2 , s - > pict_type - 1 ) ; /* pict type: I = 0 , P = 1 */
2002-04-17 07:32:12 +03:00
2005-05-14 02:11:32 +03:00
assert ( s - > time > = 0 ) ;
2005-05-01 00:43:59 +03:00
time_div = s - > time / s - > avctx - > time_base . den ;
time_mod = s - > time % s - > avctx - > time_base . den ;
2002-04-17 07:32:12 +03:00
time_incr = time_div - s - > last_time_base ;
2004-04-13 16:17:35 +03:00
assert ( time_incr > = 0 ) ;
2002-04-17 07:32:12 +03:00
while ( time_incr - - )
put_bits ( & s - > pb , 1 , 1 ) ;
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 1 , 0 ) ;
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , 1 ) ; /* marker */
put_bits ( & s - > pb , s - > time_increment_bits , time_mod ) ; /* time increment */
put_bits ( & s - > pb , 1 , 1 ) ; /* marker */
put_bits ( & s - > pb , 1 , 1 ) ; /* vop coded */
2005-12-17 20:14:38 +02:00
if ( s - > pict_type = = P_TYPE
2002-03-13 14:50:41 +02:00
| | ( s - > pict_type = = S_TYPE & & s - > vol_sprite_usage = = GMC_SPRITE ) ) {
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 1 , s - > no_rounding ) ; /* rounding type */
2001-07-22 17:18:56 +03:00
}
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 3 , 0 ) ; /* intra dc VLC threshold */
2002-09-26 03:22:25 +03:00
if ( ! s - > progressive_sequence ) {
2003-12-05 03:03:12 +02:00
put_bits ( & s - > pb , 1 , s - > current_picture_ptr - > top_field_first ) ;
2002-09-26 03:22:25 +03:00
put_bits ( & s - > pb , 1 , s - > alternate_scan ) ;
}
2002-03-13 14:50:41 +02:00
//FIXME sprite stuff
2001-07-22 17:18:56 +03:00
put_bits ( & s - > pb , 5 , s - > qscale ) ;
if ( s - > pict_type ! = I_TYPE )
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 3 , s - > f_code ) ; /* fcode_for */
2002-03-13 14:50:41 +02:00
if ( s - > pict_type = = B_TYPE )
2005-12-22 03:10:11 +02:00
put_bits ( & s - > pb , 3 , s - > b_code ) ; /* fcode_back */
2001-07-22 17:18:56 +03:00
// printf("****frame %d\n", picture_number);
}
2003-02-17 01:05:38 +02:00
# endif //CONFIG_ENCODERS
2002-10-13 16:16:04 +03:00
/**
2003-12-03 18:47:17 +02:00
* set qscale and update qscale dependant variables .
2002-10-13 16:16:04 +03:00
*/
2003-12-03 18:47:17 +02:00
void ff_set_qscale ( MpegEncContext * s , int qscale )
2001-07-22 17:18:56 +03:00
{
2003-12-03 18:47:17 +02:00
if ( qscale < 1 )
qscale = 1 ;
else if ( qscale > 31 )
qscale = 31 ;
2005-12-17 20:14:38 +02:00
2003-12-03 18:47:17 +02:00
s - > qscale = qscale ;
s - > chroma_qscale = s - > chroma_qscale_table [ qscale ] ;
2002-09-26 12:16:23 +03:00
2003-12-03 18:47:17 +02:00
s - > y_dc_scale = s - > y_dc_scale_table [ qscale ] ;
2003-12-01 17:23:14 +02:00
s - > c_dc_scale = s - > c_dc_scale_table [ s - > chroma_qscale ] ;
2001-07-22 17:18:56 +03:00
}
2003-01-27 01:09:12 +02:00
/**
* predicts the dc .
2004-05-05 03:14:22 +03:00
* encoding quantized level - > quantized diff
2005-12-17 20:14:38 +02:00
* decoding quantized diff - > quantized level
2003-01-27 01:09:12 +02:00
* @ param n block index ( 0 - 3 are luma , 4 - 5 are chroma )
* @ param dir_ptr pointer to an integer where the prediction direction will be stored
*/
2004-05-05 03:14:22 +03:00
static inline int ff_mpeg4_pred_dc ( MpegEncContext * s , int n , int level , int * dir_ptr , int encoding )
2001-07-22 17:18:56 +03:00
{
2004-05-05 03:14:22 +03:00
int a , b , c , wrap , pred , scale , ret ;
2006-09-28 01:13:44 +03:00
int16_t * dc_val ;
2001-07-22 17:18:56 +03:00
/* find prediction */
if ( n < 4 ) {
2005-12-22 03:10:11 +02:00
scale = s - > y_dc_scale ;
2001-07-22 17:18:56 +03:00
} else {
2005-12-22 03:10:11 +02:00
scale = s - > c_dc_scale ;
2001-07-22 17:18:56 +03:00
}
2003-05-18 03:07:17 +03:00
if ( IS_3IV1 )
scale = 8 ;
2002-03-15 16:57:17 +02:00
wrap = s - > block_wrap [ n ] ;
dc_val = s - > dc_val [ 0 ] + s - > block_index [ n ] ;
2001-07-22 17:18:56 +03:00
/* B C
2005-12-17 20:14:38 +02:00
* A X
2001-07-22 17:18:56 +03:00
*/
2002-03-15 16:57:17 +02:00
a = dc_val [ - 1 ] ;
b = dc_val [ - 1 - wrap ] ;
c = dc_val [ - wrap ] ;
2001-07-22 17:18:56 +03:00
2005-05-05 17:34:47 +03:00
/* outside slice handling (we can't do that by memset as we need the dc for error resilience) */
2002-10-13 16:16:04 +03:00
if ( s - > first_slice_line & & n ! = 3 ) {
if ( n ! = 2 ) b = c = 1024 ;
if ( n ! = 1 & & s - > mb_x = = s - > resync_mb_x ) b = a = 1024 ;
}
if ( s - > mb_x = = s - > resync_mb_x & & s - > mb_y = = s - > resync_mb_y + 1 ) {
if ( n = = 0 | | n = = 4 | | n = = 5 )
b = 1024 ;
}
2001-07-22 17:18:56 +03:00
if ( abs ( a - b ) < abs ( b - c ) ) {
2005-12-22 03:10:11 +02:00
pred = c ;
2001-07-22 17:18:56 +03:00
* dir_ptr = 1 ; /* top */
} else {
2005-12-22 03:10:11 +02:00
pred = a ;
2001-07-22 17:18:56 +03:00
* dir_ptr = 0 ; /* left */
}
/* we assume pred is positive */
2003-05-14 18:12:13 +03:00
pred = FASTDIV ( ( pred + ( scale > > 1 ) ) , scale ) ;
2001-07-22 17:18:56 +03:00
2004-05-05 03:14:22 +03:00
if ( encoding ) {
ret = level - pred ;
} else {
level + = pred ;
ret = level ;
if ( s - > error_resilience > = 3 ) {
if ( level < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " dc<0 at %dx%d \n " , s - > mb_x , s - > mb_y ) ;
return - 1 ;
}
if ( level * scale > 2048 + scale ) {
av_log ( s - > avctx , AV_LOG_ERROR , " dc overflow at %dx%d \n " , s - > mb_x , s - > mb_y ) ;
return - 1 ;
}
}
}
level * = scale ;
2004-05-05 22:53:40 +03:00
if ( level & ( ~ 2047 ) ) {
2005-12-17 20:14:38 +02:00
if ( level < 0 )
2004-05-05 22:53:40 +03:00
level = 0 ;
else if ( ! ( s - > workaround_bugs & FF_BUG_DC_CLIP ) )
level = 2047 ;
}
2004-05-05 03:14:22 +03:00
dc_val [ 0 ] = level ;
2001-07-22 17:18:56 +03:00
2004-05-05 03:14:22 +03:00
return ret ;
2001-07-22 17:18:56 +03:00
}
2003-01-27 01:09:12 +02:00
/**
* predicts the ac .
* @ param n block index ( 0 - 3 are luma , 4 - 5 are chroma )
* @ param dir the ac prediction direction
*/
2003-01-15 21:21:21 +02:00
void mpeg4_pred_ac ( MpegEncContext * s , DCTELEM * block , int n ,
2001-07-22 17:18:56 +03:00
int dir )
{
2002-03-15 16:57:17 +02:00
int i ;
2003-02-11 18:35:48 +02:00
int16_t * ac_val , * ac_val1 ;
2002-12-04 12:04:03 +02:00
int8_t * const qscale_table = s - > current_picture . qscale_table ;
2001-07-22 17:18:56 +03:00
/* find prediction */
2002-03-15 16:57:17 +02:00
ac_val = s - > ac_val [ 0 ] [ 0 ] + s - > block_index [ n ] * 16 ;
2001-07-22 17:18:56 +03:00
ac_val1 = ac_val ;
if ( s - > ac_pred ) {
if ( dir = = 0 ) {
2003-04-10 16:18:38 +03:00
const int xy = s - > mb_x - 1 + s - > mb_y * s - > mb_stride ;
2001-07-22 17:18:56 +03:00
/* left prediction */
ac_val - = 16 ;
2005-12-17 20:14:38 +02:00
2002-12-04 12:04:03 +02:00
if ( s - > mb_x = = 0 | | s - > qscale = = qscale_table [ xy ] | | n = = 1 | | n = = 3 ) {
2002-07-21 04:34:05 +03:00
/* same qscale */
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
block [ s - > dsp . idct_permutation [ i < < 3 ] ] + = ac_val [ i ] ;
2002-07-21 04:34:05 +03:00
}
} else {
/* different qscale, we must rescale */
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
block [ s - > dsp . idct_permutation [ i < < 3 ] ] + = ROUNDED_DIV ( ac_val [ i ] * qscale_table [ xy ] , s - > qscale ) ;
2002-07-21 04:34:05 +03:00
}
2001-07-22 17:18:56 +03:00
}
} else {
2003-04-10 16:18:38 +03:00
const int xy = s - > mb_x + s - > mb_y * s - > mb_stride - s - > mb_stride ;
2001-07-22 17:18:56 +03:00
/* top prediction */
2002-03-15 16:57:17 +02:00
ac_val - = 16 * s - > block_wrap [ n ] ;
2002-07-21 04:34:05 +03:00
2002-12-04 12:04:03 +02:00
if ( s - > mb_y = = 0 | | s - > qscale = = qscale_table [ xy ] | | n = = 2 | | n = = 3 ) {
2002-07-21 04:34:05 +03:00
/* same qscale */
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
block [ s - > dsp . idct_permutation [ i ] ] + = ac_val [ i + 8 ] ;
2002-07-21 04:34:05 +03:00
}
} else {
/* different qscale, we must rescale */
for ( i = 1 ; i < 8 ; i + + ) {
2003-03-03 16:54:00 +02:00
block [ s - > dsp . idct_permutation [ i ] ] + = ROUNDED_DIV ( ac_val [ i + 8 ] * qscale_table [ xy ] , s - > qscale ) ;
2002-07-21 04:34:05 +03:00
}
2001-07-22 17:18:56 +03:00
}
}
}
/* left copy */
for ( i = 1 ; i < 8 ; i + + )
2003-03-03 16:54:00 +02:00
ac_val1 [ i ] = block [ s - > dsp . idct_permutation [ i < < 3 ] ] ;
2002-08-02 23:27:46 +03:00
2001-07-22 17:18:56 +03:00
/* top copy */
for ( i = 1 ; i < 8 ; i + + )
2003-03-03 16:54:00 +02:00
ac_val1 [ 8 + i ] = block [ s - > dsp . idct_permutation [ i ] ] ;
2002-08-02 23:27:46 +03:00
2001-07-22 17:18:56 +03:00
}
2003-02-17 01:05:38 +02:00
# ifdef CONFIG_ENCODERS
2003-01-27 01:09:12 +02:00
/**
* encodes the dc value .
* @ param n block index ( 0 - 3 are luma , 4 - 5 are chroma )
*/
2002-06-02 15:15:17 +03:00
static inline void mpeg4_encode_dc ( PutBitContext * s , int level , int n )
2002-03-15 06:10:53 +02:00
{
2002-03-25 17:36:16 +02:00
# if 1
2002-06-02 15:15:17 +03:00
// if(level<-255 || level>255) printf("dc overflow\n");
2002-03-25 17:36:16 +02:00
level + = 256 ;
if ( n < 4 ) {
2005-12-22 03:10:11 +02:00
/* luminance */
put_bits ( s , uni_DCtab_lum_len [ level ] , uni_DCtab_lum_bits [ level ] ) ;
2002-03-25 17:36:16 +02:00
} else {
2005-12-22 03:10:11 +02:00
/* chrominance */
put_bits ( s , uni_DCtab_chrom_len [ level ] , uni_DCtab_chrom_bits [ level ] ) ;
2002-03-25 17:36:16 +02:00
}
# else
2002-03-15 06:10:53 +02:00
int size , v ;
2001-07-22 17:18:56 +03:00
/* find number of bits */
size = 0 ;
v = abs ( level ) ;
while ( v ) {
2005-12-22 03:10:11 +02:00
v > > = 1 ;
size + + ;
2001-07-22 17:18:56 +03:00
}
if ( n < 4 ) {
2005-12-22 03:10:11 +02:00
/* luminance */
put_bits ( & s - > pb , DCtab_lum [ size ] [ 1 ] , DCtab_lum [ size ] [ 0 ] ) ;
2001-07-22 17:18:56 +03:00
} else {
2005-12-22 03:10:11 +02:00
/* chrominance */
put_bits ( & s - > pb , DCtab_chrom [ size ] [ 1 ] , DCtab_chrom [ size ] [ 0 ] ) ;
2001-07-22 17:18:56 +03:00
}
/* encode remaining bits */
if ( size > 0 ) {
2005-12-22 03:10:11 +02:00
if ( level < 0 )
level = ( - level ) ^ ( ( 1 < < size ) - 1 ) ;
put_bits ( & s - > pb , size , level ) ;
if ( size > 8 )
put_bits ( & s - > pb , 1 , 1 ) ;
2001-07-22 17:18:56 +03:00
}
2002-03-25 17:36:16 +02:00
# endif
2001-07-22 17:18:56 +03:00
}
2003-02-17 01:05:38 +02:00
2005-02-06 19:01:07 +02:00
static inline int mpeg4_get_dc_length ( int level , int n ) {
if ( n < 4 ) {
return uni_DCtab_lum_len [ level + 256 ] ;
} else {
return uni_DCtab_chrom_len [ level + 256 ] ;
}
}
2003-01-27 01:09:12 +02:00
/**
* encodes a 8 x8 block
* @ param n block index ( 0 - 3 are luma , 4 - 5 are chroma )
*/
2005-12-17 20:14:38 +02:00
static inline void mpeg4_encode_block ( MpegEncContext * s , DCTELEM * block , int n , int intra_dc ,
2003-02-11 18:35:48 +02:00
uint8_t * scan_table , PutBitContext * dc_pb , PutBitContext * ac_pb )
2001-07-22 17:18:56 +03:00
{
2002-10-15 18:24:08 +03:00
int i , last_non_zero ;
#if 0 //variables for the outcommented version
int code , sign , last ;
# endif
2001-07-22 17:18:56 +03:00
const RLTable * rl ;
2003-02-11 18:35:48 +02:00
uint32_t * bits_tab ;
uint8_t * len_tab ;
2002-09-07 03:16:30 +03:00
const int last_index = s - > block_last_index [ n ] ;
2001-07-22 17:18:56 +03:00
2002-09-07 03:16:30 +03:00
if ( s - > mb_intra ) { //Note gcc (3.2.1 at least) will optimize this away
2005-12-22 03:10:11 +02:00
/* mpeg4 based DC predictor */
mpeg4_encode_dc ( dc_pb , intra_dc , n ) ;
2002-09-07 03:16:30 +03:00
if ( last_index < 1 ) return ;
2005-12-22 03:10:11 +02:00
i = 1 ;
2001-07-22 17:18:56 +03:00
rl = & rl_intra ;
2002-09-07 03:16:30 +03:00
bits_tab = uni_mpeg4_intra_rl_bits ;
len_tab = uni_mpeg4_intra_rl_len ;
2001-07-22 17:18:56 +03:00
} else {
2002-09-07 03:16:30 +03:00
if ( last_index < 0 ) return ;
2005-12-22 03:10:11 +02:00
i = 0 ;
2001-07-22 17:18:56 +03:00
rl = & rl_inter ;
2002-09-07 03:16:30 +03:00
bits_tab = uni_mpeg4_inter_rl_bits ;
len_tab = uni_mpeg4_inter_rl_len ;
2001-07-22 17:18:56 +03:00
}
/* AC coefs */
last_non_zero = i - 1 ;
2002-09-07 03:16:30 +03:00
# if 1
for ( ; i < last_index ; i + + ) {
2005-12-22 03:10:11 +02:00
int level = block [ scan_table [ i ] ] ;
if ( level ) {
int run = i - last_non_zero - 1 ;
2002-09-07 03:16:30 +03:00
level + = 64 ;
if ( ( level & ( ~ 127 ) ) = = 0 ) {
const int index = UNI_MPEG4_ENC_INDEX ( 0 , run , level ) ;
put_bits ( ac_pb , len_tab [ index ] , bits_tab [ index ] ) ;
} else { //ESC3
put_bits ( ac_pb , 7 + 2 + 1 + 6 + 1 + 12 + 1 , ( 3 < < 23 ) + ( 3 < < 21 ) + ( 0 < < 20 ) + ( run < < 14 ) + ( 1 < < 13 ) + ( ( ( level - 64 ) & 0xfff ) < < 1 ) + 1 ) ;
}
2005-12-22 03:10:11 +02:00
last_non_zero = i ;
}
2002-09-07 03:16:30 +03:00
}
/*if(i<=last_index)*/ {
2005-12-22 03:10:11 +02:00
int level = block [ scan_table [ i ] ] ;
2002-09-07 03:16:30 +03:00
int run = i - last_non_zero - 1 ;
level + = 64 ;
if ( ( level & ( ~ 127 ) ) = = 0 ) {
const int index = UNI_MPEG4_ENC_INDEX ( 1 , run , level ) ;
put_bits ( ac_pb , len_tab [ index ] , bits_tab [ index ] ) ;
} else { //ESC3
put_bits ( ac_pb , 7 + 2 + 1 + 6 + 1 + 12 + 1 , ( 3 < < 23 ) + ( 3 < < 21 ) + ( 1 < < 20 ) + ( run < < 14 ) + ( 1 < < 13 ) + ( ( ( level - 64 ) & 0xfff ) < < 1 ) + 1 ) ;
}
}
# else
for ( ; i < = last_index ; i + + ) {
2005-12-22 03:10:11 +02:00
const int slevel = block [ scan_table [ i ] ] ;
if ( slevel ) {
2002-09-07 03:16:30 +03:00
int level ;
2005-12-22 03:10:11 +02:00
int run = i - last_non_zero - 1 ;
last = ( i = = last_index ) ;
sign = 0 ;
level = slevel ;
if ( level < 0 ) {
sign = 1 ;
level = - level ;
}
2001-07-22 17:18:56 +03:00
code = get_rl_index ( rl , last , run , level ) ;
2002-06-02 15:15:17 +03:00
put_bits ( ac_pb , rl - > table_vlc [ code ] [ 1 ] , rl - > table_vlc [ code ] [ 0 ] ) ;
2001-07-22 17:18:56 +03:00
if ( code = = rl - > n ) {
int level1 , run1 ;
level1 = level - rl - > max_level [ last ] [ run ] ;
2005-12-17 20:14:38 +02:00
if ( level1 < 1 )
2001-07-22 17:18:56 +03:00
goto esc2 ;
code = get_rl_index ( rl , last , run , level1 ) ;
if ( code = = rl - > n ) {
esc2 :
2002-06-02 15:15:17 +03:00
put_bits ( ac_pb , 1 , 1 ) ;
2001-07-22 17:18:56 +03:00
if ( level > MAX_LEVEL )
goto esc3 ;
run1 = run - rl - > max_run [ last ] [ level ] - 1 ;
if ( run1 < 0 )
goto esc3 ;
code = get_rl_index ( rl , last , run1 , level ) ;
if ( code = = rl - > n ) {
esc3 :
/* third escape */
2002-06-02 15:15:17 +03:00
put_bits ( ac_pb , 1 , 1 ) ;
put_bits ( ac_pb , 1 , last ) ;
put_bits ( ac_pb , 6 , run ) ;
put_bits ( ac_pb , 1 , 1 ) ;
put_bits ( ac_pb , 12 , slevel & 0xfff ) ;
put_bits ( ac_pb , 1 , 1 ) ;
2001-07-22 17:18:56 +03:00
} else {
/* second escape */
2002-06-02 15:15:17 +03:00
put_bits ( ac_pb , 1 , 0 ) ;
put_bits ( ac_pb , rl - > table_vlc [ code ] [ 1 ] , rl - > table_vlc [ code ] [ 0 ] ) ;
put_bits ( ac_pb , 1 , sign ) ;
2001-07-22 17:18:56 +03:00
}
} else {
/* first escape */
2002-06-02 15:15:17 +03:00
put_bits ( ac_pb , 1 , 0 ) ;
put_bits ( ac_pb , rl - > table_vlc [ code ] [ 1 ] , rl - > table_vlc [ code ] [ 0 ] ) ;
put_bits ( ac_pb , 1 , sign ) ;
2001-07-22 17:18:56 +03:00
}
} else {
2002-06-02 15:15:17 +03:00
put_bits ( ac_pb , 1 , sign ) ;
2001-07-22 17:18:56 +03:00
}
2005-12-22 03:10:11 +02:00
last_non_zero = i ;
}
2001-07-22 17:18:56 +03:00
}
2002-09-07 03:16:30 +03:00
# endif
2001-07-22 17:18:56 +03:00
}
2002-12-28 01:51:46 +02:00
2005-12-17 20:14:38 +02:00
static int mpeg4_get_block_length ( MpegEncContext * s , DCTELEM * block , int n , int intra_dc ,
2003-02-11 18:35:48 +02:00
uint8_t * scan_table )
2002-12-28 01:51:46 +02:00
{
int i , last_non_zero ;
const RLTable * rl ;
2003-02-11 18:35:48 +02:00
uint8_t * len_tab ;
2002-12-28 01:51:46 +02:00
const int last_index = s - > block_last_index [ n ] ;
int len = 0 ;
if ( s - > mb_intra ) { //Note gcc (3.2.1 at least) will optimize this away
2005-12-22 03:10:11 +02:00
/* mpeg4 based DC predictor */
len + = mpeg4_get_dc_length ( intra_dc , n ) ;
2002-12-28 01:51:46 +02:00
if ( last_index < 1 ) return len ;
2005-12-22 03:10:11 +02:00
i = 1 ;
2002-12-28 01:51:46 +02:00
rl = & rl_intra ;
len_tab = uni_mpeg4_intra_rl_len ;
} else {
if ( last_index < 0 ) return 0 ;
2005-12-22 03:10:11 +02:00
i = 0 ;
2002-12-28 01:51:46 +02:00
rl = & rl_inter ;
len_tab = uni_mpeg4_inter_rl_len ;
}
/* AC coefs */
last_non_zero = i - 1 ;
for ( ; i < last_index ; i + + ) {
2005-12-22 03:10:11 +02:00
int level = block [ scan_table [ i ] ] ;
if ( level ) {
int run = i - last_non_zero - 1 ;
2002-12-28 01:51:46 +02:00
level + = 64 ;
if ( ( level & ( ~ 127 ) ) = = 0 ) {
const int index = UNI_MPEG4_ENC_INDEX ( 0 , run , level ) ;
len + = len_tab [ index ] ;
} else { //ESC3
len + = 7 + 2 + 1 + 6 + 1 + 12 + 1 ;
}
2005-12-22 03:10:11 +02:00
last_non_zero = i ;
}
2002-12-28 01:51:46 +02:00
}
/*if(i<=last_index)*/ {
2005-12-22 03:10:11 +02:00
int level = block [ scan_table [ i ] ] ;
2002-12-28 01:51:46 +02:00
int run = i - last_non_zero - 1 ;
level + = 64 ;
if ( ( level & ( ~ 127 ) ) = = 0 ) {
const int index = UNI_MPEG4_ENC_INDEX ( 1 , run , level ) ;
len + = len_tab [ index ] ;
} else { //ESC3
len + = 7 + 2 + 1 + 6 + 1 + 12 + 1 ;
}
}
2005-12-17 20:14:38 +02:00
2002-12-28 01:51:46 +02:00
return len ;
}
2002-10-31 18:11:03 +02:00
# endif
2001-07-22 17:18:56 +03:00
/***********************************************/
/* decoding */
static VLC intra_MCBPC_vlc ;
static VLC inter_MCBPC_vlc ;
static VLC cbpy_vlc ;
static VLC mv_vlc ;
static VLC dc_lum , dc_chrom ;
2002-03-07 15:27:15 +02:00
static VLC sprite_trajectory ;
2002-03-13 00:54:25 +02:00
static VLC mb_type_b_vlc ;
2003-12-04 20:34:47 +02:00
static VLC h263_mbtype_b_vlc ;
static VLC cbpc_b_vlc ;
2001-07-22 17:18:56 +03:00
2004-11-27 20:10:06 +02:00
void init_vlc_rl ( RLTable * rl , int use_static )
2001-07-22 17:18:56 +03:00
{
2002-07-13 17:55:12 +03:00
int i , q ;
2005-12-17 20:14:38 +02:00
2004-11-27 20:10:06 +02:00
/* Return if static table is already initialized */
if ( use_static & & rl - > rl_vlc [ 0 ] )
2005-12-17 20:14:38 +02:00
return ;
2004-11-27 20:10:06 +02:00
2005-12-17 20:14:38 +02:00
init_vlc ( & rl - > vlc , 9 , rl - > n + 1 ,
2001-07-22 17:18:56 +03:00
& rl - > table_vlc [ 0 ] [ 1 ] , 4 , 2 ,
2004-11-27 20:10:06 +02:00
& rl - > table_vlc [ 0 ] [ 0 ] , 4 , 2 , use_static ) ;
2002-07-13 17:55:12 +03:00
2005-12-17 20:14:38 +02:00
2002-07-13 17:55:12 +03:00
for ( q = 0 ; q < 32 ; q + + ) {
int qmul = q * 2 ;
int qadd = ( q - 1 ) | 1 ;
2005-12-17 20:14:38 +02:00
2002-07-13 17:55:12 +03:00
if ( q = = 0 ) {
qmul = 1 ;
qadd = 0 ;
}
2005-12-17 20:14:38 +02:00
if ( use_static )
2004-11-27 20:10:06 +02:00
rl - > rl_vlc [ q ] = av_mallocz_static ( rl - > vlc . table_size * sizeof ( RL_VLC_ELEM ) ) ;
else
rl - > rl_vlc [ q ] = av_malloc ( rl - > vlc . table_size * sizeof ( RL_VLC_ELEM ) ) ;
2002-07-13 17:55:12 +03:00
for ( i = 0 ; i < rl - > vlc . table_size ; i + + ) {
int code = rl - > vlc . table [ i ] [ 0 ] ;
int len = rl - > vlc . table [ i ] [ 1 ] ;
int level , run ;
2005-12-17 20:14:38 +02:00
2002-07-13 17:55:12 +03:00
if ( len = = 0 ) { // illegal code
2002-07-17 12:15:14 +03:00
run = 66 ;
2002-07-13 17:55:12 +03:00
level = MAX_LEVEL ;
} else if ( len < 0 ) { //more bits needed
run = 0 ;
level = code ;
} else {
if ( code = = rl - > n ) { //esc
2002-07-17 12:15:14 +03:00
run = 66 ;
2002-07-13 17:55:12 +03:00
level = 0 ;
} else {
run = rl - > table_run [ code ] + 1 ;
level = rl - > table_level [ code ] * qmul + qadd ;
if ( code > = rl - > last ) run + = 192 ;
}
}
rl - > rl_vlc [ q ] [ i ] . len = len ;
rl - > rl_vlc [ q ] [ i ] . level = level ;
rl - > rl_vlc [ q ] [ i ] . run = run ;
}
}
2001-07-22 17:18:56 +03:00
}
/* init vlcs */
/* XXX: find a better solution to handle static init */
void h263_decode_init_vlc ( MpegEncContext * s )
{
static int done = 0 ;
if ( ! done ) {
done = 1 ;
2005-12-17 20:14:38 +02:00
init_vlc ( & intra_MCBPC_vlc , INTRA_MCBPC_VLC_BITS , 9 ,
2001-07-22 17:18:56 +03:00
intra_MCBPC_bits , 1 , 1 ,
2004-11-27 20:10:06 +02:00
intra_MCBPC_code , 1 , 1 , 1 ) ;
2005-12-17 20:14:38 +02:00
init_vlc ( & inter_MCBPC_vlc , INTER_MCBPC_VLC_BITS , 28 ,
2001-07-22 17:18:56 +03:00
inter_MCBPC_bits , 1 , 1 ,
2004-11-27 20:10:06 +02:00
inter_MCBPC_code , 1 , 1 , 1 ) ;
2002-07-13 18:45:52 +03:00
init_vlc ( & cbpy_vlc , CBPY_VLC_BITS , 16 ,
2001-07-22 17:18:56 +03:00
& cbpy_tab [ 0 ] [ 1 ] , 2 , 1 ,
2004-11-27 20:10:06 +02:00
& cbpy_tab [ 0 ] [ 0 ] , 2 , 1 , 1 ) ;
2002-07-13 18:45:52 +03:00
init_vlc ( & mv_vlc , MV_VLC_BITS , 33 ,
2001-07-22 17:18:56 +03:00
& mvtab [ 0 ] [ 1 ] , 2 , 1 ,
2004-11-27 20:10:06 +02:00
& mvtab [ 0 ] [ 0 ] , 2 , 1 , 1 ) ;
init_rl ( & rl_inter , 1 ) ;
init_rl ( & rl_intra , 1 ) ;
init_rl ( & rvlc_rl_inter , 1 ) ;
init_rl ( & rvlc_rl_intra , 1 ) ;
init_rl ( & rl_intra_aic , 1 ) ;
init_vlc_rl ( & rl_inter , 1 ) ;
init_vlc_rl ( & rl_intra , 1 ) ;
init_vlc_rl ( & rvlc_rl_inter , 1 ) ;
init_vlc_rl ( & rvlc_rl_intra , 1 ) ;
init_vlc_rl ( & rl_intra_aic , 1 ) ;
2002-07-13 20:30:43 +03:00
init_vlc ( & dc_lum , DC_VLC_BITS , 10 /* 13 */ ,
2001-07-22 17:18:56 +03:00
& DCtab_lum [ 0 ] [ 1 ] , 2 , 1 ,
2004-11-27 20:10:06 +02:00
& DCtab_lum [ 0 ] [ 0 ] , 2 , 1 , 1 ) ;
2002-07-13 20:30:43 +03:00
init_vlc ( & dc_chrom , DC_VLC_BITS , 10 /* 13 */ ,
2001-07-22 17:18:56 +03:00
& DCtab_chrom [ 0 ] [ 1 ] , 2 , 1 ,
2004-11-27 20:10:06 +02:00
& DCtab_chrom [ 0 ] [ 0 ] , 2 , 1 , 1 ) ;
2002-07-13 18:45:52 +03:00
init_vlc ( & sprite_trajectory , SPRITE_TRAJ_VLC_BITS , 15 ,
2002-03-07 15:27:15 +02:00
& sprite_trajectory_tab [ 0 ] [ 1 ] , 4 , 2 ,
2004-11-27 20:10:06 +02:00
& sprite_trajectory_tab [ 0 ] [ 0 ] , 4 , 2 , 1 ) ;
2002-07-13 18:45:52 +03:00
init_vlc ( & mb_type_b_vlc , MB_TYPE_B_VLC_BITS , 4 ,
2002-03-13 00:54:25 +02:00
& mb_type_b_tab [ 0 ] [ 1 ] , 2 , 1 ,
2004-11-27 20:10:06 +02:00
& mb_type_b_tab [ 0 ] [ 0 ] , 2 , 1 , 1 ) ;
2003-12-04 20:34:47 +02:00
init_vlc ( & h263_mbtype_b_vlc , H263_MBTYPE_B_VLC_BITS , 15 ,
& h263_mbtype_b_tab [ 0 ] [ 1 ] , 2 , 1 ,
2004-11-27 20:10:06 +02:00
& h263_mbtype_b_tab [ 0 ] [ 0 ] , 2 , 1 , 1 ) ;
2003-12-04 20:34:47 +02:00
init_vlc ( & cbpc_b_vlc , CBPC_B_VLC_BITS , 4 ,
& cbpc_b_tab [ 0 ] [ 1 ] , 2 , 1 ,
2004-11-27 20:10:06 +02:00
& cbpc_b_tab [ 0 ] [ 0 ] , 2 , 1 , 1 ) ;
2001-07-22 17:18:56 +03:00
}
2002-10-13 16:16:04 +03:00
}
2002-08-27 19:28:19 +03:00
2002-10-13 16:16:04 +03:00
/**
* Get the GOB height based on picture height .
*/
int ff_h263_get_gob_height ( MpegEncContext * s ) {
if ( s - > height < = 400 )
return 1 ;
else if ( s - > height < = 800 )
return 2 ;
else
return 4 ;
2001-07-22 17:18:56 +03:00
}
2003-12-07 03:33:45 +02:00
int ff_h263_decode_mba ( MpegEncContext * s )
{
int i , mb_pos ;
for ( i = 0 ; i < 6 ; i + + ) {
2003-12-09 15:47:08 +02:00
if ( s - > mb_num - 1 < = ff_mba_max [ i ] ) break ;
2003-12-07 03:33:45 +02:00
}
mb_pos = get_bits ( & s - > gb , ff_mba_length [ i ] ) ;
s - > mb_x = mb_pos % s - > mb_width ;
s - > mb_y = mb_pos / s - > mb_width ;
return mb_pos ;
}
void ff_h263_encode_mba ( MpegEncContext * s )
{
int i , mb_pos ;
for ( i = 0 ; i < 6 ; i + + ) {
2003-12-09 15:47:08 +02:00
if ( s - > mb_num - 1 < = ff_mba_max [ i ] ) break ;
2003-12-07 03:33:45 +02:00
}
mb_pos = s - > mb_x + s - > mb_width * s - > mb_y ;
put_bits ( & s - > pb , ff_mba_length [ i ] , mb_pos ) ;
}
2002-10-13 16:16:04 +03:00
/**
2003-12-07 03:33:45 +02:00
* decodes the group of blocks header or slice header .
2002-10-13 16:16:04 +03:00
* @ return < 0 if an error occured
*/
static int h263_decode_gob_header ( MpegEncContext * s )
2001-07-22 17:18:56 +03:00
{
2003-12-07 03:33:45 +02:00
unsigned int val , gfid , gob_number ;
2002-10-13 16:16:04 +03:00
int left ;
2005-12-17 20:14:38 +02:00
2001-11-03 02:49:53 +02:00
/* Check for GOB Start Code */
2001-11-19 04:13:14 +02:00
val = show_bits ( & s - > gb , 16 ) ;
2002-10-13 16:16:04 +03:00
if ( val )
return - 1 ;
2001-11-19 04:13:14 +02:00
/* We have a GBSC probably with GSTUFF */
2002-10-13 16:16:04 +03:00
skip_bits ( & s - > gb , 16 ) ; /* Drop the zeros */
2003-01-21 19:34:12 +02:00
left = s - > gb . size_in_bits - get_bits_count ( & s - > gb ) ;
2002-10-13 16:16:04 +03:00
//MN: we must check the bits left or we might end in a infinite loop (or segfault)
for ( ; left > 13 ; left - - ) {
if ( get_bits1 ( & s - > gb ) ) break ; /* Seek the '1' bit */
}
2005-12-17 20:14:38 +02:00
if ( left < = 13 )
2002-10-13 16:16:04 +03:00
return - 1 ;
2003-12-07 03:33:45 +02:00
if ( s - > h263_slice_structured ) {
if ( get_bits1 ( & s - > gb ) = = 0 )
return - 1 ;
2003-12-01 17:23:14 +02:00
2003-12-07 03:33:45 +02:00
ff_h263_decode_mba ( s ) ;
if ( s - > mb_num > 1583 )
if ( get_bits1 ( & s - > gb ) = = 0 )
return - 1 ;
2005-12-17 20:14:38 +02:00
2003-12-07 03:33:45 +02:00
s - > qscale = get_bits ( & s - > gb , 5 ) ; /* SQUANT */
if ( get_bits1 ( & s - > gb ) = = 0 )
return - 1 ;
gfid = get_bits ( & s - > gb , 2 ) ; /* GFID */
} else {
gob_number = get_bits ( & s - > gb , 5 ) ; /* GN */
s - > mb_x = 0 ;
s - > mb_y = s - > gob_index * gob_number ;
gfid = get_bits ( & s - > gb , 2 ) ; /* GFID */
s - > qscale = get_bits ( & s - > gb , 5 ) ; /* GQUANT */
}
2005-12-17 20:14:38 +02:00
if ( s - > mb_y > = s - > mb_height )
2003-08-01 14:00:03 +03:00
return - 1 ;
2003-12-07 03:33:45 +02:00
2005-12-17 20:14:38 +02:00
if ( s - > qscale = = 0 )
2003-12-07 03:33:45 +02:00
return - 1 ;
2001-11-19 04:13:14 +02:00
return 0 ;
}
2002-03-24 23:25:04 +02:00
static inline void memsetw ( short * tab , int val , int n )
{
int i ;
for ( i = 0 ; i < n ; i + + )
tab [ i ] = val ;
}
2003-02-17 01:05:38 +02:00
# ifdef CONFIG_ENCODERS
2002-06-02 15:15:17 +03:00
void ff_mpeg4_init_partitions ( MpegEncContext * s )
{
2004-02-13 19:54:10 +02:00
uint8_t * start = pbBufPtr ( & s - > pb ) ;
uint8_t * end = s - > pb . buf_end ;
int size = end - start ;
2005-01-18 03:01:54 +02:00
int pb_size = ( ( ( long ) start + size / 3 ) & ( ~ 3 ) ) - ( long ) start ;
2004-03-29 03:29:27 +03:00
int tex_size = ( size - 2 * pb_size ) & ( ~ 3 ) ;
2005-12-17 20:14:38 +02:00
2004-02-13 19:54:10 +02:00
set_put_bits_buffer_size ( & s - > pb , pb_size ) ;
init_put_bits ( & s - > tex_pb , start + pb_size , tex_size ) ;
2004-03-26 23:58:55 +02:00
init_put_bits ( & s - > pb2 , start + pb_size + tex_size , pb_size ) ;
2002-06-02 15:15:17 +03:00
}
void ff_mpeg4_merge_partitions ( MpegEncContext * s )
{
2004-02-06 17:27:31 +02:00
const int pb2_len = put_bits_count ( & s - > pb2 ) ;
const int tex_pb_len = put_bits_count ( & s - > tex_pb ) ;
const int bits = put_bits_count ( & s - > pb ) ;
2002-06-02 15:15:17 +03:00
if ( s - > pict_type = = I_TYPE ) {
put_bits ( & s - > pb , 19 , DC_MARKER ) ;
s - > misc_bits + = 19 + pb2_len + bits - s - > last_bits ;
s - > i_tex_bits + = tex_pb_len ;
} else {
put_bits ( & s - > pb , 17 , MOTION_MARKER ) ;
2002-10-13 16:16:04 +03:00
s - > misc_bits + = 17 + pb2_len ;
2002-06-02 15:15:17 +03:00
s - > mv_bits + = bits - s - > last_bits ;
s - > p_tex_bits + = tex_pb_len ;
}
flush_put_bits ( & s - > pb2 ) ;
flush_put_bits ( & s - > tex_pb ) ;
2004-02-13 19:54:10 +02:00
set_put_bits_buffer_size ( & s - > pb , s - > pb2 . buf_end - s - > pb . buf ) ;
ff_copy_bits ( & s - > pb , s - > pb2 . buf , pb2_len ) ;
ff_copy_bits ( & s - > pb , s - > tex_pb . buf , tex_pb_len ) ;
2004-02-06 17:27:31 +02:00
s - > last_bits = put_bits_count ( & s - > pb ) ;
2002-06-02 15:15:17 +03:00
}
2003-02-17 01:05:38 +02:00
# endif //CONFIG_ENCODERS
2002-10-13 16:16:04 +03:00
int ff_mpeg4_get_video_packet_prefix_length ( MpegEncContext * s ) {
switch ( s - > pict_type ) {
case I_TYPE :
return 16 ;
case P_TYPE :
case S_TYPE :
return s - > f_code + 15 ;
case B_TYPE :
2002-11-10 13:46:59 +02:00
return FFMAX ( FFMAX ( s - > f_code , s - > b_code ) + 15 , 17 ) ;
2002-10-13 16:16:04 +03:00
default :
return - 1 ;
}
}
2003-02-17 01:05:38 +02:00
# ifdef CONFIG_ENCODERS
2002-06-02 15:15:17 +03:00
void ff_mpeg4_encode_video_packet_header ( MpegEncContext * s )
2002-03-24 23:25:04 +02:00
{
int mb_num_bits = av_log2 ( s - > mb_num - 1 ) + 1 ;
2002-10-13 16:16:04 +03:00
put_bits ( & s - > pb , ff_mpeg4_get_video_packet_prefix_length ( s ) , 0 ) ;
2002-06-02 15:15:17 +03:00
put_bits ( & s - > pb , 1 , 1 ) ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
put_bits ( & s - > pb , mb_num_bits , s - > mb_x + s - > mb_y * s - > mb_width ) ;
2002-10-13 16:16:04 +03:00
put_bits ( & s - > pb , s - > quant_precision , s - > qscale ) ;
2002-06-02 15:15:17 +03:00
put_bits ( & s - > pb , 1 , 0 ) ; /* no HEC */
}
2002-03-24 23:25:04 +02:00
2003-02-17 01:05:38 +02:00
# endif //CONFIG_ENCODERS
2002-06-02 15:15:17 +03:00
/**
2002-10-13 16:16:04 +03:00
* check if the next stuff is a resync marker or the end .
* @ return 0 if not
2002-06-02 15:15:17 +03:00
*/
2002-10-13 16:16:04 +03:00
static inline int mpeg4_is_resync ( MpegEncContext * s ) {
const int bits_count = get_bits_count ( & s - > gb ) ;
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
if ( s - > workaround_bugs & FF_BUG_NO_PADDING ) {
return 0 ;
}
2003-01-21 19:34:12 +02:00
if ( bits_count + 8 > = s - > gb . size_in_bits ) {
2002-10-13 16:16:04 +03:00
int v = show_bits ( & s - > gb , 8 ) ;
v | = 0x7F > > ( 7 - ( bits_count & 7 ) ) ;
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
if ( v = = 0x7F )
return 1 ;
} else {
if ( show_bits ( & s - > gb , 16 ) = = ff_mpeg4_resync_prefix [ bits_count & 7 ] ) {
int len ;
GetBitContext gb = s - > gb ;
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
skip_bits ( & s - > gb , 1 ) ;
align_get_bits ( & s - > gb ) ;
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
for ( len = 0 ; len < 32 ; len + + ) {
if ( get_bits1 ( & s - > gb ) ) break ;
}
s - > gb = gb ;
if ( len > = ff_mpeg4_get_video_packet_prefix_length ( s ) )
return 1 ;
}
}
return 0 ;
}
/**
* decodes the next video packet .
* @ return < 0 if something went wrong
*/
static int mpeg4_decode_video_packet_header ( MpegEncContext * s )
2002-06-02 15:15:17 +03:00
{
int mb_num_bits = av_log2 ( s - > mb_num - 1 ) + 1 ;
2002-10-13 16:16:04 +03:00
int header_extension = 0 , mb_num , len ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
/* is there enough space left for a video packet + header */
2003-01-21 19:34:12 +02:00
if ( get_bits_count ( & s - > gb ) > s - > gb . size_in_bits - 20 ) return - 1 ;
2002-06-02 15:15:17 +03:00
2002-10-13 16:16:04 +03:00
for ( len = 0 ; len < 32 ; len + + ) {
if ( get_bits1 ( & s - > gb ) ) break ;
2002-03-24 23:25:04 +02:00
}
2002-06-02 15:15:17 +03:00
2002-10-13 16:16:04 +03:00
if ( len ! = ff_mpeg4_get_video_packet_prefix_length ( s ) ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " marker does not match f_code \n " ) ;
2002-06-02 15:15:17 +03:00
return - 1 ;
}
2005-12-17 20:14:38 +02:00
2002-03-24 23:25:04 +02:00
if ( s - > shape ! = RECT_SHAPE ) {
2002-10-13 16:16:04 +03:00
header_extension = get_bits1 ( & s - > gb ) ;
2002-03-24 23:25:04 +02:00
//FIXME more stuff here
}
2002-10-13 16:16:04 +03:00
mb_num = get_bits ( & s - > gb , mb_num_bits ) ;
if ( mb_num > = s - > mb_num ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " illegal mb_num in video packet (%d %d) \n " , mb_num , s - > mb_num ) ;
2002-06-02 15:15:17 +03:00
return - 1 ;
}
2003-04-10 11:47:08 +03:00
if ( s - > pict_type = = B_TYPE ) {
2003-04-10 16:18:38 +03:00
while ( s - > next_picture . mbskip_table [ s - > mb_index2xy [ mb_num ] ] ) mb_num + + ;
2005-04-24 20:21:11 +03:00
if ( mb_num > = s - > mb_num ) return - 1 ; // slice contains just skipped MBs which where allready decoded
2003-04-10 11:47:08 +03:00
}
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
s - > mb_x = mb_num % s - > mb_width ;
s - > mb_y = mb_num / s - > mb_width ;
2002-03-24 23:25:04 +02:00
if ( s - > shape ! = BIN_ONLY_SHAPE ) {
2005-12-17 20:14:38 +02:00
int qscale = get_bits ( & s - > gb , s - > quant_precision ) ;
2002-10-13 16:16:04 +03:00
if ( qscale )
2003-12-01 17:23:14 +02:00
s - > chroma_qscale = s - > qscale = qscale ;
2002-03-24 23:25:04 +02:00
}
if ( s - > shape = = RECT_SHAPE ) {
2002-10-13 16:16:04 +03:00
header_extension = get_bits1 ( & s - > gb ) ;
2002-03-24 23:25:04 +02:00
}
if ( header_extension ) {
2002-06-02 15:15:17 +03:00
int time_increment ;
2002-03-24 23:25:04 +02:00
int time_incr = 0 ;
2002-06-02 15:15:17 +03:00
2005-12-17 20:14:38 +02:00
while ( get_bits1 ( & s - > gb ) ! = 0 )
2002-03-24 23:25:04 +02:00
time_incr + + ;
2002-10-13 16:16:04 +03:00
check_marker ( & s - > gb , " before time_increment in video packed header " ) ;
time_increment = get_bits ( & s - > gb , s - > time_increment_bits ) ;
check_marker ( & s - > gb , " before vop_coding_type in video packed header " ) ;
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
skip_bits ( & s - > gb , 2 ) ; /* vop coding type */
2002-03-24 23:25:04 +02:00
//FIXME not rect stuff here
if ( s - > shape ! = BIN_ONLY_SHAPE ) {
2002-10-13 16:16:04 +03:00
skip_bits ( & s - > gb , 3 ) ; /* intra dc vlc threshold */
2005-05-05 17:34:47 +03:00
//FIXME don't just ignore everything
2002-11-01 15:25:22 +02:00
if ( s - > pict_type = = S_TYPE & & s - > vol_sprite_usage = = GMC_SPRITE ) {
2004-04-02 19:21:55 +03:00
mpeg4_decode_sprite_trajectory ( s , & s - > gb ) ;
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " untested \n " ) ;
2002-03-24 23:25:04 +02:00
}
//FIXME reduced res stuff here
2005-12-17 20:14:38 +02:00
2002-03-24 23:25:04 +02:00
if ( s - > pict_type ! = I_TYPE ) {
2005-12-22 03:10:11 +02:00
int f_code = get_bits ( & s - > gb , 3 ) ; /* fcode_for */
2002-09-12 18:22:14 +03:00
if ( f_code = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Error, video packet header damaged (f_code=0) \n " ) ;
2002-03-24 23:25:04 +02:00
}
}
if ( s - > pict_type = = B_TYPE ) {
2002-10-13 16:16:04 +03:00
int b_code = get_bits ( & s - > gb , 3 ) ;
2002-09-12 18:22:14 +03:00
if ( b_code = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Error, video packet header damaged (b_code=0) \n " ) ;
2002-09-12 18:22:14 +03:00
}
2005-12-17 20:14:38 +02:00
}
2002-03-24 23:25:04 +02:00
}
}
//FIXME new-pred stuff
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
//printf("parse ok %d %d %d %d\n", mb_num, s->mb_x + s->mb_y*s->mb_width, get_bits_count(gb), get_bits_count(&s->gb));
2002-10-13 16:16:04 +03:00
return 0 ;
2002-06-02 15:15:17 +03:00
}
void ff_mpeg4_clean_buffers ( MpegEncContext * s )
{
int c_wrap , c_xy , l_wrap , l_xy ;
2002-03-24 23:25:04 +02:00
2004-04-16 04:01:45 +03:00
l_wrap = s - > b8_stride ;
l_xy = ( 2 * s - > mb_y - 1 ) * l_wrap + s - > mb_x * 2 - 1 ;
c_wrap = s - > mb_stride ;
c_xy = ( s - > mb_y - 1 ) * c_wrap + s - > mb_x - 1 ;
2002-03-24 23:25:04 +02:00
2002-10-13 16:16:04 +03:00
#if 0
2002-03-24 23:25:04 +02:00
/* clean DC */
2002-06-02 15:15:17 +03:00
memsetw ( s - > dc_val [ 0 ] + l_xy , 1024 , l_wrap * 2 + 1 ) ;
memsetw ( s - > dc_val [ 1 ] + c_xy , 1024 , c_wrap + 1 ) ;
memsetw ( s - > dc_val [ 2 ] + c_xy , 1024 , c_wrap + 1 ) ;
2002-10-13 16:16:04 +03:00
# endif
2002-03-24 23:25:04 +02:00
/* clean AC */
2003-02-11 18:35:48 +02:00
memset ( s - > ac_val [ 0 ] + l_xy , 0 , ( l_wrap * 2 + 1 ) * 16 * sizeof ( int16_t ) ) ;
memset ( s - > ac_val [ 1 ] + c_xy , 0 , ( c_wrap + 1 ) * 16 * sizeof ( int16_t ) ) ;
memset ( s - > ac_val [ 2 ] + c_xy , 0 , ( c_wrap + 1 ) * 16 * sizeof ( int16_t ) ) ;
2002-03-24 23:25:04 +02:00
/* clean MV */
2005-05-05 17:34:47 +03:00
// we can't clear the MVs as they might be needed by a b frame
2003-02-11 18:35:48 +02:00
// memset(s->motion_val + l_xy, 0, (l_wrap*2+1)*2*sizeof(int16_t));
// memset(s->motion_val, 0, 2*sizeof(int16_t)*(2 + s->mb_width*2)*(2 + s->mb_height*2));
2002-06-02 15:15:17 +03:00
s - > last_mv [ 0 ] [ 0 ] [ 0 ] =
s - > last_mv [ 0 ] [ 0 ] [ 1 ] =
s - > last_mv [ 1 ] [ 0 ] [ 0 ] =
s - > last_mv [ 1 ] [ 0 ] [ 1 ] = 0 ;
}
2002-10-13 16:16:04 +03:00
/**
* decodes the group of blocks / video packet header .
* @ return < 0 if no resync found
*/
int ff_h263_resync ( MpegEncContext * s ) {
int left , ret ;
2005-12-17 20:14:38 +02:00
2003-10-12 22:18:37 +03:00
if ( s - > codec_id = = CODEC_ID_MPEG4 ) {
2002-10-13 16:16:04 +03:00
skip_bits1 ( & s - > gb ) ;
2003-10-12 22:18:37 +03:00
align_get_bits ( & s - > gb ) ;
}
2002-06-02 15:15:17 +03:00
2002-10-13 16:16:04 +03:00
if ( show_bits ( & s - > gb , 16 ) = = 0 ) {
if ( s - > codec_id = = CODEC_ID_MPEG4 )
ret = mpeg4_decode_video_packet_header ( s ) ;
else
ret = h263_decode_gob_header ( s ) ;
if ( ret > = 0 )
return 0 ;
2002-06-02 15:15:17 +03:00
}
2005-05-05 17:34:47 +03:00
//ok, it's not where its supposed to be ...
2002-10-13 16:16:04 +03:00
s - > gb = s - > last_resync_gb ;
align_get_bits ( & s - > gb ) ;
2003-01-21 19:34:12 +02:00
left = s - > gb . size_in_bits - get_bits_count ( & s - > gb ) ;
2005-12-17 20:14:38 +02:00
for ( ; left > 16 + 1 + 5 + 5 ; left - = 8 ) {
2002-10-13 16:16:04 +03:00
if ( show_bits ( & s - > gb , 16 ) = = 0 ) {
GetBitContext bak = s - > gb ;
2002-06-02 15:15:17 +03:00
2002-10-13 16:16:04 +03:00
if ( s - > codec_id = = CODEC_ID_MPEG4 )
ret = mpeg4_decode_video_packet_header ( s ) ;
else
ret = h263_decode_gob_header ( s ) ;
if ( ret > = 0 )
return 0 ;
2002-06-02 15:15:17 +03:00
2002-10-13 16:16:04 +03:00
s - > gb = bak ;
}
skip_bits ( & s - > gb , 8 ) ;
}
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
2002-10-16 22:55:49 +03:00
/**
2003-01-27 01:09:12 +02:00
* gets the average motion vector for a GMC MB .
2002-10-16 22:55:49 +03:00
* @ param n either 0 for the x component or 1 for y
* @ returns the average MV for a GMC MB
*/
static inline int get_amv ( MpegEncContext * s , int n ) {
int x , y , mb_v , sum , dx , dy , shift ;
int len = 1 < < ( s - > f_code + 4 ) ;
const int a = s - > sprite_warping_accuracy ;
2005-12-17 20:14:38 +02:00
2004-04-30 21:56:33 +03:00
if ( s - > workaround_bugs & FF_BUG_AMV )
len > > = s - > quarter_sample ;
2002-10-16 22:55:49 +03:00
if ( s - > real_sprite_warping_points = = 1 ) {
if ( s - > divx_version = = 500 & & s - > divx_build = = 413 )
sum = s - > sprite_offset [ 0 ] [ n ] / ( 1 < < ( a - s - > quarter_sample ) ) ;
else
sum = RSHIFT ( s - > sprite_offset [ 0 ] [ n ] < < s - > quarter_sample , a ) ;
} else {
dx = s - > sprite_delta [ n ] [ 0 ] ;
dy = s - > sprite_delta [ n ] [ 1 ] ;
shift = s - > sprite_shift [ 0 ] ;
if ( n ) dy - = 1 < < ( shift + a + 1 ) ;
else dx - = 1 < < ( shift + a + 1 ) ;
mb_v = s - > sprite_offset [ 0 ] [ n ] + dx * s - > mb_x * 16 + dy * s - > mb_y * 16 ;
sum = 0 ;
for ( y = 0 ; y < 16 ; y + + ) {
int v ;
2005-12-17 20:14:38 +02:00
2002-10-16 22:55:49 +03:00
v = mb_v + dy * y ;
//XXX FIXME optimize
for ( x = 0 ; x < 16 ; x + + ) {
sum + = v > > shift ;
v + = dx ;
}
}
2003-01-12 14:16:36 +02:00
sum = RSHIFT ( sum , a + 8 - s - > quarter_sample ) ;
2002-10-16 22:55:49 +03:00
}
if ( sum < - len ) sum = - len ;
else if ( sum > = len ) sum = len - 1 ;
return sum ;
}
2002-06-02 15:15:17 +03:00
/**
2002-10-13 16:16:04 +03:00
* decodes first partition .
* @ return number of MBs decoded or < 0 if an error occured
2002-06-02 15:15:17 +03:00
*/
2002-10-13 16:16:04 +03:00
static int mpeg4_decode_partition_a ( MpegEncContext * s ) {
2002-06-02 15:15:17 +03:00
int mb_num ;
2003-02-11 18:35:48 +02:00
static const int8_t quant_tab [ 4 ] = { - 1 , - 2 , 1 , 2 } ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
/* decode first partition */
mb_num = 0 ;
2002-03-24 23:25:04 +02:00
s - > first_slice_line = 1 ;
2002-10-13 16:16:04 +03:00
for ( ; s - > mb_y < s - > mb_height ; s - > mb_y + + ) {
ff_init_block_index ( s ) ;
for ( ; s - > mb_x < s - > mb_width ; s - > mb_x + + ) {
2003-04-10 16:18:38 +03:00
const int xy = s - > mb_x + s - > mb_y * s - > mb_stride ;
2002-06-02 15:15:17 +03:00
int cbpc ;
int dir = 0 ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
mb_num + + ;
2002-10-13 16:16:04 +03:00
ff_update_block_index ( s ) ;
2002-06-02 15:15:17 +03:00
if ( s - > mb_x = = s - > resync_mb_x & & s - > mb_y = = s - > resync_mb_y + 1 )
s - > first_slice_line = 0 ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( s - > pict_type = = I_TYPE ) {
int i ;
2003-09-27 01:18:25 +03:00
do {
2004-03-11 01:13:43 +02:00
if ( show_bits_long ( & s - > gb , 19 ) = = DC_MARKER ) {
return mb_num - 1 ;
}
2003-09-27 01:18:25 +03:00
cbpc = get_vlc2 ( & s - > gb , intra_MCBPC_vlc . table , INTRA_MCBPC_VLC_BITS , 2 ) ;
if ( cbpc < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " cbpc corrupted at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2003-09-27 01:18:25 +03:00
return - 1 ;
}
} while ( cbpc = = 8 ) ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
s - > cbp_table [ xy ] = cbpc & 3 ;
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_INTRA ;
2002-06-02 15:15:17 +03:00
s - > mb_intra = 1 ;
if ( cbpc & 4 ) {
2003-12-03 18:47:17 +02:00
ff_set_qscale ( s , s - > qscale + quant_tab [ get_bits ( & s - > gb , 2 ) ] ) ;
2002-06-02 15:15:17 +03:00
}
2002-12-04 12:04:03 +02:00
s - > current_picture . qscale_table [ xy ] = s - > qscale ;
2002-06-02 15:15:17 +03:00
s - > mbintra_table [ xy ] = 1 ;
for ( i = 0 ; i < 6 ; i + + ) {
int dc_pred_dir ;
2005-12-17 20:14:38 +02:00
int dc = mpeg4_decode_dc ( s , i , & dc_pred_dir ) ;
2002-06-02 15:15:17 +03:00
if ( dc < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " DC corrupted at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
dir < < = 1 ;
if ( dc_pred_dir ) dir | = 1 ;
}
s - > pred_dir_table [ xy ] = dir ;
} else { /* P/S_TYPE */
2002-10-13 16:16:04 +03:00
int mx , my , pred_x , pred_y , bits ;
2003-12-09 03:49:56 +02:00
int16_t * const mot_val = s - > current_picture . motion_val [ 0 ] [ s - > block_index [ 0 ] ] ;
2004-04-16 04:01:45 +03:00
const int stride = s - > b8_stride * 2 ;
2002-06-02 15:15:17 +03:00
2004-03-11 01:13:43 +02:00
try_again :
2002-10-13 16:16:04 +03:00
bits = show_bits ( & s - > gb , 17 ) ;
if ( bits = = MOTION_MARKER ) {
return mb_num - 1 ;
}
skip_bits1 ( & s - > gb ) ;
if ( bits & 0x10000 ) {
2002-06-02 15:15:17 +03:00
/* skip mb */
if ( s - > pict_type = = S_TYPE & & s - > vol_sprite_usage = = GMC_SPRITE ) {
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0 ;
2002-10-16 22:55:49 +03:00
mx = get_amv ( s , 0 ) ;
my = get_amv ( s , 1 ) ;
2002-06-02 15:15:17 +03:00
} else {
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0 ;
2002-10-16 22:55:49 +03:00
mx = my = 0 ;
2002-06-02 15:15:17 +03:00
}
mot_val [ 0 ] = mot_val [ 2 ] =
mot_val [ 0 + stride ] = mot_val [ 2 + stride ] = mx ;
mot_val [ 1 ] = mot_val [ 3 ] =
mot_val [ 1 + stride ] = mot_val [ 3 + stride ] = my ;
if ( s - > mbintra_table [ xy ] )
ff_clean_intra_table_entries ( s ) ;
continue ;
}
2003-09-27 01:18:25 +03:00
2002-07-13 18:45:52 +03:00
cbpc = get_vlc2 ( & s - > gb , inter_MCBPC_vlc . table , INTER_MCBPC_VLC_BITS , 2 ) ;
2002-06-02 15:15:17 +03:00
if ( cbpc < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " cbpc corrupted at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
2004-03-11 01:13:43 +02:00
if ( cbpc = = 20 )
goto try_again ;
2003-09-27 01:18:25 +03:00
2002-06-02 15:15:17 +03:00
s - > cbp_table [ xy ] = cbpc & ( 8 + 3 ) ; //8 is dquant
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
s - > mb_intra = ( ( cbpc & 4 ) ! = 0 ) ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( s - > mb_intra ) {
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_INTRA ;
2002-06-02 15:15:17 +03:00
s - > mbintra_table [ xy ] = 1 ;
2005-12-17 20:14:38 +02:00
mot_val [ 0 ] = mot_val [ 2 ] =
2002-06-02 15:15:17 +03:00
mot_val [ 0 + stride ] = mot_val [ 2 + stride ] = 0 ;
mot_val [ 1 ] = mot_val [ 3 ] =
mot_val [ 1 + stride ] = mot_val [ 3 + stride ] = 0 ;
} else {
if ( s - > mbintra_table [ xy ] )
ff_clean_intra_table_entries ( s ) ;
if ( s - > pict_type = = S_TYPE & & s - > vol_sprite_usage = = GMC_SPRITE & & ( cbpc & 16 ) = = 0 )
s - > mcsel = get_bits1 ( & s - > gb ) ;
else s - > mcsel = 0 ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( ( cbpc & 16 ) = = 0 ) {
/* 16x16 motion prediction */
2004-04-16 04:01:45 +03:00
h263_pred_motion ( s , 0 , 0 , & pred_x , & pred_y ) ;
2002-10-16 22:55:49 +03:00
if ( ! s - > mcsel ) {
mx = h263_decode_motion ( s , pred_x , s - > f_code ) ;
if ( mx > = 0xffff )
return - 1 ;
my = h263_decode_motion ( s , pred_y , s - > f_code ) ;
if ( my > = 0xffff )
return - 1 ;
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_16x16 | MB_TYPE_L0 ;
2002-10-16 22:55:49 +03:00
} else {
mx = get_amv ( s , 0 ) ;
my = get_amv ( s , 1 ) ;
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0 ;
2002-06-02 15:15:17 +03:00
}
2002-10-16 22:55:49 +03:00
2002-06-02 15:15:17 +03:00
mot_val [ 0 ] = mot_val [ 2 ] =
mot_val [ 0 + stride ] = mot_val [ 2 + stride ] = mx ;
mot_val [ 1 ] = mot_val [ 3 ] =
mot_val [ 1 + stride ] = mot_val [ 3 + stride ] = my ;
} else {
int i ;
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_8x8 | MB_TYPE_L0 ;
2002-06-02 15:15:17 +03:00
for ( i = 0 ; i < 4 ; i + + ) {
2004-04-16 04:01:45 +03:00
int16_t * mot_val = h263_pred_motion ( s , i , 0 , & pred_x , & pred_y ) ;
2002-06-02 15:15:17 +03:00
mx = h263_decode_motion ( s , pred_x , s - > f_code ) ;
if ( mx > = 0xffff )
2002-10-13 16:16:04 +03:00
return - 1 ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
my = h263_decode_motion ( s , pred_y , s - > f_code ) ;
if ( my > = 0xffff )
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
mot_val [ 0 ] = mx ;
mot_val [ 1 ] = my ;
}
}
}
}
}
s - > mb_x = 0 ;
}
2002-10-13 16:16:04 +03:00
return mb_num ;
}
/**
* decode second partition .
* @ return < 0 if an error occured
*/
static int mpeg4_decode_partition_b ( MpegEncContext * s , int mb_count ) {
int mb_num = 0 ;
2003-02-11 18:35:48 +02:00
static const int8_t quant_tab [ 4 ] = { - 1 , - 2 , 1 , 2 } ;
2002-06-02 15:15:17 +03:00
s - > mb_x = s - > resync_mb_x ;
2002-10-13 16:16:04 +03:00
s - > first_slice_line = 1 ;
for ( s - > mb_y = s - > resync_mb_y ; mb_num < mb_count ; s - > mb_y + + ) {
ff_init_block_index ( s ) ;
for ( ; mb_num < mb_count & & s - > mb_x < s - > mb_width ; s - > mb_x + + ) {
2003-04-10 16:18:38 +03:00
const int xy = s - > mb_x + s - > mb_y * s - > mb_stride ;
2002-06-02 15:15:17 +03:00
mb_num + + ;
2002-10-13 16:16:04 +03:00
ff_update_block_index ( s ) ;
if ( s - > mb_x = = s - > resync_mb_x & & s - > mb_y = = s - > resync_mb_y + 1 )
s - > first_slice_line = 0 ;
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( s - > pict_type = = I_TYPE ) {
int ac_pred = get_bits1 ( & s - > gb ) ;
2002-07-13 18:45:52 +03:00
int cbpy = get_vlc2 ( & s - > gb , cbpy_vlc . table , CBPY_VLC_BITS , 1 ) ;
2002-06-02 15:15:17 +03:00
if ( cbpy < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " cbpy corrupted at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
s - > cbp_table [ xy ] | = cbpy < < 2 ;
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] | = ac_pred * MB_TYPE_ACPRED ;
2002-06-02 15:15:17 +03:00
} else { /* P || S_TYPE */
2005-12-17 20:14:38 +02:00
if ( IS_INTRA ( s - > current_picture . mb_type [ xy ] ) ) {
2002-06-02 15:15:17 +03:00
int dir = 0 , i ;
int ac_pred = get_bits1 ( & s - > gb ) ;
2002-07-13 18:45:52 +03:00
int cbpy = get_vlc2 ( & s - > gb , cbpy_vlc . table , CBPY_VLC_BITS , 1 ) ;
2002-06-02 15:15:17 +03:00
if ( cbpy < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " I cbpy corrupted at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( s - > cbp_table [ xy ] & 8 ) {
2003-12-03 18:47:17 +02:00
ff_set_qscale ( s , s - > qscale + quant_tab [ get_bits ( & s - > gb , 2 ) ] ) ;
2002-06-02 15:15:17 +03:00
}
2002-12-04 12:04:03 +02:00
s - > current_picture . qscale_table [ xy ] = s - > qscale ;
2002-06-02 15:15:17 +03:00
for ( i = 0 ; i < 6 ; i + + ) {
int dc_pred_dir ;
2005-12-17 20:14:38 +02:00
int dc = mpeg4_decode_dc ( s , i , & dc_pred_dir ) ;
2002-06-02 15:15:17 +03:00
if ( dc < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " DC corrupted at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
dir < < = 1 ;
if ( dc_pred_dir ) dir | = 1 ;
}
s - > cbp_table [ xy ] & = 3 ; //remove dquant
s - > cbp_table [ xy ] | = cbpy < < 2 ;
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] | = ac_pred * MB_TYPE_ACPRED ;
2003-04-10 16:18:38 +03:00
s - > pred_dir_table [ xy ] = dir ;
} else if ( IS_SKIP ( s - > current_picture . mb_type [ xy ] ) ) {
2002-12-04 12:04:03 +02:00
s - > current_picture . qscale_table [ xy ] = s - > qscale ;
2002-06-02 15:15:17 +03:00
s - > cbp_table [ xy ] = 0 ;
} else {
2002-07-13 18:45:52 +03:00
int cbpy = get_vlc2 ( & s - > gb , cbpy_vlc . table , CBPY_VLC_BITS , 1 ) ;
2002-06-02 15:15:17 +03:00
if ( cbpy < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " P cbpy corrupted at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( s - > cbp_table [ xy ] & 8 ) {
2003-12-03 18:47:17 +02:00
ff_set_qscale ( s , s - > qscale + quant_tab [ get_bits ( & s - > gb , 2 ) ] ) ;
2002-06-02 15:15:17 +03:00
}
2002-12-04 12:04:03 +02:00
s - > current_picture . qscale_table [ xy ] = s - > qscale ;
2002-06-02 15:15:17 +03:00
s - > cbp_table [ xy ] & = 3 ; //remove dquant
s - > cbp_table [ xy ] | = ( cbpy ^ 0xf ) < < 2 ;
}
}
}
2002-10-13 16:16:04 +03:00
if ( mb_num > = mb_count ) return 0 ;
2002-06-02 15:15:17 +03:00
s - > mb_x = 0 ;
}
2002-10-13 16:16:04 +03:00
return 0 ;
}
/**
* decodes the first & second partition
* @ return < 0 if error ( and sets error type in the error_status_table )
*/
int ff_mpeg4_decode_partitions ( MpegEncContext * s )
{
int mb_num ;
2003-03-20 03:00:57 +02:00
const int part_a_error = s - > pict_type = = I_TYPE ? ( DC_ERROR | MV_ERROR ) : MV_ERROR ;
const int part_a_end = s - > pict_type = = I_TYPE ? ( DC_END | MV_END ) : MV_END ;
2005-12-17 20:14:38 +02:00
mb_num = mpeg4_decode_partition_a ( s ) ;
2003-03-20 03:00:57 +02:00
if ( mb_num < 0 ) {
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x , s - > mb_y , part_a_error ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2003-03-20 03:00:57 +02:00
}
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
if ( s - > resync_mb_x + s - > resync_mb_y * s - > mb_width + mb_num > s - > mb_num ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " slice below monitor ... \n " ) ;
2003-03-20 03:00:57 +02:00
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x , s - > mb_y , part_a_error ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
}
s - > mb_num_left = mb_num ;
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
if ( s - > pict_type = = I_TYPE ) {
2004-03-11 01:13:43 +02:00
while ( show_bits ( & s - > gb , 9 ) = = 1 )
skip_bits ( & s - > gb , 9 ) ;
2003-05-14 13:55:59 +03:00
if ( get_bits_long ( & s - > gb , 19 ) ! = DC_MARKER ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " marker missing after first I partition at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2003-03-20 03:00:57 +02:00
}
2002-10-13 16:16:04 +03:00
} else {
2004-03-11 01:13:43 +02:00
while ( show_bits ( & s - > gb , 10 ) = = 1 )
skip_bits ( & s - > gb , 10 ) ;
2002-10-13 16:16:04 +03:00
if ( get_bits ( & s - > gb , 17 ) ! = MOTION_MARKER ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " marker missing after first P partition at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2003-03-20 03:00:57 +02:00
}
2002-10-13 16:16:04 +03:00
}
2003-03-20 03:00:57 +02:00
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x - 1 , s - > mb_y , part_a_end ) ;
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
if ( mpeg4_decode_partition_b ( s , mb_num ) < 0 ) {
2003-03-20 03:00:57 +02:00
if ( s - > pict_type = = P_TYPE )
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x , s - > mb_y , DC_ERROR ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2003-03-20 03:00:57 +02:00
} else {
if ( s - > pict_type = = P_TYPE )
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x - 1 , s - > mb_y , DC_END ) ;
2002-10-13 16:16:04 +03:00
}
2002-06-02 15:15:17 +03:00
2005-12-17 20:14:38 +02:00
return 0 ;
2002-06-02 15:15:17 +03:00
}
2002-10-13 16:16:04 +03:00
/**
* decode partition C of one MB .
* @ return < 0 if an error occured
*/
static int mpeg4_decode_partitioned_mb ( MpegEncContext * s , DCTELEM block [ 6 ] [ 64 ] )
2002-06-02 15:15:17 +03:00
{
int cbp , mb_type ;
2003-04-10 16:18:38 +03:00
const int xy = s - > mb_x + s - > mb_y * s - > mb_stride ;
2002-06-02 15:15:17 +03:00
2003-04-10 16:18:38 +03:00
mb_type = s - > current_picture . mb_type [ xy ] ;
2002-10-13 16:16:04 +03:00
cbp = s - > cbp_table [ xy ] ;
2002-06-02 15:15:17 +03:00
2006-04-28 20:29:07 +03:00
s - > use_intra_dc_vlc = s - > qscale < s - > intra_dc_threshold ;
2002-12-04 12:04:03 +02:00
if ( s - > current_picture . qscale_table [ xy ] ! = s - > qscale ) {
2003-12-03 18:47:17 +02:00
ff_set_qscale ( s , s - > current_picture . qscale_table [ xy ] ) ;
2002-06-02 15:15:17 +03:00
}
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
if ( s - > pict_type = = P_TYPE | | s - > pict_type = = S_TYPE ) {
int i ;
for ( i = 0 ; i < 4 ; i + + ) {
2003-12-09 03:49:56 +02:00
s - > mv [ 0 ] [ i ] [ 0 ] = s - > current_picture . motion_val [ 0 ] [ s - > block_index [ i ] ] [ 0 ] ;
s - > mv [ 0 ] [ i ] [ 1 ] = s - > current_picture . motion_val [ 0 ] [ s - > block_index [ i ] ] [ 1 ] ;
2002-06-02 15:15:17 +03:00
}
2003-04-10 16:18:38 +03:00
s - > mb_intra = IS_INTRA ( mb_type ) ;
2002-06-02 15:15:17 +03:00
2003-04-10 16:18:38 +03:00
if ( IS_SKIP ( mb_type ) ) {
2002-06-02 15:15:17 +03:00
/* skip mb */
for ( i = 0 ; i < 6 ; i + + )
s - > block_last_index [ i ] = - 1 ;
s - > mv_dir = MV_DIR_FORWARD ;
s - > mv_type = MV_TYPE_16X16 ;
if ( s - > pict_type = = S_TYPE & & s - > vol_sprite_usage = = GMC_SPRITE ) {
s - > mcsel = 1 ;
2005-04-24 20:21:11 +03:00
s - > mb_skipped = 0 ;
2002-06-02 15:15:17 +03:00
} else {
s - > mcsel = 0 ;
2005-04-24 20:21:11 +03:00
s - > mb_skipped = 1 ;
2002-06-02 15:15:17 +03:00
}
2002-10-13 16:16:04 +03:00
} else if ( s - > mb_intra ) {
2003-04-10 16:18:38 +03:00
s - > ac_pred = IS_ACPRED ( s - > current_picture . mb_type [ xy ] ) ;
2002-06-02 15:15:17 +03:00
} else if ( ! s - > mb_intra ) {
// s->mcsel= 0; //FIXME do we need to init that
2005-12-17 20:14:38 +02:00
2002-06-02 15:15:17 +03:00
s - > mv_dir = MV_DIR_FORWARD ;
2003-04-10 16:18:38 +03:00
if ( IS_8X8 ( mb_type ) ) {
2002-06-02 15:15:17 +03:00
s - > mv_type = MV_TYPE_8X8 ;
} else {
s - > mv_type = MV_TYPE_16X16 ;
}
}
} else { /* I-Frame */
s - > mb_intra = 1 ;
2003-04-10 16:18:38 +03:00
s - > ac_pred = IS_ACPRED ( s - > current_picture . mb_type [ xy ] ) ;
2003-03-13 01:09:18 +02:00
}
2003-04-10 16:18:38 +03:00
if ( ! IS_SKIP ( mb_type ) ) {
2003-03-13 01:09:18 +02:00
int i ;
2005-04-25 03:57:48 +03:00
s - > dsp . clear_blocks ( s - > block [ 0 ] ) ;
2002-06-02 15:15:17 +03:00
/* decode each block */
for ( i = 0 ; i < 6 ; i + + ) {
2003-03-13 01:09:18 +02:00
if ( mpeg4_decode_block ( s , block [ i ] , i , cbp & 32 , s - > mb_intra , s - > rvlc ) < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " texture corrupted at %d %d %d \n " , s - > mb_x , s - > mb_y , s - > mb_intra ) ;
2002-06-02 15:15:17 +03:00
return - 1 ;
}
2002-10-03 01:56:58 +03:00
cbp + = cbp ;
2002-06-02 15:15:17 +03:00
}
}
2002-03-24 23:25:04 +02:00
2002-10-13 16:16:04 +03:00
/* per-MB end of slice check */
2002-08-27 19:28:19 +03:00
2002-10-13 16:16:04 +03:00
if ( - - s - > mb_num_left < = 0 ) {
2003-01-21 19:34:12 +02:00
//printf("%06X %d\n", show_bits(&s->gb, 24), s->gb.size_in_bits - get_bits_count(&s->gb));
2002-10-13 16:16:04 +03:00
if ( mpeg4_is_resync ( s ) )
return SLICE_END ;
else
2005-12-17 20:14:38 +02:00
return SLICE_NOEND ;
2002-10-13 16:16:04 +03:00
} else {
2003-04-10 16:18:38 +03:00
if ( mpeg4_is_resync ( s ) ) {
const int delta = s - > mb_x + 1 = = s - > mb_width ? 2 : 1 ;
if ( s - > cbp_table [ xy + delta ] )
return SLICE_END ;
}
return SLICE_OK ;
2002-08-27 19:28:19 +03:00
}
}
2002-06-02 15:15:17 +03:00
2003-11-28 23:31:20 +02:00
/**
* read the next MVs for OBMC . yes this is a ugly hack , feel free to send a patch : )
*/
static void preview_obmc ( MpegEncContext * s ) {
GetBitContext gb = s - > gb ;
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
int cbpc , i , pred_x , pred_y , mx , my ;
int16_t * mot_val ;
const int xy = s - > mb_x + 1 + s - > mb_y * s - > mb_stride ;
2004-04-16 04:01:45 +03:00
const int stride = s - > b8_stride * 2 ;
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
for ( i = 0 ; i < 4 ; i + + )
s - > block_index [ i ] + = 2 ;
for ( i = 4 ; i < 6 ; i + + )
s - > block_index [ i ] + = 1 ;
s - > mb_x + + ;
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
assert ( s - > pict_type = = P_TYPE ) ;
do {
if ( get_bits1 ( & s - > gb ) ) {
/* skip mb */
2003-12-09 03:49:56 +02:00
mot_val = s - > current_picture . motion_val [ 0 ] [ s - > block_index [ 0 ] ] ;
2005-12-17 20:14:38 +02:00
mot_val [ 0 ] = mot_val [ 2 ] =
2003-11-28 23:31:20 +02:00
mot_val [ 0 + stride ] = mot_val [ 2 + stride ] = 0 ;
mot_val [ 1 ] = mot_val [ 3 ] =
mot_val [ 1 + stride ] = mot_val [ 3 + stride ] = 0 ;
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0 ;
goto end ;
}
cbpc = get_vlc2 ( & s - > gb , inter_MCBPC_vlc . table , INTER_MCBPC_VLC_BITS , 2 ) ;
} while ( cbpc = = 20 ) ;
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
if ( cbpc & 4 ) {
s - > current_picture . mb_type [ xy ] = MB_TYPE_INTRA ;
} else {
get_vlc2 ( & s - > gb , cbpy_vlc . table , CBPY_VLC_BITS , 1 ) ;
if ( cbpc & 8 ) {
2003-12-04 20:46:49 +02:00
if ( s - > modified_quant ) {
if ( get_bits1 ( & s - > gb ) ) skip_bits ( & s - > gb , 1 ) ;
else skip_bits ( & s - > gb , 5 ) ;
} else
skip_bits ( & s - > gb , 2 ) ;
2003-11-28 23:31:20 +02:00
}
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
if ( ( cbpc & 16 ) = = 0 ) {
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_16x16 | MB_TYPE_L0 ;
2003-11-28 23:31:20 +02:00
/* 16x16 motion prediction */
2004-04-16 04:01:45 +03:00
mot_val = h263_pred_motion ( s , 0 , 0 , & pred_x , & pred_y ) ;
2003-11-28 23:31:20 +02:00
if ( s - > umvplus )
mx = h263p_decode_umotion ( s , pred_x ) ;
else
2003-12-04 20:34:47 +02:00
mx = h263_decode_motion ( s , pred_x , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
if ( s - > umvplus )
my = h263p_decode_umotion ( s , pred_y ) ;
else
2003-12-04 20:34:47 +02:00
my = h263_decode_motion ( s , pred_y , 1 ) ;
2005-12-17 20:14:38 +02:00
mot_val [ 0 ] = mot_val [ 2 ] =
2003-11-28 23:31:20 +02:00
mot_val [ 0 + stride ] = mot_val [ 2 + stride ] = mx ;
mot_val [ 1 ] = mot_val [ 3 ] =
mot_val [ 1 + stride ] = mot_val [ 3 + stride ] = my ;
} else {
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_8x8 | MB_TYPE_L0 ;
2003-11-28 23:31:20 +02:00
for ( i = 0 ; i < 4 ; i + + ) {
2004-04-16 04:01:45 +03:00
mot_val = h263_pred_motion ( s , i , 0 , & pred_x , & pred_y ) ;
2003-11-28 23:31:20 +02:00
if ( s - > umvplus )
mx = h263p_decode_umotion ( s , pred_x ) ;
else
2003-12-04 20:34:47 +02:00
mx = h263_decode_motion ( s , pred_x , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
if ( s - > umvplus )
my = h263p_decode_umotion ( s , pred_y ) ;
2005-12-17 20:14:38 +02:00
else
2003-12-04 20:34:47 +02:00
my = h263_decode_motion ( s , pred_y , 1 ) ;
2003-11-28 23:31:20 +02:00
if ( s - > umvplus & & ( mx - pred_x ) = = 1 & & ( my - pred_y ) = = 1 )
skip_bits1 ( & s - > gb ) ; /* Bit stuffing to prevent PSC */
mot_val [ 0 ] = mx ;
mot_val [ 1 ] = my ;
}
}
}
end :
2005-12-17 20:14:38 +02:00
2003-11-28 23:31:20 +02:00
for ( i = 0 ; i < 4 ; i + + )
s - > block_index [ i ] - = 2 ;
for ( i = 4 ; i < 6 ; i + + )
s - > block_index [ i ] - = 1 ;
s - > mb_x - - ;
s - > gb = gb ;
}
2003-12-04 20:46:49 +02:00
static void h263_decode_dquant ( MpegEncContext * s ) {
static const int8_t quant_tab [ 4 ] = { - 1 , - 2 , 1 , 2 } ;
if ( s - > modified_quant ) {
if ( get_bits1 ( & s - > gb ) )
s - > qscale = modified_quant_tab [ get_bits1 ( & s - > gb ) ] [ s - > qscale ] ;
else
s - > qscale = get_bits ( & s - > gb , 5 ) ;
} else
s - > qscale + = quant_tab [ get_bits ( & s - > gb , 2 ) ] ;
ff_set_qscale ( s , s - > qscale ) ;
}
2002-10-13 16:16:04 +03:00
int ff_h263_decode_mb ( MpegEncContext * s ,
DCTELEM block [ 6 ] [ 64 ] )
2001-11-19 04:13:14 +02:00
{
int cbpc , cbpy , i , cbp , pred_x , pred_y , mx , my , dquant ;
2003-02-11 18:35:48 +02:00
int16_t * mot_val ;
2003-04-10 16:18:38 +03:00
const int xy = s - > mb_x + s - > mb_y * s - > mb_stride ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
assert ( ! s - > h263_pred ) ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
if ( s - > pict_type = = P_TYPE ) {
do {
if ( get_bits1 ( & s - > gb ) ) {
/* skip mb */
s - > mb_intra = 0 ;
for ( i = 0 ; i < 6 ; i + + )
s - > block_last_index [ i ] = - 1 ;
s - > mv_dir = MV_DIR_FORWARD ;
s - > mv_type = MV_TYPE_16X16 ;
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0 ;
2002-03-09 15:01:16 +02:00
s - > mv [ 0 ] [ 0 ] [ 0 ] = 0 ;
s - > mv [ 0 ] [ 0 ] [ 1 ] = 0 ;
2005-04-24 20:21:11 +03:00
s - > mb_skipped = ! ( s - > obmc | s - > loop_filter ) ;
2003-12-03 03:16:35 +02:00
goto end ;
2002-03-09 15:01:16 +02:00
}
2003-12-03 03:16:35 +02:00
cbpc = get_vlc2 ( & s - > gb , inter_MCBPC_vlc . table , INTER_MCBPC_VLC_BITS , 2 ) ;
//fprintf(stderr, "\tCBPC: %d", cbpc);
if ( cbpc < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " cbpc damaged at %d %d \n " , s - > mb_x , s - > mb_y ) ;
return - 1 ;
}
} while ( cbpc = = 20 ) ;
2005-12-17 20:14:38 +02:00
2005-04-25 03:57:48 +03:00
s - > dsp . clear_blocks ( s - > block [ 0 ] ) ;
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
dquant = cbpc & 8 ;
s - > mb_intra = ( ( cbpc & 4 ) ! = 0 ) ;
2002-03-13 00:54:25 +02:00
if ( s - > mb_intra ) goto intra ;
2005-12-17 20:14:38 +02:00
2002-07-13 18:45:52 +03:00
cbpy = get_vlc2 ( & s - > gb , cbpy_vlc . table , CBPY_VLC_BITS , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-11-29 10:37:51 +02:00
if ( s - > alt_inter_vlc = = 0 | | ( cbpc & 3 ) ! = 3 )
cbpy ^ = 0xF ;
2005-12-17 20:14:38 +02:00
2003-11-29 10:37:51 +02:00
cbp = ( cbpc & 3 ) | ( cbpy < < 2 ) ;
2001-07-22 17:18:56 +03:00
if ( dquant ) {
2003-12-04 20:46:49 +02:00
h263_decode_dquant ( s ) ;
2001-07-22 17:18:56 +03:00
}
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
s - > mv_dir = MV_DIR_FORWARD ;
if ( ( cbpc & 16 ) = = 0 ) {
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_16x16 | MB_TYPE_L0 ;
2003-12-03 03:16:35 +02:00
/* 16x16 motion prediction */
s - > mv_type = MV_TYPE_16X16 ;
2004-04-16 04:01:45 +03:00
h263_pred_motion ( s , 0 , 0 , & pred_x , & pred_y ) ;
2003-12-03 03:16:35 +02:00
if ( s - > umvplus )
mx = h263p_decode_umotion ( s , pred_x ) ;
else
2003-12-04 20:34:47 +02:00
mx = h263_decode_motion ( s , pred_x , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
if ( mx > = 0xffff )
return - 1 ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
if ( s - > umvplus )
my = h263p_decode_umotion ( s , pred_y ) ;
else
2003-12-04 20:34:47 +02:00
my = h263_decode_motion ( s , pred_y , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
if ( my > = 0xffff )
return - 1 ;
s - > mv [ 0 ] [ 0 ] [ 0 ] = mx ;
s - > mv [ 0 ] [ 0 ] [ 1 ] = my ;
if ( s - > umvplus & & ( mx - pred_x ) = = 1 & & ( my - pred_y ) = = 1 )
2005-12-17 20:14:38 +02:00
skip_bits1 ( & s - > gb ) ; /* Bit stuffing to prevent PSC */
2003-12-03 03:16:35 +02:00
} else {
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_8x8 | MB_TYPE_L0 ;
2003-12-03 03:16:35 +02:00
s - > mv_type = MV_TYPE_8X8 ;
for ( i = 0 ; i < 4 ; i + + ) {
2004-04-16 04:01:45 +03:00
mot_val = h263_pred_motion ( s , i , 0 , & pred_x , & pred_y ) ;
2003-12-03 03:16:35 +02:00
if ( s - > umvplus )
mx = h263p_decode_umotion ( s , pred_x ) ;
else
2003-12-04 20:34:47 +02:00
mx = h263_decode_motion ( s , pred_x , 1 ) ;
2003-12-03 03:16:35 +02:00
if ( mx > = 0xffff )
return - 1 ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
if ( s - > umvplus )
my = h263p_decode_umotion ( s , pred_y ) ;
2005-12-17 20:14:38 +02:00
else
2003-12-04 20:34:47 +02:00
my = h263_decode_motion ( s , pred_y , 1 ) ;
2003-12-03 03:16:35 +02:00
if ( my > = 0xffff )
return - 1 ;
s - > mv [ 0 ] [ i ] [ 0 ] = mx ;
s - > mv [ 0 ] [ i ] [ 1 ] = my ;
if ( s - > umvplus & & ( mx - pred_x ) = = 1 & & ( my - pred_y ) = = 1 )
skip_bits1 ( & s - > gb ) ; /* Bit stuffing to prevent PSC */
mot_val [ 0 ] = mx ;
mot_val [ 1 ] = my ;
}
}
2003-12-04 20:34:47 +02:00
2004-02-09 17:23:35 +02:00
/* decode each block */
for ( i = 0 ; i < 6 ; i + + ) {
if ( h263_decode_block ( s , block [ i ] , i , cbp & 32 ) < 0 )
return - 1 ;
cbp + = cbp ;
}
2003-12-04 20:34:47 +02:00
if ( s - > obmc ) {
2004-02-09 17:23:35 +02:00
if ( s - > pict_type = = P_TYPE & & s - > mb_x + 1 < s - > mb_width & & s - > mb_num_left ! = 1 )
2003-12-04 20:34:47 +02:00
preview_obmc ( s ) ;
}
} else if ( s - > pict_type = = B_TYPE ) {
int mb_type ;
const int stride = s - > b8_stride ;
2003-12-21 22:06:59 +02:00
int16_t * mot_val0 = s - > current_picture . motion_val [ 0 ] [ 2 * ( s - > mb_x + s - > mb_y * stride ) ] ;
int16_t * mot_val1 = s - > current_picture . motion_val [ 1 ] [ 2 * ( s - > mb_x + s - > mb_y * stride ) ] ;
2003-12-04 20:34:47 +02:00
// const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
2005-12-17 20:14:38 +02:00
//FIXME ugly
mot_val0 [ 0 ] = mot_val0 [ 2 ] = mot_val0 [ 0 + 2 * stride ] = mot_val0 [ 2 + 2 * stride ] =
mot_val0 [ 1 ] = mot_val0 [ 3 ] = mot_val0 [ 1 + 2 * stride ] = mot_val0 [ 3 + 2 * stride ] =
mot_val1 [ 0 ] = mot_val1 [ 2 ] = mot_val1 [ 0 + 2 * stride ] = mot_val1 [ 2 + 2 * stride ] =
2003-12-21 22:06:59 +02:00
mot_val1 [ 1 ] = mot_val1 [ 3 ] = mot_val1 [ 1 + 2 * stride ] = mot_val1 [ 3 + 2 * stride ] = 0 ;
2003-12-04 20:34:47 +02:00
do {
mb_type = get_vlc2 ( & s - > gb , h263_mbtype_b_vlc . table , H263_MBTYPE_B_VLC_BITS , 2 ) ;
if ( mb_type < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " b mb_type damaged at %d %d \n " , s - > mb_x , s - > mb_y ) ;
return - 1 ;
}
mb_type = h263_mb_type_b_map [ mb_type ] ;
} while ( ! mb_type ) ;
s - > mb_intra = IS_INTRA ( mb_type ) ;
if ( HAS_CBP ( mb_type ) ) {
2005-04-25 03:57:48 +03:00
s - > dsp . clear_blocks ( s - > block [ 0 ] ) ;
2003-12-04 20:34:47 +02:00
cbpc = get_vlc2 ( & s - > gb , cbpc_b_vlc . table , CBPC_B_VLC_BITS , 1 ) ;
if ( s - > mb_intra ) {
dquant = IS_QUANT ( mb_type ) ;
goto intra ;
}
cbpy = get_vlc2 ( & s - > gb , cbpy_vlc . table , CBPY_VLC_BITS , 1 ) ;
if ( cbpy < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " b cbpy damaged at %d %d \n " , s - > mb_x , s - > mb_y ) ;
return - 1 ;
}
2005-12-17 20:14:38 +02:00
2003-12-04 20:34:47 +02:00
if ( s - > alt_inter_vlc = = 0 | | ( cbpc & 3 ) ! = 3 )
cbpy ^ = 0xF ;
2005-12-17 20:14:38 +02:00
2003-12-04 20:34:47 +02:00
cbp = ( cbpc & 3 ) | ( cbpy < < 2 ) ;
} else
cbp = 0 ;
2005-12-17 20:14:38 +02:00
2003-12-04 20:34:47 +02:00
assert ( ! s - > mb_intra ) ;
if ( IS_QUANT ( mb_type ) ) {
2003-12-04 20:46:49 +02:00
h263_decode_dquant ( s ) ;
2003-12-04 20:34:47 +02:00
}
if ( IS_DIRECT ( mb_type ) ) {
s - > mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT ;
mb_type | = ff_mpeg4_set_direct_mv ( s , 0 , 0 ) ;
} else {
s - > mv_dir = 0 ;
s - > mv_type = MV_TYPE_16X16 ;
//FIXME UMV
if ( USES_LIST ( mb_type , 0 ) ) {
2004-04-16 04:01:45 +03:00
int16_t * mot_val = h263_pred_motion ( s , 0 , 0 , & mx , & my ) ;
2003-12-04 20:34:47 +02:00
s - > mv_dir = MV_DIR_FORWARD ;
mx = h263_decode_motion ( s , mx , 1 ) ;
my = h263_decode_motion ( s , my , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-12-04 20:34:47 +02:00
s - > mv [ 0 ] [ 0 ] [ 0 ] = mx ;
s - > mv [ 0 ] [ 0 ] [ 1 ] = my ;
2003-12-21 22:06:59 +02:00
mot_val [ 0 ] = mot_val [ 2 ] = mot_val [ 0 + 2 * stride ] = mot_val [ 2 + 2 * stride ] = mx ;
mot_val [ 1 ] = mot_val [ 3 ] = mot_val [ 1 + 2 * stride ] = mot_val [ 3 + 2 * stride ] = my ;
2003-12-04 20:34:47 +02:00
}
2005-12-17 20:14:38 +02:00
2003-12-04 20:34:47 +02:00
if ( USES_LIST ( mb_type , 1 ) ) {
2004-04-16 04:01:45 +03:00
int16_t * mot_val = h263_pred_motion ( s , 0 , 1 , & mx , & my ) ;
2003-12-04 20:34:47 +02:00
s - > mv_dir | = MV_DIR_BACKWARD ;
2005-12-17 20:14:38 +02:00
2003-12-04 20:34:47 +02:00
mx = h263_decode_motion ( s , mx , 1 ) ;
my = h263_decode_motion ( s , my , 1 ) ;
2003-12-21 22:06:59 +02:00
2003-12-04 20:34:47 +02:00
s - > mv [ 1 ] [ 0 ] [ 0 ] = mx ;
s - > mv [ 1 ] [ 0 ] [ 1 ] = my ;
2003-12-21 22:06:59 +02:00
mot_val [ 0 ] = mot_val [ 2 ] = mot_val [ 0 + 2 * stride ] = mot_val [ 2 + 2 * stride ] = mx ;
mot_val [ 1 ] = mot_val [ 3 ] = mot_val [ 1 + 2 * stride ] = mot_val [ 3 + 2 * stride ] = my ;
2003-12-04 20:34:47 +02:00
}
}
2005-12-17 20:14:38 +02:00
2003-12-04 20:34:47 +02:00
s - > current_picture . mb_type [ xy ] = mb_type ;
2004-02-09 17:23:35 +02:00
/* decode each block */
for ( i = 0 ; i < 6 ; i + + ) {
if ( h263_decode_block ( s , block [ i ] , i , cbp & 32 ) < 0 )
return - 1 ;
cbp + = cbp ;
}
2003-12-03 03:16:35 +02:00
} else { /* I-Frame */
do {
cbpc = get_vlc2 ( & s - > gb , intra_MCBPC_vlc . table , INTRA_MCBPC_VLC_BITS , 2 ) ;
if ( cbpc < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " I cbpc damaged at %d %d \n " , s - > mb_x , s - > mb_y ) ;
return - 1 ;
}
} while ( cbpc = = 8 ) ;
2005-04-25 03:57:48 +03:00
s - > dsp . clear_blocks ( s - > block [ 0 ] ) ;
2003-12-03 03:16:35 +02:00
dquant = cbpc & 4 ;
s - > mb_intra = 1 ;
intra :
s - > current_picture . mb_type [ xy ] = MB_TYPE_INTRA ;
if ( s - > h263_aic ) {
s - > ac_pred = get_bits1 ( & s - > gb ) ;
if ( s - > ac_pred ) {
s - > current_picture . mb_type [ xy ] = MB_TYPE_INTRA | MB_TYPE_ACPRED ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
s - > h263_aic_dir = get_bits1 ( & s - > gb ) ;
}
} else
s - > ac_pred = 0 ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
cbpy = get_vlc2 ( & s - > gb , cbpy_vlc . table , CBPY_VLC_BITS , 1 ) ;
if ( cbpy < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " I cbpy damaged at %d %d \n " , s - > mb_x , s - > mb_y ) ;
return - 1 ;
}
cbp = ( cbpc & 3 ) | ( cbpy < < 2 ) ;
if ( dquant ) {
2003-12-04 20:46:49 +02:00
h263_decode_dquant ( s ) ;
2003-12-03 03:16:35 +02:00
}
2004-02-09 17:23:35 +02:00
/* decode each block */
for ( i = 0 ; i < 6 ; i + + ) {
if ( h263_decode_block ( s , block [ i ] , i , cbp & 32 ) < 0 )
return - 1 ;
cbp + = cbp ;
}
2003-12-03 03:16:35 +02:00
}
end :
/* per-MB end of slice check */
{
int v = show_bits ( & s - > gb , 16 ) ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
if ( get_bits_count ( & s - > gb ) + 16 > s - > gb . size_in_bits ) {
v > > = get_bits_count ( & s - > gb ) + 16 - s - > gb . size_in_bits ;
}
if ( v = = 0 )
return SLICE_END ;
}
2005-12-17 20:14:38 +02:00
return SLICE_OK ;
2003-12-03 03:16:35 +02:00
}
int ff_mpeg4_decode_mb ( MpegEncContext * s ,
DCTELEM block [ 6 ] [ 64 ] )
{
int cbpc , cbpy , i , cbp , pred_x , pred_y , mx , my , dquant ;
int16_t * mot_val ;
static int8_t quant_tab [ 4 ] = { - 1 , - 2 , 1 , 2 } ;
const int xy = s - > mb_x + s - > mb_y * s - > mb_stride ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
assert ( s - > h263_pred ) ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
if ( s - > pict_type = = P_TYPE | | s - > pict_type = = S_TYPE ) {
do {
if ( get_bits1 ( & s - > gb ) ) {
/* skip mb */
s - > mb_intra = 0 ;
for ( i = 0 ; i < 6 ; i + + )
s - > block_last_index [ i ] = - 1 ;
s - > mv_dir = MV_DIR_FORWARD ;
s - > mv_type = MV_TYPE_16X16 ;
if ( s - > pict_type = = S_TYPE & & s - > vol_sprite_usage = = GMC_SPRITE ) {
s - > current_picture . mb_type [ xy ] = MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0 ;
s - > mcsel = 1 ;
s - > mv [ 0 ] [ 0 ] [ 0 ] = get_amv ( s , 0 ) ;
s - > mv [ 0 ] [ 0 ] [ 1 ] = get_amv ( s , 1 ) ;
2005-04-24 20:21:11 +03:00
s - > mb_skipped = 0 ;
2003-12-03 03:16:35 +02:00
} else {
s - > current_picture . mb_type [ xy ] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0 ;
s - > mcsel = 0 ;
s - > mv [ 0 ] [ 0 ] [ 0 ] = 0 ;
s - > mv [ 0 ] [ 0 ] [ 1 ] = 0 ;
2005-04-24 20:21:11 +03:00
s - > mb_skipped = 1 ;
2003-12-03 03:16:35 +02:00
}
goto end ;
}
cbpc = get_vlc2 ( & s - > gb , inter_MCBPC_vlc . table , INTER_MCBPC_VLC_BITS , 2 ) ;
//fprintf(stderr, "\tCBPC: %d", cbpc);
if ( cbpc < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " cbpc damaged at %d %d \n " , s - > mb_x , s - > mb_y ) ;
return - 1 ;
}
} while ( cbpc = = 20 ) ;
2005-12-17 20:14:38 +02:00
2005-04-25 03:57:48 +03:00
s - > dsp . clear_blocks ( s - > block [ 0 ] ) ;
2003-12-03 03:16:35 +02:00
dquant = cbpc & 8 ;
s - > mb_intra = ( ( cbpc & 4 ) ! = 0 ) ;
if ( s - > mb_intra ) goto intra ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
if ( s - > pict_type = = S_TYPE & & s - > vol_sprite_usage = = GMC_SPRITE & & ( cbpc & 16 ) = = 0 )
s - > mcsel = get_bits1 ( & s - > gb ) ;
else s - > mcsel = 0 ;
cbpy = get_vlc2 ( & s - > gb , cbpy_vlc . table , CBPY_VLC_BITS , 1 ) ^ 0x0F ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
cbp = ( cbpc & 3 ) | ( cbpy < < 2 ) ;
if ( dquant ) {
2003-12-03 18:47:17 +02:00
ff_set_qscale ( s , s - > qscale + quant_tab [ get_bits ( & s - > gb , 2 ) ] ) ;
2003-12-03 03:16:35 +02:00
}
2002-10-13 16:16:04 +03:00
if ( ( ! s - > progressive_sequence ) & & ( cbp | | ( s - > workaround_bugs & FF_BUG_XVID_ILACE ) ) )
2002-08-27 19:28:19 +03:00
s - > interlaced_dct = get_bits1 ( & s - > gb ) ;
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
s - > mv_dir = MV_DIR_FORWARD ;
if ( ( cbpc & 16 ) = = 0 ) {
2002-08-27 19:28:19 +03:00
if ( s - > mcsel ) {
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0 ;
2002-08-27 19:28:19 +03:00
/* 16x16 global motion prediction */
s - > mv_type = MV_TYPE_16X16 ;
2002-10-16 22:55:49 +03:00
mx = get_amv ( s , 0 ) ;
my = get_amv ( s , 1 ) ;
2002-08-27 19:28:19 +03:00
s - > mv [ 0 ] [ 0 ] [ 0 ] = mx ;
s - > mv [ 0 ] [ 0 ] [ 1 ] = my ;
} else if ( ( ! s - > progressive_sequence ) & & get_bits1 ( & s - > gb ) ) {
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED ;
2002-08-27 19:28:19 +03:00
/* 16x8 field motion prediction */
s - > mv_type = MV_TYPE_FIELD ;
s - > field_select [ 0 ] [ 0 ] = get_bits1 ( & s - > gb ) ;
s - > field_select [ 0 ] [ 1 ] = get_bits1 ( & s - > gb ) ;
2004-04-16 04:01:45 +03:00
h263_pred_motion ( s , 0 , 0 , & pred_x , & pred_y ) ;
2005-12-17 20:14:38 +02:00
2002-08-27 19:28:19 +03:00
for ( i = 0 ; i < 2 ; i + + ) {
mx = h263_decode_motion ( s , pred_x , s - > f_code ) ;
if ( mx > = 0xffff )
return - 1 ;
2005-12-17 20:14:38 +02:00
2002-08-27 19:28:19 +03:00
my = h263_decode_motion ( s , pred_y / 2 , s - > f_code ) ;
if ( my > = 0xffff )
return - 1 ;
s - > mv [ 0 ] [ i ] [ 0 ] = mx ;
2002-09-12 21:28:17 +03:00
s - > mv [ 0 ] [ i ] [ 1 ] = my ;
2002-03-29 07:15:49 +02:00
}
2002-08-27 19:28:19 +03:00
} else {
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_16x16 | MB_TYPE_L0 ;
2002-08-27 19:28:19 +03:00
/* 16x16 motion prediction */
s - > mv_type = MV_TYPE_16X16 ;
2004-04-16 04:01:45 +03:00
h263_pred_motion ( s , 0 , 0 , & pred_x , & pred_y ) ;
2003-12-03 03:16:35 +02:00
mx = h263_decode_motion ( s , pred_x , s - > f_code ) ;
2005-12-17 20:14:38 +02:00
2002-08-27 19:28:19 +03:00
if ( mx > = 0xffff )
return - 1 ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
my = h263_decode_motion ( s , pred_y , s - > f_code ) ;
2005-12-17 20:14:38 +02:00
2002-08-27 19:28:19 +03:00
if ( my > = 0xffff )
return - 1 ;
s - > mv [ 0 ] [ 0 ] [ 0 ] = mx ;
s - > mv [ 0 ] [ 0 ] [ 1 ] = my ;
2002-03-09 15:01:16 +02:00
}
2001-07-22 17:18:56 +03:00
} else {
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_8x8 | MB_TYPE_L0 ;
2001-07-22 17:18:56 +03:00
s - > mv_type = MV_TYPE_8X8 ;
for ( i = 0 ; i < 4 ; i + + ) {
2004-04-16 04:01:45 +03:00
mot_val = h263_pred_motion ( s , i , 0 , & pred_x , & pred_y ) ;
2003-12-03 03:16:35 +02:00
mx = h263_decode_motion ( s , pred_x , s - > f_code ) ;
2001-07-22 17:18:56 +03:00
if ( mx > = 0xffff )
return - 1 ;
2005-12-17 20:14:38 +02:00
2003-12-03 03:16:35 +02:00
my = h263_decode_motion ( s , pred_y , s - > f_code ) ;
2001-07-22 17:18:56 +03:00
if ( my > = 0xffff )
return - 1 ;
s - > mv [ 0 ] [ i ] [ 0 ] = mx ;
s - > mv [ 0 ] [ i ] [ 1 ] = my ;
mot_val [ 0 ] = mx ;
mot_val [ 1 ] = my ;
}
}
2002-03-13 00:54:25 +02:00
} else if ( s - > pict_type = = B_TYPE ) {
int modb1 ; // first bit of modb
int modb2 ; // second bit of modb
int mb_type ;
s - > mb_intra = 0 ; //B-frames never contain intra blocks
s - > mcsel = 0 ; // ... true gmc blocks
if ( s - > mb_x = = 0 ) {
2002-09-14 20:18:26 +03:00
for ( i = 0 ; i < 2 ; i + + ) {
2005-12-17 20:14:38 +02:00
s - > last_mv [ i ] [ 0 ] [ 0 ] =
s - > last_mv [ i ] [ 0 ] [ 1 ] =
s - > last_mv [ i ] [ 1 ] [ 0 ] =
2002-09-14 20:18:26 +03:00
s - > last_mv [ i ] [ 1 ] [ 1 ] = 0 ;
}
2002-03-13 00:54:25 +02:00
}
/* if we skipped it in the future P Frame than skip it now too */
2005-04-24 20:21:11 +03:00
s - > mb_skipped = s - > next_picture . mbskip_table [ s - > mb_y * s - > mb_stride + s - > mb_x ] ; // Note, skiptab=0 if last was GMC
2002-03-13 00:54:25 +02:00
2005-04-24 20:21:11 +03:00
if ( s - > mb_skipped ) {
2002-03-13 00:54:25 +02:00
/* skip mb */
for ( i = 0 ; i < 6 ; i + + )
s - > block_last_index [ i ] = - 1 ;
s - > mv_dir = MV_DIR_FORWARD ;
s - > mv_type = MV_TYPE_16X16 ;
s - > mv [ 0 ] [ 0 ] [ 0 ] = 0 ;
s - > mv [ 0 ] [ 0 ] [ 1 ] = 0 ;
s - > mv [ 1 ] [ 0 ] [ 0 ] = 0 ;
s - > mv [ 1 ] [ 0 ] [ 1 ] = 0 ;
2005-12-17 20:14:38 +02:00
s - > current_picture . mb_type [ xy ] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0 ;
2002-10-13 16:16:04 +03:00
goto end ;
2002-03-13 00:54:25 +02:00
}
2005-12-17 20:14:38 +02:00
modb1 = get_bits1 ( & s - > gb ) ;
2002-09-13 14:24:58 +03:00
if ( modb1 ) {
2003-04-10 16:18:38 +03:00
mb_type = MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1 ; //like MB_TYPE_B_DIRECT but no vectors coded
2002-09-13 14:24:58 +03:00
cbp = 0 ;
} else {
2002-03-13 00:54:25 +02:00
modb2 = get_bits1 ( & s - > gb ) ;
2002-07-13 18:45:52 +03:00
mb_type = get_vlc2 ( & s - > gb , mb_type_b_vlc . table , MB_TYPE_B_VLC_BITS , 1 ) ;
2003-04-10 16:18:38 +03:00
if ( mb_type < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " illegal MB_type \n " ) ;
2003-04-10 16:18:38 +03:00
return - 1 ;
}
mb_type = mb_type_b_map [ mb_type ] ;
2002-09-13 14:24:58 +03:00
if ( modb2 ) cbp = 0 ;
2005-04-25 03:57:48 +03:00
else {
s - > dsp . clear_blocks ( s - > block [ 0 ] ) ;
cbp = get_bits ( & s - > gb , 6 ) ;
}
2002-09-13 14:24:58 +03:00
2003-04-10 16:18:38 +03:00
if ( ( ! IS_DIRECT ( mb_type ) ) & & cbp ) {
2002-03-13 00:54:25 +02:00
if ( get_bits1 ( & s - > gb ) ) {
2003-12-03 18:47:17 +02:00
ff_set_qscale ( s , s - > qscale + get_bits1 ( & s - > gb ) * 4 - 2 ) ;
2002-03-13 00:54:25 +02:00
}
}
2002-09-13 12:45:32 +03:00
if ( ! s - > progressive_sequence ) {
if ( cbp )
s - > interlaced_dct = get_bits1 ( & s - > gb ) ;
2003-04-10 16:18:38 +03:00
if ( ! IS_DIRECT ( mb_type ) & & get_bits1 ( & s - > gb ) ) {
mb_type | = MB_TYPE_16x8 | MB_TYPE_INTERLACED ;
mb_type & = ~ MB_TYPE_16x16 ;
2002-09-13 14:47:57 +03:00
2003-04-10 16:18:38 +03:00
if ( USES_LIST ( mb_type , 0 ) ) {
2002-09-13 14:47:57 +03:00
s - > field_select [ 0 ] [ 0 ] = get_bits1 ( & s - > gb ) ;
s - > field_select [ 0 ] [ 1 ] = get_bits1 ( & s - > gb ) ;
}
2003-04-10 16:18:38 +03:00
if ( USES_LIST ( mb_type , 1 ) ) {
2002-09-13 14:47:57 +03:00
s - > field_select [ 1 ] [ 0 ] = get_bits1 ( & s - > gb ) ;
s - > field_select [ 1 ] [ 1 ] = get_bits1 ( & s - > gb ) ;
}
}
2002-09-13 12:45:32 +03:00
}
2002-09-13 14:47:57 +03:00
s - > mv_dir = 0 ;
2003-04-10 16:18:38 +03:00
if ( ( mb_type & ( MB_TYPE_DIRECT2 | MB_TYPE_INTERLACED ) ) = = 0 ) {
2002-09-13 14:24:58 +03:00
s - > mv_type = MV_TYPE_16X16 ;
2003-04-10 16:18:38 +03:00
if ( USES_LIST ( mb_type , 0 ) ) {
2002-09-13 14:24:58 +03:00
s - > mv_dir = MV_DIR_FORWARD ;
mx = h263_decode_motion ( s , s - > last_mv [ 0 ] [ 0 ] [ 0 ] , s - > f_code ) ;
my = h263_decode_motion ( s , s - > last_mv [ 0 ] [ 0 ] [ 1 ] , s - > f_code ) ;
s - > last_mv [ 0 ] [ 1 ] [ 0 ] = s - > last_mv [ 0 ] [ 0 ] [ 0 ] = s - > mv [ 0 ] [ 0 ] [ 0 ] = mx ;
s - > last_mv [ 0 ] [ 1 ] [ 1 ] = s - > last_mv [ 0 ] [ 0 ] [ 1 ] = s - > mv [ 0 ] [ 0 ] [ 1 ] = my ;
2002-09-13 14:47:57 +03:00
}
2005-12-17 20:14:38 +02:00
2003-04-10 16:18:38 +03:00
if ( USES_LIST ( mb_type , 1 ) ) {
2002-09-13 14:24:58 +03:00
s - > mv_dir | = MV_DIR_BACKWARD ;
mx = h263_decode_motion ( s , s - > last_mv [ 1 ] [ 0 ] [ 0 ] , s - > b_code ) ;
my = h263_decode_motion ( s , s - > last_mv [ 1 ] [ 0 ] [ 1 ] , s - > b_code ) ;
s - > last_mv [ 1 ] [ 1 ] [ 0 ] = s - > last_mv [ 1 ] [ 0 ] [ 0 ] = s - > mv [ 1 ] [ 0 ] [ 0 ] = mx ;
s - > last_mv [ 1 ] [ 1 ] [ 1 ] = s - > last_mv [ 1 ] [ 0 ] [ 1 ] = s - > mv [ 1 ] [ 0 ] [ 1 ] = my ;
}
2003-04-10 16:18:38 +03:00
} else if ( ! IS_DIRECT ( mb_type ) ) {
2002-09-13 14:24:58 +03:00
s - > mv_type = MV_TYPE_FIELD ;
2002-09-13 14:47:57 +03:00
2003-04-10 16:18:38 +03:00
if ( USES_LIST ( mb_type , 0 ) ) {
2002-09-13 14:24:58 +03:00
s - > mv_dir = MV_DIR_FORWARD ;
2005-12-17 20:14:38 +02:00
2002-09-13 14:24:58 +03:00
for ( i = 0 ; i < 2 ; i + + ) {
mx = h263_decode_motion ( s , s - > last_mv [ 0 ] [ i ] [ 0 ] , s - > f_code ) ;
my = h263_decode_motion ( s , s - > last_mv [ 0 ] [ i ] [ 1 ] / 2 , s - > f_code ) ;
s - > last_mv [ 0 ] [ i ] [ 0 ] = s - > mv [ 0 ] [ i ] [ 0 ] = mx ;
s - > last_mv [ 0 ] [ i ] [ 1 ] = ( s - > mv [ 0 ] [ i ] [ 1 ] = my ) * 2 ;
}
2002-09-13 14:47:57 +03:00
}
2005-12-17 20:14:38 +02:00
2003-04-10 16:18:38 +03:00
if ( USES_LIST ( mb_type , 1 ) ) {
2002-09-13 14:24:58 +03:00
s - > mv_dir | = MV_DIR_BACKWARD ;
for ( i = 0 ; i < 2 ; i + + ) {
mx = h263_decode_motion ( s , s - > last_mv [ 1 ] [ i ] [ 0 ] , s - > b_code ) ;
my = h263_decode_motion ( s , s - > last_mv [ 1 ] [ i ] [ 1 ] / 2 , s - > b_code ) ;
s - > last_mv [ 1 ] [ i ] [ 0 ] = s - > mv [ 1 ] [ i ] [ 0 ] = mx ;
s - > last_mv [ 1 ] [ i ] [ 1 ] = ( s - > mv [ 1 ] [ i ] [ 1 ] = my ) * 2 ;
}
2002-09-13 12:45:32 +03:00
}
}
}
2005-12-17 20:14:38 +02:00
2003-04-10 16:18:38 +03:00
if ( IS_DIRECT ( mb_type ) ) {
if ( IS_SKIP ( mb_type ) )
2002-09-13 14:24:58 +03:00
mx = my = 0 ;
else {
mx = h263_decode_motion ( s , 0 , 1 ) ;
my = h263_decode_motion ( s , 0 , 1 ) ;
}
2005-12-17 20:14:38 +02:00
2002-03-13 00:54:25 +02:00
s - > mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT ;
2003-04-10 16:18:38 +03:00
mb_type | = ff_mpeg4_set_direct_mv ( s , mx , my ) ;
2002-03-13 00:54:25 +02:00
}
2003-04-10 16:18:38 +03:00
s - > current_picture . mb_type [ xy ] = mb_type ;
2002-03-13 00:54:25 +02:00
} else { /* I-Frame */
2003-09-27 01:18:25 +03:00
do {
cbpc = get_vlc2 ( & s - > gb , intra_MCBPC_vlc . table , INTRA_MCBPC_VLC_BITS , 2 ) ;
if ( cbpc < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " I cbpc damaged at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2003-09-27 01:18:25 +03:00
return - 1 ;
}
} while ( cbpc = = 8 ) ;
2002-03-13 00:54:25 +02:00
dquant = cbpc & 4 ;
s - > mb_intra = 1 ;
intra :
2003-12-03 03:16:35 +02:00
s - > ac_pred = get_bits1 ( & s - > gb ) ;
if ( s - > ac_pred )
s - > current_picture . mb_type [ xy ] = MB_TYPE_INTRA | MB_TYPE_ACPRED ;
else
s - > current_picture . mb_type [ xy ] = MB_TYPE_INTRA ;
2005-12-17 20:14:38 +02:00
2002-07-13 18:45:52 +03:00
cbpy = get_vlc2 ( & s - > gb , cbpy_vlc . table , CBPY_VLC_BITS , 1 ) ;
2003-09-27 01:18:25 +03:00
if ( cbpy < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " I cbpy damaged at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2003-09-27 01:18:25 +03:00
return - 1 ;
}
2001-07-22 17:18:56 +03:00
cbp = ( cbpc & 3 ) | ( cbpy < < 2 ) ;
2006-04-28 20:29:07 +03:00
s - > use_intra_dc_vlc = s - > qscale < s - > intra_dc_threshold ;
2001-07-22 17:18:56 +03:00
if ( dquant ) {
2003-12-03 18:47:17 +02:00
ff_set_qscale ( s , s - > qscale + quant_tab [ get_bits ( & s - > gb , 2 ) ] ) ;
2001-07-22 17:18:56 +03:00
}
2005-12-17 20:14:38 +02:00
2002-08-27 19:28:19 +03:00
if ( ! s - > progressive_sequence )
s - > interlaced_dct = get_bits1 ( & s - > gb ) ;
2002-07-21 04:34:05 +03:00
2005-04-25 03:57:48 +03:00
s - > dsp . clear_blocks ( s - > block [ 0 ] ) ;
2002-07-21 04:34:05 +03:00
/* decode each block */
2003-12-03 03:16:35 +02:00
for ( i = 0 ; i < 6 ; i + + ) {
if ( mpeg4_decode_block ( s , block [ i ] , i , cbp & 32 , 1 , 0 ) < 0 )
return - 1 ;
cbp + = cbp ;
2002-07-21 04:34:05 +03:00
}
2002-10-13 16:16:04 +03:00
goto end ;
2001-07-22 17:18:56 +03:00
}
/* decode each block */
2003-12-03 03:16:35 +02:00
for ( i = 0 ; i < 6 ; i + + ) {
if ( mpeg4_decode_block ( s , block [ i ] , i , cbp & 32 , 0 , 0 ) < 0 )
return - 1 ;
cbp + = cbp ;
2001-07-22 17:18:56 +03:00
}
2002-10-13 16:16:04 +03:00
end :
/* per-MB end of slice check */
if ( s - > codec_id = = CODEC_ID_MPEG4 ) {
2006-05-08 16:44:54 +03:00
#if 0 //http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_IEC_14496-4_2004_Conformance_Testing/video_conformance/version_1/simple/ERROR.ZIP/mit025.m4v needs this but its unclear if the mpeg4 standard allows this at all (MN)
if ( s - > pict_type ! = B_TYPE ) {
while ( show_bits ( & s - > gb , 9 + ( s - > pict_type = = P_TYPE ) ) = = 1 )
skip_bits ( & s - > gb , 9 + ( s - > pict_type = = P_TYPE ) ) ;
}
# endif
2002-10-13 16:16:04 +03:00
if ( mpeg4_is_resync ( s ) ) {
2003-04-10 16:18:38 +03:00
const int delta = s - > mb_x + 1 = = s - > mb_width ? 2 : 1 ;
if ( s - > pict_type = = B_TYPE & & s - > next_picture . mbskip_table [ xy + delta ] )
2002-10-13 16:16:04 +03:00
return SLICE_OK ;
return SLICE_END ;
}
}
2005-12-17 20:14:38 +02:00
return SLICE_OK ;
2001-07-22 17:18:56 +03:00
}
2002-03-13 00:54:25 +02:00
static int h263_decode_motion ( MpegEncContext * s , int pred , int f_code )
2001-07-22 17:18:56 +03:00
{
2002-09-12 15:26:09 +03:00
int code , val , sign , shift , l ;
2002-07-13 18:45:52 +03:00
code = get_vlc2 ( & s - > gb , mv_vlc . table , MV_VLC_BITS , 2 ) ;
2001-07-22 17:18:56 +03:00
if ( code = = 0 )
return pred ;
2003-04-10 16:18:38 +03:00
if ( code < 0 )
return 0xffff ;
2002-09-30 01:44:22 +03:00
2001-08-04 03:46:50 +03:00
sign = get_bits1 ( & s - > gb ) ;
2002-03-13 00:54:25 +02:00
shift = f_code - 1 ;
2003-05-14 04:08:02 +03:00
val = code ;
if ( shift ) {
val = ( val - 1 ) < < shift ;
2001-07-22 17:18:56 +03:00
val | = get_bits ( & s - > gb , shift ) ;
2003-05-14 04:08:02 +03:00
val + + ;
}
2001-07-22 17:18:56 +03:00
if ( sign )
val = - val ;
val + = pred ;
2002-06-04 21:35:31 +03:00
2001-07-22 17:18:56 +03:00
/* modulo decoding */
if ( ! s - > h263_long_vectors ) {
2004-06-25 17:11:44 +03:00
l = INT_BIT - 5 - f_code ;
val = ( val < < l ) > > l ;
2001-07-22 17:18:56 +03:00
} else {
/* horrible h263 long vector mode */
if ( pred < - 31 & & val < - 63 )
val + = 64 ;
if ( pred > 32 & & val > 63 )
val - = 64 ;
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
}
return val ;
}
2001-08-29 02:32:34 +03:00
/* Decodes RVLC of H.263+ UMV */
static int h263p_decode_umotion ( MpegEncContext * s , int pred )
{
int code = 0 , sign ;
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
if ( get_bits1 ( & s - > gb ) ) /* Motion difference = 0 */
return pred ;
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
code = 2 + get_bits1 ( & s - > gb ) ;
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
while ( get_bits1 ( & s - > gb ) )
{
code < < = 1 ;
code + = get_bits1 ( & s - > gb ) ;
}
sign = code & 1 ;
code > > = 1 ;
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
code = ( sign ) ? ( pred - code ) : ( pred + code ) ;
# ifdef DEBUG
2005-08-26 22:05:44 +03:00
av_log ( s - > avctx , AV_LOG_DEBUG , " H.263+ UMV Motion = %d \n " , code ) ;
2001-08-29 02:32:34 +03:00
# endif
2005-12-17 20:14:38 +02:00
return code ;
2001-08-29 02:32:34 +03:00
}
2001-07-22 17:18:56 +03:00
static int h263_decode_block ( MpegEncContext * s , DCTELEM * block ,
int n , int coded )
{
int code , level , i , j , last , run ;
RLTable * rl = & rl_inter ;
2003-02-11 18:35:48 +02:00
const uint8_t * scan_table ;
2003-11-29 10:37:51 +02:00
GetBitContext gb = s - > gb ;
2001-07-22 17:18:56 +03:00
2002-09-30 01:44:22 +03:00
scan_table = s - > intra_scantable . permutated ;
2002-02-19 21:23:34 +02:00
if ( s - > h263_aic & & s - > mb_intra ) {
2002-02-18 21:33:27 +02:00
rl = & rl_intra_aic ;
i = 0 ;
if ( s - > ac_pred ) {
2005-12-17 20:14:38 +02:00
if ( s - > h263_aic_dir )
2002-09-30 01:44:22 +03:00
scan_table = s - > intra_v_scantable . permutated ; /* left */
2002-02-18 21:33:27 +02:00
else
2002-09-30 01:44:22 +03:00
scan_table = s - > intra_h_scantable . permutated ; /* top */
2002-02-18 21:33:27 +02:00
}
} else if ( s - > mb_intra ) {
/* DC coef */
2003-11-30 19:30:18 +02:00
if ( s - > codec_id = = CODEC_ID_RV10 ) {
2005-05-03 01:14:42 +03:00
# ifdef CONFIG_RV10_DECODER
2003-02-28 18:06:40 +02:00
if ( s - > rv10_version = = 3 & & s - > pict_type = = I_TYPE ) {
2001-07-22 17:18:56 +03:00
int component , diff ;
component = ( n < = 3 ? 0 : n - 4 + 1 ) ;
level = s - > last_dc [ component ] ;
if ( s - > rv10_first_dc_coded [ component ] ) {
diff = rv_decode_dc ( s , n ) ;
if ( diff = = 0xffff )
return - 1 ;
level + = diff ;
level = level & 0xff ; /* handle wrap round */
s - > last_dc [ component ] = level ;
} else {
s - > rv10_first_dc_coded [ component ] = 1 ;
}
2003-02-28 18:06:40 +02:00
} else {
level = get_bits ( & s - > gb , 8 ) ;
2004-04-25 19:14:13 +03:00
if ( level = = 255 )
level = 128 ;
2003-02-28 18:06:40 +02:00
}
2005-05-03 01:14:42 +03:00
# endif
2003-02-28 18:06:40 +02:00
} else {
2001-07-22 17:18:56 +03:00
level = get_bits ( & s - > gb , 8 ) ;
2003-02-28 15:07:07 +02:00
if ( ( level & 0x7F ) = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " illegal dc %d at %d %d \n " , level , s - > mb_x , s - > mb_y ) ;
2004-01-21 21:14:26 +02:00
if ( s - > error_resilience > = FF_ER_COMPLIANT )
return - 1 ;
2003-02-28 15:07:07 +02:00
}
2001-07-22 17:18:56 +03:00
if ( level = = 255 )
level = 128 ;
}
block [ 0 ] = level ;
2002-02-18 21:33:27 +02:00
i = 1 ;
2001-07-22 17:18:56 +03:00
} else {
2002-02-18 21:33:27 +02:00
i = 0 ;
2001-07-22 17:18:56 +03:00
}
if ( ! coded ) {
2002-02-19 21:23:34 +02:00
if ( s - > mb_intra & & s - > h263_aic )
goto not_coded ;
2001-07-22 17:18:56 +03:00
s - > block_last_index [ n ] = i - 1 ;
return 0 ;
}
2003-11-29 10:37:51 +02:00
retry :
2001-07-22 17:18:56 +03:00
for ( ; ; ) {
2002-07-13 18:45:52 +03:00
code = get_vlc2 ( & s - > gb , rl - > vlc . table , TEX_VLC_BITS , 2 ) ;
2002-10-13 16:16:04 +03:00
if ( code < 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " illegal ac vlc code at %dx%d \n " , s - > mb_x , s - > mb_y ) ;
2001-07-22 17:18:56 +03:00
return - 1 ;
2002-10-13 16:16:04 +03:00
}
2001-07-22 17:18:56 +03:00
if ( code = = rl - > n ) {
/* escape */
2003-07-10 02:10:59 +03:00
if ( s - > h263_flv > 1 ) {
int is11 = get_bits1 ( & s - > gb ) ;
last = get_bits1 ( & s - > gb ) ;
run = get_bits ( & s - > gb , 6 ) ;
if ( is11 ) {
2003-07-10 13:24:47 +03:00
level = get_sbits ( & s - > gb , 11 ) ;
2003-07-10 02:10:59 +03:00
} else {
2003-07-10 13:24:47 +03:00
level = get_sbits ( & s - > gb , 7 ) ;
2003-07-10 02:10:59 +03:00
}
} else {
last = get_bits1 ( & s - > gb ) ;
run = get_bits ( & s - > gb , 6 ) ;
level = ( int8_t ) get_bits ( & s - > gb , 8 ) ;
if ( level = = - 128 ) {
2003-11-30 19:30:18 +02:00
if ( s - > codec_id = = CODEC_ID_RV10 ) {
2003-07-10 02:10:59 +03:00
/* XXX: should patch encoder too */
level = get_sbits ( & s - > gb , 12 ) ;
} else {
level = get_bits ( & s - > gb , 5 ) ;
level | = get_sbits ( & s - > gb , 6 ) < < 5 ;
}
2003-02-28 15:07:07 +02:00
}
2001-07-22 17:18:56 +03:00
}
} else {
run = rl - > table_run [ code ] ;
level = rl - > table_level [ code ] ;
last = code > = rl - > last ;
2001-08-04 03:46:50 +03:00
if ( get_bits1 ( & s - > gb ) )
2001-07-22 17:18:56 +03:00
level = - level ;
}
i + = run ;
2002-10-13 16:16:04 +03:00
if ( i > = 64 ) {
2003-11-29 10:37:51 +02:00
if ( s - > alt_inter_vlc & & rl = = & rl_inter & & ! s - > mb_intra ) {
2005-05-05 17:34:47 +03:00
//looks like a hack but no, it's the way its supposed to work ...
2003-11-29 10:37:51 +02:00
rl = & rl_intra_aic ;
i = 0 ;
s - > gb = gb ;
memset ( block , 0 , sizeof ( DCTELEM ) * 64 ) ;
goto retry ;
}
2005-01-02 01:02:09 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " run overflow at %dx%d i:%d \n " , s - > mb_x , s - > mb_y , s - > mb_intra ) ;
2001-07-22 17:18:56 +03:00
return - 1 ;
2002-10-13 16:16:04 +03:00
}
2002-02-18 21:33:27 +02:00
j = scan_table [ i ] ;
2001-07-22 17:18:56 +03:00
block [ j ] = level ;
if ( last )
break ;
i + + ;
}
2005-12-17 20:14:38 +02:00
not_coded :
2002-02-19 21:23:34 +02:00
if ( s - > mb_intra & & s - > h263_aic ) {
h263_pred_acdc ( s , block , n ) ;
2002-03-15 06:10:53 +02:00
i = 63 ;
2002-02-18 21:33:27 +02:00
}
2001-07-22 17:18:56 +03:00
s - > block_last_index [ n ] = i ;
return 0 ;
}
2003-01-27 01:09:12 +02:00
/**
* decodes the dc value .
* @ param n block index ( 0 - 3 are luma , 4 - 5 are chroma )
* @ param dir_ptr the prediction direction will be stored here
* @ return the quantized dc
*/
2002-06-02 15:15:17 +03:00
static inline int mpeg4_decode_dc ( MpegEncContext * s , int n , int * dir_ptr )
2001-07-22 17:18:56 +03:00
{
2004-05-05 03:14:22 +03:00
int level , code ;
2001-07-22 17:18:56 +03:00
2005-12-17 20:14:38 +02:00
if ( n < 4 )
2002-07-13 18:45:52 +03:00
code = get_vlc2 ( & s - > gb , dc_lum . table , DC_VLC_BITS , 1 ) ;
2005-12-17 20:14:38 +02:00
else
2002-07-13 18:45:52 +03:00
code = get_vlc2 ( & s - > gb , dc_chrom . table , DC_VLC_BITS , 1 ) ;
2002-06-02 15:15:17 +03:00
if ( code < 0 | | code > 9 /* && s->nbit<9 */ ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " illegal dc vlc \n " ) ;
2001-07-22 17:18:56 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
2001-07-22 17:18:56 +03:00
if ( code = = 0 ) {
level = 0 ;
} else {
2003-05-18 03:07:17 +03:00
if ( IS_3IV1 ) {
if ( code = = 1 )
level = 2 * get_bits1 ( & s - > gb ) - 1 ;
else {
if ( get_bits1 ( & s - > gb ) )
level = get_bits ( & s - > gb , code - 1 ) + ( 1 < < ( code - 1 ) ) ;
else
level = - get_bits ( & s - > gb , code - 1 ) - ( 1 < < ( code - 1 ) ) ;
}
} else {
level = get_xbits ( & s - > gb , code ) ;
}
2002-06-02 15:15:17 +03:00
if ( code > 8 ) {
if ( get_bits1 ( & s - > gb ) = = 0 ) { /* marker */
2002-10-13 16:16:04 +03:00
if ( s - > error_resilience > = 2 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " dc marker bit missing \n " ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
}
2002-06-02 15:15:17 +03:00
}
}
2001-07-22 17:18:56 +03:00
}
2004-05-05 03:14:22 +03:00
return ff_mpeg4_pred_dc ( s , n , level , dir_ptr , 0 ) ;
2001-07-22 17:18:56 +03:00
}
2002-06-02 15:15:17 +03:00
/**
2002-10-13 16:16:04 +03:00
* decodes a block .
* @ return < 0 if an error occured
2002-06-02 15:15:17 +03:00
*/
static inline int mpeg4_decode_block ( MpegEncContext * s , DCTELEM * block ,
2003-03-13 01:09:18 +02:00
int n , int coded , int intra , int rvlc )
2001-07-22 17:18:56 +03:00
{
2002-07-13 20:30:43 +03:00
int level , i , last , run ;
2001-07-22 17:18:56 +03:00
int dc_pred_dir ;
2002-07-21 04:34:05 +03:00
RLTable * rl ;
RL_VLC_ELEM * rl_vlc ;
2003-02-11 18:35:48 +02:00
const uint8_t * scan_table ;
2002-07-13 20:30:43 +03:00
int qmul , qadd ;
2001-07-22 17:18:56 +03:00
2003-03-13 01:09:18 +02:00
//Note intra & rvlc should be optimized away if this is inlined
2005-12-17 20:14:38 +02:00
2002-07-21 04:34:05 +03:00
if ( intra ) {
2006-04-28 20:29:07 +03:00
if ( s - > use_intra_dc_vlc ) {
2005-12-22 03:10:11 +02:00
/* DC coef */
2002-10-13 16:16:04 +03:00
if ( s - > partitioned_frame ) {
2002-06-02 15:15:17 +03:00
level = s - > dc_val [ 0 ] [ s - > block_index [ n ] ] ;
2003-05-14 18:12:13 +03:00
if ( n < 4 ) level = FASTDIV ( ( level + ( s - > y_dc_scale > > 1 ) ) , s - > y_dc_scale ) ;
else level = FASTDIV ( ( level + ( s - > c_dc_scale > > 1 ) ) , s - > c_dc_scale ) ;
2003-04-10 16:18:38 +03:00
dc_pred_dir = ( s - > pred_dir_table [ s - > mb_x + s - > mb_y * s - > mb_stride ] < < n ) & 32 ;
2002-06-02 15:15:17 +03:00
} else {
level = mpeg4_decode_dc ( s , n , & dc_pred_dir ) ;
if ( level < 0 )
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
2001-07-22 17:18:56 +03:00
block [ 0 ] = level ;
2002-07-13 20:30:43 +03:00
i = 0 ;
2003-10-12 17:01:53 +03:00
} else {
i = - 1 ;
2006-03-10 20:40:41 +02:00
ff_mpeg4_pred_dc ( s , n , 0 , & dc_pred_dir , 0 ) ;
2005-12-17 20:14:38 +02:00
}
if ( ! coded )
2001-07-22 17:18:56 +03:00
goto not_coded ;
2005-12-17 20:14:38 +02:00
if ( rvlc ) {
2003-03-13 01:09:18 +02:00
rl = & rvlc_rl_intra ;
rl_vlc = rvlc_rl_intra . rl_vlc [ 0 ] ;
} else {
rl = & rl_intra ;
rl_vlc = rl_intra . rl_vlc [ 0 ] ;
}
2002-10-03 01:56:58 +03:00
if ( s - > ac_pred ) {
2005-12-17 20:14:38 +02:00
if ( dc_pred_dir = = 0 )
2002-09-30 01:44:22 +03:00
scan_table = s - > intra_v_scantable . permutated ; /* left */
2001-07-22 17:18:56 +03:00
else
2002-09-30 01:44:22 +03:00
scan_table = s - > intra_h_scantable . permutated ; /* top */
2001-07-22 17:18:56 +03:00
} else {
2002-09-30 01:44:22 +03:00
scan_table = s - > intra_scantable . permutated ;
2001-07-22 17:18:56 +03:00
}
2002-07-13 20:30:43 +03:00
qmul = 1 ;
qadd = 0 ;
2001-07-22 17:18:56 +03:00
} else {
2002-07-13 20:30:43 +03:00
i = - 1 ;
2001-07-22 17:18:56 +03:00
if ( ! coded ) {
2002-07-13 20:30:43 +03:00
s - > block_last_index [ n ] = i ;
2001-07-22 17:18:56 +03:00
return 0 ;
}
2003-03-13 01:09:18 +02:00
if ( rvlc ) rl = & rvlc_rl_inter ;
else rl = & rl_inter ;
2005-12-17 20:14:38 +02:00
2002-10-03 01:56:58 +03:00
scan_table = s - > intra_scantable . permutated ;
2002-09-12 21:28:17 +03:00
2002-08-02 23:27:46 +03:00
if ( s - > mpeg_quant ) {
qmul = 1 ;
qadd = 0 ;
2005-12-17 20:14:38 +02:00
if ( rvlc ) {
rl_vlc = rvlc_rl_inter . rl_vlc [ 0 ] ;
2003-03-13 01:09:18 +02:00
} else {
2005-12-17 20:14:38 +02:00
rl_vlc = rl_inter . rl_vlc [ 0 ] ;
2003-03-13 01:09:18 +02:00
}
2002-08-02 23:27:46 +03:00
} else {
qmul = s - > qscale < < 1 ;
qadd = ( s - > qscale - 1 ) | 1 ;
2005-12-17 20:14:38 +02:00
if ( rvlc ) {
rl_vlc = rvlc_rl_inter . rl_vlc [ s - > qscale ] ;
2003-03-13 01:09:18 +02:00
} else {
2005-12-17 20:14:38 +02:00
rl_vlc = rl_inter . rl_vlc [ s - > qscale ] ;
2003-03-13 01:09:18 +02:00
}
2002-08-02 23:27:46 +03:00
}
2001-07-22 17:18:56 +03:00
}
2002-07-13 20:30:43 +03:00
{
OPEN_READER ( re , & s - > gb ) ;
2001-07-22 17:18:56 +03:00
for ( ; ; ) {
2002-07-13 20:30:43 +03:00
UPDATE_CACHE ( re , & s - > gb ) ;
2005-04-18 23:07:48 +03:00
GET_RL_VLC ( level , run , re , & s - > gb , rl_vlc , TEX_VLC_BITS , 2 , 0 ) ;
2002-07-13 20:30:43 +03:00
if ( level = = 0 ) {
2005-12-17 20:14:38 +02:00
/* escape */
2003-03-13 01:09:18 +02:00
if ( rvlc ) {
if ( SHOW_UBITS ( re , & s - > gb , 1 ) = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " 1. marker bit missing in rvlc esc \n " ) ;
2003-03-13 01:09:18 +02:00
return - 1 ;
} ; SKIP_CACHE ( re , & s - > gb , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-03-13 01:09:18 +02:00
last = SHOW_UBITS ( re , & s - > gb , 1 ) ; SKIP_CACHE ( re , & s - > gb , 1 ) ;
run = SHOW_UBITS ( re , & s - > gb , 6 ) ; LAST_SKIP_CACHE ( re , & s - > gb , 6 ) ;
SKIP_COUNTER ( re , & s - > gb , 1 + 1 + 6 ) ;
UPDATE_CACHE ( re , & s - > gb ) ;
2005-12-17 20:14:38 +02:00
2003-03-13 01:09:18 +02:00
if ( SHOW_UBITS ( re , & s - > gb , 1 ) = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " 2. marker bit missing in rvlc esc \n " ) ;
2003-03-13 01:09:18 +02:00
return - 1 ;
} ; SKIP_CACHE ( re , & s - > gb , 1 ) ;
2005-12-17 20:14:38 +02:00
2003-03-13 01:09:18 +02:00
level = SHOW_UBITS ( re , & s - > gb , 11 ) ; SKIP_CACHE ( re , & s - > gb , 11 ) ;
2005-12-17 20:14:38 +02:00
2003-03-13 01:09:18 +02:00
if ( SHOW_UBITS ( re , & s - > gb , 5 ) ! = 0x10 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " reverse esc missing \n " ) ;
2003-03-13 01:09:18 +02:00
return - 1 ;
} ; SKIP_CACHE ( re , & s - > gb , 5 ) ;
level = level * qmul + qadd ;
level = ( level ^ SHOW_SBITS ( re , & s - > gb , 1 ) ) - SHOW_SBITS ( re , & s - > gb , 1 ) ; LAST_SKIP_CACHE ( re , & s - > gb , 1 ) ;
SKIP_COUNTER ( re , & s - > gb , 1 + 11 + 5 + 1 ) ;
i + = run + 1 ;
2003-05-18 03:07:17 +03:00
if ( last ) i + = 192 ;
2003-03-13 01:09:18 +02:00
} else {
2002-07-13 20:30:43 +03:00
int cache ;
cache = GET_CACHE ( re , & s - > gb ) ;
2003-05-18 03:07:17 +03:00
2005-12-17 20:14:38 +02:00
if ( IS_3IV1 )
2003-05-18 03:07:17 +03:00
cache ^ = 0xC0000000 ;
2002-07-13 20:30:43 +03:00
if ( cache & 0x80000000 ) {
if ( cache & 0x40000000 ) {
2001-07-22 17:18:56 +03:00
/* third escape */
2002-07-13 20:30:43 +03:00
SKIP_CACHE ( re , & s - > gb , 2 ) ;
last = SHOW_UBITS ( re , & s - > gb , 1 ) ; SKIP_CACHE ( re , & s - > gb , 1 ) ;
run = SHOW_UBITS ( re , & s - > gb , 6 ) ; LAST_SKIP_CACHE ( re , & s - > gb , 6 ) ;
SKIP_COUNTER ( re , & s - > gb , 2 + 1 + 6 ) ;
UPDATE_CACHE ( re , & s - > gb ) ;
2003-05-18 03:07:17 +03:00
if ( IS_3IV1 ) {
level = SHOW_SBITS ( re , & s - > gb , 12 ) ; LAST_SKIP_BITS ( re , & s - > gb , 12 ) ;
} else {
if ( SHOW_UBITS ( re , & s - > gb , 1 ) = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " 1. marker bit missing in 3. esc \n " ) ;
2003-05-18 03:07:17 +03:00
return - 1 ;
} ; SKIP_CACHE ( re , & s - > gb , 1 ) ;
level = SHOW_SBITS ( re , & s - > gb , 12 ) ; SKIP_CACHE ( re , & s - > gb , 12 ) ;
if ( SHOW_UBITS ( re , & s - > gb , 1 ) = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " 2. marker bit missing in 3. esc \n " ) ;
2003-05-18 03:07:17 +03:00
return - 1 ;
} ; LAST_SKIP_CACHE ( re , & s - > gb , 1 ) ;
SKIP_COUNTER ( re , & s - > gb , 1 + 12 + 1 ) ;
}
2005-12-17 20:14:38 +02:00
2003-10-13 14:13:10 +03:00
#if 0
if ( s - > error_resilience > = FF_ER_COMPLIANT ) {
2002-06-02 15:15:17 +03:00
const int abs_level = ABS ( level ) ;
2003-10-13 14:13:10 +03:00
if ( abs_level < = MAX_LEVEL & & run < = MAX_RUN ) {
2002-06-18 03:46:02 +03:00
const int run1 = run - rl - > max_run [ last ] [ abs_level ] - 1 ;
2002-06-02 15:15:17 +03:00
if ( abs_level < = rl - > max_level [ last ] [ run ] ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " illegal 3. esc, vlc encoding possible \n " ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-06-02 15:15:17 +03:00
}
2002-12-04 13:47:24 +02:00
if ( s - > error_resilience > FF_ER_COMPLIANT ) {
if ( abs_level < = rl - > max_level [ last ] [ run ] * 2 ) {
2005-08-26 22:05:44 +03:00
av_log ( s - > avctx , AV_LOG_ERROR , " illegal 3. esc, esc 1 encoding possible \n " ) ;
2002-12-04 13:47:24 +02:00
return - 1 ;
}
if ( run1 > = 0 & & abs_level < = rl - > max_level [ last ] [ run1 ] ) {
2005-08-26 22:05:44 +03:00
av_log ( s - > avctx , AV_LOG_ERROR , " illegal 3. esc, esc 2 encoding possible \n " ) ;
2002-12-04 13:47:24 +02:00
return - 1 ;
}
2002-06-02 15:15:17 +03:00
}
}
}
# endif
2005-12-22 03:10:11 +02:00
if ( level > 0 ) level = level * qmul + qadd ;
2002-07-13 20:30:43 +03:00
else level = level * qmul - qadd ;
2004-06-15 02:41:41 +03:00
if ( ( unsigned ) ( level + 2048 ) > 4095 ) {
if ( s - > error_resilience > FF_ER_COMPLIANT ) {
if ( level > 2560 | | level < - 2560 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " |level| overflow in 3. esc, qp=%d \n " , s - > qscale ) ;
return - 1 ;
}
}
level = level < 0 ? - 2048 : 2047 ;
}
2002-07-13 20:30:43 +03:00
i + = run + 1 ;
if ( last ) i + = 192 ;
2001-07-22 17:18:56 +03:00
} else {
/* second escape */
2002-07-13 20:30:43 +03:00
# if MIN_CACHE_BITS < 20
LAST_SKIP_BITS ( re , & s - > gb , 2 ) ;
UPDATE_CACHE ( re , & s - > gb ) ;
# else
SKIP_BITS ( re , & s - > gb , 2 ) ;
# endif
2005-04-18 23:07:48 +03:00
GET_RL_VLC ( level , run , re , & s - > gb , rl_vlc , TEX_VLC_BITS , 2 , 1 ) ;
2002-07-13 20:30:43 +03:00
i + = run + rl - > max_run [ run > > 7 ] [ level / qmul ] + 1 ; //FIXME opt indexing
level = ( level ^ SHOW_SBITS ( re , & s - > gb , 1 ) ) - SHOW_SBITS ( re , & s - > gb , 1 ) ;
LAST_SKIP_BITS ( re , & s - > gb , 1 ) ;
2001-07-22 17:18:56 +03:00
}
} else {
/* first escape */
2002-07-13 20:30:43 +03:00
# if MIN_CACHE_BITS < 19
LAST_SKIP_BITS ( re , & s - > gb , 1 ) ;
UPDATE_CACHE ( re , & s - > gb ) ;
# else
SKIP_BITS ( re , & s - > gb , 1 ) ;
# endif
2005-04-18 23:07:48 +03:00
GET_RL_VLC ( level , run , re , & s - > gb , rl_vlc , TEX_VLC_BITS , 2 , 1 ) ;
2002-07-13 20:30:43 +03:00
i + = run ;
level = level + rl - > max_level [ run > > 7 ] [ ( run - 1 ) & 63 ] * qmul ; //FIXME opt indexing
level = ( level ^ SHOW_SBITS ( re , & s - > gb , 1 ) ) - SHOW_SBITS ( re , & s - > gb , 1 ) ;
LAST_SKIP_BITS ( re , & s - > gb , 1 ) ;
2001-07-22 17:18:56 +03:00
}
2003-03-13 01:09:18 +02:00
}
2001-07-22 17:18:56 +03:00
} else {
2002-07-13 20:30:43 +03:00
i + = run ;
level = ( level ^ SHOW_SBITS ( re , & s - > gb , 1 ) ) - SHOW_SBITS ( re , & s - > gb , 1 ) ;
LAST_SKIP_BITS ( re , & s - > gb , 1 ) ;
}
if ( i > 62 ) {
i - = 192 ;
if ( i & ( ~ 63 ) ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " ac-tex damaged at %d %d \n " , s - > mb_x , s - > mb_y ) ;
2002-10-13 16:16:04 +03:00
return - 1 ;
2002-07-13 20:30:43 +03:00
}
block [ scan_table [ i ] ] = level ;
2001-07-22 17:18:56 +03:00
break ;
2002-07-13 20:30:43 +03:00
}
block [ scan_table [ i ] ] = level ;
2001-07-22 17:18:56 +03:00
}
2002-07-13 20:30:43 +03:00
CLOSE_READER ( re , & s - > gb ) ;
}
2001-07-22 17:18:56 +03:00
not_coded :
2003-10-12 17:01:53 +03:00
if ( intra ) {
2006-04-28 20:29:07 +03:00
if ( ! s - > use_intra_dc_vlc ) {
2004-05-05 03:14:22 +03:00
block [ 0 ] = ff_mpeg4_pred_dc ( s , n , block [ 0 ] , & dc_pred_dir , 0 ) ;
2005-12-17 20:14:38 +02:00
2006-03-10 20:37:18 +02:00
i - = i > > 31 ; //if(i == -1) i=0;
2003-10-12 17:01:53 +03:00
}
2001-07-22 17:18:56 +03:00
mpeg4_pred_ac ( s , block , n , dc_pred_dir ) ;
if ( s - > ac_pred ) {
2002-07-13 20:30:43 +03:00
i = 63 ; /* XXX: not optimal */
2001-07-22 17:18:56 +03:00
}
}
2002-07-13 20:30:43 +03:00
s - > block_last_index [ n ] = i ;
2001-07-22 17:18:56 +03:00
return 0 ;
}
/* most is hardcoded. should extend to handle all h263 streams */
int h263_decode_picture_header ( MpegEncContext * s )
{
2003-05-22 17:12:22 +03:00
int format , width , height , i ;
uint32_t startcode ;
2005-12-17 20:14:38 +02:00
2003-05-22 17:12:22 +03:00
align_get_bits ( & s - > gb ) ;
startcode = get_bits ( & s - > gb , 22 - 8 ) ;
2001-07-22 17:18:56 +03:00
2003-08-01 14:00:03 +03:00
for ( i = s - > gb . size_in_bits - get_bits_count ( & s - > gb ) ; i > 24 ; i - = 8 ) {
2003-05-22 17:12:22 +03:00
startcode = ( ( startcode < < 8 ) | get_bits ( & s - > gb , 8 ) ) & 0x003FFFFF ;
2005-12-17 20:14:38 +02:00
2003-05-22 17:12:22 +03:00
if ( startcode = = 0x20 )
break ;
}
2005-12-17 20:14:38 +02:00
2003-05-22 17:12:22 +03:00
if ( startcode ! = 0x20 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Bad picture start code \n " ) ;
2001-07-22 17:18:56 +03:00
return - 1 ;
2002-05-03 21:11:23 +03:00
}
/* temporal reference */
2004-03-06 14:33:56 +02:00
i = get_bits ( & s - > gb , 8 ) ; /* picture timestamp */
if ( ( s - > picture_number & ~ 0xFF ) + i < s - > picture_number )
i + = 256 ;
2005-09-19 15:03:51 +03:00
s - > current_picture_ptr - > pts =
2004-03-06 14:33:56 +02:00
s - > picture_number = ( s - > picture_number & ~ 0xFF ) + i ;
2002-05-03 21:11:23 +03:00
2005-12-17 20:14:38 +02:00
/* PTYPE starts here */
2002-05-03 21:11:23 +03:00
if ( get_bits1 ( & s - > gb ) ! = 1 ) {
/* marker */
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Bad marker \n " ) ;
2002-05-03 21:11:23 +03:00
return - 1 ;
}
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Bad H263 id \n " ) ;
2005-12-22 03:10:11 +02:00
return - 1 ; /* h263 id */
2002-05-03 21:11:23 +03:00
}
2005-12-22 03:10:11 +02:00
skip_bits1 ( & s - > gb ) ; /* split screen off */
skip_bits1 ( & s - > gb ) ; /* camera off */
skip_bits1 ( & s - > gb ) ; /* freeze picture release off */
2001-07-22 17:18:56 +03:00
format = get_bits ( & s - > gb , 3 ) ;
2002-05-03 21:11:23 +03:00
/*
0 forbidden
1 sub - QCIF
10 QCIF
2005-12-22 03:10:11 +02:00
7 extended PTYPE ( PLUSPTYPE )
2002-05-03 21:11:23 +03:00
*/
2001-07-22 17:18:56 +03:00
2001-11-17 23:14:54 +02:00
if ( format ! = 7 & & format ! = 6 ) {
2001-07-22 17:18:56 +03:00
s - > h263_plus = 0 ;
/* H.263v1 */
width = h263_format [ format ] [ 0 ] ;
height = h263_format [ format ] [ 1 ] ;
if ( ! width )
return - 1 ;
2005-12-17 20:14:38 +02:00
2001-08-04 03:46:50 +03:00
s - > pict_type = I_TYPE + get_bits1 ( & s - > gb ) ;
2001-07-22 17:18:56 +03:00
2005-12-17 20:14:38 +02:00
s - > h263_long_vectors = get_bits1 ( & s - > gb ) ;
2001-07-22 17:18:56 +03:00
2002-05-03 21:11:23 +03:00
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " H263 SAC not supported \n " ) ;
2005-12-22 03:10:11 +02:00
return - 1 ; /* SAC: off */
2002-05-03 21:11:23 +03:00
}
2003-11-28 23:31:20 +02:00
s - > obmc = get_bits1 ( & s - > gb ) ; /* Advanced prediction mode */
s - > unrestricted_mv = s - > h263_long_vectors | | s - > obmc ;
2005-12-17 20:14:38 +02:00
2002-05-03 21:11:23 +03:00
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " H263 PB frame not supported \n " ) ;
2005-12-22 03:10:11 +02:00
return - 1 ; /* not PB frame */
2002-05-03 21:11:23 +03:00
}
2003-12-01 17:23:14 +02:00
s - > chroma_qscale = s - > qscale = get_bits ( & s - > gb , 5 ) ;
2005-12-22 03:10:11 +02:00
skip_bits1 ( & s - > gb ) ; /* Continuous Presence Multipoint mode: off */
2003-08-01 14:00:03 +03:00
s - > width = width ;
s - > height = height ;
2004-03-06 14:33:56 +02:00
s - > avctx - > sample_aspect_ratio = ( AVRational ) { 12 , 11 } ;
2005-05-01 00:43:59 +03:00
s - > avctx - > time_base = ( AVRational ) { 1001 , 30000 } ;
2001-07-22 17:18:56 +03:00
} else {
2001-11-17 23:14:54 +02:00
int ufep ;
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
/* H.263v2 */
2001-11-17 23:14:54 +02:00
s - > h263_plus = 1 ;
ufep = get_bits ( & s - > gb , 3 ) ; /* Update Full Extended PTYPE */
2002-05-03 21:11:23 +03:00
2005-12-17 20:14:38 +02:00
/* ufep other than 0 and 1 are reserved */
2001-11-17 23:14:54 +02:00
if ( ufep = = 1 ) {
2005-12-17 20:14:38 +02:00
/* OPPTYPE */
2001-11-17 23:14:54 +02:00
format = get_bits ( & s - > gb , 3 ) ;
2002-05-03 21:11:23 +03:00
dprintf ( " ufep=1, format: %d \n " , format ) ;
2004-03-11 00:11:49 +02:00
s - > custom_pcf = get_bits1 ( & s - > gb ) ;
2003-02-28 15:07:07 +02:00
s - > umvplus = get_bits ( & s - > gb , 1 ) ; /* Unrestricted Motion Vector */
2003-05-22 17:12:22 +03:00
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-12-01 17:23:14 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Syntax-based Arithmetic Coding (SAC) not supported \n " ) ;
2003-05-22 17:12:22 +03:00
}
2003-12-01 17:23:14 +02:00
s - > obmc = get_bits1 ( & s - > gb ) ; /* Advanced prediction mode */
s - > h263_aic = get_bits1 ( & s - > gb ) ; /* Advanced Intra Coding (AIC) */
s - > loop_filter = get_bits1 ( & s - > gb ) ;
s - > unrestricted_mv = s - > umvplus | | s - > obmc | | s - > loop_filter ;
2005-12-17 20:14:38 +02:00
2003-12-07 03:33:45 +02:00
s - > h263_slice_structured = get_bits1 ( & s - > gb ) ;
2003-05-22 17:12:22 +03:00
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Reference Picture Selection not supported \n " ) ;
2003-05-22 17:12:22 +03:00
}
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Independent Segment Decoding not supported \n " ) ;
2003-05-22 17:12:22 +03:00
}
2003-11-29 10:37:51 +02:00
s - > alt_inter_vlc = get_bits1 ( & s - > gb ) ;
2003-11-30 16:35:35 +02:00
s - > modified_quant = get_bits1 ( & s - > gb ) ;
2003-12-01 17:23:14 +02:00
if ( s - > modified_quant )
s - > chroma_qscale_table = ff_h263_chroma_qscale_table ;
2005-12-17 20:14:38 +02:00
2003-05-22 17:12:22 +03:00
skip_bits ( & s - > gb , 1 ) ; /* Prevent start code emulation */
2002-05-03 21:11:23 +03:00
2001-11-17 23:14:54 +02:00
skip_bits ( & s - > gb , 3 ) ; /* Reserved */
2002-05-03 21:11:23 +03:00
} else if ( ufep ! = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Bad UFEP type (%d) \n " , ufep ) ;
2001-11-17 23:14:54 +02:00
return - 1 ;
2002-05-03 21:11:23 +03:00
}
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
/* MPPTYPE */
2003-12-04 20:34:47 +02:00
s - > pict_type = get_bits ( & s - > gb , 3 ) ;
switch ( s - > pict_type ) {
case 0 : s - > pict_type = I_TYPE ; break ;
case 1 : s - > pict_type = P_TYPE ; break ;
case 3 : s - > pict_type = B_TYPE ; break ;
case 7 : s - > pict_type = I_TYPE ; break ; //ZYGO
default :
2001-07-22 17:18:56 +03:00
return - 1 ;
2003-12-04 20:34:47 +02:00
}
2002-02-22 05:35:41 +02:00
skip_bits ( & s - > gb , 2 ) ;
s - > no_rounding = get_bits1 ( & s - > gb ) ;
skip_bits ( & s - > gb , 4 ) ;
2005-12-17 20:14:38 +02:00
2001-08-29 02:32:34 +03:00
/* Get the picture dimensions */
2001-11-17 23:14:54 +02:00
if ( ufep ) {
if ( format = = 6 ) {
/* Custom Picture Format (CPFMT) */
2002-05-03 21:11:23 +03:00
s - > aspect_ratio_info = get_bits ( & s - > gb , 4 ) ;
dprintf ( " aspect: %d \n " , s - > aspect_ratio_info ) ;
/* aspect ratios:
0 - forbidden
1 - 1 : 1
2 - 12 : 11 ( CIF 4 : 3 )
3 - 10 : 11 ( 525 - type 4 : 3 )
4 - 16 : 11 ( CIF 16 : 9 )
5 - 40 : 33 ( 525 - type 16 : 9 )
6 - 14 - reserved
*/
2001-11-17 23:14:54 +02:00
width = ( get_bits ( & s - > gb , 9 ) + 1 ) * 4 ;
skip_bits1 ( & s - > gb ) ;
height = get_bits ( & s - > gb , 9 ) * 4 ;
2002-05-03 21:11:23 +03:00
dprintf ( " \n H.263+ Custom picture: %dx%d \n " , width , height ) ;
2002-09-13 22:31:32 +03:00
if ( s - > aspect_ratio_info = = FF_ASPECT_EXTENDED ) {
2002-05-03 21:11:23 +03:00
/* aspected dimensions */
2003-10-20 23:23:46 +03:00
s - > avctx - > sample_aspect_ratio . num = get_bits ( & s - > gb , 8 ) ;
s - > avctx - > sample_aspect_ratio . den = get_bits ( & s - > gb , 8 ) ;
2002-11-25 11:23:19 +02:00
} else {
2003-10-20 23:23:46 +03:00
s - > avctx - > sample_aspect_ratio = pixel_aspect [ s - > aspect_ratio_info ] ;
2002-05-03 21:11:23 +03:00
}
} else {
2001-11-17 23:14:54 +02:00
width = h263_format [ format ] [ 0 ] ;
height = h263_format [ format ] [ 1 ] ;
2004-03-06 14:33:56 +02:00
s - > avctx - > sample_aspect_ratio = ( AVRational ) { 12 , 11 } ;
2001-11-17 23:14:54 +02:00
}
if ( ( width = = 0 ) | | ( height = = 0 ) )
return - 1 ;
s - > width = width ;
s - > height = height ;
2004-03-11 00:11:49 +02:00
if ( s - > custom_pcf ) {
int gcd ;
2005-05-01 00:43:59 +03:00
s - > avctx - > time_base . den = 1800000 ;
s - > avctx - > time_base . num = 1000 + get_bits1 ( & s - > gb ) ;
s - > avctx - > time_base . num * = get_bits ( & s - > gb , 7 ) ;
if ( s - > avctx - > time_base . num = = 0 ) {
2004-03-11 00:11:49 +02:00
av_log ( s , AV_LOG_ERROR , " zero framerate \n " ) ;
return - 1 ;
}
2005-05-01 00:43:59 +03:00
gcd = ff_gcd ( s - > avctx - > time_base . den , s - > avctx - > time_base . num ) ;
s - > avctx - > time_base . den / = gcd ;
s - > avctx - > time_base . num / = gcd ;
// av_log(s->avctx, AV_LOG_DEBUG, "%d/%d\n", s->avctx->time_base.den, s->avctx->time_base.num);
2004-03-11 00:11:49 +02:00
} else {
2005-05-01 00:43:59 +03:00
s - > avctx - > time_base = ( AVRational ) { 1001 , 30000 } ;
2004-03-11 00:11:49 +02:00
}
}
2005-12-17 20:14:38 +02:00
2004-03-11 00:11:49 +02:00
if ( s - > custom_pcf ) {
skip_bits ( & s - > gb , 2 ) ; //extended Temporal reference
}
if ( ufep ) {
2003-02-28 15:07:07 +02:00
if ( s - > umvplus ) {
if ( get_bits1 ( & s - > gb ) = = 0 ) /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */
2005-12-17 20:14:38 +02:00
skip_bits1 ( & s - > gb ) ;
2001-11-17 23:14:54 +02:00
}
2003-12-07 03:33:45 +02:00
if ( s - > h263_slice_structured ) {
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " rectangular slices not supported \n " ) ;
}
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " unordered slices not supported \n " ) ;
}
}
2001-08-29 02:32:34 +03:00
}
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
s - > qscale = get_bits ( & s - > gb , 5 ) ;
}
2003-12-09 15:47:08 +02:00
2004-03-19 00:45:37 +02:00
s - > mb_width = ( s - > width + 15 ) / 16 ;
s - > mb_height = ( s - > height + 15 ) / 16 ;
s - > mb_num = s - > mb_width * s - > mb_height ;
2001-07-22 17:18:56 +03:00
/* PEI */
2001-08-04 03:46:50 +03:00
while ( get_bits1 ( & s - > gb ) ! = 0 ) {
skip_bits ( & s - > gb , 8 ) ;
2001-07-22 17:18:56 +03:00
}
2004-03-19 00:45:37 +02:00
2003-12-09 15:47:08 +02:00
if ( s - > h263_slice_structured ) {
if ( get_bits1 ( & s - > gb ) ! = 1 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " SEPB1 marker missing \n " ) ;
return - 1 ;
}
ff_h263_decode_mba ( s ) ;
if ( get_bits1 ( & s - > gb ) ! = 1 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " SEPB2 marker missing \n " ) ;
return - 1 ;
}
}
2001-07-22 17:18:56 +03:00
s - > f_code = 1 ;
2005-12-17 20:14:38 +02:00
2002-06-18 03:46:02 +03:00
if ( s - > h263_aic ) {
2005-12-17 20:14:38 +02:00
s - > y_dc_scale_table =
2003-11-30 16:35:35 +02:00
s - > c_dc_scale_table = ff_aic_dc_scale_table ;
2002-06-18 03:46:02 +03:00
} else {
s - > y_dc_scale_table =
s - > c_dc_scale_table = ff_mpeg1_dc_scale_table ;
}
2003-05-22 17:12:22 +03:00
if ( s - > avctx - > debug & FF_DEBUG_PICT_INFO ) {
2005-12-17 20:14:38 +02:00
av_log ( s - > avctx , AV_LOG_DEBUG , " qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s %d/%d \n " ,
2003-05-22 17:12:22 +03:00
s - > qscale , av_get_pict_type_char ( s - > pict_type ) ,
s - > gb . size_in_bits , 1 - s - > no_rounding ,
2003-11-28 23:31:20 +02:00
s - > obmc ? " AP " : " " ,
s - > umvplus ? " UMV " : " " ,
s - > h263_long_vectors ? " LONG " : " " ,
s - > h263_plus ? " + " : " " ,
2003-11-29 10:37:51 +02:00
s - > h263_aic ? " AIC " : " " ,
2003-11-30 16:35:35 +02:00
s - > alt_inter_vlc ? " AIV " : " " ,
2003-12-01 17:23:14 +02:00
s - > modified_quant ? " MQ " : " " ,
2003-12-07 03:33:45 +02:00
s - > loop_filter ? " LOOP " : " " ,
2004-03-11 00:11:49 +02:00
s - > h263_slice_structured ? " SS " : " " ,
2005-05-01 00:43:59 +03:00
s - > avctx - > time_base . den , s - > avctx - > time_base . num
2005-12-17 20:14:38 +02:00
) ;
2003-05-22 17:12:22 +03:00
}
2003-10-29 19:30:13 +02:00
# if 1
if ( s - > pict_type = = I_TYPE & & s - > avctx - > codec_tag = = ff_get_fourcc ( " ZYGO " ) ) {
int i , j ;
2003-11-03 15:26:22 +02:00
for ( i = 0 ; i < 85 ; i + + ) av_log ( s - > avctx , AV_LOG_DEBUG , " %d " , get_bits1 ( & s - > gb ) ) ;
av_log ( s - > avctx , AV_LOG_DEBUG , " \n " ) ;
2003-10-29 19:30:13 +02:00
for ( i = 0 ; i < 13 ; i + + ) {
for ( j = 0 ; j < 3 ; j + + ) {
int v = get_bits ( & s - > gb , 8 ) ;
v | = get_sbits ( & s - > gb , 8 ) < < 8 ;
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_DEBUG , " %5d " , v ) ;
2003-10-29 19:30:13 +02:00
}
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_DEBUG , " \n " ) ;
2003-10-29 19:30:13 +02:00
}
2003-11-03 15:26:22 +02:00
for ( i = 0 ; i < 50 ; i + + ) av_log ( s - > avctx , AV_LOG_DEBUG , " %d " , get_bits1 ( & s - > gb ) ) ;
2003-10-29 19:30:13 +02:00
}
# endif
2003-05-22 17:12:22 +03:00
2001-07-22 17:18:56 +03:00
return 0 ;
}
2004-04-02 19:21:55 +03:00
static void mpeg4_decode_sprite_trajectory ( MpegEncContext * s , GetBitContext * gb )
2002-03-07 15:27:15 +02:00
{
int i ;
int a = 2 < < s - > sprite_warping_accuracy ;
int rho = 3 - s - > sprite_warping_accuracy ;
int r = 16 / a ;
const int vop_ref [ 4 ] [ 2 ] = { { 0 , 0 } , { s - > width , 0 } , { 0 , s - > height } , { s - > width , s - > height } } ; // only true for rectangle shapes
int d [ 4 ] [ 2 ] = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } , { 0 , 0 } } ;
int sprite_ref [ 4 ] [ 2 ] ;
int virtual_ref [ 2 ] [ 2 ] ;
2002-10-16 22:55:49 +03:00
int w2 , h2 , w3 , h3 ;
2002-03-07 15:27:15 +02:00
int alpha = 0 , beta = 0 ;
int w = s - > width ;
int h = s - > height ;
2002-10-16 22:55:49 +03:00
int min_ab ;
2002-03-07 15:27:15 +02:00
for ( i = 0 ; i < s - > num_sprite_warping_points ; i + + ) {
int length ;
int x = 0 , y = 0 ;
2006-01-08 23:19:39 +02:00
length = get_vlc2 ( gb , sprite_trajectory . table , SPRITE_TRAJ_VLC_BITS , 3 ) ;
2002-03-07 15:27:15 +02:00
if ( length ) {
2004-04-02 19:21:55 +03:00
x = get_xbits ( gb , length ) ;
2002-03-07 15:27:15 +02:00
}
2004-04-02 19:21:55 +03:00
if ( ! ( s - > divx_version = = 500 & & s - > divx_build = = 413 ) ) skip_bits1 ( gb ) ; /* marker bit */
2005-12-17 20:14:38 +02:00
2006-01-08 23:19:39 +02:00
length = get_vlc2 ( gb , sprite_trajectory . table , SPRITE_TRAJ_VLC_BITS , 3 ) ;
2002-03-07 15:27:15 +02:00
if ( length ) {
2004-04-02 19:21:55 +03:00
y = get_xbits ( gb , length ) ;
2002-03-07 15:27:15 +02:00
}
2004-04-02 19:21:55 +03:00
skip_bits1 ( gb ) ; /* marker bit */
2002-03-09 15:01:16 +02:00
//printf("%d %d %d %d\n", x, y, i, s->sprite_warping_accuracy);
2002-03-07 15:27:15 +02:00
d [ i ] [ 0 ] = x ;
d [ i ] [ 1 ] = y ;
}
while ( ( 1 < < alpha ) < w ) alpha + + ;
while ( ( 1 < < beta ) < h ) beta + + ; // there seems to be a typo in the mpeg4 std for the definition of w' and h'
w2 = 1 < < alpha ;
h2 = 1 < < beta ;
2005-05-05 17:34:47 +03:00
// Note, the 4th point isn't used for GMC
2002-03-13 00:54:25 +02:00
if ( s - > divx_version = = 500 & & s - > divx_build = = 413 ) {
sprite_ref [ 0 ] [ 0 ] = a * vop_ref [ 0 ] [ 0 ] + d [ 0 ] [ 0 ] ;
sprite_ref [ 0 ] [ 1 ] = a * vop_ref [ 0 ] [ 1 ] + d [ 0 ] [ 1 ] ;
sprite_ref [ 1 ] [ 0 ] = a * vop_ref [ 1 ] [ 0 ] + d [ 0 ] [ 0 ] + d [ 1 ] [ 0 ] ;
sprite_ref [ 1 ] [ 1 ] = a * vop_ref [ 1 ] [ 1 ] + d [ 0 ] [ 1 ] + d [ 1 ] [ 1 ] ;
sprite_ref [ 2 ] [ 0 ] = a * vop_ref [ 2 ] [ 0 ] + d [ 0 ] [ 0 ] + d [ 2 ] [ 0 ] ;
sprite_ref [ 2 ] [ 1 ] = a * vop_ref [ 2 ] [ 1 ] + d [ 0 ] [ 1 ] + d [ 2 ] [ 1 ] ;
} else {
sprite_ref [ 0 ] [ 0 ] = ( a > > 1 ) * ( 2 * vop_ref [ 0 ] [ 0 ] + d [ 0 ] [ 0 ] ) ;
sprite_ref [ 0 ] [ 1 ] = ( a > > 1 ) * ( 2 * vop_ref [ 0 ] [ 1 ] + d [ 0 ] [ 1 ] ) ;
sprite_ref [ 1 ] [ 0 ] = ( a > > 1 ) * ( 2 * vop_ref [ 1 ] [ 0 ] + d [ 0 ] [ 0 ] + d [ 1 ] [ 0 ] ) ;
sprite_ref [ 1 ] [ 1 ] = ( a > > 1 ) * ( 2 * vop_ref [ 1 ] [ 1 ] + d [ 0 ] [ 1 ] + d [ 1 ] [ 1 ] ) ;
sprite_ref [ 2 ] [ 0 ] = ( a > > 1 ) * ( 2 * vop_ref [ 2 ] [ 0 ] + d [ 0 ] [ 0 ] + d [ 2 ] [ 0 ] ) ;
sprite_ref [ 2 ] [ 1 ] = ( a > > 1 ) * ( 2 * vop_ref [ 2 ] [ 1 ] + d [ 0 ] [ 1 ] + d [ 2 ] [ 1 ] ) ;
}
2002-03-07 15:27:15 +02:00
/* sprite_ref[3][0]= (a>>1)*(2*vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]);
sprite_ref [ 3 ] [ 1 ] = ( a > > 1 ) * ( 2 * vop_ref [ 3 ] [ 1 ] + d [ 0 ] [ 1 ] + d [ 1 ] [ 1 ] + d [ 2 ] [ 1 ] + d [ 3 ] [ 1 ] ) ; */
2005-12-17 20:14:38 +02:00
2002-03-07 15:27:15 +02:00
// this is mostly identical to the mpeg4 std (and is totally unreadable because of that ...)
// perhaps it should be reordered to be more readable ...
// the idea behind this virtual_ref mess is to be able to use shifts later per pixel instead of divides
// so the distance between points is converted from w&h based to w2&h2 based which are of the 2^x form
2005-12-17 20:14:38 +02:00
virtual_ref [ 0 ] [ 0 ] = 16 * ( vop_ref [ 0 ] [ 0 ] + w2 )
2002-05-04 21:58:07 +03:00
+ ROUNDED_DIV ( ( ( w - w2 ) * ( r * sprite_ref [ 0 ] [ 0 ] - 16 * vop_ref [ 0 ] [ 0 ] ) + w2 * ( r * sprite_ref [ 1 ] [ 0 ] - 16 * vop_ref [ 1 ] [ 0 ] ) ) , w ) ;
2005-12-17 20:14:38 +02:00
virtual_ref [ 0 ] [ 1 ] = 16 * vop_ref [ 0 ] [ 1 ]
2002-05-04 21:58:07 +03:00
+ ROUNDED_DIV ( ( ( w - w2 ) * ( r * sprite_ref [ 0 ] [ 1 ] - 16 * vop_ref [ 0 ] [ 1 ] ) + w2 * ( r * sprite_ref [ 1 ] [ 1 ] - 16 * vop_ref [ 1 ] [ 1 ] ) ) , w ) ;
2005-12-17 20:14:38 +02:00
virtual_ref [ 1 ] [ 0 ] = 16 * vop_ref [ 0 ] [ 0 ]
2002-05-04 21:58:07 +03:00
+ ROUNDED_DIV ( ( ( h - h2 ) * ( r * sprite_ref [ 0 ] [ 0 ] - 16 * vop_ref [ 0 ] [ 0 ] ) + h2 * ( r * sprite_ref [ 2 ] [ 0 ] - 16 * vop_ref [ 2 ] [ 0 ] ) ) , h ) ;
2005-12-17 20:14:38 +02:00
virtual_ref [ 1 ] [ 1 ] = 16 * ( vop_ref [ 0 ] [ 1 ] + h2 )
2002-05-04 21:58:07 +03:00
+ ROUNDED_DIV ( ( ( h - h2 ) * ( r * sprite_ref [ 0 ] [ 1 ] - 16 * vop_ref [ 0 ] [ 1 ] ) + h2 * ( r * sprite_ref [ 2 ] [ 1 ] - 16 * vop_ref [ 2 ] [ 1 ] ) ) , h ) ;
2005-12-17 20:14:38 +02:00
2002-03-07 15:27:15 +02:00
switch ( s - > num_sprite_warping_points )
{
case 0 :
s - > sprite_offset [ 0 ] [ 0 ] = 0 ;
s - > sprite_offset [ 0 ] [ 1 ] = 0 ;
s - > sprite_offset [ 1 ] [ 0 ] = 0 ;
s - > sprite_offset [ 1 ] [ 1 ] = 0 ;
2002-10-16 22:55:49 +03:00
s - > sprite_delta [ 0 ] [ 0 ] = a ;
s - > sprite_delta [ 0 ] [ 1 ] = 0 ;
s - > sprite_delta [ 1 ] [ 0 ] = 0 ;
s - > sprite_delta [ 1 ] [ 1 ] = a ;
s - > sprite_shift [ 0 ] = 0 ;
s - > sprite_shift [ 1 ] = 0 ;
2002-03-07 15:27:15 +02:00
break ;
case 1 : //GMC only
s - > sprite_offset [ 0 ] [ 0 ] = sprite_ref [ 0 ] [ 0 ] - a * vop_ref [ 0 ] [ 0 ] ;
s - > sprite_offset [ 0 ] [ 1 ] = sprite_ref [ 0 ] [ 1 ] - a * vop_ref [ 0 ] [ 1 ] ;
s - > sprite_offset [ 1 ] [ 0 ] = ( ( sprite_ref [ 0 ] [ 0 ] > > 1 ) | ( sprite_ref [ 0 ] [ 0 ] & 1 ) ) - a * ( vop_ref [ 0 ] [ 0 ] / 2 ) ;
s - > sprite_offset [ 1 ] [ 1 ] = ( ( sprite_ref [ 0 ] [ 1 ] > > 1 ) | ( sprite_ref [ 0 ] [ 1 ] & 1 ) ) - a * ( vop_ref [ 0 ] [ 1 ] / 2 ) ;
2002-10-16 22:55:49 +03:00
s - > sprite_delta [ 0 ] [ 0 ] = a ;
s - > sprite_delta [ 0 ] [ 1 ] = 0 ;
s - > sprite_delta [ 1 ] [ 0 ] = 0 ;
s - > sprite_delta [ 1 ] [ 1 ] = a ;
s - > sprite_shift [ 0 ] = 0 ;
s - > sprite_shift [ 1 ] = 0 ;
2002-03-07 15:27:15 +02:00
break ;
case 2 :
s - > sprite_offset [ 0 ] [ 0 ] = ( sprite_ref [ 0 ] [ 0 ] < < ( alpha + rho ) )
2002-10-16 22:55:49 +03:00
+ ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 0 ] [ 0 ] ) * ( - vop_ref [ 0 ] [ 0 ] )
+ ( r * sprite_ref [ 0 ] [ 1 ] - virtual_ref [ 0 ] [ 1 ] ) * ( - vop_ref [ 0 ] [ 1 ] )
+ ( 1 < < ( alpha + rho - 1 ) ) ;
2002-03-07 15:27:15 +02:00
s - > sprite_offset [ 0 ] [ 1 ] = ( sprite_ref [ 0 ] [ 1 ] < < ( alpha + rho ) )
2002-10-16 22:55:49 +03:00
+ ( - r * sprite_ref [ 0 ] [ 1 ] + virtual_ref [ 0 ] [ 1 ] ) * ( - vop_ref [ 0 ] [ 0 ] )
+ ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 0 ] [ 0 ] ) * ( - vop_ref [ 0 ] [ 1 ] )
+ ( 1 < < ( alpha + rho - 1 ) ) ;
s - > sprite_offset [ 1 ] [ 0 ] = ( ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 0 ] [ 0 ] ) * ( - 2 * vop_ref [ 0 ] [ 0 ] + 1 )
+ ( r * sprite_ref [ 0 ] [ 1 ] - virtual_ref [ 0 ] [ 1 ] ) * ( - 2 * vop_ref [ 0 ] [ 1 ] + 1 )
2005-12-17 20:14:38 +02:00
+ 2 * w2 * r * sprite_ref [ 0 ] [ 0 ]
- 16 * w2
2002-10-16 22:55:49 +03:00
+ ( 1 < < ( alpha + rho + 1 ) ) ) ;
2005-12-17 20:14:38 +02:00
s - > sprite_offset [ 1 ] [ 1 ] = ( ( - r * sprite_ref [ 0 ] [ 1 ] + virtual_ref [ 0 ] [ 1 ] ) * ( - 2 * vop_ref [ 0 ] [ 0 ] + 1 )
2002-10-16 22:55:49 +03:00
+ ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 0 ] [ 0 ] ) * ( - 2 * vop_ref [ 0 ] [ 1 ] + 1 )
2005-12-17 20:14:38 +02:00
+ 2 * w2 * r * sprite_ref [ 0 ] [ 1 ]
2002-10-16 22:55:49 +03:00
- 16 * w2
+ ( 1 < < ( alpha + rho + 1 ) ) ) ;
s - > sprite_delta [ 0 ] [ 0 ] = ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 0 ] [ 0 ] ) ;
s - > sprite_delta [ 0 ] [ 1 ] = ( + r * sprite_ref [ 0 ] [ 1 ] - virtual_ref [ 0 ] [ 1 ] ) ;
s - > sprite_delta [ 1 ] [ 0 ] = ( - r * sprite_ref [ 0 ] [ 1 ] + virtual_ref [ 0 ] [ 1 ] ) ;
s - > sprite_delta [ 1 ] [ 1 ] = ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 0 ] [ 0 ] ) ;
2005-12-17 20:14:38 +02:00
2002-10-16 22:55:49 +03:00
s - > sprite_shift [ 0 ] = alpha + rho ;
s - > sprite_shift [ 1 ] = alpha + rho + 2 ;
2002-03-07 15:27:15 +02:00
break ;
2002-10-16 22:55:49 +03:00
case 3 :
2002-11-10 13:46:59 +02:00
min_ab = FFMIN ( alpha , beta ) ;
2002-10-16 22:55:49 +03:00
w3 = w2 > > min_ab ;
h3 = h2 > > min_ab ;
s - > sprite_offset [ 0 ] [ 0 ] = ( sprite_ref [ 0 ] [ 0 ] < < ( alpha + beta + rho - min_ab ) )
+ ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 0 ] [ 0 ] ) * h3 * ( - vop_ref [ 0 ] [ 0 ] )
+ ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 1 ] [ 0 ] ) * w3 * ( - vop_ref [ 0 ] [ 1 ] )
+ ( 1 < < ( alpha + beta + rho - min_ab - 1 ) ) ;
s - > sprite_offset [ 0 ] [ 1 ] = ( sprite_ref [ 0 ] [ 1 ] < < ( alpha + beta + rho - min_ab ) )
+ ( - r * sprite_ref [ 0 ] [ 1 ] + virtual_ref [ 0 ] [ 1 ] ) * h3 * ( - vop_ref [ 0 ] [ 0 ] )
+ ( - r * sprite_ref [ 0 ] [ 1 ] + virtual_ref [ 1 ] [ 1 ] ) * w3 * ( - vop_ref [ 0 ] [ 1 ] )
+ ( 1 < < ( alpha + beta + rho - min_ab - 1 ) ) ;
s - > sprite_offset [ 1 ] [ 0 ] = ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 0 ] [ 0 ] ) * h3 * ( - 2 * vop_ref [ 0 ] [ 0 ] + 1 )
+ ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 1 ] [ 0 ] ) * w3 * ( - 2 * vop_ref [ 0 ] [ 1 ] + 1 )
+ 2 * w2 * h3 * r * sprite_ref [ 0 ] [ 0 ]
- 16 * w2 * h3
+ ( 1 < < ( alpha + beta + rho - min_ab + 1 ) ) ;
s - > sprite_offset [ 1 ] [ 1 ] = ( - r * sprite_ref [ 0 ] [ 1 ] + virtual_ref [ 0 ] [ 1 ] ) * h3 * ( - 2 * vop_ref [ 0 ] [ 0 ] + 1 )
+ ( - r * sprite_ref [ 0 ] [ 1 ] + virtual_ref [ 1 ] [ 1 ] ) * w3 * ( - 2 * vop_ref [ 0 ] [ 1 ] + 1 )
+ 2 * w2 * h3 * r * sprite_ref [ 0 ] [ 1 ]
- 16 * w2 * h3
+ ( 1 < < ( alpha + beta + rho - min_ab + 1 ) ) ;
s - > sprite_delta [ 0 ] [ 0 ] = ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 0 ] [ 0 ] ) * h3 ;
s - > sprite_delta [ 0 ] [ 1 ] = ( - r * sprite_ref [ 0 ] [ 0 ] + virtual_ref [ 1 ] [ 0 ] ) * w3 ;
s - > sprite_delta [ 1 ] [ 0 ] = ( - r * sprite_ref [ 0 ] [ 1 ] + virtual_ref [ 0 ] [ 1 ] ) * h3 ;
s - > sprite_delta [ 1 ] [ 1 ] = ( - r * sprite_ref [ 0 ] [ 1 ] + virtual_ref [ 1 ] [ 1 ] ) * w3 ;
2005-12-17 20:14:38 +02:00
2002-10-16 22:55:49 +03:00
s - > sprite_shift [ 0 ] = alpha + beta + rho - min_ab ;
s - > sprite_shift [ 1 ] = alpha + beta + rho - min_ab + 2 ;
2002-03-07 15:27:15 +02:00
break ;
}
2005-12-17 20:14:38 +02:00
/* try to simplify the situation */
2002-10-16 22:55:49 +03:00
if ( s - > sprite_delta [ 0 ] [ 0 ] = = a < < s - > sprite_shift [ 0 ]
& & s - > sprite_delta [ 0 ] [ 1 ] = = 0
& & s - > sprite_delta [ 1 ] [ 0 ] = = 0
& & s - > sprite_delta [ 1 ] [ 1 ] = = a < < s - > sprite_shift [ 0 ] )
2002-03-09 15:01:16 +02:00
{
2002-10-16 22:55:49 +03:00
s - > sprite_offset [ 0 ] [ 0 ] > > = s - > sprite_shift [ 0 ] ;
s - > sprite_offset [ 0 ] [ 1 ] > > = s - > sprite_shift [ 0 ] ;
s - > sprite_offset [ 1 ] [ 0 ] > > = s - > sprite_shift [ 1 ] ;
s - > sprite_offset [ 1 ] [ 1 ] > > = s - > sprite_shift [ 1 ] ;
s - > sprite_delta [ 0 ] [ 0 ] = a ;
s - > sprite_delta [ 0 ] [ 1 ] = 0 ;
s - > sprite_delta [ 1 ] [ 0 ] = 0 ;
s - > sprite_delta [ 1 ] [ 1 ] = a ;
s - > sprite_shift [ 0 ] = 0 ;
s - > sprite_shift [ 1 ] = 0 ;
2002-03-09 15:01:16 +02:00
s - > real_sprite_warping_points = 1 ;
}
2002-10-16 22:55:49 +03:00
else {
int shift_y = 16 - s - > sprite_shift [ 0 ] ;
int shift_c = 16 - s - > sprite_shift [ 1 ] ;
//printf("shifts %d %d\n", shift_y, shift_c);
for ( i = 0 ; i < 2 ; i + + ) {
s - > sprite_offset [ 0 ] [ i ] < < = shift_y ;
s - > sprite_offset [ 1 ] [ i ] < < = shift_c ;
s - > sprite_delta [ 0 ] [ i ] < < = shift_y ;
s - > sprite_delta [ 1 ] [ i ] < < = shift_y ;
s - > sprite_shift [ i ] = 16 ;
}
2002-03-09 15:01:16 +02:00
s - > real_sprite_warping_points = s - > num_sprite_warping_points ;
2002-10-16 22:55:49 +03:00
}
#if 0
printf ( " vop:%d:%d %d:%d %d:%d, sprite:%d:%d %d:%d %d:%d, virtual: %d:%d %d:%d \n " ,
vop_ref [ 0 ] [ 0 ] , vop_ref [ 0 ] [ 1 ] ,
vop_ref [ 1 ] [ 0 ] , vop_ref [ 1 ] [ 1 ] ,
vop_ref [ 2 ] [ 0 ] , vop_ref [ 2 ] [ 1 ] ,
2005-12-17 20:14:38 +02:00
sprite_ref [ 0 ] [ 0 ] , sprite_ref [ 0 ] [ 1 ] ,
sprite_ref [ 1 ] [ 0 ] , sprite_ref [ 1 ] [ 1 ] ,
sprite_ref [ 2 ] [ 0 ] , sprite_ref [ 2 ] [ 1 ] ,
virtual_ref [ 0 ] [ 0 ] , virtual_ref [ 0 ] [ 1 ] ,
2002-10-16 22:55:49 +03:00
virtual_ref [ 1 ] [ 0 ] , virtual_ref [ 1 ] [ 1 ]
) ;
2005-12-17 20:14:38 +02:00
2002-10-16 22:55:49 +03:00
printf ( " offset: %d:%d , delta: %d %d %d %d, shift %d \n " ,
s - > sprite_offset [ 0 ] [ 0 ] , s - > sprite_offset [ 0 ] [ 1 ] ,
s - > sprite_delta [ 0 ] [ 0 ] , s - > sprite_delta [ 0 ] [ 1 ] ,
s - > sprite_delta [ 1 ] [ 0 ] , s - > sprite_delta [ 1 ] [ 1 ] ,
s - > sprite_shift [ 0 ]
) ;
# endif
2002-03-07 15:27:15 +02:00
}
2002-12-30 02:28:42 +02:00
static int mpeg4_decode_gop_header ( MpegEncContext * s , GetBitContext * gb ) {
int hours , minutes , seconds ;
hours = get_bits ( gb , 5 ) ;
minutes = get_bits ( gb , 6 ) ;
skip_bits1 ( gb ) ;
seconds = get_bits ( gb , 6 ) ;
s - > time_base = seconds + 60 * ( minutes + 60 * hours ) ;
skip_bits1 ( gb ) ;
skip_bits1 ( gb ) ;
2005-12-17 20:14:38 +02:00
2002-12-30 02:28:42 +02:00
return 0 ;
}
2002-10-14 15:21:54 +03:00
static int decode_vol_header ( MpegEncContext * s , GetBitContext * gb ) {
int width , height , vo_ver_id ;
/* vol header */
skip_bits ( gb , 1 ) ; /* random access */
s - > vo_type = get_bits ( gb , 8 ) ;
if ( get_bits1 ( gb ) ! = 0 ) { /* is_ol_id */
vo_ver_id = get_bits ( gb , 4 ) ; /* vo_ver_id */
skip_bits ( gb , 3 ) ; /* vo_priority */
} else {
vo_ver_id = 1 ;
}
//printf("vo type:%d\n",s->vo_type);
s - > aspect_ratio_info = get_bits ( gb , 4 ) ;
2005-12-17 20:14:38 +02:00
if ( s - > aspect_ratio_info = = FF_ASPECT_EXTENDED ) {
2003-10-20 23:23:46 +03:00
s - > avctx - > sample_aspect_ratio . num = get_bits ( gb , 8 ) ; // par_width
s - > avctx - > sample_aspect_ratio . den = get_bits ( gb , 8 ) ; // par_height
2002-11-25 11:23:19 +02:00
} else {
2003-10-20 23:23:46 +03:00
s - > avctx - > sample_aspect_ratio = pixel_aspect [ s - > aspect_ratio_info ] ;
2002-10-14 15:21:54 +03:00
}
2001-07-22 17:18:56 +03:00
2002-10-14 15:21:54 +03:00
if ( ( s - > vol_control_parameters = get_bits1 ( gb ) ) ) { /* vol control parameter */
int chroma_format = get_bits ( gb , 2 ) ;
if ( chroma_format ! = 1 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " illegal chroma format \n " ) ;
2001-07-22 17:18:56 +03:00
}
2002-10-14 15:21:54 +03:00
s - > low_delay = get_bits1 ( gb ) ;
if ( get_bits1 ( gb ) ) { /* vbv parameters */
2005-12-22 03:10:11 +02:00
get_bits ( gb , 15 ) ; /* first_half_bitrate */
skip_bits1 ( gb ) ; /* marker */
get_bits ( gb , 15 ) ; /* latter_half_bitrate */
skip_bits1 ( gb ) ; /* marker */
get_bits ( gb , 15 ) ; /* first_half_vbv_buffer_size */
skip_bits1 ( gb ) ; /* marker */
get_bits ( gb , 3 ) ; /* latter_half_vbv_buffer_size */
get_bits ( gb , 11 ) ; /* first_half_vbv_occupancy */
skip_bits1 ( gb ) ; /* marker */
get_bits ( gb , 15 ) ; /* latter_half_vbv_occupancy */
skip_bits1 ( gb ) ; /* marker */
2002-03-13 14:50:41 +02:00
}
2002-10-14 15:21:54 +03:00
} else {
2005-05-05 17:34:47 +03:00
// set low delay flag only once the smartest? low delay detection won't be overriden
2002-10-14 15:21:54 +03:00
if ( s - > picture_number = = 0 )
s - > low_delay = 0 ;
2001-07-22 17:18:56 +03:00
}
2002-03-23 01:22:08 +02:00
2002-10-14 15:21:54 +03:00
s - > shape = get_bits ( gb , 2 ) ; /* vol shape */
2003-11-03 15:26:22 +02:00
if ( s - > shape ! = RECT_SHAPE ) av_log ( s - > avctx , AV_LOG_ERROR , " only rectangular vol supported \n " ) ;
2002-10-14 15:21:54 +03:00
if ( s - > shape = = GRAY_SHAPE & & vo_ver_id ! = 1 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Gray shape not supported \n " ) ;
2002-10-14 15:21:54 +03:00
skip_bits ( gb , 4 ) ; //video_object_layer_shape_extension
}
2002-04-22 22:04:28 +03:00
2003-08-23 01:18:08 +03:00
check_marker ( gb , " before time_increment_resolution " ) ;
2005-12-17 20:14:38 +02:00
2005-05-01 00:43:59 +03:00
s - > avctx - > time_base . den = get_bits ( gb , 16 ) ;
2005-07-30 19:15:36 +03:00
if ( ! s - > avctx - > time_base . den ) {
av_log ( s - > avctx , AV_LOG_ERROR , " time_base.den==0 \n " ) ;
return - 1 ;
}
2005-12-17 20:14:38 +02:00
2005-05-01 00:43:59 +03:00
s - > time_increment_bits = av_log2 ( s - > avctx - > time_base . den - 1 ) + 1 ;
2002-10-14 15:21:54 +03:00
if ( s - > time_increment_bits < 1 )
s - > time_increment_bits = 1 ;
2005-12-17 20:14:38 +02:00
2003-08-23 01:18:08 +03:00
check_marker ( gb , " before fixed_vop_rate " ) ;
2002-10-14 15:21:54 +03:00
if ( get_bits1 ( gb ) ! = 0 ) { /* fixed_vop_rate */
2005-05-01 00:43:59 +03:00
s - > avctx - > time_base . num = get_bits ( gb , s - > time_increment_bits ) ;
} else
s - > avctx - > time_base . num = 1 ;
2004-05-26 22:42:00 +03:00
s - > t_frame = 0 ;
2002-03-05 15:58:13 +02:00
2002-10-14 15:21:54 +03:00
if ( s - > shape ! = BIN_ONLY_SHAPE ) {
if ( s - > shape = = RECT_SHAPE ) {
skip_bits1 ( gb ) ; /* marker */
width = get_bits ( gb , 13 ) ;
skip_bits1 ( gb ) ; /* marker */
height = get_bits ( gb , 13 ) ;
skip_bits1 ( gb ) ; /* marker */
2005-02-06 20:43:06 +02:00
if ( width & & height & & ! ( s - > width & & s - > avctx - > codec_tag = = ff_get_fourcc ( " MP4S " ) ) ) { /* they should be non zero but who knows ... */
2002-10-14 15:21:54 +03:00
s - > width = width ;
s - > height = height ;
// printf("width/height: %d %d\n", width, height);
}
}
2005-12-17 20:14:38 +02:00
s - > progressive_sequence =
2003-12-05 03:03:12 +02:00
s - > progressive_frame = get_bits1 ( gb ) ^ 1 ;
2006-03-12 21:55:52 +02:00
s - > interlaced_dct = 0 ;
2005-12-17 20:14:38 +02:00
if ( ! get_bits1 ( gb ) & & ( s - > avctx - > debug & FF_DEBUG_PICT_INFO ) )
2003-12-01 17:23:14 +02:00
av_log ( s - > avctx , AV_LOG_INFO , " MPEG4 OBMC not supported (very likely buggy encoder) \n " ) ; /* OBMC Disable */
2002-10-14 15:21:54 +03:00
if ( vo_ver_id = = 1 ) {
s - > vol_sprite_usage = get_bits1 ( gb ) ; /* vol_sprite_usage */
} else {
s - > vol_sprite_usage = get_bits ( gb , 2 ) ; /* vol_sprite_usage */
}
2003-11-03 15:26:22 +02:00
if ( s - > vol_sprite_usage = = STATIC_SPRITE ) av_log ( s - > avctx , AV_LOG_ERROR , " Static Sprites not supported \n " ) ;
2002-10-14 15:21:54 +03:00
if ( s - > vol_sprite_usage = = STATIC_SPRITE | | s - > vol_sprite_usage = = GMC_SPRITE ) {
if ( s - > vol_sprite_usage = = STATIC_SPRITE ) {
s - > sprite_width = get_bits ( gb , 13 ) ;
skip_bits1 ( gb ) ; /* marker */
s - > sprite_height = get_bits ( gb , 13 ) ;
skip_bits1 ( gb ) ; /* marker */
s - > sprite_left = get_bits ( gb , 13 ) ;
skip_bits1 ( gb ) ; /* marker */
s - > sprite_top = get_bits ( gb , 13 ) ;
skip_bits1 ( gb ) ; /* marker */
}
s - > num_sprite_warping_points = get_bits ( gb , 6 ) ;
s - > sprite_warping_accuracy = get_bits ( gb , 2 ) ;
s - > sprite_brightness_change = get_bits1 ( gb ) ;
if ( s - > vol_sprite_usage = = STATIC_SPRITE )
2005-12-17 20:14:38 +02:00
s - > low_latency_sprite = get_bits1 ( gb ) ;
2002-10-14 15:21:54 +03:00
}
// FIXME sadct disable bit if verid!=1 && shape not rect
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
if ( get_bits1 ( gb ) = = 1 ) { /* not_8_bit */
s - > quant_precision = get_bits ( gb , 4 ) ; /* quant_precision */
2003-11-03 15:26:22 +02:00
if ( get_bits ( gb , 4 ) ! = 8 ) av_log ( s - > avctx , AV_LOG_ERROR , " N-bit not supported \n " ) ; /* bits_per_pixel */
2005-04-24 20:21:11 +03:00
if ( s - > quant_precision ! = 5 ) av_log ( s - > avctx , AV_LOG_ERROR , " quant precision %d \n " , s - > quant_precision ) ;
2002-10-14 15:21:54 +03:00
} else {
s - > quant_precision = 5 ;
2001-08-14 00:46:21 +03:00
}
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
// FIXME a bunch of grayscale shape things
2001-08-14 00:46:21 +03:00
2002-10-14 15:21:54 +03:00
if ( ( s - > mpeg_quant = get_bits1 ( gb ) ) ) { /* vol_quant_type */
2003-02-10 11:35:32 +02:00
int i , v ;
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
/* load default matrixes */
for ( i = 0 ; i < 64 ; i + + ) {
2003-03-03 16:54:00 +02:00
int j = s - > dsp . idct_permutation [ i ] ;
2002-10-14 15:21:54 +03:00
v = ff_mpeg4_default_intra_matrix [ i ] ;
s - > intra_matrix [ j ] = v ;
s - > chroma_intra_matrix [ j ] = v ;
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
v = ff_mpeg4_default_non_intra_matrix [ i ] ;
s - > inter_matrix [ j ] = v ;
s - > chroma_inter_matrix [ j ] = v ;
2001-08-14 00:46:21 +03:00
}
2002-04-07 05:03:32 +03:00
2002-10-14 15:21:54 +03:00
/* load custom intra matrix */
if ( get_bits1 ( gb ) ) {
int last = 0 ;
2005-12-22 03:10:11 +02:00
for ( i = 0 ; i < 64 ; i + + ) {
2003-02-10 11:35:32 +02:00
int j ;
2002-10-14 15:21:54 +03:00
v = get_bits ( gb , 8 ) ;
if ( v = = 0 ) break ;
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
last = v ;
2003-03-03 16:54:00 +02:00
j = s - > dsp . idct_permutation [ ff_zigzag_direct [ i ] ] ;
2002-09-30 01:44:22 +03:00
s - > intra_matrix [ j ] = v ;
s - > chroma_intra_matrix [ j ] = v ;
2002-04-07 05:03:32 +03:00
}
2002-10-14 15:21:54 +03:00
/* replicate last value */
for ( ; i < 64 ; i + + ) {
2005-12-22 03:10:11 +02:00
int j = s - > dsp . idct_permutation [ ff_zigzag_direct [ i ] ] ;
2003-08-23 01:18:08 +03:00
s - > intra_matrix [ j ] = last ;
s - > chroma_intra_matrix [ j ] = last ;
2002-04-07 05:03:32 +03:00
}
2002-10-14 15:21:54 +03:00
}
2002-04-07 05:03:32 +03:00
2002-10-14 15:21:54 +03:00
/* load custom non intra matrix */
if ( get_bits1 ( gb ) ) {
int last = 0 ;
2005-12-22 03:10:11 +02:00
for ( i = 0 ; i < 64 ; i + + ) {
2003-02-10 11:35:32 +02:00
int j ;
2002-10-14 15:21:54 +03:00
v = get_bits ( gb , 8 ) ;
if ( v = = 0 ) break ;
2002-04-07 05:03:32 +03:00
2002-10-14 15:21:54 +03:00
last = v ;
2003-03-03 16:54:00 +02:00
j = s - > dsp . idct_permutation [ ff_zigzag_direct [ i ] ] ;
2002-10-14 15:21:54 +03:00
s - > inter_matrix [ j ] = v ;
s - > chroma_inter_matrix [ j ] = v ;
2002-04-07 05:03:32 +03:00
}
2002-10-14 15:21:54 +03:00
/* replicate last value */
for ( ; i < 64 ; i + + ) {
2005-12-22 03:10:11 +02:00
int j = s - > dsp . idct_permutation [ ff_zigzag_direct [ i ] ] ;
2002-10-14 15:21:54 +03:00
s - > inter_matrix [ j ] = last ;
s - > chroma_inter_matrix [ j ] = last ;
}
2002-08-02 23:27:46 +03:00
}
2002-04-07 05:03:32 +03:00
2002-10-14 15:21:54 +03:00
// FIXME a bunch of grayscale shape things
}
2002-03-13 21:26:38 +02:00
2002-10-14 15:21:54 +03:00
if ( vo_ver_id ! = 1 )
s - > quarter_sample = get_bits1 ( gb ) ;
else s - > quarter_sample = 0 ;
2002-03-24 23:25:04 +02:00
2003-11-03 15:26:22 +02:00
if ( ! get_bits1 ( gb ) ) av_log ( s - > avctx , AV_LOG_ERROR , " Complexity estimation not supported \n " ) ;
2002-03-24 23:25:04 +02:00
2002-10-14 15:21:54 +03:00
s - > resync_marker = ! get_bits1 ( gb ) ; /* resync_marker_disabled */
2002-03-05 15:58:13 +02:00
2002-10-14 15:21:54 +03:00
s - > data_partitioning = get_bits1 ( gb ) ;
if ( s - > data_partitioning ) {
s - > rvlc = get_bits1 ( gb ) ;
2001-08-14 00:46:21 +03:00
}
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
if ( vo_ver_id ! = 1 ) {
s - > new_pred = get_bits1 ( gb ) ;
if ( s - > new_pred ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " new pred not supported \n " ) ;
2002-10-14 15:21:54 +03:00
skip_bits ( gb , 2 ) ; /* requested upstream message type */
skip_bits1 ( gb ) ; /* newpred segment type */
2002-03-09 15:01:16 +02:00
}
2002-10-14 15:21:54 +03:00
s - > reduced_res_vop = get_bits1 ( gb ) ;
2003-11-03 15:26:22 +02:00
if ( s - > reduced_res_vop ) av_log ( s - > avctx , AV_LOG_ERROR , " reduced resolution VOP not supported \n " ) ;
2002-10-14 15:21:54 +03:00
}
else {
s - > new_pred = 0 ;
s - > reduced_res_vop = 0 ;
}
s - > scalability = get_bits1 ( gb ) ;
if ( s - > scalability ) {
GetBitContext bak = * gb ;
2002-10-15 18:24:08 +03:00
int ref_layer_id ;
int ref_layer_sampling_dir ;
int h_sampling_factor_n ;
int h_sampling_factor_m ;
int v_sampling_factor_n ;
int v_sampling_factor_m ;
2005-12-17 20:14:38 +02:00
2002-10-15 18:24:08 +03:00
s - > hierachy_type = get_bits1 ( gb ) ;
ref_layer_id = get_bits ( gb , 4 ) ;
ref_layer_sampling_dir = get_bits1 ( gb ) ;
h_sampling_factor_n = get_bits ( gb , 5 ) ;
h_sampling_factor_m = get_bits ( gb , 5 ) ;
v_sampling_factor_n = get_bits ( gb , 5 ) ;
v_sampling_factor_m = get_bits ( gb , 5 ) ;
2002-10-14 15:21:54 +03:00
s - > enhancement_type = get_bits1 ( gb ) ;
2005-12-17 20:14:38 +02:00
if ( h_sampling_factor_n = = 0 | | h_sampling_factor_m = = 0
2002-10-14 15:21:54 +03:00
| | v_sampling_factor_n = = 0 | | v_sampling_factor_m = = 0 ) {
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
// fprintf(stderr, "illegal scalability header (VERY broken encoder), trying to workaround\n");
s - > scalability = 0 ;
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
* gb = bak ;
} else
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " scalability not supported \n " ) ;
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
// bin shape stuff FIXME
2002-03-09 15:01:16 +02:00
}
2002-10-14 15:21:54 +03:00
}
return 0 ;
}
2003-01-27 01:09:12 +02:00
/**
* decodes the user data stuff in the header .
* allso inits divx / xvid / lavc_version / build
*/
2002-10-14 15:21:54 +03:00
static int decode_user_data ( MpegEncContext * s , GetBitContext * gb ) {
char buf [ 256 ] ;
int i ;
int e ;
2005-12-17 13:31:56 +02:00
int ver = 0 , build = 0 , ver2 = 0 , ver3 = 0 ;
2003-03-20 19:52:30 +02:00
char last ;
2002-10-14 15:21:54 +03:00
2006-08-24 12:24:50 +03:00
for ( i = 0 ; i < 255 & & get_bits_count ( gb ) < gb - > size_in_bits ; i + + ) {
2005-07-23 14:16:18 +03:00
if ( show_bits ( gb , 23 ) = = 0 ) break ;
buf [ i ] = get_bits ( gb , 8 ) ;
2002-10-14 15:21:54 +03:00
}
2005-07-23 14:16:18 +03:00
buf [ i ] = 0 ;
2003-03-20 19:52:30 +02:00
2002-10-22 22:48:52 +03:00
/* divx detection */
2003-03-20 19:52:30 +02:00
e = sscanf ( buf , " DivX%dBuild%d%c " , & ver , & build , & last ) ;
if ( e < 2 )
e = sscanf ( buf , " DivX%db%d%c " , & ver , & build , & last ) ;
if ( e > = 2 ) {
2002-10-14 15:21:54 +03:00
s - > divx_version = ver ;
s - > divx_build = build ;
2003-03-20 19:52:30 +02:00
s - > divx_packed = e = = 3 & & last = = ' p ' ;
2002-10-14 15:21:54 +03:00
}
2005-12-17 20:14:38 +02:00
2002-10-22 22:48:52 +03:00
/* ffmpeg detection */
2005-07-24 12:28:24 +03:00
e = sscanf ( buf , " FFmpe%*[^b]b%d " , & build ) + 3 ;
2002-10-14 15:21:54 +03:00
if ( e ! = 4 )
2005-12-17 20:14:38 +02:00
e = sscanf ( buf , " FFmpeg v%d.%d.%d / libavcodec build: %d " , & ver , & ver2 , & ver3 , & build ) ;
2005-07-31 13:51:04 +03:00
if ( e ! = 4 ) {
e = sscanf ( buf , " Lavc%d.%d.%d " , & ver , & ver2 , & ver3 ) + 1 ;
2005-12-17 13:31:56 +02:00
if ( e > 1 )
build = ( ver < < 16 ) + ( ver2 < < 8 ) + ver3 ;
2005-07-31 13:51:04 +03:00
}
2002-10-14 15:21:54 +03:00
if ( e ! = 4 ) {
if ( strcmp ( buf , " ffmpeg " ) = = 0 ) {
s - > lavc_build = 4600 ;
2002-10-13 16:16:04 +03:00
}
2001-07-22 17:18:56 +03:00
}
2002-10-14 15:21:54 +03:00
if ( e = = 4 ) {
s - > lavc_build = build ;
}
2005-12-17 20:14:38 +02:00
2002-10-22 22:48:52 +03:00
/* xvid detection */
e = sscanf ( buf , " XviD%d " , & build ) ;
if ( e = = 1 ) {
s - > xvid_build = build ;
}
2002-10-14 15:21:54 +03:00
//printf("User Data: %s\n", buf);
return 0 ;
}
static int decode_vop_header ( MpegEncContext * s , GetBitContext * gb ) {
int time_incr , time_increment ;
2005-12-22 03:10:11 +02:00
s - > pict_type = get_bits ( gb , 2 ) + I_TYPE ; /* pict type: I = 0 , P = 1 */
2003-07-07 00:24:04 +03:00
if ( s - > pict_type = = B_TYPE & & s - > low_delay & & s - > vol_control_parameters = = 0 & & ! ( s - > flags & CODEC_FLAG_LOW_DELAY ) ) {
2005-04-24 20:21:11 +03:00
av_log ( s - > avctx , AV_LOG_ERROR , " low_delay flag incorrectly, clearing it \n " ) ;
2002-05-06 16:15:05 +03:00
s - > low_delay = 0 ;
}
2005-12-17 20:14:38 +02:00
2002-10-13 16:16:04 +03:00
s - > partitioned_frame = s - > data_partitioning & & s - > pict_type ! = B_TYPE ;
if ( s - > partitioned_frame )
s - > decode_mb = mpeg4_decode_partitioned_mb ;
else
2003-12-03 03:16:35 +02:00
s - > decode_mb = ff_mpeg4_decode_mb ;
2002-10-13 16:16:04 +03:00
2002-03-13 00:54:25 +02:00
time_incr = 0 ;
2005-12-17 20:14:38 +02:00
while ( get_bits1 ( gb ) ! = 0 )
2001-07-22 17:18:56 +03:00
time_incr + + ;
2002-10-14 15:21:54 +03:00
check_marker ( gb , " before time_increment " ) ;
2005-05-11 20:13:42 +03:00
if ( s - > time_increment_bits = = 0 | | ! ( show_bits ( gb , s - > time_increment_bits + 1 ) & 1 ) ) {
2005-04-24 20:21:11 +03:00
av_log ( s - > avctx , AV_LOG_ERROR , " hmm, seems the headers are not complete, trying to guess time_increment_bits \n " ) ;
2003-02-14 03:47:10 +02:00
for ( s - > time_increment_bits = 1 ; s - > time_increment_bits < 16 ; s - > time_increment_bits + + ) {
if ( show_bits ( gb , s - > time_increment_bits + 1 ) & 1 ) break ;
}
2003-08-05 13:19:43 +03:00
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " my guess is %d bits ;) \n " , s - > time_increment_bits ) ;
2003-02-14 03:47:10 +02:00
}
2005-12-17 20:14:38 +02:00
2003-08-23 01:18:08 +03:00
if ( IS_3IV1 ) time_increment = get_bits1 ( gb ) ; //FIXME investigate further
else time_increment = get_bits ( gb , s - > time_increment_bits ) ;
2005-12-17 20:14:38 +02:00
2003-08-23 01:18:08 +03:00
// printf("%d %X\n", s->time_increment_bits, time_increment);
2004-05-26 22:42:00 +03:00
//av_log(s->avctx, AV_LOG_DEBUG, " type:%d modulo_time_base:%d increment:%d t_frame %d\n", s->pict_type, time_incr, time_increment, s->t_frame);
2002-03-13 00:54:25 +02:00
if ( s - > pict_type ! = B_TYPE ) {
2002-04-17 07:32:12 +03:00
s - > last_time_base = s - > time_base ;
2002-03-13 00:54:25 +02:00
s - > time_base + = time_incr ;
2005-05-01 00:43:59 +03:00
s - > time = s - > time_base * s - > avctx - > time_base . den + time_increment ;
2002-10-13 16:16:04 +03:00
if ( s - > workaround_bugs & FF_BUG_UMP4 ) {
2002-09-27 02:27:22 +03:00
if ( s - > time < s - > last_non_b_time ) {
// fprintf(stderr, "header is not mpeg4 compatible, broken encoder, trying to workaround\n");
s - > time_base + + ;
2005-05-01 00:43:59 +03:00
s - > time + = s - > avctx - > time_base . den ;
2002-09-27 02:27:22 +03:00
}
2002-09-13 12:45:32 +03:00
}
2002-04-17 07:32:12 +03:00
s - > pp_time = s - > time - s - > last_non_b_time ;
s - > last_non_b_time = s - > time ;
2002-03-13 00:54:25 +02:00
} else {
2005-05-01 00:43:59 +03:00
s - > time = ( s - > last_time_base + time_incr ) * s - > avctx - > time_base . den + time_increment ;
2002-09-13 12:45:32 +03:00
s - > pb_time = s - > pp_time - ( s - > last_non_b_time - s - > time ) ;
if ( s - > pp_time < = s - > pb_time | | s - > pp_time < = s - > pp_time - s - > pb_time | | s - > pp_time < = 0 ) {
2005-04-24 20:21:11 +03:00
// printf("messed up order, maybe after seeking? skipping current b frame\n");
return FRAME_SKIPPED ;
2002-04-22 20:33:43 +03:00
}
2006-04-03 10:52:24 +03:00
ff_mpeg4_init_direct_mv ( s ) ;
2005-12-17 20:14:38 +02:00
2004-05-26 22:42:00 +03:00
if ( s - > t_frame = = 0 ) s - > t_frame = s - > pb_time ;
2002-09-13 12:45:32 +03:00
if ( s - > t_frame = = 0 ) s - > t_frame = 1 ; // 1/0 protection
2005-12-17 20:14:38 +02:00
s - > pp_field_time = ( ROUNDED_DIV ( s - > last_non_b_time , s - > t_frame )
2002-09-13 12:45:32 +03:00
- ROUNDED_DIV ( s - > last_non_b_time - s - > pp_time , s - > t_frame ) ) * 2 ;
2005-12-17 20:14:38 +02:00
s - > pb_field_time = ( ROUNDED_DIV ( s - > time , s - > t_frame )
2002-09-13 12:45:32 +03:00
- ROUNDED_DIV ( s - > last_non_b_time - s - > pp_time , s - > t_frame ) ) * 2 ;
2002-03-13 00:54:25 +02:00
}
2004-05-26 22:42:00 +03:00
//av_log(s->avctx, AV_LOG_DEBUG, "last nonb %Ld last_base %d time %Ld pp %d pb %d t %d ppf %d pbf %d\n", s->last_non_b_time, s->last_time_base, s->time, s->pp_time, s->pb_time, s->t_frame, s->pp_field_time, s->pb_field_time);
2005-12-17 20:14:38 +02:00
2005-07-31 13:00:25 +03:00
if ( s - > avctx - > time_base . num )
s - > current_picture_ptr - > pts = ( s - > time + s - > avctx - > time_base . num / 2 ) / s - > avctx - > time_base . num ;
else
s - > current_picture_ptr - > pts = AV_NOPTS_VALUE ;
2002-12-30 02:28:42 +02:00
if ( s - > avctx - > debug & FF_DEBUG_PTS )
2005-12-12 03:56:46 +02:00
av_log ( s - > avctx , AV_LOG_DEBUG , " MPEG4 PTS: % " PRId64 " \n " , s - > current_picture_ptr - > pts ) ;
2004-05-26 22:42:00 +03:00
2003-02-14 03:47:10 +02:00
check_marker ( gb , " before vop_coded " ) ;
2005-12-17 20:14:38 +02:00
2001-07-22 17:18:56 +03:00
/* vop coded */
2002-10-14 15:21:54 +03:00
if ( get_bits1 ( gb ) ! = 1 ) {
2004-09-27 20:46:07 +03:00
if ( s - > avctx - > debug & FF_DEBUG_PICT_INFO )
av_log ( s - > avctx , AV_LOG_ERROR , " vop not coded \n " ) ;
2005-04-24 20:21:11 +03:00
return FRAME_SKIPPED ;
2002-10-14 15:21:54 +03:00
}
2005-05-01 00:43:59 +03:00
//printf("time %d %d %d || %Ld %Ld %Ld\n", s->time_increment_bits, s->avctx->time_base.den, s->time_base,
2005-12-17 20:14:38 +02:00
//s->time, s->last_non_b_time, s->last_non_b_time - s->pp_time);
2002-03-05 15:58:13 +02:00
if ( s - > shape ! = BIN_ONLY_SHAPE & & ( s - > pict_type = = P_TYPE
| | ( s - > pict_type = = S_TYPE & & s - > vol_sprite_usage = = GMC_SPRITE ) ) ) {
2001-07-22 17:18:56 +03:00
/* rounding type for motion estimation */
2005-12-22 03:10:11 +02:00
s - > no_rounding = get_bits1 ( gb ) ;
2001-08-14 00:46:21 +03:00
} else {
2005-12-22 03:10:11 +02:00
s - > no_rounding = 0 ;
2001-07-22 17:18:56 +03:00
}
2002-03-05 15:58:13 +02:00
//FIXME reduced res stuff
if ( s - > shape ! = RECT_SHAPE ) {
2001-08-14 00:46:21 +03:00
if ( s - > vol_sprite_usage ! = 1 | | s - > pict_type ! = I_TYPE ) {
int width , height , hor_spat_ref , ver_spat_ref ;
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
width = get_bits ( gb , 13 ) ;
skip_bits1 ( gb ) ; /* marker */
height = get_bits ( gb , 13 ) ;
skip_bits1 ( gb ) ; /* marker */
hor_spat_ref = get_bits ( gb , 13 ) ; /* hor_spat_ref */
skip_bits1 ( gb ) ; /* marker */
ver_spat_ref = get_bits ( gb , 13 ) ; /* ver_spat_ref */
2001-08-14 00:46:21 +03:00
}
2002-10-14 15:21:54 +03:00
skip_bits1 ( gb ) ; /* change_CR_disable */
2005-12-17 20:14:38 +02:00
2002-10-14 15:21:54 +03:00
if ( get_bits1 ( gb ) ! = 0 ) {
skip_bits ( gb , 8 ) ; /* constant_alpha_value */
2001-08-14 00:46:21 +03:00
}
}
2002-03-05 15:58:13 +02:00
//FIXME complexity estimation stuff
2005-12-17 20:14:38 +02:00
2002-03-05 15:58:13 +02:00
if ( s - > shape ! = BIN_ONLY_SHAPE ) {
2003-10-12 17:01:53 +03:00
s - > intra_dc_threshold = mpeg4_dc_threshold [ get_bits ( gb , 3 ) ] ;
2002-08-27 19:28:19 +03:00
if ( ! s - > progressive_sequence ) {
2002-10-14 15:21:54 +03:00
s - > top_field_first = get_bits1 ( gb ) ;
s - > alternate_scan = get_bits1 ( gb ) ;
2002-09-12 21:28:17 +03:00
} else
s - > alternate_scan = 0 ;
2002-03-05 15:58:13 +02:00
}
2002-03-07 15:27:15 +02:00
2002-10-03 01:56:58 +03:00
if ( s - > alternate_scan ) {
2003-05-19 16:30:59 +03:00
ff_init_scantable ( s - > dsp . idct_permutation , & s - > inter_scantable , ff_alternate_vertical_scan ) ;
ff_init_scantable ( s - > dsp . idct_permutation , & s - > intra_scantable , ff_alternate_vertical_scan ) ;
ff_init_scantable ( s - > dsp . idct_permutation , & s - > intra_h_scantable , ff_alternate_vertical_scan ) ;
ff_init_scantable ( s - > dsp . idct_permutation , & s - > intra_v_scantable , ff_alternate_vertical_scan ) ;
2002-10-03 01:56:58 +03:00
} else {
2003-05-19 16:30:59 +03:00
ff_init_scantable ( s - > dsp . idct_permutation , & s - > inter_scantable , ff_zigzag_direct ) ;
ff_init_scantable ( s - > dsp . idct_permutation , & s - > intra_scantable , ff_zigzag_direct ) ;
ff_init_scantable ( s - > dsp . idct_permutation , & s - > intra_h_scantable , ff_alternate_horizontal_scan ) ;
ff_init_scantable ( s - > dsp . idct_permutation , & s - > intra_v_scantable , ff_alternate_vertical_scan ) ;
2002-10-03 01:56:58 +03:00
}
2005-12-17 20:14:38 +02:00
2002-03-05 15:58:13 +02:00
if ( s - > pict_type = = S_TYPE & & ( s - > vol_sprite_usage = = STATIC_SPRITE | | s - > vol_sprite_usage = = GMC_SPRITE ) ) {
2004-04-02 19:21:55 +03:00
mpeg4_decode_sprite_trajectory ( s , gb ) ;
2003-11-03 15:26:22 +02:00
if ( s - > sprite_brightness_change ) av_log ( s - > avctx , AV_LOG_ERROR , " sprite_brightness_change not supported \n " ) ;
if ( s - > vol_sprite_usage = = STATIC_SPRITE ) av_log ( s - > avctx , AV_LOG_ERROR , " static sprite not supported \n " ) ;
2002-03-05 15:58:13 +02:00
}
2002-03-07 15:27:15 +02:00
2002-03-05 15:58:13 +02:00
if ( s - > shape ! = BIN_ONLY_SHAPE ) {
2003-12-01 17:23:14 +02:00
s - > chroma_qscale = s - > qscale = get_bits ( gb , s - > quant_precision ) ;
2002-03-13 21:26:38 +02:00
if ( s - > qscale = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Error, header damaged or not MPEG4 header (qscale=0) \n " ) ;
2002-03-13 21:26:38 +02:00
return - 1 ; // makes no sense to continue, as there is nothing left from the image then
}
2005-12-17 20:14:38 +02:00
2001-08-14 00:46:21 +03:00
if ( s - > pict_type ! = I_TYPE ) {
2005-12-22 03:10:11 +02:00
s - > f_code = get_bits ( gb , 3 ) ; /* fcode_for */
2002-03-13 21:26:38 +02:00
if ( s - > f_code = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Error, header damaged or not MPEG4 header (f_code=0) \n " ) ;
2002-03-13 21:26:38 +02:00
return - 1 ; // makes no sense to continue, as the MV decoding will break very quickly
}
2002-07-25 23:22:36 +03:00
} else
s - > f_code = 1 ;
2005-12-17 20:14:38 +02:00
2002-03-05 15:58:13 +02:00
if ( s - > pict_type = = B_TYPE ) {
2002-10-14 15:21:54 +03:00
s - > b_code = get_bits ( gb , 3 ) ;
2002-07-25 23:22:36 +03:00
} else
s - > b_code = 1 ;
2002-12-04 14:09:27 +02:00
if ( s - > avctx - > debug & FF_DEBUG_PICT_INFO ) {
2005-12-17 20:14:38 +02:00
av_log ( s - > avctx , AV_LOG_DEBUG , " qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d \n " ,
s - > qscale , s - > f_code , s - > b_code ,
s - > pict_type = = I_TYPE ? " I " : ( s - > pict_type = = P_TYPE ? " P " : ( s - > pict_type = = B_TYPE ? " B " : " S " ) ) ,
gb - > size_in_bits , s - > progressive_sequence , s - > alternate_scan , s - > top_field_first ,
2002-12-17 13:25:29 +02:00
s - > quarter_sample ? " q " : " h " , s - > data_partitioning , s - > resync_marker , s - > num_sprite_warping_points ,
2005-12-17 20:14:38 +02:00
s - > sprite_warping_accuracy , 1 - s - > no_rounding , s - > vo_type , s - > vol_control_parameters ? " VOLC " : " " , s - > intra_dc_threshold ) ;
2002-12-04 14:09:27 +02:00
}
2002-03-05 15:58:13 +02:00
if ( ! s - > scalability ) {
if ( s - > shape ! = RECT_SHAPE & & s - > pict_type ! = I_TYPE ) {
2002-10-14 15:21:54 +03:00
skip_bits1 ( gb ) ; // vop shape coding type
2002-03-05 15:58:13 +02:00
}
2002-07-21 04:34:05 +03:00
} else {
if ( s - > enhancement_type ) {
2002-10-14 15:21:54 +03:00
int load_backward_shape = get_bits1 ( gb ) ;
2002-07-21 04:34:05 +03:00
if ( load_backward_shape ) {
2005-05-05 17:34:47 +03:00
av_log ( s - > avctx , AV_LOG_ERROR , " load backward shape isn't supported \n " ) ;
2002-07-21 04:34:05 +03:00
}
}
2002-10-14 15:21:54 +03:00
skip_bits ( gb , 2 ) ; //ref_select_code
2001-08-14 00:46:21 +03:00
}
}
2005-05-05 17:34:47 +03:00
/* detect buggy encoders which don't set the low_delay flag (divx4/xvid/opendivx)*/
// note we cannot detect divx5 without b-frames easily (although it's buggy too)
2002-05-06 16:15:05 +03:00
if ( s - > vo_type = = 0 & & s - > vol_control_parameters = = 0 & & s - > divx_version = = 0 & & s - > picture_number = = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag \n " ) ;
2002-04-27 17:10:47 +03:00
s - > low_delay = 1 ;
}
2005-05-05 17:34:47 +03:00
s - > picture_number + + ; // better than pic number==0 always ;)
2002-04-27 17:10:47 +03:00
2005-12-17 20:14:38 +02:00
s - > y_dc_scale_table = ff_mpeg4_y_dc_scale_table ; //FIXME add short header support
2002-06-18 03:46:02 +03:00
s - > c_dc_scale_table = ff_mpeg4_c_dc_scale_table ;
2003-07-16 21:12:14 +03:00
if ( s - > workaround_bugs & FF_BUG_EDGE ) {
2002-07-25 23:22:36 +03:00
s - > h_edge_pos = s - > width ;
s - > v_edge_pos = s - > height ;
}
2001-08-14 00:46:21 +03:00
return 0 ;
2001-07-22 17:18:56 +03:00
}
2002-10-14 15:21:54 +03:00
/**
* decode mpeg4 headers
* @ return < 0 if no VOP found ( or a damaged one )
* FRAME_SKIPPED if a not coded VOP is found
* 0 if a VOP is found
*/
int ff_mpeg4_decode_picture_header ( MpegEncContext * s , GetBitContext * gb )
{
int startcode , v ;
/* search next start code */
align_get_bits ( gb ) ;
2005-01-02 01:02:09 +02:00
if ( s - > avctx - > codec_tag = = ff_get_fourcc ( " WV1F " ) & & show_bits ( gb , 24 ) = = 0x575630 ) {
skip_bits ( gb , 24 ) ;
if ( get_bits ( gb , 8 ) = = 0xF0 )
return decode_vop_header ( s , gb ) ;
}
2002-10-14 15:21:54 +03:00
startcode = 0xff ;
for ( ; ; ) {
2003-01-21 19:34:12 +02:00
if ( get_bits_count ( gb ) > = gb - > size_in_bits ) {
2005-03-08 16:39:58 +02:00
if ( gb - > size_in_bits = = 8 & & ( s - > divx_version | | s - > xvid_build ) ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " frame skip %d \n " , gb - > size_in_bits ) ;
2005-04-24 20:21:11 +03:00
return FRAME_SKIPPED ; //divx bug
2002-10-14 15:21:54 +03:00
} else
return - 1 ; //end of stream
}
2005-12-17 13:31:56 +02:00
/* use the bits after the test */
v = get_bits ( gb , 8 ) ;
startcode = ( ( startcode < < 8 ) | v ) & 0xffffffff ;
2002-10-14 15:21:54 +03:00
if ( ( startcode & 0xFFFFFF00 ) ! = 0x100 )
continue ; //no startcode
2005-12-17 20:14:38 +02:00
2002-12-30 02:28:42 +02:00
if ( s - > avctx - > debug & FF_DEBUG_STARTCODE ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_DEBUG , " startcode: %3X " , startcode ) ;
if ( startcode < = 0x11F ) av_log ( s - > avctx , AV_LOG_DEBUG , " Video Object Start " ) ;
else if ( startcode < = 0x12F ) av_log ( s - > avctx , AV_LOG_DEBUG , " Video Object Layer Start " ) ;
else if ( startcode < = 0x13F ) av_log ( s - > avctx , AV_LOG_DEBUG , " Reserved " ) ;
else if ( startcode < = 0x15F ) av_log ( s - > avctx , AV_LOG_DEBUG , " FGS bp start " ) ;
else if ( startcode < = 0x1AF ) av_log ( s - > avctx , AV_LOG_DEBUG , " Reserved " ) ;
else if ( startcode = = 0x1B0 ) av_log ( s - > avctx , AV_LOG_DEBUG , " Visual Object Seq Start " ) ;
else if ( startcode = = 0x1B1 ) av_log ( s - > avctx , AV_LOG_DEBUG , " Visual Object Seq End " ) ;
else if ( startcode = = 0x1B2 ) av_log ( s - > avctx , AV_LOG_DEBUG , " User Data " ) ;
else if ( startcode = = 0x1B3 ) av_log ( s - > avctx , AV_LOG_DEBUG , " Group of VOP start " ) ;
else if ( startcode = = 0x1B4 ) av_log ( s - > avctx , AV_LOG_DEBUG , " Video Session Error " ) ;
else if ( startcode = = 0x1B5 ) av_log ( s - > avctx , AV_LOG_DEBUG , " Visual Object Start " ) ;
else if ( startcode = = 0x1B6 ) av_log ( s - > avctx , AV_LOG_DEBUG , " Video Object Plane start " ) ;
else if ( startcode = = 0x1B7 ) av_log ( s - > avctx , AV_LOG_DEBUG , " slice start " ) ;
else if ( startcode = = 0x1B8 ) av_log ( s - > avctx , AV_LOG_DEBUG , " extension start " ) ;
else if ( startcode = = 0x1B9 ) av_log ( s - > avctx , AV_LOG_DEBUG , " fgs start " ) ;
else if ( startcode = = 0x1BA ) av_log ( s - > avctx , AV_LOG_DEBUG , " FBA Object start " ) ;
else if ( startcode = = 0x1BB ) av_log ( s - > avctx , AV_LOG_DEBUG , " FBA Object Plane start " ) ;
else if ( startcode = = 0x1BC ) av_log ( s - > avctx , AV_LOG_DEBUG , " Mesh Object start " ) ;
else if ( startcode = = 0x1BD ) av_log ( s - > avctx , AV_LOG_DEBUG , " Mesh Object Plane start " ) ;
2005-04-24 20:21:11 +03:00
else if ( startcode = = 0x1BE ) av_log ( s - > avctx , AV_LOG_DEBUG , " Still Texture Object start " ) ;
else if ( startcode = = 0x1BF ) av_log ( s - > avctx , AV_LOG_DEBUG , " Texture Spatial Layer start " ) ;
else if ( startcode = = 0x1C0 ) av_log ( s - > avctx , AV_LOG_DEBUG , " Texture SNR Layer start " ) ;
else if ( startcode = = 0x1C1 ) av_log ( s - > avctx , AV_LOG_DEBUG , " Texture Tile start " ) ;
else if ( startcode = = 0x1C2 ) av_log ( s - > avctx , AV_LOG_DEBUG , " Texture Shape Layer start " ) ;
2003-11-03 15:26:22 +02:00
else if ( startcode = = 0x1C3 ) av_log ( s - > avctx , AV_LOG_DEBUG , " stuffing start " ) ;
else if ( startcode < = 0x1C5 ) av_log ( s - > avctx , AV_LOG_DEBUG , " reserved " ) ;
else if ( startcode < = 0x1FF ) av_log ( s - > avctx , AV_LOG_DEBUG , " System start " ) ;
av_log ( s - > avctx , AV_LOG_DEBUG , " at %d \n " , get_bits_count ( gb ) ) ;
2002-12-30 02:28:42 +02:00
}
2003-10-11 11:27:07 +03:00
if ( startcode > = 0x120 & & startcode < = 0x12F ) {
2005-12-17 20:14:38 +02:00
if ( decode_vol_header ( s , gb ) < 0 )
2003-08-05 13:19:43 +03:00
return - 1 ;
2003-10-11 11:27:07 +03:00
}
else if ( startcode = = USER_DATA_STARTCODE ) {
2002-10-14 15:21:54 +03:00
decode_user_data ( s , gb ) ;
2003-10-11 11:27:07 +03:00
}
else if ( startcode = = GOP_STARTCODE ) {
2002-12-30 02:28:42 +02:00
mpeg4_decode_gop_header ( s , gb ) ;
2003-10-11 11:27:07 +03:00
}
else if ( startcode = = VOP_STARTCODE ) {
2002-10-14 15:21:54 +03:00
return decode_vop_header ( s , gb ) ;
}
align_get_bits ( gb ) ;
startcode = 0xff ;
}
}
2001-07-22 17:18:56 +03:00
/* don't understand why they choose a different header ! */
int intel_h263_decode_picture_header ( MpegEncContext * s )
{
int format ;
/* picture header */
2003-05-14 13:55:59 +03:00
if ( get_bits_long ( & s - > gb , 22 ) ! = 0x20 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Bad picture start code \n " ) ;
2001-07-22 17:18:56 +03:00
return - 1 ;
2002-05-03 21:11:23 +03:00
}
s - > picture_number = get_bits ( & s - > gb , 8 ) ; /* picture timestamp */
2001-07-22 17:18:56 +03:00
2002-05-03 21:11:23 +03:00
if ( get_bits1 ( & s - > gb ) ! = 1 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Bad marker \n " ) ;
2005-12-22 03:10:11 +02:00
return - 1 ; /* marker */
2002-05-03 21:11:23 +03:00
}
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Bad H263 id \n " ) ;
2005-12-22 03:10:11 +02:00
return - 1 ; /* h263 id */
2002-05-03 21:11:23 +03:00
}
2005-12-22 03:10:11 +02:00
skip_bits1 ( & s - > gb ) ; /* split screen off */
skip_bits1 ( & s - > gb ) ; /* camera off */
skip_bits1 ( & s - > gb ) ; /* freeze picture release off */
2001-07-22 17:18:56 +03:00
format = get_bits ( & s - > gb , 3 ) ;
2002-05-03 21:11:23 +03:00
if ( format ! = 7 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Intel H263 free format not supported \n " ) ;
2001-07-22 17:18:56 +03:00
return - 1 ;
2002-05-03 21:11:23 +03:00
}
2001-07-22 17:18:56 +03:00
s - > h263_plus = 0 ;
2001-08-04 03:46:50 +03:00
s - > pict_type = I_TYPE + get_bits1 ( & s - > gb ) ;
2005-12-17 20:14:38 +02:00
s - > unrestricted_mv = get_bits1 ( & s - > gb ) ;
2001-07-22 17:18:56 +03:00
s - > h263_long_vectors = s - > unrestricted_mv ;
2002-05-03 21:11:23 +03:00
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " SAC not supported \n " ) ;
2005-12-22 03:10:11 +02:00
return - 1 ; /* SAC: off */
2002-05-03 21:11:23 +03:00
}
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-11-28 23:31:20 +02:00
s - > obmc = 1 ;
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Advanced Prediction Mode not supported \n " ) ;
2005-12-22 03:10:11 +02:00
// return -1; /* advanced prediction mode: off */
2002-05-03 21:11:23 +03:00
}
if ( get_bits1 ( & s - > gb ) ! = 0 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " PB frame mode no supported \n " ) ;
2005-12-22 03:10:11 +02:00
return - 1 ; /* PB frame mode */
2002-05-03 21:11:23 +03:00
}
2001-07-22 17:18:56 +03:00
/* skip unknown header garbage */
2001-08-04 03:46:50 +03:00
skip_bits ( & s - > gb , 41 ) ;
2001-07-22 17:18:56 +03:00
2003-12-01 17:23:14 +02:00
s - > chroma_qscale = s - > qscale = get_bits ( & s - > gb , 5 ) ;
2005-12-22 03:10:11 +02:00
skip_bits1 ( & s - > gb ) ; /* Continuous Presence Multipoint mode: off */
2001-07-22 17:18:56 +03:00
/* PEI */
2001-08-04 03:46:50 +03:00
while ( get_bits1 ( & s - > gb ) ! = 0 ) {
skip_bits ( & s - > gb , 8 ) ;
2001-07-22 17:18:56 +03:00
}
s - > f_code = 1 ;
2002-10-26 21:56:43 +03:00
s - > y_dc_scale_table =
s - > c_dc_scale_table = ff_mpeg1_dc_scale_table ;
2001-07-22 17:18:56 +03:00
return 0 ;
}
2001-11-03 02:49:53 +02:00
2003-07-10 02:10:59 +03:00
int flv_h263_decode_picture_header ( MpegEncContext * s )
{
int format , width , height ;
/* picture header */
if ( get_bits_long ( & s - > gb , 17 ) ! = 1 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Bad picture start code \n " ) ;
2003-07-10 02:10:59 +03:00
return - 1 ;
}
format = get_bits ( & s - > gb , 5 ) ;
if ( format ! = 0 & & format ! = 1 ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " Bad picture format \n " ) ;
2003-07-10 02:10:59 +03:00
return - 1 ;
}
s - > h263_flv = format + 1 ;
s - > picture_number = get_bits ( & s - > gb , 8 ) ; /* picture timestamp */
format = get_bits ( & s - > gb , 3 ) ;
switch ( format ) {
case 0 :
width = get_bits ( & s - > gb , 8 ) ;
height = get_bits ( & s - > gb , 8 ) ;
break ;
case 1 :
width = get_bits ( & s - > gb , 16 ) ;
height = get_bits ( & s - > gb , 16 ) ;
break ;
case 2 :
width = 352 ;
height = 288 ;
break ;
case 3 :
width = 176 ;
height = 144 ;
break ;
case 4 :
width = 128 ;
height = 96 ;
break ;
case 5 :
width = 320 ;
height = 240 ;
break ;
case 6 :
width = 160 ;
height = 120 ;
break ;
default :
width = height = 0 ;
break ;
}
2005-01-12 02:16:25 +02:00
if ( avcodec_check_dimensions ( s - > avctx , width , height ) )
2003-07-10 02:10:59 +03:00
return - 1 ;
s - > width = width ;
s - > height = height ;
s - > pict_type = I_TYPE + get_bits ( & s - > gb , 2 ) ;
2004-04-17 16:36:21 +03:00
s - > dropable = s - > pict_type > P_TYPE ;
if ( s - > dropable )
2003-07-10 02:10:59 +03:00
s - > pict_type = P_TYPE ;
2005-12-17 20:14:38 +02:00
2005-12-22 03:10:11 +02:00
skip_bits1 ( & s - > gb ) ; /* deblocking flag */
2003-12-01 17:23:14 +02:00
s - > chroma_qscale = s - > qscale = get_bits ( & s - > gb , 5 ) ;
2003-07-10 02:10:59 +03:00
s - > h263_plus = 0 ;
s - > unrestricted_mv = 1 ;
2003-07-15 23:22:22 +03:00
s - > h263_long_vectors = 0 ;
2003-07-10 02:10:59 +03:00
/* PEI */
while ( get_bits1 ( & s - > gb ) ! = 0 ) {
skip_bits ( & s - > gb , 8 ) ;
}
s - > f_code = 1 ;
2003-07-15 23:22:22 +03:00
if ( s - > avctx - > debug & FF_DEBUG_PICT_INFO ) {
2003-11-03 15:26:22 +02:00
av_log ( s - > avctx , AV_LOG_DEBUG , " %c esc_type:%d, qp:%d num:%d \n " ,
2005-01-06 03:02:36 +02:00
s - > dropable ? ' D ' : av_get_pict_type_char ( s - > pict_type ) , s - > h263_flv - 1 , s - > qscale , s - > picture_number ) ;
2003-07-15 23:22:22 +03:00
}
2005-12-17 20:14:38 +02:00
2003-07-10 02:10:59 +03:00
s - > y_dc_scale_table =
s - > c_dc_scale_table = ff_mpeg1_dc_scale_table ;
return 0 ;
}