@ -81,14 +81,6 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
static void filter_mb_fast ( H264Context * h , int mb_x , int mb_y , uint8_t * img_y , uint8_t * img_cb , uint8_t * img_cr , unsigned int linesize , unsigned int uvlinesize ) ;
static Picture * remove_long ( H264Context * h , int i , int ref_mask ) ;
static av_always_inline uint32_t pack16to32 ( int a , int b ) {
# if HAVE_BIGENDIAN
return ( b & 0xFFFF ) + ( a < < 16 ) ;
# else
return ( a & 0xFFFF ) + ( b < < 16 ) ;
# endif
}
static const uint8_t rem6 [ 52 ] = {
0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 ,
} ;
@ -546,7 +538,7 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){
h - > neighbor_transform_size = ! ! IS_8x8DCT ( top_type ) + ! ! IS_8x8DCT ( left_type [ 0 ] ) ;
}
static inline void write_back_intra_pred_mode ( H264Context * h ) {
void ff_h264_ write_back_intra_pred_mode( H264Context * h ) {
const int mb_xy = h - > mb_xy ;
h - > intra4x4_pred_mode [ mb_xy ] [ 0 ] = h - > intra4x4_pred_mode_cache [ 7 + 8 * 1 ] ;
@ -561,46 +553,7 @@ static inline void write_back_intra_pred_mode(H264Context *h){
/**
* checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks .
*/
static inline int check_intra4x4_pred_mode ( H264Context * h ) {
MpegEncContext * const s = & h - > s ;
static const int8_t top [ 12 ] = { - 1 , 0 , LEFT_DC_PRED , - 1 , - 1 , - 1 , - 1 , - 1 , 0 } ;
static const int8_t left [ 12 ] = { 0 , - 1 , TOP_DC_PRED , 0 , - 1 , - 1 , - 1 , 0 , - 1 , DC_128_PRED } ;
int i ;
if ( ! ( h - > top_samples_available & 0x8000 ) ) {
for ( i = 0 ; i < 4 ; i + + ) {
int status = top [ h - > intra4x4_pred_mode_cache [ scan8 [ 0 ] + i ] ] ;
if ( status < 0 ) {
av_log ( h - > s . avctx , AV_LOG_ERROR , " top block unavailable for requested intra4x4 mode %d at %d %d \n " , status , s - > mb_x , s - > mb_y ) ;
return - 1 ;
} else if ( status ) {
h - > intra4x4_pred_mode_cache [ scan8 [ 0 ] + i ] = status ;
}
}
}
if ( ( h - > left_samples_available & 0x8888 ) ! = 0x8888 ) {
static const int mask [ 4 ] = { 0x8000 , 0x2000 , 0x80 , 0x20 } ;
for ( i = 0 ; i < 4 ; i + + ) {
if ( ! ( h - > left_samples_available & mask [ i ] ) ) {
int status = left [ h - > intra4x4_pred_mode_cache [ scan8 [ 0 ] + 8 * i ] ] ;
if ( status < 0 ) {
av_log ( h - > s . avctx , AV_LOG_ERROR , " left block unavailable for requested intra4x4 mode %d at %d %d \n " , status , s - > mb_x , s - > mb_y ) ;
return - 1 ;
} else if ( status ) {
h - > intra4x4_pred_mode_cache [ scan8 [ 0 ] + 8 * i ] = status ;
}
}
}
}
return 0 ;
} //FIXME cleanup like next
/**
* checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks .
*/
static inline int check_intra_pred_mode ( H264Context * h , int mode ) {
int ff_h264_check_intra_pred_mode ( H264Context * h , int mode ) {
MpegEncContext * const s = & h - > s ;
static const int8_t top [ 7 ] = { LEFT_DC_PRED8x8 , 1 , - 1 , - 1 } ;
static const int8_t left [ 7 ] = { TOP_DC_PRED8x8 , - 1 , 2 , - 1 , DC_128_PRED8x8 } ;
@ -684,119 +637,6 @@ static inline int pred_non_zero_count(H264Context *h, int n){
return i & 31 ;
}
static inline int fetch_diagonal_mv ( H264Context * h , const int16_t * * C , int i , int list , int part_width ) {
const int topright_ref = h - > ref_cache [ list ] [ i - 8 + part_width ] ;
MpegEncContext * s = & h - > s ;
/* there is no consistent mapping of mvs to neighboring locations that will
* make mbaff happy , so we can ' t move all this logic to fill_caches */
if ( FRAME_MBAFF ) {
const uint32_t * mb_types = s - > current_picture_ptr - > mb_type ;
const int16_t * mv ;
* ( uint32_t * ) h - > mv_cache [ list ] [ scan8 [ 0 ] - 2 ] = 0 ;
* C = h - > mv_cache [ list ] [ scan8 [ 0 ] - 2 ] ;
if ( ! MB_FIELD
& & ( s - > mb_y & 1 ) & & i < scan8 [ 0 ] + 8 & & topright_ref ! = PART_NOT_AVAILABLE ) {
int topright_xy = s - > mb_x + ( s - > mb_y - 1 ) * s - > mb_stride + ( i = = scan8 [ 0 ] + 3 ) ;
if ( IS_INTERLACED ( mb_types [ topright_xy ] ) ) {
# define SET_DIAG_MV(MV_OP, REF_OP, X4, Y4)\
const int x4 = X4 , y4 = Y4 ; \
const int mb_type = mb_types [ ( x4 > > 2 ) + ( y4 > > 2 ) * s - > mb_stride ] ; \
if ( ! USES_LIST ( mb_type , list ) ) \
return LIST_NOT_USED ; \
mv = s - > current_picture_ptr - > motion_val [ list ] [ x4 + y4 * h - > b_stride ] ; \
h - > mv_cache [ list ] [ scan8 [ 0 ] - 2 ] [ 0 ] = mv [ 0 ] ; \
h - > mv_cache [ list ] [ scan8 [ 0 ] - 2 ] [ 1 ] = mv [ 1 ] MV_OP ; \
return s - > current_picture_ptr - > ref_index [ list ] [ ( x4 > > 1 ) + ( y4 > > 1 ) * h - > b8_stride ] REF_OP ;
SET_DIAG_MV ( * 2 , > > 1 , s - > mb_x * 4 + ( i & 7 ) - 4 + part_width , s - > mb_y * 4 - 1 ) ;
}
}
if ( topright_ref = = PART_NOT_AVAILABLE
& & ( ( s - > mb_y & 1 ) | | i > = scan8 [ 0 ] + 8 ) & & ( i & 7 ) = = 4
& & h - > ref_cache [ list ] [ scan8 [ 0 ] - 1 ] ! = PART_NOT_AVAILABLE ) {
if ( ! MB_FIELD
& & IS_INTERLACED ( mb_types [ h - > left_mb_xy [ 0 ] ] ) ) {
SET_DIAG_MV ( * 2 , > > 1 , s - > mb_x * 4 - 1 , ( s - > mb_y | 1 ) * 4 + ( s - > mb_y & 1 ) * 2 + ( i > > 4 ) - 1 ) ;
}
if ( MB_FIELD
& & ! IS_INTERLACED ( mb_types [ h - > left_mb_xy [ 0 ] ] )
& & i > = scan8 [ 0 ] + 8 ) {
// left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK.
SET_DIAG_MV ( / 2 , < < 1 , s - > mb_x * 4 - 1 , ( s - > mb_y & ~ 1 ) * 4 - 1 + ( ( i - scan8 [ 0 ] ) > > 3 ) * 2 ) ;
}
}
# undef SET_DIAG_MV
}
if ( topright_ref ! = PART_NOT_AVAILABLE ) {
* C = h - > mv_cache [ list ] [ i - 8 + part_width ] ;
return topright_ref ;
} else {
tprintf ( s - > avctx , " topright MV not available \n " ) ;
* C = h - > mv_cache [ list ] [ i - 8 - 1 ] ;
return h - > ref_cache [ list ] [ i - 8 - 1 ] ;
}
}
/**
* gets the predicted MV .
* @ param n the block index
* @ param part_width the width of the partition ( 4 , 8 , 16 ) - > ( 1 , 2 , 4 )
* @ param mx the x component of the predicted motion vector
* @ param my the y component of the predicted motion vector
*/
static inline void pred_motion ( H264Context * const h , int n , int part_width , int list , int ref , int * const mx , int * const my ) {
const int index8 = scan8 [ n ] ;
const int top_ref = h - > ref_cache [ list ] [ index8 - 8 ] ;
const int left_ref = h - > ref_cache [ list ] [ index8 - 1 ] ;
const int16_t * const A = h - > mv_cache [ list ] [ index8 - 1 ] ;
const int16_t * const B = h - > mv_cache [ list ] [ index8 - 8 ] ;
const int16_t * C ;
int diagonal_ref , match_count ;
assert ( part_width = = 1 | | part_width = = 2 | | part_width = = 4 ) ;
/* mv_cache
B . . A T T T T
U . . L . . , .
U . . L . . . .
U . . L . . , .
. . . L . . . .
*/
diagonal_ref = fetch_diagonal_mv ( h , & C , index8 , list , part_width ) ;
match_count = ( diagonal_ref = = ref ) + ( top_ref = = ref ) + ( left_ref = = ref ) ;
tprintf ( h - > s . avctx , " pred_motion match_count=%d \n " , match_count ) ;
if ( match_count > 1 ) { //most common
* mx = mid_pred ( A [ 0 ] , B [ 0 ] , C [ 0 ] ) ;
* my = mid_pred ( A [ 1 ] , B [ 1 ] , C [ 1 ] ) ;
} else if ( match_count = = 1 ) {
if ( left_ref = = ref ) {
* mx = A [ 0 ] ;
* my = A [ 1 ] ;
} else if ( top_ref = = ref ) {
* mx = B [ 0 ] ;
* my = B [ 1 ] ;
} else {
* mx = C [ 0 ] ;
* my = C [ 1 ] ;
}
} else {
if ( top_ref = = PART_NOT_AVAILABLE & & diagonal_ref = = PART_NOT_AVAILABLE & & left_ref ! = PART_NOT_AVAILABLE ) {
* mx = A [ 0 ] ;
* my = A [ 1 ] ;
} else {
* mx = mid_pred ( A [ 0 ] , B [ 0 ] , C [ 0 ] ) ;
* my = mid_pred ( A [ 1 ] , B [ 1 ] , C [ 1 ] ) ;
}
}
tprintf ( h - > s . avctx , " pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d \n " , top_ref , B [ 0 ] , B [ 1 ] , diagonal_ref , C [ 0 ] , C [ 1 ] , left_ref , A [ 0 ] , A [ 1 ] , ref , * mx , * my , h - > s . mb_x , h - > s . mb_y , n , list ) ;
}
/**
* gets the directionally predicted 16 x8 MV .
* @ param n the block index
@ -2070,11 +1910,7 @@ static void init_dequant_tables(H264Context *h){
}
/**
* allocates tables .
* needs width / height
*/
static int alloc_tables ( H264Context * h ) {
int ff_h264_alloc_tables ( H264Context * h ) {
MpegEncContext * const s = & h - > s ;
const int big_mb_num = s - > mb_stride * ( s - > mb_height + 1 ) ;
int x , y ;
@ -2180,7 +2016,7 @@ static void reset_sei(H264Context *h) {
h - > sei_buffering_period_present = 0 ;
}
static av_cold int decode_init ( AVCodecContext * avctx ) {
av_cold int ff_h264_ decode_init( AVCodecContext * avctx ) {
H264Context * h = avctx - > priv_data ;
MpegEncContext * const s = & h - > s ;
@ -2223,7 +2059,7 @@ static av_cold int decode_init(AVCodecContext *avctx){
return 0 ;
}
static int frame_start ( H264Context * h ) {
int ff_h264_ frame_start( H264Context * h ) {
MpegEncContext * const s = & h - > s ;
int i ;
@ -2686,7 +2522,7 @@ static void av_noinline hl_decode_mb_complex(H264Context *h){
hl_decode_mb_internal ( h , 0 ) ;
}
static void hl_decode_mb ( H264Context * h ) {
void ff_h264_ hl_decode_mb( H264Context * h ) {
MpegEncContext * const s = & h - > s ;
const int mb_xy = h - > mb_xy ;
const int mb_type = s - > current_picture . mb_type [ mb_xy ] ;
@ -3838,7 +3674,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
h - > prev_interlaced_frame = 1 ;
init_scan_tables ( h ) ;
alloc_tables ( h ) ;
ff_h264_ alloc_tables( h ) ;
for ( i = 1 ; i < s - > avctx - > thread_count ; i + + ) {
H264Context * c ;
@ -3877,7 +3713,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
while ( h - > frame_num ! = h - > prev_frame_num & &
h - > frame_num ! = ( h - > prev_frame_num + 1 ) % ( 1 < < h - > sps . log2_max_frame_num ) ) {
av_log ( NULL , AV_LOG_DEBUG , " Frame num gap %d %d \n " , h - > frame_num , h - > prev_frame_num ) ;
if ( frame_start ( h ) < 0 )
if ( ff_h264_f rame_start ( h ) < 0 )
return - 1 ;
h - > prev_frame_num + + ;
h - > prev_frame_num % = 1 < < h - > sps . log2_max_frame_num ;
@ -3925,7 +3761,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
s0 - > first_field = FIELD_PICTURE ;
}
if ( ( ! FIELD_PICTURE | | s0 - > first_field ) & & frame_start ( h ) < 0 ) {
if ( ( ! FIELD_PICTURE | | s0 - > first_field ) & & ff_h264_f rame_start ( h ) < 0 ) {
s0 - > first_field = 0 ;
return - 1 ;
}
@ -4561,16 +4397,16 @@ decode_intra_mb:
else
h - > intra4x4_pred_mode_cache [ scan8 [ i ] ] = mode ;
}
write_back_intra_pred_mode ( h ) ;
ff_h264_ write_back_intra_pred_mode( h ) ;
if ( check_intra4x4_pred_mode ( h ) < 0 )
return - 1 ;
} else {
h - > intra16x16_pred_mode = check_intra_pred_mode ( h , h - > intra16x16_pred_mode ) ;
h - > intra16x16_pred_mode = ff_h264_ check_intra_pred_mode( h , h - > intra16x16_pred_mode ) ;
if ( h - > intra16x16_pred_mode < 0 )
return - 1 ;
}
if ( CHROMA ) {
pred_mode = check_intra_pred_mode ( h , get_ue_golomb_31 ( & s - > gb ) ) ;
pred_mode = ff_h264_ check_intra_pred_mode( h , get_ue_golomb_31 ( & s - > gb ) ) ;
if ( pred_mode < 0 )
return - 1 ;
h - > chroma_pred_mode = pred_mode ;
@ -5662,17 +5498,17 @@ decode_intra_mb:
//av_log( s->avctx, AV_LOG_ERROR, "i4x4 pred=%d mode=%d\n", pred, h->intra4x4_pred_mode_cache[ scan8[i] ] );
}
}
write_back_intra_pred_mode ( h ) ;
ff_h264_ write_back_intra_pred_mode( h ) ;
if ( check_intra4x4_pred_mode ( h ) < 0 ) return - 1 ;
} else {
h - > intra16x16_pred_mode = check_intra_pred_mode ( h , h - > intra16x16_pred_mode ) ;
h - > intra16x16_pred_mode = ff_h264_ check_intra_pred_mode( h , h - > intra16x16_pred_mode ) ;
if ( h - > intra16x16_pred_mode < 0 ) return - 1 ;
}
if ( CHROMA ) {
h - > chroma_pred_mode_table [ mb_xy ] =
pred_mode = decode_cabac_mb_chroma_pre_mode ( h ) ;
pred_mode = check_intra_pred_mode ( h , pred_mode ) ;
pred_mode = ff_h264_ check_intra_pred_mode( h , pred_mode ) ;
if ( pred_mode < 0 ) return - 1 ;
h - > chroma_pred_mode = pred_mode ;
}
@ -6734,14 +6570,14 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
int eos ;
//STOP_TIMER("decode_mb_cabac")
if ( ret > = 0 ) hl_decode_mb ( h ) ;
if ( ret > = 0 ) ff_h264_ hl_decode_mb( h ) ;
if ( ret > = 0 & & FRAME_MBAFF ) { //FIXME optimal? or let mb_decode decode 16x32 ?
s - > mb_y + + ;
ret = decode_mb_cabac ( h ) ;
if ( ret > = 0 ) hl_decode_mb ( h ) ;
if ( ret > = 0 ) ff_h264_ hl_decode_mb( h ) ;
s - > mb_y - - ;
}
eos = get_cabac_terminate ( & h - > cabac ) ;
@ -6772,13 +6608,13 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
for ( ; ; ) {
int ret = decode_mb_cavlc ( h ) ;
if ( ret > = 0 ) hl_decode_mb ( h ) ;
if ( ret > = 0 ) ff_h264_ hl_decode_mb( h ) ;
if ( ret > = 0 & & FRAME_MBAFF ) { //FIXME optimal? or let mb_decode decode 16x32 ?
s - > mb_y + + ;
ret = decode_mb_cavlc ( h ) ;
if ( ret > = 0 ) hl_decode_mb ( h ) ;
if ( ret > = 0 ) ff_h264_ hl_decode_mb( h ) ;
s - > mb_y - - ;
}
@ -6831,7 +6667,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
for ( ; s - > mb_x < s - > mb_width ; s - > mb_x + + ) {
int ret = decode_mb ( h ) ;
hl_decode_mb ( h ) ;
ff_h264_ hl_decode_mb( h ) ;
if ( ret < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " error while decoding MB %d %d \n " , s - > mb_x , s - > mb_y ) ;
@ -8176,7 +8012,7 @@ av_cold void ff_h264_free_context(H264Context *h)
av_freep ( h - > pps_buffers + i ) ;
}
static av_cold int decode_end ( AVCodecContext * avctx )
av_cold int ff_h264_ decode_end( AVCodecContext * avctx )
{
H264Context * h = avctx - > priv_data ;
MpegEncContext * s = & h - > s ;
@ -8196,9 +8032,9 @@ AVCodec h264_decoder = {
CODEC_TYPE_VIDEO ,
CODEC_ID_H264 ,
sizeof ( H264Context ) ,
decode_init ,
ff_h264_ decode_init,
NULL ,
decode_end ,
ff_h264_ decode_end,
decode_frame ,
/*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY ,
. flush = flush_dpb ,
@ -8212,9 +8048,9 @@ AVCodec h264_vdpau_decoder = {
CODEC_TYPE_VIDEO ,
CODEC_ID_H264 ,
sizeof ( H264Context ) ,
decode_init ,
ff_h264_ decode_init,
NULL ,
decode_end ,
ff_h264_ decode_end,
decode_frame ,
CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU ,
. flush = flush_dpb ,
@ -8222,7 +8058,3 @@ AVCodec h264_vdpau_decoder = {
. pix_fmts = ( const enum PixelFormat [ ] ) { PIX_FMT_VDPAU_H264 , PIX_FMT_NONE } ,
} ;
# endif
# if CONFIG_SVQ3_DECODER
# include "svq3.c"
# endif