2003-04-04 17:42:28 +03:00
/*
2011-01-22 05:49:55 +02:00
* H .26 L / H .264 / AVC / JVT / 14496 - 10 / . . . decoder
2003-04-04 17:42:28 +03:00
* Copyright ( c ) 2003 Michael Niedermayer < michaelni @ gmx . at >
*
2006-10-07 18:30:46 +03:00
* This file is part of FFmpeg .
*
* FFmpeg is free software ; you can redistribute it and / or
2003-04-04 17:42:28 +03:00
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
2006-10-07 18:30:46 +03:00
* version 2.1 of the License , or ( at your option ) any later version .
2003-04-04 17:42:28 +03:00
*
2006-10-07 18:30:46 +03:00
* FFmpeg is distributed in the hope that it will be useful ,
2003-04-04 17:42:28 +03:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
2006-10-07 18:30:46 +03:00
* License along with FFmpeg ; 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
2003-04-04 17:42:28 +03:00
*/
2005-12-17 20:14:38 +02:00
2003-04-04 17:42:28 +03:00
/**
2010-04-20 17:45:34 +03:00
* @ file
2003-04-04 17:42:28 +03:00
* H .264 / AVC / MPEG4 part10 codec .
* @ author Michael Niedermayer < michaelni @ gmx . at >
*/
2011-12-18 05:17:44 +03:00
# define UNCHECKED_BITSTREAM_READER 1
2011-02-07 15:37:08 +02:00
# include "libavutil/imgutils.h"
2011-11-02 20:39:42 +03:00
# include "libavutil/opt.h"
2009-02-23 15:44:51 +02:00
# include "internal.h"
2012-01-12 23:56:02 +03:00
# include "cabac.h"
# include "cabac_functions.h"
2003-04-04 17:42:28 +03:00
# include "dsputil.h"
# include "avcodec.h"
# include "mpegvideo.h"
2007-05-11 01:26:44 +03:00
# include "h264.h"
2003-04-04 17:42:28 +03:00
# include "h264data.h"
2010-01-12 23:36:26 +02:00
# include "h264_mvpred.h"
2003-04-04 17:42:28 +03:00
# include "golomb.h"
2009-01-19 00:57:40 +02:00
# include "mathops.h"
2007-12-15 08:06:16 +02:00
# include "rectangle.h"
2011-03-22 23:36:57 +02:00
# include "thread.h"
2009-01-05 01:55:27 +02:00
# include "vdpau_internal.h"
2010-10-05 04:43:25 +03:00
# include "libavutil/avassert.h"
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
// #undef NDEBUG
2003-04-04 17:42:28 +03:00
# include <assert.h>
2012-04-04 15:53:25 +03:00
const uint16_t ff_h264_mb_sizes [ 4 ] = { 256 , 384 , 512 , 768 } ;
2012-03-16 20:40:05 +03:00
static const uint8_t rem6 [ QP_MAX_NUM + 1 ] = {
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 , 4 , 5 , 0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 ,
2006-12-07 11:59:05 +02:00
} ;
2012-03-16 20:40:05 +03:00
static const uint8_t div6 [ QP_MAX_NUM + 1 ] = {
0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 ,
3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 6 , 6 ,
7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 ,
2006-12-07 11:59:05 +02:00
} ;
2010-05-29 02:15:30 +03:00
static const enum PixelFormat hwaccel_pixfmt_list_h264_jpeg_420 [ ] = {
PIX_FMT_DXVA2_VLD ,
PIX_FMT_VAAPI_VLD ,
2011-11-02 02:55:09 +03:00
PIX_FMT_VDA_VLD ,
2010-05-29 02:15:30 +03:00
PIX_FMT_YUVJ420P ,
PIX_FMT_NONE
} ;
2010-01-12 23:17:26 +02:00
/**
2011-12-07 15:03:53 +03:00
* Check if the top & left blocks are available if needed and
* change the dc mode so it only uses the available blocks .
2010-01-12 23:17:26 +02:00
*/
2012-03-16 20:40:05 +03:00
int ff_h264_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
} ;
2010-01-12 23:17:26 +02:00
int i ;
2012-03-16 20:40:05 +03:00
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 ) ;
2010-01-12 23:17:26 +02:00
return - 1 ;
2012-03-16 20:40:05 +03:00
} else if ( status ) {
h - > intra4x4_pred_mode_cache [ scan8 [ 0 ] + i ] = status ;
2010-01-12 23:17:26 +02:00
}
}
}
2012-03-16 20:40:05 +03:00
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 ) ;
2010-01-12 23:17:26 +02:00
return - 1 ;
2012-03-16 20:40:05 +03:00
} else if ( status ) {
h - > intra4x4_pred_mode_cache [ scan8 [ 0 ] + 8 * i ] = status ;
2010-01-12 23:17:26 +02:00
}
}
}
return 0 ;
2012-03-16 20:40:05 +03:00
} // FIXME cleanup like ff_h264_check_intra_pred_mode
2005-12-17 20:14:38 +02:00
2003-04-04 17:42:28 +03:00
/**
2011-12-07 15:03:53 +03:00
* Check if the top & left blocks are available if needed and
* change the dc mode so it only uses the available blocks .
2003-04-04 17:42:28 +03:00
*/
2012-03-16 20:40:05 +03:00
int ff_h264_check_intra_pred_mode ( H264Context * h , int mode , int is_chroma )
{
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 } ;
if ( mode > 6U ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" out of range intra chroma pred mode at %d %d \n " ,
s - > mb_x , s - > mb_y ) ;
2004-08-03 04:50:52 +03:00
return - 1 ;
2004-12-18 05:49:07 +02:00
}
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( ! ( h - > top_samples_available & 0x8000 ) ) {
mode = top [ mode ] ;
if ( mode < 0 ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" top block unavailable for requested intra mode at %d %d \n " ,
s - > mb_x , s - > mb_y ) ;
2003-04-04 17:42:28 +03:00
return - 1 ;
}
}
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( ( h - > left_samples_available & 0x8080 ) ! = 0x8080 ) {
mode = left [ mode ] ;
if ( is_chroma & & ( h - > left_samples_available & 0x8080 ) ) {
// mad cow disease mode, aka MBAFF + constrained_intra_pred
mode = ALZHEIMER_DC_L0T_PRED8x8 +
( ! ( h - > left_samples_available & 0x8000 ) ) +
2 * ( mode = = DC_128_PRED8x8 ) ;
2008-08-11 05:21:33 +03:00
}
2012-03-16 20:40:05 +03:00
if ( mode < 0 ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" left block unavailable for requested intra mode at %d %d \n " ,
s - > mb_x , s - > mb_y ) ;
2003-04-04 17:42:28 +03:00
return - 1 ;
2005-12-17 20:14:38 +02:00
}
2003-04-04 17:42:28 +03:00
}
return mode ;
}
2012-03-16 20:40:05 +03:00
const uint8_t * ff_h264_decode_nal ( H264Context * h , const uint8_t * src ,
int * dst_length , int * consumed , int length )
{
2003-04-04 17:42:28 +03:00
int i , si , di ;
uint8_t * dst ;
2007-06-20 11:53:53 +03:00
int bufidx ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
// src[0]&0x80; // forbidden bit
h - > nal_ref_idc = src [ 0 ] > > 5 ;
h - > nal_unit_type = src [ 0 ] & 0x1F ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
src + + ;
length - - ;
2008-12-23 02:38:45 +02:00
2009-01-14 01:44:16 +02:00
# if HAVE_FAST_UNALIGNED
2012-03-16 20:40:05 +03:00
# if HAVE_FAST_64BIT
# define RS 7
for ( i = 0 ; i + 1 < length ; i + = 9 ) {
if ( ! ( ( ~ AV_RN64A ( src + i ) &
( AV_RN64A ( src + i ) - 0x0100010001000101ULL ) ) &
0x8000800080008080ULL ) )
# else
# define RS 3
for ( i = 0 ; i + 1 < length ; i + = 5 ) {
if ( ! ( ( ~ AV_RN32A ( src + i ) &
( AV_RN32A ( src + i ) - 0x01000101U ) ) &
0x80008080U ) )
# endif
2008-12-23 02:38:45 +02:00
continue ;
2012-03-16 20:40:05 +03:00
if ( i > 0 & & ! src [ i ] )
i - - ;
while ( src [ i ] )
i + + ;
2008-12-23 02:38:45 +02:00
# else
2012-03-16 20:40:05 +03:00
# define RS 0
for ( i = 0 ; i + 1 < length ; i + = 2 ) {
if ( src [ i ] )
continue ;
if ( i > 0 & & src [ i - 1 ] = = 0 )
i - - ;
2008-12-23 02:38:45 +02:00
# endif
2012-03-16 20:40:05 +03:00
if ( i + 2 < length & & src [ i + 1 ] = = 0 & & src [ i + 2 ] < = 3 ) {
if ( src [ i + 2 ] ! = 3 ) {
2003-04-04 17:42:28 +03:00
/* startcode, so we must be past the end */
2012-03-16 20:40:05 +03:00
length = i ;
2003-04-04 17:42:28 +03:00
}
break ;
}
2012-03-16 20:40:05 +03:00
i - = RS ;
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
// use second escape buffer for inter data
bufidx = h - > nal_unit_type = = NAL_DPC ? 1 : 0 ;
2012-03-17 06:43:12 +03:00
si = h - > rbsp_buffer_size [ bufidx ] ;
2012-02-19 05:47:52 +03:00
av_fast_padded_malloc ( & h - > rbsp_buffer [ bufidx ] , & h - > rbsp_buffer_size [ bufidx ] , length + MAX_MBPAIR_SIZE ) ;
2012-03-16 20:40:05 +03:00
dst = h - > rbsp_buffer [ bufidx ] ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( dst = = NULL )
2007-01-19 11:37:04 +02:00
return NULL ;
2011-09-10 17:28:53 +03:00
if ( i > = length - 1 ) { //no escaped 0
* dst_length = length ;
* consumed = length + 1 ; //+1 for the header
2011-09-14 21:48:00 +03:00
if ( h - > s . avctx - > flags2 & CODEC_FLAG2_FAST ) {
return src ;
} else {
memcpy ( dst , src , length ) ;
return dst ;
}
2011-09-10 17:28:53 +03:00
}
2012-03-16 20:40:05 +03:00
// printf("decoding esc\n");
2008-12-23 20:31:44 +02:00
memcpy ( dst , src , i ) ;
2012-03-16 20:40:05 +03:00
si = di = i ;
while ( si + 2 < length ) {
// remove escapes (very rare 1:2^22)
if ( src [ si + 2 ] > 3 ) {
dst [ di + + ] = src [ si + + ] ;
dst [ di + + ] = src [ si + + ] ;
} else if ( src [ si ] = = 0 & & src [ si + 1 ] = = 0 ) {
if ( src [ si + 2 ] = = 3 ) { // escape
dst [ di + + ] = 0 ;
dst [ di + + ] = 0 ;
si + = 3 ;
2004-04-23 22:44:27 +03:00
continue ;
2012-03-16 20:40:05 +03:00
} else // next start code
2008-12-23 20:31:44 +02:00
goto nsc ;
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
dst [ di + + ] = src [ si + + ] ;
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
while ( si < length )
dst [ di + + ] = src [ si + + ] ;
2008-12-23 20:31:44 +02:00
nsc :
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
memset ( dst + di , 0 , FF_INPUT_BUFFER_PADDING_SIZE ) ;
2008-12-19 03:11:52 +02:00
2012-03-16 20:40:05 +03:00
* dst_length = di ;
* consumed = si + 1 ; // +1 for the header
/* FIXME store exact number of bits in the getbitcontext
* ( it is needed for decoding ) */
2003-04-04 17:42:28 +03:00
return dst ;
}
2011-01-25 03:29:42 +02:00
/**
* Identify the exact end of the bitstream
* @ return the length of the trailing , or 0 if damaged
*/
2012-03-29 15:15:16 +03:00
static int decode_rbsp_trailing ( H264Context * h , const uint8_t * src )
2012-03-16 20:40:05 +03:00
{
int v = * src ;
2003-04-04 17:42:28 +03:00
int r ;
2007-02-27 11:39:04 +02:00
tprintf ( h - > s . avctx , " rbsp trailing %X \n " , v ) ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
for ( r = 1 ; r < 9 ; r + + ) {
if ( v & 1 )
return r ;
v > > = 1 ;
2003-04-04 17:42:28 +03:00
}
return 0 ;
}
2012-03-16 20:40:05 +03:00
static inline int get_lowest_part_list_y ( H264Context * h , Picture * pic , int n ,
int height , int y_offset , int list )
{
int raw_my = h - > mv_cache [ list ] [ scan8 [ n ] ] [ 1 ] ;
int filter_height = ( raw_my & 3 ) ? 2 : 0 ;
int full_my = ( raw_my > > 2 ) + y_offset ;
int top = full_my - filter_height ;
int bottom = full_my + filter_height + height ;
2011-06-02 20:15:58 +03:00
return FFMAX ( abs ( top ) , bottom ) ;
}
2012-03-16 20:40:05 +03:00
static inline void get_lowest_part_y ( H264Context * h , int refs [ 2 ] [ 48 ] , int n ,
int height , int y_offset , int list0 ,
int list1 , int * nrefs )
{
MpegEncContext * const s = & h - > s ;
2011-06-02 20:15:58 +03:00
int my ;
2012-03-16 20:40:05 +03:00
y_offset + = 16 * ( s - > mb_y > > MB_FIELD ) ;
2011-06-02 20:15:58 +03:00
2012-03-16 20:40:05 +03:00
if ( list0 ) {
int ref_n = h - > ref_cache [ 0 ] [ scan8 [ n ] ] ;
Picture * ref = & h - > ref_list [ 0 ] [ ref_n ] ;
2011-06-02 20:15:58 +03:00
// Error resilience puts the current picture in the ref list.
// Don't try to wait on these as it will cause a deadlock.
// Fields can wait on each other, though.
2012-03-16 20:40:05 +03:00
if ( ref - > f . thread_opaque ! = s - > current_picture . f . thread_opaque | |
( ref - > f . reference & 3 ) ! = s - > picture_structure ) {
2011-06-02 20:15:58 +03:00
my = get_lowest_part_list_y ( h , ref , n , height , y_offset , 0 ) ;
2012-03-16 20:40:05 +03:00
if ( refs [ 0 ] [ ref_n ] < 0 )
nrefs [ 0 ] + = 1 ;
2011-06-02 20:15:58 +03:00
refs [ 0 ] [ ref_n ] = FFMAX ( refs [ 0 ] [ ref_n ] , my ) ;
}
}
2012-03-16 20:40:05 +03:00
if ( list1 ) {
int ref_n = h - > ref_cache [ 1 ] [ scan8 [ n ] ] ;
Picture * ref = & h - > ref_list [ 1 ] [ ref_n ] ;
2011-06-02 20:15:58 +03:00
2012-03-16 20:40:05 +03:00
if ( ref - > f . thread_opaque ! = s - > current_picture . f . thread_opaque | |
( ref - > f . reference & 3 ) ! = s - > picture_structure ) {
2011-06-02 20:15:58 +03:00
my = get_lowest_part_list_y ( h , ref , n , height , y_offset , 1 ) ;
2012-03-16 20:40:05 +03:00
if ( refs [ 1 ] [ ref_n ] < 0 )
nrefs [ 1 ] + = 1 ;
2011-06-02 20:15:58 +03:00
refs [ 1 ] [ ref_n ] = FFMAX ( refs [ 1 ] [ ref_n ] , my ) ;
}
}
}
/**
* Wait until all reference frames are available for MC operations .
*
* @ param h the H264 context
*/
2012-03-16 20:40:05 +03:00
static void await_references ( H264Context * h )
{
MpegEncContext * const s = & h - > s ;
const int mb_xy = h - > mb_xy ;
2011-07-06 21:08:30 +03:00
const int mb_type = s - > current_picture . f . mb_type [ mb_xy ] ;
2011-06-02 20:15:58 +03:00
int refs [ 2 ] [ 48 ] ;
2012-03-16 20:40:05 +03:00
int nrefs [ 2 ] = { 0 } ;
2011-06-02 20:15:58 +03:00
int ref , list ;
memset ( refs , - 1 , sizeof ( refs ) ) ;
2012-03-16 20:40:05 +03:00
if ( IS_16X16 ( mb_type ) ) {
2011-06-02 20:15:58 +03:00
get_lowest_part_y ( h , refs , 0 , 16 , 0 ,
2012-03-16 20:40:05 +03:00
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) , nrefs ) ;
} else if ( IS_16X8 ( mb_type ) ) {
2011-06-02 20:15:58 +03:00
get_lowest_part_y ( h , refs , 0 , 8 , 0 ,
2012-03-16 20:40:05 +03:00
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) , nrefs ) ;
2011-06-02 20:15:58 +03:00
get_lowest_part_y ( h , refs , 8 , 8 , 8 ,
2012-03-16 20:40:05 +03:00
IS_DIR ( mb_type , 1 , 0 ) , IS_DIR ( mb_type , 1 , 1 ) , nrefs ) ;
} else if ( IS_8X16 ( mb_type ) ) {
2011-06-02 20:15:58 +03:00
get_lowest_part_y ( h , refs , 0 , 16 , 0 ,
2012-03-16 20:40:05 +03:00
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) , nrefs ) ;
2011-06-02 20:15:58 +03:00
get_lowest_part_y ( h , refs , 4 , 16 , 0 ,
2012-03-16 20:40:05 +03:00
IS_DIR ( mb_type , 1 , 0 ) , IS_DIR ( mb_type , 1 , 1 ) , nrefs ) ;
} else {
2011-06-02 20:15:58 +03:00
int i ;
assert ( IS_8X8 ( mb_type ) ) ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 4 ; i + + ) {
const int sub_mb_type = h - > sub_mb_type [ i ] ;
const int n = 4 * i ;
int y_offset = ( i & 2 ) < < 2 ;
if ( IS_SUB_8X8 ( sub_mb_type ) ) {
get_lowest_part_y ( h , refs , n , 8 , y_offset ,
IS_DIR ( sub_mb_type , 0 , 0 ) ,
IS_DIR ( sub_mb_type , 0 , 1 ) ,
nrefs ) ;
} else if ( IS_SUB_8X4 ( sub_mb_type ) ) {
get_lowest_part_y ( h , refs , n , 4 , y_offset ,
IS_DIR ( sub_mb_type , 0 , 0 ) ,
IS_DIR ( sub_mb_type , 0 , 1 ) ,
nrefs ) ;
get_lowest_part_y ( h , refs , n + 2 , 4 , y_offset + 4 ,
IS_DIR ( sub_mb_type , 0 , 0 ) ,
IS_DIR ( sub_mb_type , 0 , 1 ) ,
nrefs ) ;
} else if ( IS_SUB_4X8 ( sub_mb_type ) ) {
get_lowest_part_y ( h , refs , n , 8 , y_offset ,
IS_DIR ( sub_mb_type , 0 , 0 ) ,
IS_DIR ( sub_mb_type , 0 , 1 ) ,
nrefs ) ;
get_lowest_part_y ( h , refs , n + 1 , 8 , y_offset ,
IS_DIR ( sub_mb_type , 0 , 0 ) ,
IS_DIR ( sub_mb_type , 0 , 1 ) ,
nrefs ) ;
} else {
2011-06-02 20:15:58 +03:00
int j ;
assert ( IS_SUB_4X4 ( sub_mb_type ) ) ;
2012-03-16 20:40:05 +03:00
for ( j = 0 ; j < 4 ; j + + ) {
int sub_y_offset = y_offset + 2 * ( j & 2 ) ;
get_lowest_part_y ( h , refs , n + j , 4 , sub_y_offset ,
IS_DIR ( sub_mb_type , 0 , 0 ) ,
IS_DIR ( sub_mb_type , 0 , 1 ) ,
nrefs ) ;
2011-06-02 20:15:58 +03:00
}
}
}
}
2012-03-16 20:40:05 +03:00
for ( list = h - > list_count - 1 ; list > = 0 ; list - - )
for ( ref = 0 ; ref < 48 & & nrefs [ list ] ; ref + + ) {
2011-06-02 20:15:58 +03:00
int row = refs [ list ] [ ref ] ;
2012-03-16 20:40:05 +03:00
if ( row > = 0 ) {
Picture * ref_pic = & h - > ref_list [ list ] [ ref ] ;
int ref_field = ref_pic - > f . reference - 1 ;
2011-06-02 20:15:58 +03:00
int ref_field_picture = ref_pic - > field_picture ;
2012-03-16 20:40:05 +03:00
int pic_height = 16 * s - > mb_height > > ref_field_picture ;
2011-06-02 20:15:58 +03:00
row < < = MB_MBAFF ;
nrefs [ list ] - - ;
2012-03-16 20:40:05 +03:00
if ( ! FIELD_PICTURE & & ref_field_picture ) { // frame referencing two fields
ff_thread_await_progress ( & ref_pic - > f ,
FFMIN ( ( row > > 1 ) - ! ( row & 1 ) ,
pic_height - 1 ) ,
1 ) ;
ff_thread_await_progress ( & ref_pic - > f ,
FFMIN ( ( row > > 1 ) , pic_height - 1 ) ,
0 ) ;
} else if ( FIELD_PICTURE & & ! ref_field_picture ) { // field referencing one field of a frame
ff_thread_await_progress ( & ref_pic - > f ,
FFMIN ( row * 2 + ref_field ,
pic_height - 1 ) ,
0 ) ;
} else if ( FIELD_PICTURE ) {
ff_thread_await_progress ( & ref_pic - > f ,
FFMIN ( row , pic_height - 1 ) ,
ref_field ) ;
} else {
ff_thread_await_progress ( & ref_pic - > f ,
FFMIN ( row , pic_height - 1 ) ,
0 ) ;
2011-06-02 20:15:58 +03:00
}
}
}
}
2012-03-16 20:40:05 +03:00
static av_always_inline void mc_dir_part ( H264Context * h , Picture * pic ,
int n , int square , int height ,
int delta , int list ,
uint8_t * dest_y , uint8_t * dest_cb ,
uint8_t * dest_cr ,
int src_x_offset , int src_y_offset ,
qpel_mc_func * qpix_op ,
h264_chroma_mc_func chroma_op ,
int pixel_shift , int chroma_idc )
2011-10-21 10:01:16 +03:00
{
2012-03-16 20:40:05 +03:00
MpegEncContext * const s = & h - > s ;
const int mx = h - > mv_cache [ list ] [ scan8 [ n ] ] [ 0 ] + src_x_offset * 8 ;
int my = h - > mv_cache [ list ] [ scan8 [ n ] ] [ 1 ] + src_y_offset * 8 ;
const int luma_xy = ( mx & 3 ) + ( ( my & 3 ) < < 2 ) ;
int offset = ( ( mx > > 2 ) < < pixel_shift ) + ( my > > 2 ) * h - > mb_linesize ;
uint8_t * src_y = pic - > f . data [ 0 ] + offset ;
uint8_t * src_cb , * src_cr ;
int extra_width = h - > emu_edge_width ;
int extra_height = h - > emu_edge_height ;
int emu = 0 ;
const int full_mx = mx > > 2 ;
const int full_my = my > > 2 ;
const int pic_width = 16 * s - > mb_width ;
const int pic_height = 16 * s - > mb_height > > MB_FIELD ;
2011-10-12 18:55:37 +03:00
int ysh ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
if ( mx & 7 )
extra_width - = 3 ;
if ( my & 7 )
extra_height - = 3 ;
if ( full_mx < 0 - extra_width | |
full_my < 0 - extra_height | |
full_mx + 16 /*FIXME*/ > pic_width + extra_width | |
full_my + 16 /*FIXME*/ > pic_height + extra_height ) {
s - > dsp . emulated_edge_mc ( s - > edge_emu_buffer ,
src_y - ( 2 < < pixel_shift ) - 2 * h - > mb_linesize ,
h - > mb_linesize ,
16 + 5 , 16 + 5 /*FIXME*/ , full_mx - 2 ,
full_my - 2 , pic_width , pic_height ) ;
src_y = s - > edge_emu_buffer + ( 2 < < pixel_shift ) + 2 * h - > mb_linesize ;
emu = 1 ;
}
qpix_op [ luma_xy ] ( dest_y , src_y , h - > mb_linesize ) ; // FIXME try variable height perhaps?
if ( ! square )
2011-06-13 04:00:53 +03:00
qpix_op [ luma_xy ] ( dest_y + delta , src_y + delta , h - > mb_linesize ) ;
2012-03-16 20:40:05 +03:00
if ( CONFIG_GRAY & & s - > flags & CODEC_FLAG_GRAY )
return ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
if ( chroma_idc = = 3 /* yuv444 */ ) {
2011-07-06 21:08:30 +03:00
src_cb = pic - > f . data [ 1 ] + offset ;
2012-03-16 20:40:05 +03:00
if ( emu ) {
s - > dsp . emulated_edge_mc ( s - > edge_emu_buffer ,
src_cb - ( 2 < < pixel_shift ) - 2 * h - > mb_linesize ,
h - > mb_linesize ,
16 + 5 , 16 + 5 /*FIXME*/ ,
full_mx - 2 , full_my - 2 ,
pic_width , pic_height ) ;
src_cb = s - > edge_emu_buffer + ( 2 < < pixel_shift ) + 2 * h - > mb_linesize ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
qpix_op [ luma_xy ] ( dest_cb , src_cb , h - > mb_linesize ) ; // FIXME try variable height perhaps?
if ( ! square )
2011-06-03 11:12:28 +03:00
qpix_op [ luma_xy ] ( dest_cb + delta , src_cb + delta , h - > mb_linesize ) ;
2011-07-06 21:08:30 +03:00
src_cr = pic - > f . data [ 2 ] + offset ;
2012-03-16 20:40:05 +03:00
if ( emu ) {
s - > dsp . emulated_edge_mc ( s - > edge_emu_buffer ,
src_cr - ( 2 < < pixel_shift ) - 2 * h - > mb_linesize ,
h - > mb_linesize ,
16 + 5 , 16 + 5 /*FIXME*/ ,
full_mx - 2 , full_my - 2 ,
pic_width , pic_height ) ;
src_cr = s - > edge_emu_buffer + ( 2 < < pixel_shift ) + 2 * h - > mb_linesize ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
qpix_op [ luma_xy ] ( dest_cr , src_cr , h - > mb_linesize ) ; // FIXME try variable height perhaps?
if ( ! square )
2011-06-03 11:12:28 +03:00
qpix_op [ luma_xy ] ( dest_cr + delta , src_cr + delta , h - > mb_linesize ) ;
return ;
}
2011-10-21 10:01:16 +03:00
ysh = 3 - ( chroma_idc = = 2 /* yuv422 */ ) ;
2012-03-16 20:40:05 +03:00
if ( chroma_idc = = 1 /* yuv420 */ & & MB_FIELD ) {
2011-06-13 04:00:53 +03:00
// chroma offset when predicting from a field of opposite parity
2012-03-16 20:40:05 +03:00
my + = 2 * ( ( s - > mb_y & 1 ) - ( pic - > f . reference - 1 ) ) ;
emu | = ( my > > 3 ) < 0 | | ( my > > 3 ) + 8 > = ( pic_height > > 1 ) ;
2011-06-13 04:00:53 +03:00
}
2011-10-12 18:55:37 +03:00
2012-03-16 20:40:05 +03:00
src_cb = pic - > f . data [ 1 ] + ( ( mx > > 3 ) < < pixel_shift ) +
( my > > ysh ) * h - > mb_uvlinesize ;
src_cr = pic - > f . data [ 2 ] + ( ( mx > > 3 ) < < pixel_shift ) +
( my > > ysh ) * h - > mb_uvlinesize ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
if ( emu ) {
2011-10-21 10:01:16 +03:00
s - > dsp . emulated_edge_mc ( s - > edge_emu_buffer , src_cb , h - > mb_uvlinesize ,
9 , 8 * chroma_idc + 1 , ( mx > > 3 ) , ( my > > ysh ) ,
pic_width > > 1 , pic_height > > ( chroma_idc = = 1 /* yuv420 */ ) ) ;
2012-03-16 20:40:05 +03:00
src_cb = s - > edge_emu_buffer ;
2011-06-13 04:00:53 +03:00
}
2012-03-16 20:40:05 +03:00
chroma_op ( dest_cb , src_cb , h - > mb_uvlinesize ,
height > > ( chroma_idc = = 1 /* yuv420 */ ) ,
mx & 7 , ( my < < ( chroma_idc = = 2 /* yuv422 */ ) ) & 7 ) ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
if ( emu ) {
2011-10-21 10:01:16 +03:00
s - > dsp . emulated_edge_mc ( s - > edge_emu_buffer , src_cr , h - > mb_uvlinesize ,
9 , 8 * chroma_idc + 1 , ( mx > > 3 ) , ( my > > ysh ) ,
pic_width > > 1 , pic_height > > ( chroma_idc = = 1 /* yuv420 */ ) ) ;
2012-03-16 20:40:05 +03:00
src_cr = s - > edge_emu_buffer ;
2011-06-13 04:00:53 +03:00
}
2011-10-21 10:01:16 +03:00
chroma_op ( dest_cr , src_cr , h - > mb_uvlinesize , height > > ( chroma_idc = = 1 /* yuv420 */ ) ,
2012-03-16 20:40:05 +03:00
mx & 7 , ( my < < ( chroma_idc = = 2 /* yuv422 */ ) ) & 7 ) ;
2011-06-13 04:00:53 +03:00
}
2012-03-16 20:40:05 +03:00
static av_always_inline void mc_part_std ( H264Context * h , int n , int square ,
int height , int delta ,
uint8_t * dest_y , uint8_t * dest_cb ,
uint8_t * dest_cr ,
int x_offset , int y_offset ,
qpel_mc_func * qpix_put ,
h264_chroma_mc_func chroma_put ,
qpel_mc_func * qpix_avg ,
h264_chroma_mc_func chroma_avg ,
int list0 , int list1 ,
int pixel_shift , int chroma_idc )
2011-10-21 10:01:16 +03:00
{
2012-03-16 20:40:05 +03:00
MpegEncContext * const s = & h - > s ;
qpel_mc_func * qpix_op = qpix_put ;
h264_chroma_mc_func chroma_op = chroma_put ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
dest_y + = ( 2 * x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_linesize ;
2011-10-21 10:01:16 +03:00
if ( chroma_idc = = 3 /* yuv444 */ ) {
2012-03-16 20:40:05 +03:00
dest_cb + = ( 2 * x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_linesize ;
dest_cr + = ( 2 * x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_linesize ;
2011-10-21 10:01:16 +03:00
} else if ( chroma_idc = = 2 /* yuv422 */ ) {
2012-03-16 20:40:05 +03:00
dest_cb + = ( x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_uvlinesize ;
dest_cr + = ( x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_uvlinesize ;
} else { /* yuv420 */
dest_cb + = ( x_offset < < pixel_shift ) + y_offset * h - > mb_uvlinesize ;
dest_cr + = ( x_offset < < pixel_shift ) + y_offset * h - > mb_uvlinesize ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
x_offset + = 8 * s - > mb_x ;
y_offset + = 8 * ( s - > mb_y > > MB_FIELD ) ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
if ( list0 ) {
Picture * ref = & h - > ref_list [ 0 ] [ h - > ref_cache [ 0 ] [ scan8 [ n ] ] ] ;
2011-10-21 10:00:39 +03:00
mc_dir_part ( h , ref , n , square , height , delta , 0 ,
2012-03-16 20:40:05 +03:00
dest_y , dest_cb , dest_cr , x_offset , y_offset ,
qpix_op , chroma_op , pixel_shift , chroma_idc ) ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
qpix_op = qpix_avg ;
chroma_op = chroma_avg ;
2011-06-13 04:00:53 +03:00
}
2012-03-16 20:40:05 +03:00
if ( list1 ) {
Picture * ref = & h - > ref_list [ 1 ] [ h - > ref_cache [ 1 ] [ scan8 [ n ] ] ] ;
2011-10-21 10:00:39 +03:00
mc_dir_part ( h , ref , n , square , height , delta , 1 ,
2012-03-16 20:40:05 +03:00
dest_y , dest_cb , dest_cr , x_offset , y_offset ,
qpix_op , chroma_op , pixel_shift , chroma_idc ) ;
2011-06-13 04:00:53 +03:00
}
}
2012-03-16 20:40:05 +03:00
static av_always_inline void mc_part_weighted ( H264Context * h , int n , int square ,
int height , int delta ,
uint8_t * dest_y , uint8_t * dest_cb ,
uint8_t * dest_cr ,
int x_offset , int y_offset ,
qpel_mc_func * qpix_put ,
h264_chroma_mc_func chroma_put ,
h264_weight_func luma_weight_op ,
h264_weight_func chroma_weight_op ,
h264_biweight_func luma_weight_avg ,
h264_biweight_func chroma_weight_avg ,
int list0 , int list1 ,
int pixel_shift , int chroma_idc )
{
MpegEncContext * const s = & h - > s ;
2011-10-21 10:00:39 +03:00
int chroma_height ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
dest_y + = ( 2 * x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_linesize ;
2011-10-21 10:01:16 +03:00
if ( chroma_idc = = 3 /* yuv444 */ ) {
2012-03-16 20:40:05 +03:00
chroma_height = height ;
2011-06-03 11:12:28 +03:00
chroma_weight_avg = luma_weight_avg ;
2012-03-16 20:40:05 +03:00
chroma_weight_op = luma_weight_op ;
dest_cb + = ( 2 * x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_linesize ;
dest_cr + = ( 2 * x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_linesize ;
2011-10-21 10:01:16 +03:00
} else if ( chroma_idc = = 2 /* yuv422 */ ) {
2011-10-21 10:00:39 +03:00
chroma_height = height ;
2012-03-16 20:40:05 +03:00
dest_cb + = ( x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_uvlinesize ;
dest_cr + = ( x_offset < < pixel_shift ) + 2 * y_offset * h - > mb_uvlinesize ;
} else { /* yuv420 */
2011-10-21 10:00:39 +03:00
chroma_height = height > > 1 ;
2012-03-16 20:40:05 +03:00
dest_cb + = ( x_offset < < pixel_shift ) + y_offset * h - > mb_uvlinesize ;
dest_cr + = ( x_offset < < pixel_shift ) + y_offset * h - > mb_uvlinesize ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
x_offset + = 8 * s - > mb_x ;
y_offset + = 8 * ( s - > mb_y > > MB_FIELD ) ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
if ( list0 & & list1 ) {
2011-06-13 04:00:53 +03:00
/* don't optimize for luma-only case, since B-frames usually
* use implicit weights = > chroma too . */
uint8_t * tmp_cb = s - > obmc_scratchpad ;
2011-06-03 11:12:28 +03:00
uint8_t * tmp_cr = s - > obmc_scratchpad + ( 16 < < pixel_shift ) ;
2012-03-16 20:40:05 +03:00
uint8_t * tmp_y = s - > obmc_scratchpad + 16 * h - > mb_uvlinesize ;
int refn0 = h - > ref_cache [ 0 ] [ scan8 [ n ] ] ;
int refn1 = h - > ref_cache [ 1 ] [ scan8 [ n ] ] ;
2011-06-13 04:00:53 +03:00
2011-10-21 10:00:39 +03:00
mc_dir_part ( h , & h - > ref_list [ 0 ] [ refn0 ] , n , square , height , delta , 0 ,
2011-06-13 04:00:53 +03:00
dest_y , dest_cb , dest_cr ,
2011-10-21 10:01:16 +03:00
x_offset , y_offset , qpix_put , chroma_put ,
pixel_shift , chroma_idc ) ;
2011-10-21 10:00:39 +03:00
mc_dir_part ( h , & h - > ref_list [ 1 ] [ refn1 ] , n , square , height , delta , 1 ,
2011-06-13 04:00:53 +03:00
tmp_y , tmp_cb , tmp_cr ,
2011-10-21 10:01:16 +03:00
x_offset , y_offset , qpix_put , chroma_put ,
pixel_shift , chroma_idc ) ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > use_weight = = 2 ) {
int weight0 = h - > implicit_weight [ refn0 ] [ refn1 ] [ s - > mb_y & 1 ] ;
2011-06-13 04:00:53 +03:00
int weight1 = 64 - weight0 ;
2012-03-16 20:40:05 +03:00
luma_weight_avg ( dest_y , tmp_y , h - > mb_linesize ,
height , 5 , weight0 , weight1 , 0 ) ;
2011-10-21 10:00:39 +03:00
chroma_weight_avg ( dest_cb , tmp_cb , h - > mb_uvlinesize ,
chroma_height , 5 , weight0 , weight1 , 0 ) ;
chroma_weight_avg ( dest_cr , tmp_cr , h - > mb_uvlinesize ,
chroma_height , 5 , weight0 , weight1 , 0 ) ;
2012-03-16 20:40:05 +03:00
} else {
luma_weight_avg ( dest_y , tmp_y , h - > mb_linesize , height ,
h - > luma_log2_weight_denom ,
h - > luma_weight [ refn0 ] [ 0 ] [ 0 ] ,
h - > luma_weight [ refn1 ] [ 1 ] [ 0 ] ,
h - > luma_weight [ refn0 ] [ 0 ] [ 1 ] +
h - > luma_weight [ refn1 ] [ 1 ] [ 1 ] ) ;
chroma_weight_avg ( dest_cb , tmp_cb , h - > mb_uvlinesize , chroma_height ,
h - > chroma_log2_weight_denom ,
h - > chroma_weight [ refn0 ] [ 0 ] [ 0 ] [ 0 ] ,
h - > chroma_weight [ refn1 ] [ 1 ] [ 0 ] [ 0 ] ,
h - > chroma_weight [ refn0 ] [ 0 ] [ 0 ] [ 1 ] +
h - > chroma_weight [ refn1 ] [ 1 ] [ 0 ] [ 1 ] ) ;
chroma_weight_avg ( dest_cr , tmp_cr , h - > mb_uvlinesize , chroma_height ,
h - > chroma_log2_weight_denom ,
h - > chroma_weight [ refn0 ] [ 0 ] [ 1 ] [ 0 ] ,
h - > chroma_weight [ refn1 ] [ 1 ] [ 1 ] [ 0 ] ,
h - > chroma_weight [ refn0 ] [ 0 ] [ 1 ] [ 1 ] +
h - > chroma_weight [ refn1 ] [ 1 ] [ 1 ] [ 1 ] ) ;
2011-06-13 04:00:53 +03:00
}
2012-03-16 20:40:05 +03:00
} else {
int list = list1 ? 1 : 0 ;
int refn = h - > ref_cache [ list ] [ scan8 [ n ] ] ;
Picture * ref = & h - > ref_list [ list ] [ refn ] ;
2011-10-21 10:00:39 +03:00
mc_dir_part ( h , ref , n , square , height , delta , list ,
2011-06-13 04:00:53 +03:00
dest_y , dest_cb , dest_cr , x_offset , y_offset ,
2011-10-21 10:01:16 +03:00
qpix_put , chroma_put , pixel_shift , chroma_idc ) ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
luma_weight_op ( dest_y , h - > mb_linesize , height ,
h - > luma_log2_weight_denom ,
h - > luma_weight [ refn ] [ list ] [ 0 ] ,
h - > luma_weight [ refn ] [ list ] [ 1 ] ) ;
if ( h - > use_weight_chroma ) {
chroma_weight_op ( dest_cb , h - > mb_uvlinesize , chroma_height ,
h - > chroma_log2_weight_denom ,
h - > chroma_weight [ refn ] [ list ] [ 0 ] [ 0 ] ,
h - > chroma_weight [ refn ] [ list ] [ 0 ] [ 1 ] ) ;
chroma_weight_op ( dest_cr , h - > mb_uvlinesize , chroma_height ,
h - > chroma_log2_weight_denom ,
h - > chroma_weight [ refn ] [ list ] [ 1 ] [ 0 ] ,
h - > chroma_weight [ refn ] [ list ] [ 1 ] [ 1 ] ) ;
2011-06-13 04:00:53 +03:00
}
}
}
2012-03-16 20:40:05 +03:00
static av_always_inline void mc_part ( H264Context * h , int n , int square ,
int height , int delta ,
uint8_t * dest_y , uint8_t * dest_cb ,
uint8_t * dest_cr ,
int x_offset , int y_offset ,
qpel_mc_func * qpix_put ,
h264_chroma_mc_func chroma_put ,
qpel_mc_func * qpix_avg ,
h264_chroma_mc_func chroma_avg ,
h264_weight_func * weight_op ,
h264_biweight_func * weight_avg ,
int list0 , int list1 ,
int pixel_shift , int chroma_idc )
2011-10-21 10:01:16 +03:00
{
2012-03-16 20:40:05 +03:00
if ( ( h - > use_weight = = 2 & & list0 & & list1 & &
( h - > implicit_weight [ h - > ref_cache [ 0 ] [ scan8 [ n ] ] ] [ h - > ref_cache [ 1 ] [ scan8 [ n ] ] ] [ h - > s . mb_y & 1 ] ! = 32 ) ) | |
h - > use_weight = = 1 )
2011-10-21 10:00:39 +03:00
mc_part_weighted ( h , n , square , height , delta , dest_y , dest_cb , dest_cr ,
2011-06-13 04:00:53 +03:00
x_offset , y_offset , qpix_put , chroma_put ,
2011-10-21 10:00:39 +03:00
weight_op [ 0 ] , weight_op [ 1 ] , weight_avg [ 0 ] ,
2011-10-21 10:01:16 +03:00
weight_avg [ 1 ] , list0 , list1 , pixel_shift , chroma_idc ) ;
2011-06-13 04:00:53 +03:00
else
2011-10-21 10:00:39 +03:00
mc_part_std ( h , n , square , height , delta , dest_y , dest_cb , dest_cr ,
2011-06-13 04:30:56 +03:00
x_offset , y_offset , qpix_put , chroma_put , qpix_avg ,
2011-10-21 10:01:16 +03:00
chroma_avg , list0 , list1 , pixel_shift , chroma_idc ) ;
2011-06-13 04:00:53 +03:00
}
2012-03-16 20:40:05 +03:00
static av_always_inline void prefetch_motion ( H264Context * h , int list ,
int pixel_shift , int chroma_idc )
2011-10-21 09:36:23 +03:00
{
2011-06-13 04:00:53 +03:00
/* fetch pixels for estimated mv 4 macroblocks ahead
* optimized for 64 byte cache lines */
2012-03-16 20:40:05 +03:00
MpegEncContext * const s = & h - > s ;
2011-06-13 04:00:53 +03:00
const int refn = h - > ref_cache [ list ] [ scan8 [ 0 ] ] ;
2012-03-16 20:40:05 +03:00
if ( refn > = 0 ) {
const int mx = ( h - > mv_cache [ list ] [ scan8 [ 0 ] ] [ 0 ] > > 2 ) + 16 * s - > mb_x + 8 ;
const int my = ( h - > mv_cache [ list ] [ scan8 [ 0 ] ] [ 1 ] > > 2 ) + 16 * s - > mb_y ;
2011-07-06 21:08:30 +03:00
uint8_t * * src = h - > ref_list [ list ] [ refn ] . f . data ;
2012-03-16 20:40:05 +03:00
int off = ( mx < < pixel_shift ) +
( my + ( s - > mb_x & 3 ) * 4 ) * h - > mb_linesize +
( 64 < < pixel_shift ) ;
s - > dsp . prefetch ( src [ 0 ] + off , s - > linesize , 4 ) ;
2011-10-21 10:01:16 +03:00
if ( chroma_idc = = 3 /* yuv444 */ ) {
2012-03-16 20:40:05 +03:00
s - > dsp . prefetch ( src [ 1 ] + off , s - > linesize , 4 ) ;
s - > dsp . prefetch ( src [ 2 ] + off , s - > linesize , 4 ) ;
} else {
2011-06-15 03:15:25 +03:00
off = ( ( ( mx > > 1 ) + 64 ) < < pixel_shift ) + ( ( my > > 1 ) + ( s - > mb_x & 7 ) ) * s - > uvlinesize ;
2012-03-16 20:40:05 +03:00
s - > dsp . prefetch ( src [ 1 ] + off , src [ 2 ] - src [ 1 ] , 2 ) ;
2011-06-03 11:12:28 +03:00
}
2011-06-13 04:00:53 +03:00
}
}
2012-03-16 20:40:05 +03:00
static av_always_inline void hl_motion ( H264Context * h , uint8_t * dest_y ,
uint8_t * dest_cb , uint8_t * dest_cr ,
qpel_mc_func ( * qpix_put ) [ 16 ] ,
h264_chroma_mc_func ( * chroma_put ) ,
qpel_mc_func ( * qpix_avg ) [ 16 ] ,
h264_chroma_mc_func ( * chroma_avg ) ,
h264_weight_func * weight_op ,
h264_biweight_func * weight_avg ,
int pixel_shift , int chroma_idc )
2011-10-21 10:01:16 +03:00
{
2012-03-16 20:40:05 +03:00
MpegEncContext * const s = & h - > s ;
const int mb_xy = h - > mb_xy ;
2011-07-06 21:08:30 +03:00
const int mb_type = s - > current_picture . f . mb_type [ mb_xy ] ;
2011-06-13 04:00:53 +03:00
assert ( IS_INTER ( mb_type ) ) ;
2012-03-16 20:40:05 +03:00
if ( HAVE_THREADS & & ( s - > avctx - > active_thread_type & FF_THREAD_FRAME ) )
2011-06-13 04:00:53 +03:00
await_references ( h ) ;
2011-10-21 10:01:16 +03:00
prefetch_motion ( h , 0 , pixel_shift , chroma_idc ) ;
2011-06-13 04:00:53 +03:00
2012-03-16 20:40:05 +03:00
if ( IS_16X16 ( mb_type ) ) {
2011-10-21 10:00:39 +03:00
mc_part ( h , 0 , 1 , 16 , 0 , dest_y , dest_cb , dest_cr , 0 , 0 ,
2011-06-13 04:00:53 +03:00
qpix_put [ 0 ] , chroma_put [ 0 ] , qpix_avg [ 0 ] , chroma_avg [ 0 ] ,
weight_op , weight_avg ,
2011-06-13 04:30:56 +03:00
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ,
2011-10-21 10:01:16 +03:00
pixel_shift , chroma_idc ) ;
2012-03-16 20:40:05 +03:00
} else if ( IS_16X8 ( mb_type ) ) {
2011-10-21 10:00:39 +03:00
mc_part ( h , 0 , 0 , 8 , 8 < < pixel_shift , dest_y , dest_cb , dest_cr , 0 , 0 ,
2011-06-13 04:00:53 +03:00
qpix_put [ 1 ] , chroma_put [ 0 ] , qpix_avg [ 1 ] , chroma_avg [ 0 ] ,
2011-10-21 10:00:39 +03:00
weight_op , weight_avg ,
2011-06-13 04:30:56 +03:00
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ,
2011-10-21 10:01:16 +03:00
pixel_shift , chroma_idc ) ;
2011-10-21 10:00:39 +03:00
mc_part ( h , 8 , 0 , 8 , 8 < < pixel_shift , dest_y , dest_cb , dest_cr , 0 , 4 ,
2011-06-13 04:00:53 +03:00
qpix_put [ 1 ] , chroma_put [ 0 ] , qpix_avg [ 1 ] , chroma_avg [ 0 ] ,
2011-10-21 10:00:39 +03:00
weight_op , weight_avg ,
2011-06-13 04:30:56 +03:00
IS_DIR ( mb_type , 1 , 0 ) , IS_DIR ( mb_type , 1 , 1 ) ,
2011-10-21 10:01:16 +03:00
pixel_shift , chroma_idc ) ;
2012-03-16 20:40:05 +03:00
} else if ( IS_8X16 ( mb_type ) ) {
mc_part ( h , 0 , 0 , 16 , 8 * h - > mb_linesize , dest_y , dest_cb , dest_cr , 0 , 0 ,
2011-06-13 04:00:53 +03:00
qpix_put [ 1 ] , chroma_put [ 1 ] , qpix_avg [ 1 ] , chroma_avg [ 1 ] ,
2011-10-21 10:00:39 +03:00
& weight_op [ 1 ] , & weight_avg [ 1 ] ,
2011-06-13 04:30:56 +03:00
IS_DIR ( mb_type , 0 , 0 ) , IS_DIR ( mb_type , 0 , 1 ) ,
2011-10-21 10:01:16 +03:00
pixel_shift , chroma_idc ) ;
2012-03-16 20:40:05 +03:00
mc_part ( h , 4 , 0 , 16 , 8 * h - > mb_linesize , dest_y , dest_cb , dest_cr , 4 , 0 ,
2011-06-13 04:00:53 +03:00
qpix_put [ 1 ] , chroma_put [ 1 ] , qpix_avg [ 1 ] , chroma_avg [ 1 ] ,
2011-10-21 10:00:39 +03:00
& weight_op [ 1 ] , & weight_avg [ 1 ] ,
2011-06-13 04:30:56 +03:00
IS_DIR ( mb_type , 1 , 0 ) , IS_DIR ( mb_type , 1 , 1 ) ,
2011-10-21 10:01:16 +03:00
pixel_shift , chroma_idc ) ;
2012-03-16 20:40:05 +03:00
} else {
2011-06-13 04:00:53 +03:00
int i ;
assert ( IS_8X8 ( mb_type ) ) ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 4 ; i + + ) {
const int sub_mb_type = h - > sub_mb_type [ i ] ;
const int n = 4 * i ;
int x_offset = ( i & 1 ) < < 2 ;
int y_offset = ( i & 2 ) < < 1 ;
if ( IS_SUB_8X8 ( sub_mb_type ) ) {
mc_part ( h , n , 1 , 8 , 0 , dest_y , dest_cb , dest_cr ,
x_offset , y_offset ,
qpix_put [ 1 ] , chroma_put [ 1 ] , qpix_avg [ 1 ] , chroma_avg [ 1 ] ,
& weight_op [ 1 ] , & weight_avg [ 1 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift , chroma_idc ) ;
} else if ( IS_SUB_8X4 ( sub_mb_type ) ) {
mc_part ( h , n , 0 , 4 , 4 < < pixel_shift , dest_y , dest_cb , dest_cr ,
x_offset , y_offset ,
qpix_put [ 2 ] , chroma_put [ 1 ] , qpix_avg [ 2 ] , chroma_avg [ 1 ] ,
& weight_op [ 1 ] , & weight_avg [ 1 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift , chroma_idc ) ;
mc_part ( h , n + 2 , 0 , 4 , 4 < < pixel_shift ,
dest_y , dest_cb , dest_cr , x_offset , y_offset + 2 ,
qpix_put [ 2 ] , chroma_put [ 1 ] , qpix_avg [ 2 ] , chroma_avg [ 1 ] ,
& weight_op [ 1 ] , & weight_avg [ 1 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift , chroma_idc ) ;
} else if ( IS_SUB_4X8 ( sub_mb_type ) ) {
mc_part ( h , n , 0 , 8 , 4 * h - > mb_linesize ,
dest_y , dest_cb , dest_cr , x_offset , y_offset ,
2003-04-04 17:42:28 +03:00
qpix_put [ 2 ] , chroma_put [ 2 ] , qpix_avg [ 2 ] , chroma_avg [ 2 ] ,
2011-10-21 10:00:39 +03:00
& weight_op [ 2 ] , & weight_avg [ 2 ] ,
2011-03-29 18:48:57 +03:00
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
2011-10-21 10:01:16 +03:00
pixel_shift , chroma_idc ) ;
2012-03-16 20:40:05 +03:00
mc_part ( h , n + 1 , 0 , 8 , 4 * h - > mb_linesize ,
dest_y , dest_cb , dest_cr , x_offset + 2 , y_offset ,
2011-06-13 04:00:53 +03:00
qpix_put [ 2 ] , chroma_put [ 2 ] , qpix_avg [ 2 ] , chroma_avg [ 2 ] ,
2011-10-21 10:00:39 +03:00
& weight_op [ 2 ] , & weight_avg [ 2 ] ,
2011-06-13 04:30:56 +03:00
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
2011-10-21 10:01:16 +03:00
pixel_shift , chroma_idc ) ;
2012-03-16 20:40:05 +03:00
} else {
int j ;
assert ( IS_SUB_4X4 ( sub_mb_type ) ) ;
for ( j = 0 ; j < 4 ; j + + ) {
int sub_x_offset = x_offset + 2 * ( j & 1 ) ;
int sub_y_offset = y_offset + ( j & 2 ) ;
mc_part ( h , n + j , 1 , 4 , 0 ,
dest_y , dest_cb , dest_cr , sub_x_offset , sub_y_offset ,
qpix_put [ 2 ] , chroma_put [ 2 ] , qpix_avg [ 2 ] , chroma_avg [ 2 ] ,
& weight_op [ 2 ] , & weight_avg [ 2 ] ,
IS_DIR ( sub_mb_type , 0 , 0 ) , IS_DIR ( sub_mb_type , 0 , 1 ) ,
pixel_shift , chroma_idc ) ;
2011-06-13 04:00:53 +03:00
}
}
}
}
2011-10-21 10:01:16 +03:00
prefetch_motion ( h , 1 , pixel_shift , chroma_idc ) ;
}
2012-03-16 20:40:05 +03:00
static av_always_inline void hl_motion_420 ( H264Context * h , uint8_t * dest_y ,
uint8_t * dest_cb , uint8_t * dest_cr ,
qpel_mc_func ( * qpix_put ) [ 16 ] ,
h264_chroma_mc_func ( * chroma_put ) ,
qpel_mc_func ( * qpix_avg ) [ 16 ] ,
h264_chroma_mc_func ( * chroma_avg ) ,
h264_weight_func * weight_op ,
h264_biweight_func * weight_avg ,
int pixel_shift )
2011-10-21 10:01:16 +03:00
{
hl_motion ( h , dest_y , dest_cb , dest_cr , qpix_put , chroma_put ,
qpix_avg , chroma_avg , weight_op , weight_avg , pixel_shift , 1 ) ;
}
2012-03-16 20:40:05 +03:00
static av_always_inline void hl_motion_422 ( H264Context * h , uint8_t * dest_y ,
uint8_t * dest_cb , uint8_t * dest_cr ,
qpel_mc_func ( * qpix_put ) [ 16 ] ,
h264_chroma_mc_func ( * chroma_put ) ,
qpel_mc_func ( * qpix_avg ) [ 16 ] ,
h264_chroma_mc_func ( * chroma_avg ) ,
h264_weight_func * weight_op ,
h264_biweight_func * weight_avg ,
int pixel_shift )
2011-10-21 10:01:16 +03:00
{
hl_motion ( h , dest_y , dest_cb , dest_cr , qpix_put , chroma_put ,
qpix_avg , chroma_avg , weight_op , weight_avg , pixel_shift , 2 ) ;
2011-06-13 04:00:53 +03:00
}
2012-03-16 20:40:05 +03:00
static void free_tables ( H264Context * h , int free_rbsp )
{
2007-05-29 17:35:29 +03:00
int i ;
2007-09-05 19:18:15 +03:00
H264Context * hx ;
2011-06-02 20:15:58 +03:00
2003-04-04 17:42:28 +03:00
av_freep ( & h - > intra4x4_pred_mode ) ;
2004-03-26 21:35:53 +02:00
av_freep ( & h - > chroma_pred_mode_table ) ;
av_freep ( & h - > cbp_table ) ;
2004-04-11 19:28:31 +03:00
av_freep ( & h - > mvd_table [ 0 ] ) ;
av_freep ( & h - > mvd_table [ 1 ] ) ;
2004-12-29 06:17:52 +02:00
av_freep ( & h - > direct_table ) ;
2003-04-04 17:42:28 +03:00
av_freep ( & h - > non_zero_count ) ;
av_freep ( & h - > slice_table_base ) ;
2012-03-16 20:40:05 +03:00
h - > slice_table = NULL ;
2010-01-17 22:35:55 +02:00
av_freep ( & h - > list_counts ) ;
2004-03-26 21:35:53 +02:00
2003-04-04 17:42:28 +03:00
av_freep ( & h - > mb2b_xy ) ;
2010-02-25 04:42:25 +02:00
av_freep ( & h - > mb2br_xy ) ;
2005-01-07 07:56:07 +02:00
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < MAX_THREADS ; i + + ) {
2007-09-05 19:18:15 +03:00
hx = h - > thread_context [ i ] ;
2012-03-16 20:40:05 +03:00
if ( ! hx )
continue ;
2007-09-05 19:18:15 +03:00
av_freep ( & hx - > top_borders [ 1 ] ) ;
av_freep ( & hx - > top_borders [ 0 ] ) ;
av_freep ( & hx - > s . obmc_scratchpad ) ;
2012-03-16 20:40:05 +03:00
if ( free_rbsp ) {
2011-01-22 16:42:57 +02:00
av_freep ( & hx - > rbsp_buffer [ 1 ] ) ;
av_freep ( & hx - > rbsp_buffer [ 0 ] ) ;
hx - > rbsp_buffer_size [ 0 ] = 0 ;
hx - > rbsp_buffer_size [ 1 ] = 0 ;
2011-01-22 16:42:56 +02:00
}
2012-03-16 20:40:05 +03:00
if ( i )
av_freep ( & h - > thread_context [ i ] ) ;
2007-09-05 19:18:15 +03:00
}
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
static void init_dequant8_coeff_table ( H264Context * h )
{
int i , j , q , x ;
const int max_qp = 51 + 6 * ( h - > sps . bit_depth_luma - 8 ) ;
2005-10-25 04:17:20 +03:00
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 6 ; i + + ) {
2011-06-03 11:12:28 +03:00
h - > dequant8_coeff [ i ] = h - > dequant8_buffer [ i ] ;
2012-03-16 20:40:05 +03:00
for ( j = 0 ; j < i ; j + + )
if ( ! memcmp ( h - > pps . scaling_matrix8 [ j ] , h - > pps . scaling_matrix8 [ i ] ,
64 * sizeof ( uint8_t ) ) ) {
2011-06-03 11:12:28 +03:00
h - > dequant8_coeff [ i ] = h - > dequant8_buffer [ j ] ;
break ;
}
2012-03-16 20:40:05 +03:00
if ( j < i )
2011-06-03 11:12:28 +03:00
continue ;
2005-10-25 04:17:20 +03:00
2012-03-16 20:40:05 +03:00
for ( q = 0 ; q < max_qp + 1 ; q + + ) {
2008-10-04 12:36:35 +03:00
int shift = div6 [ q ] ;
2012-03-16 20:40:05 +03:00
int idx = rem6 [ q ] ;
for ( x = 0 ; x < 64 ; x + + )
h - > dequant8_coeff [ i ] [ q ] [ ( x > > 3 ) | ( ( x & 7 ) < < 3 ) ] =
( ( uint32_t ) dequant8_coeff_init [ idx ] [ dequant8_coeff_init_scan [ ( ( x > > 1 ) & 12 ) | ( x & 3 ) ] ] *
h - > pps . scaling_matrix8 [ i ] [ x ] ) < < shift ;
2005-10-25 04:17:20 +03:00
}
}
}
2012-03-16 20:40:05 +03:00
static void init_dequant4_coeff_table ( H264Context * h )
{
int i , j , q , x ;
const int max_qp = 51 + 6 * ( h - > sps . bit_depth_luma - 8 ) ;
for ( i = 0 ; i < 6 ; i + + ) {
2005-10-25 04:17:20 +03:00
h - > dequant4_coeff [ i ] = h - > dequant4_buffer [ i ] ;
2012-03-16 20:40:05 +03:00
for ( j = 0 ; j < i ; j + + )
if ( ! memcmp ( h - > pps . scaling_matrix4 [ j ] , h - > pps . scaling_matrix4 [ i ] ,
16 * sizeof ( uint8_t ) ) ) {
2005-10-25 04:17:20 +03:00
h - > dequant4_coeff [ i ] = h - > dequant4_buffer [ j ] ;
break ;
}
2012-03-16 20:40:05 +03:00
if ( j < i )
2005-10-25 04:17:20 +03:00
continue ;
2012-03-16 20:40:05 +03:00
for ( q = 0 ; q < max_qp + 1 ; q + + ) {
2008-10-04 12:36:35 +03:00
int shift = div6 [ q ] + 2 ;
2012-03-16 20:40:05 +03:00
int idx = rem6 [ q ] ;
for ( x = 0 ; x < 16 ; x + + )
h - > dequant4_coeff [ i ] [ q ] [ ( x > > 2 ) | ( ( x < < 2 ) & 0xF ) ] =
( ( uint32_t ) dequant4_coeff_init [ idx ] [ ( x & 1 ) + ( ( x > > 2 ) & 1 ) ] *
h - > pps . scaling_matrix4 [ i ] [ x ] ) < < shift ;
2005-10-25 04:17:20 +03:00
}
}
}
2012-03-16 20:40:05 +03:00
static void init_dequant_tables ( H264Context * h )
{
int i , x ;
2005-10-25 04:17:20 +03:00
init_dequant4_coeff_table ( h ) ;
2012-03-16 20:40:05 +03:00
if ( h - > pps . transform_8x8_mode )
2005-10-25 04:17:20 +03:00
init_dequant8_coeff_table ( h ) ;
2012-03-16 20:40:05 +03:00
if ( h - > sps . transform_bypass ) {
for ( i = 0 ; i < 6 ; i + + )
for ( x = 0 ; x < 16 ; x + + )
h - > dequant4_coeff [ i ] [ 0 ] [ x ] = 1 < < 6 ;
if ( h - > pps . transform_8x8_mode )
for ( i = 0 ; i < 6 ; i + + )
for ( x = 0 ; x < 64 ; x + + )
h - > dequant8_coeff [ i ] [ 0 ] [ x ] = 1 < < 6 ;
2005-10-25 04:17:20 +03:00
}
}
2012-03-16 20:40:05 +03:00
int ff_h264_alloc_tables ( H264Context * h )
{
MpegEncContext * const s = & h - > s ;
const int big_mb_num = s - > mb_stride * ( s - > mb_height + 1 ) ;
2012-03-17 06:43:12 +03:00
const int row_mb_num = 2 * s - > mb_stride * FFMAX ( s - > avctx - > thread_count , 1 ) ;
2012-03-16 20:40:05 +03:00
int x , y ;
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > intra4x4_pred_mode ,
row_mb_num * 8 * sizeof ( uint8_t ) , fail )
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > non_zero_count ,
big_mb_num * 48 * sizeof ( uint8_t ) , fail )
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > slice_table_base ,
( big_mb_num + s - > mb_stride ) * sizeof ( * h - > slice_table_base ) , fail )
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > cbp_table ,
big_mb_num * sizeof ( uint16_t ) , fail )
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > chroma_pred_mode_table ,
big_mb_num * sizeof ( uint8_t ) , fail )
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > mvd_table [ 0 ] ,
16 * row_mb_num * sizeof ( uint8_t ) , fail ) ;
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > mvd_table [ 1 ] ,
16 * row_mb_num * sizeof ( uint8_t ) , fail ) ;
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > direct_table ,
4 * big_mb_num * sizeof ( uint8_t ) , fail ) ;
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > list_counts ,
big_mb_num * sizeof ( uint8_t ) , fail )
memset ( h - > slice_table_base , - 1 ,
( big_mb_num + s - > mb_stride ) * sizeof ( * h - > slice_table_base ) ) ;
h - > slice_table = h - > slice_table_base + s - > mb_stride * 2 + 1 ;
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > mb2b_xy ,
big_mb_num * sizeof ( uint32_t ) , fail ) ;
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > mb2br_xy ,
big_mb_num * sizeof ( uint32_t ) , fail ) ;
for ( y = 0 ; y < s - > mb_height ; y + + )
for ( x = 0 ; x < s - > mb_width ; x + + ) {
const int mb_xy = x + y * s - > mb_stride ;
const int b_xy = 4 * x + 4 * y * h - > b_stride ;
h - > mb2b_xy [ mb_xy ] = b_xy ;
h - > mb2br_xy [ mb_xy ] = 8 * ( FMO ? mb_xy : ( mb_xy % ( 2 * s - > mb_stride ) ) ) ;
2003-04-04 17:42:28 +03:00
}
2005-01-07 07:56:07 +02:00
2005-01-09 02:48:37 +02:00
s - > obmc_scratchpad = NULL ;
2012-03-16 20:40:05 +03:00
if ( ! h - > dequant4_coeff [ 0 ] )
2005-10-26 06:58:06 +03:00
init_dequant_tables ( h ) ;
2003-04-04 17:42:28 +03:00
return 0 ;
2012-03-16 20:40:05 +03:00
2003-04-04 17:42:28 +03:00
fail :
2011-01-22 16:42:56 +02:00
free_tables ( h , 1 ) ;
2003-04-04 17:42:28 +03:00
return - 1 ;
}
2007-09-05 19:18:15 +03:00
/**
* Mimic alloc_tables ( ) , but for every context thread .
*/
2012-03-16 20:40:05 +03:00
static void clone_tables ( H264Context * dst , H264Context * src , int i )
{
MpegEncContext * const s = & src - > s ;
dst - > intra4x4_pred_mode = src - > intra4x4_pred_mode + i * 8 * 2 * s - > mb_stride ;
dst - > non_zero_count = src - > non_zero_count ;
dst - > slice_table = src - > slice_table ;
dst - > cbp_table = src - > cbp_table ;
dst - > mb2b_xy = src - > mb2b_xy ;
dst - > mb2br_xy = src - > mb2br_xy ;
dst - > chroma_pred_mode_table = src - > chroma_pred_mode_table ;
dst - > mvd_table [ 0 ] = src - > mvd_table [ 0 ] + i * 8 * 2 * s - > mb_stride ;
dst - > mvd_table [ 1 ] = src - > mvd_table [ 1 ] + i * 8 * 2 * s - > mb_stride ;
dst - > direct_table = src - > direct_table ;
dst - > list_counts = src - > list_counts ;
dst - > s . obmc_scratchpad = NULL ;
ff_h264_pred_init ( & dst - > hpc , src - > s . codec_id , src - > sps . bit_depth_luma ,
src - > sps . chroma_format_idc ) ;
2007-09-05 19:18:15 +03:00
}
/**
* Init context
* Allocate buffers which are not shared amongst multiple threads .
*/
2012-03-16 20:40:05 +03:00
static int context_init ( H264Context * h )
{
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > top_borders [ 0 ] ,
h - > s . mb_width * 16 * 3 * sizeof ( uint8_t ) * 2 , fail )
FF_ALLOCZ_OR_GOTO ( h - > s . avctx , h - > top_borders [ 1 ] ,
h - > s . mb_width * 16 * 3 * sizeof ( uint8_t ) * 2 , fail )
h - > ref_cache [ 0 ] [ scan8 [ 5 ] + 1 ] =
h - > ref_cache [ 0 ] [ scan8 [ 7 ] + 1 ] =
h - > ref_cache [ 0 ] [ scan8 [ 13 ] + 1 ] =
h - > ref_cache [ 1 ] [ scan8 [ 5 ] + 1 ] =
h - > ref_cache [ 1 ] [ scan8 [ 7 ] + 1 ] =
h - > ref_cache [ 1 ] [ scan8 [ 13 ] + 1 ] = PART_NOT_AVAILABLE ;
2010-03-02 04:24:37 +02:00
2007-09-05 19:18:15 +03:00
return 0 ;
2012-03-16 20:40:05 +03:00
2007-09-05 19:18:15 +03:00
fail :
return - 1 ; // free_tables will clean up for us
}
2010-02-23 03:07:39 +02:00
static int decode_nal_units ( H264Context * h , const uint8_t * buf , int buf_size ) ;
2012-03-16 20:40:05 +03:00
static av_cold void common_init ( H264Context * h )
{
MpegEncContext * const s = & h - > s ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
s - > width = s - > avctx - > width ;
s - > height = s - > avctx - > height ;
s - > codec_id = s - > avctx - > codec - > id ;
2005-12-17 20:14:38 +02:00
2011-10-04 23:13:56 +03:00
s - > avctx - > bits_per_raw_sample = 8 ;
h - > cur_chroma_format_idc = 1 ;
ff_h264dsp_init ( & h - > h264dsp ,
s - > avctx - > bits_per_raw_sample , h - > cur_chroma_format_idc ) ;
ff_h264_pred_init ( & h - > hpc , s - > codec_id ,
s - > avctx - > bits_per_raw_sample , h - > cur_chroma_format_idc ) ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
h - > dequant_coeff_pps = - 1 ;
s - > unrestricted_mv = 1 ;
2005-10-26 06:58:06 +03:00
2011-10-04 23:13:56 +03:00
s - > dsp . dct_bits = 16 ;
2012-03-16 20:40:05 +03:00
/* needed so that IDCT permutation is known early */
ff_dsputil_init ( & s - > dsp , s - > avctx ) ;
2008-12-19 11:21:54 +02:00
2012-03-16 20:40:05 +03:00
memset ( h - > pps . scaling_matrix4 , 16 , 6 * 16 * sizeof ( uint8_t ) ) ;
memset ( h - > pps . scaling_matrix8 , 16 , 2 * 64 * sizeof ( uint8_t ) ) ;
2003-04-04 17:42:28 +03:00
}
2011-09-23 06:42:45 +03:00
int ff_h264_decode_extradata ( H264Context * h , const uint8_t * buf , int size )
2010-05-26 22:00:59 +03:00
{
AVCodecContext * avctx = h - > s . avctx ;
2010-02-23 03:07:39 +02:00
2012-03-17 06:43:12 +03:00
if ( ! buf | | size < = 0 )
2011-09-24 19:00:16 +03:00
return - 1 ;
2012-03-17 06:43:12 +03:00
if ( buf [ 0 ] = = 1 ) {
2010-02-23 03:07:39 +02:00
int i , cnt , nalsize ;
2011-09-23 06:42:45 +03:00
const unsigned char * p = buf ;
2010-02-23 03:07:39 +02:00
h - > is_avc = 1 ;
2012-03-17 06:43:12 +03:00
if ( size < 7 ) {
2010-02-23 03:07:39 +02:00
av_log ( avctx , AV_LOG_ERROR , " avcC too short \n " ) ;
return - 1 ;
}
/* sps and pps in the avcC always have length coded with 2 bytes,
2012-03-16 20:40:05 +03:00
* so put a fake nal_length_size = 2 while parsing them */
2010-02-23 03:07:39 +02:00
h - > nal_length_size = 2 ;
// Decode sps from avcC
2012-03-16 20:40:05 +03:00
cnt = * ( p + 5 ) & 0x1f ; // Number of sps
p + = 6 ;
2010-02-23 03:07:39 +02:00
for ( i = 0 ; i < cnt ; i + + ) {
nalsize = AV_RB16 ( p ) + 2 ;
2011-09-24 17:44:14 +03:00
if ( nalsize > size - ( p - buf ) )
return - 1 ;
2012-03-16 20:40:05 +03:00
if ( decode_nal_units ( h , p , nalsize ) < 0 ) {
av_log ( avctx , AV_LOG_ERROR ,
" Decoding sps %d from avcC failed \n " , i ) ;
2010-02-23 03:07:39 +02:00
return - 1 ;
}
p + = nalsize ;
}
// Decode pps from avcC
cnt = * ( p + + ) ; // Number of pps
for ( i = 0 ; i < cnt ; i + + ) {
nalsize = AV_RB16 ( p ) + 2 ;
2011-09-24 17:44:14 +03:00
if ( nalsize > size - ( p - buf ) )
return - 1 ;
2011-03-01 16:59:00 +02:00
if ( decode_nal_units ( h , p , nalsize ) < 0 ) {
2012-03-16 20:40:05 +03:00
av_log ( avctx , AV_LOG_ERROR ,
" Decoding pps %d from avcC failed \n " , i ) ;
2010-02-23 03:07:39 +02:00
return - 1 ;
}
p + = nalsize ;
}
2012-03-16 20:40:05 +03:00
// Now store right nal length size, that will be used to parse all other nals
2011-09-23 06:42:45 +03:00
h - > nal_length_size = ( buf [ 4 ] & 0x03 ) + 1 ;
2010-02-23 03:07:39 +02:00
} else {
h - > is_avc = 0 ;
2012-03-17 06:43:12 +03:00
if ( decode_nal_units ( h , buf , size ) < 0 )
2010-02-23 03:07:39 +02:00
return - 1 ;
}
2012-01-29 23:06:09 +03:00
return size ;
2010-05-26 22:00:59 +03:00
}
2012-03-16 20:40:05 +03:00
av_cold int ff_h264_decode_init ( AVCodecContext * avctx )
{
H264Context * h = avctx - > priv_data ;
MpegEncContext * const s = & h - > s ;
2011-10-29 23:44:50 +03:00
int i ;
2010-05-26 22:00:59 +03:00
2012-02-15 15:10:33 +03:00
ff_MPV_decode_defaults ( s ) ;
2010-05-26 22:00:59 +03:00
s - > avctx = avctx ;
common_init ( h ) ;
2012-03-16 20:40:05 +03:00
s - > out_format = FMT_H264 ;
s - > workaround_bugs = avctx - > workaround_bugs ;
2010-05-26 22:00:59 +03:00
2012-03-16 20:40:05 +03:00
/* set defaults */
// s->decode_mb = ff_h263_decode_mb;
2010-05-26 22:00:59 +03:00
s - > quarter_sample = 1 ;
2012-03-16 20:40:05 +03:00
if ( ! avctx - > has_b_frames )
s - > low_delay = 1 ;
2010-05-26 22:00:59 +03:00
avctx - > chroma_sample_location = AVCHROMA_LOC_LEFT ;
ff_h264_decode_init_vlc ( ) ;
2011-04-10 17:12:56 +03:00
h - > pixel_shift = 0 ;
2011-03-29 18:48:59 +03:00
h - > sps . bit_depth_luma = avctx - > bits_per_raw_sample = 8 ;
2011-03-29 18:48:57 +03:00
2010-05-26 22:00:59 +03:00
h - > thread_context [ 0 ] = h ;
2012-03-16 20:40:05 +03:00
h - > outputed_poc = h - > next_outputed_poc = INT_MIN ;
2011-10-29 23:44:50 +03:00
for ( i = 0 ; i < MAX_DELAYED_PIC_COUNT ; i + + )
h - > last_pocs [ i ] = INT_MIN ;
2012-03-16 20:40:05 +03:00
h - > prev_poc_msb = 1 < < 16 ;
2012-03-17 06:43:12 +03:00
h - > prev_frame_num = - 1 ;
2012-03-16 20:40:05 +03:00
h - > x264_build = - 1 ;
2010-05-26 22:00:59 +03:00
ff_h264_reset_sei ( h ) ;
2012-03-16 20:40:05 +03:00
if ( avctx - > codec_id = = CODEC_ID_H264 ) {
if ( avctx - > ticks_per_frame = = 1 )
s - > avctx - > time_base . den * = 2 ;
2010-05-26 22:00:59 +03:00
avctx - > ticks_per_frame = 2 ;
}
2012-03-16 20:40:05 +03:00
if ( avctx - > extradata_size > 0 & & avctx - > extradata & &
2012-04-10 21:31:03 +03:00
ff_h264_decode_extradata ( h , avctx - > extradata , avctx - > extradata_size ) < 0 ) {
ff_h264_free_context ( h ) ;
2010-05-26 22:00:59 +03:00
return - 1 ;
2012-04-10 21:31:03 +03:00
}
2010-05-26 22:00:59 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > sps . bitstream_restriction_flag & &
s - > avctx - > has_b_frames < h - > sps . num_reorder_frames ) {
2010-02-23 03:08:54 +02:00
s - > avctx - > has_b_frames = h - > sps . num_reorder_frames ;
2012-03-16 20:40:05 +03:00
s - > low_delay = 0 ;
2010-02-23 03:08:54 +02:00
}
2010-02-23 03:07:39 +02:00
2003-04-04 17:42:28 +03:00
return 0 ;
}
2012-03-16 20:40:05 +03:00
# define IN_RANGE(a, b, size) (((a) >= (b)) && ((a) < ((b) + (size))))
static void copy_picture_range ( Picture * * to , Picture * * from , int count ,
MpegEncContext * new_base ,
MpegEncContext * old_base )
2011-03-22 23:36:57 +02:00
{
int i ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < count ; i + + ) {
2011-05-21 04:11:50 +03:00
assert ( ( IN_RANGE ( from [ i ] , old_base , sizeof ( * old_base ) ) | |
2012-03-16 20:40:05 +03:00
IN_RANGE ( from [ i ] , old_base - > picture ,
sizeof ( Picture ) * old_base - > picture_count ) | |
2011-05-21 04:11:50 +03:00
! from [ i ] ) ) ;
2011-03-22 23:36:57 +02:00
to [ i ] = REBASE_PICTURE ( from [ i ] , new_base , old_base ) ;
}
}
static void copy_parameter_set ( void * * to , void * * from , int count , int size )
{
int i ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < count ; i + + ) {
if ( to [ i ] & & ! from [ i ] )
av_freep ( & to [ i ] ) ;
else if ( from [ i ] & & ! to [ i ] )
to [ i ] = av_malloc ( size ) ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
if ( from [ i ] )
memcpy ( to [ i ] , from [ i ] , size ) ;
2011-03-22 23:36:57 +02:00
}
}
2012-03-16 20:40:05 +03:00
static int decode_init_thread_copy ( AVCodecContext * avctx )
{
H264Context * h = avctx - > priv_data ;
2011-03-22 23:36:57 +02:00
2011-11-15 23:34:50 +03:00
if ( ! avctx - > internal - > is_copy )
return 0 ;
2011-03-22 23:36:57 +02:00
memset ( h - > sps_buffers , 0 , sizeof ( h - > sps_buffers ) ) ;
memset ( h - > pps_buffers , 0 , sizeof ( h - > pps_buffers ) ) ;
return 0 ;
}
2012-03-16 20:40:05 +03:00
# define copy_fields(to, from, start_field, end_field) \
memcpy ( & to - > start_field , & from - > start_field , \
( char * ) & to - > end_field - ( char * ) & to - > start_field )
static int decode_update_thread_context ( AVCodecContext * dst ,
const AVCodecContext * src )
{
H264Context * h = dst - > priv_data , * h1 = src - > priv_data ;
MpegEncContext * const s = & h - > s , * const s1 = & h1 - > s ;
2011-03-22 23:36:57 +02:00
int inited = s - > context_initialized , err ;
int i ;
2012-03-17 06:43:12 +03:00
if ( dst = = src )
2012-03-16 20:40:05 +03:00
return 0 ;
2011-03-22 23:36:57 +02:00
err = ff_mpeg_update_thread_context ( dst , src ) ;
2012-03-16 20:40:05 +03:00
if ( err )
return err ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
// FIXME handle width/height changing
if ( ! inited ) {
for ( i = 0 ; i < MAX_SPS_COUNT ; i + + )
2011-03-22 23:36:57 +02:00
av_freep ( h - > sps_buffers + i ) ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < MAX_PPS_COUNT ; i + + )
2011-03-22 23:36:57 +02:00
av_freep ( h - > pps_buffers + i ) ;
2012-03-16 20:40:05 +03:00
// copy all fields after MpegEnc
memcpy ( & h - > s + 1 , & h1 - > s + 1 ,
sizeof ( H264Context ) - sizeof ( MpegEncContext ) ) ;
2011-03-22 23:36:57 +02:00
memset ( h - > sps_buffers , 0 , sizeof ( h - > sps_buffers ) ) ;
memset ( h - > pps_buffers , 0 , sizeof ( h - > pps_buffers ) ) ;
2012-01-30 00:37:37 +03:00
if ( s1 - > context_initialized ) {
2011-08-11 15:57:58 +03:00
if ( ff_h264_alloc_tables ( h ) < 0 ) {
av_log ( dst , AV_LOG_ERROR , " Could not allocate memory for h264 \n " ) ;
return AVERROR ( ENOMEM ) ;
}
2011-03-22 23:36:57 +02:00
context_init ( h ) ;
2012-03-17 06:43:12 +03:00
/* frame_start may not be called for the next thread (if it's decoding
* a bottom field ) so this has to be allocated here */
h - > s . obmc_scratchpad = av_malloc ( 16 * 6 * s - > linesize ) ;
2012-01-30 00:37:37 +03:00
}
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 2 ; i + + ) {
h - > rbsp_buffer [ i ] = NULL ;
2011-03-22 23:36:57 +02:00
h - > rbsp_buffer_size [ i ] = 0 ;
}
h - > thread_context [ 0 ] = h ;
s - > dsp . clear_blocks ( h - > mb ) ;
2012-03-16 20:40:05 +03:00
s - > dsp . clear_blocks ( h - > mb + ( 24 * 16 < < h - > pixel_shift ) ) ;
2011-03-22 23:36:57 +02:00
}
2012-03-16 20:40:05 +03:00
// extradata/NAL handling
h - > is_avc = h1 - > is_avc ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
// SPS/PPS
copy_parameter_set ( ( void * * ) h - > sps_buffers , ( void * * ) h1 - > sps_buffers ,
MAX_SPS_COUNT , sizeof ( SPS ) ) ;
h - > sps = h1 - > sps ;
copy_parameter_set ( ( void * * ) h - > pps_buffers , ( void * * ) h1 - > pps_buffers ,
MAX_PPS_COUNT , sizeof ( PPS ) ) ;
h - > pps = h1 - > pps ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
// Dequantization matrices
// FIXME these are big - can they be only copied when PPS changes?
2011-03-22 23:36:57 +02:00
copy_fields ( h , h1 , dequant4_buffer , dequant4_coeff ) ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 6 ; i + + )
h - > dequant4_coeff [ i ] = h - > dequant4_buffer [ 0 ] +
( h1 - > dequant4_coeff [ i ] - h1 - > dequant4_buffer [ 0 ] ) ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 6 ; i + + )
h - > dequant8_coeff [ i ] = h - > dequant8_buffer [ 0 ] +
( h1 - > dequant8_coeff [ i ] - h1 - > dequant8_buffer [ 0 ] ) ;
2011-03-22 23:36:57 +02:00
h - > dequant_coeff_pps = h1 - > dequant_coeff_pps ;
2012-03-16 20:40:05 +03:00
// POC timing
2011-03-22 23:36:57 +02:00
copy_fields ( h , h1 , poc_lsb , redundant_pic_count ) ;
2012-03-16 20:40:05 +03:00
// reference lists
2011-06-02 20:15:58 +03:00
copy_fields ( h , h1 , ref_count , list_count ) ;
2012-03-16 20:40:05 +03:00
copy_fields ( h , h1 , ref_list , intra_gb ) ;
2011-03-22 23:36:57 +02:00
copy_fields ( h , h1 , short_ref , cabac_init_idc ) ;
2012-03-16 20:40:05 +03:00
copy_picture_range ( h - > short_ref , h1 - > short_ref , 32 , s , s1 ) ;
copy_picture_range ( h - > long_ref , h1 - > long_ref , 32 , s , s1 ) ;
copy_picture_range ( h - > delayed_pic , h1 - > delayed_pic ,
MAX_DELAYED_PIC_COUNT + 2 , s , s1 ) ;
2011-03-22 23:36:57 +02:00
h - > last_slice_type = h1 - > last_slice_type ;
2011-09-18 20:02:37 +03:00
h - > sync = h1 - > sync ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
if ( ! s - > current_picture_ptr )
return 0 ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
if ( ! s - > dropable ) {
2011-08-05 00:47:16 +03:00
err = ff_h264_execute_ref_pic_marking ( h , h - > mmco , h - > mmco_index ) ;
2012-03-16 20:40:05 +03:00
h - > prev_poc_msb = h - > poc_msb ;
h - > prev_poc_lsb = h - > poc_lsb ;
2011-03-22 23:36:57 +02:00
}
2012-03-16 20:40:05 +03:00
h - > prev_frame_num_offset = h - > frame_num_offset ;
h - > prev_frame_num = h - > frame_num ;
h - > outputed_poc = h - > next_outputed_poc ;
2011-03-22 23:36:57 +02:00
2011-08-05 00:47:16 +03:00
return err ;
2011-03-22 23:36:57 +02:00
}
2012-03-16 20:40:05 +03:00
int ff_h264_frame_start ( H264Context * h )
{
MpegEncContext * const s = & h - > s ;
2003-04-04 17:42:28 +03:00
int i ;
2011-03-29 18:48:57 +03:00
const int pixel_shift = h - > pixel_shift ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( ff_MPV_frame_start ( s , s - > avctx ) < 0 )
2005-11-09 13:29:29 +02:00
return - 1 ;
2003-04-04 17:42:28 +03:00
ff_er_frame_start ( s ) ;
2007-10-04 09:50:44 +03:00
/*
2012-02-15 15:10:33 +03:00
* ff_MPV_frame_start uses pict_type to derive key_frame .
2007-10-04 09:50:44 +03:00
* This is incorrect for H .264 ; IDR markings must be used .
2008-07-24 13:55:36 +03:00
* Zero here ; IDR markings per slice in frame or fields are ORed in later .
2007-10-04 09:50:44 +03:00
* See decode_nal_units ( ) .
*/
2011-07-06 21:08:30 +03:00
s - > current_picture_ptr - > f . key_frame = 0 ;
2012-03-17 06:43:12 +03:00
s - > current_picture_ptr - > sync = 0 ;
2012-03-16 20:40:05 +03:00
s - > current_picture_ptr - > mmco_reset = 0 ;
2003-04-04 17:42:28 +03:00
assert ( s - > linesize & & s - > uvlinesize ) ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 16 ; i + + ) {
h - > block_offset [ i ] = ( 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) < < pixel_shift ) + 4 * s - > linesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
h - > block_offset [ 48 + i ] = ( 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) < < pixel_shift ) + 8 * s - > linesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 16 ; i + + ) {
h - > block_offset [ 16 + i ] =
h - > block_offset [ 32 + i ] = ( 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) < < pixel_shift ) + 4 * s - > uvlinesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
h - > block_offset [ 48 + 16 + i ] =
h - > block_offset [ 48 + 32 + i ] = ( 4 * ( ( scan8 [ i ] - scan8 [ 0 ] ) & 7 ) < < pixel_shift ) + 8 * s - > uvlinesize * ( ( scan8 [ i ] - scan8 [ 0 ] ) > > 3 ) ;
2003-04-04 17:42:28 +03:00
}
2005-01-08 10:56:18 +02:00
/* can't be in alloc_tables because linesize isn't known there.
* FIXME : redo bipred weight to not require extra buffer ? */
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < s - > slice_context_count ; i + + )
if ( h - > thread_context [ i ] & & ! h - > thread_context [ i ] - > s . obmc_scratchpad )
h - > thread_context [ i ] - > s . obmc_scratchpad = av_malloc ( 16 * 6 * s - > linesize ) ;
/* Some macroblocks can be accessed before they're available in case
* of lost slices , MBAFF or threading . */
memset ( h - > slice_table , - 1 ,
( s - > mb_height * s - > mb_stride - 1 ) * sizeof ( * h - > slice_table ) ) ;
// s->decode = (s->flags & CODEC_FLAG_PSNR) || !s->encoding ||
// s->current_picture.f.reference /* || h->contains_intra */ || 1;
/* We mark the current picture as non-reference after allocating it, so
* that if we break out due to an error it can be released automatically
* in the next ff_MPV_frame_start ( ) .
* SVQ3 as well as most other codecs have only last / next / current and thus
* get released even with set reference , besides SVQ3 and others do not
* mark frames as reference later " naturally " . */
if ( s - > codec_id ! = CODEC_ID_SVQ3 )
2011-07-06 21:08:30 +03:00
s - > current_picture_ptr - > f . reference = 0 ;
2008-07-25 02:43:44 +03:00
2012-03-16 20:40:05 +03:00
s - > current_picture_ptr - > field_poc [ 0 ] =
s - > current_picture_ptr - > field_poc [ 1 ] = INT_MAX ;
2011-03-22 23:36:57 +02:00
h - > next_output_pic = NULL ;
2012-03-16 20:40:05 +03:00
assert ( s - > current_picture_ptr - > long_ref = = 0 ) ;
2008-07-25 02:43:44 +03:00
2005-11-09 13:29:29 +02:00
return 0 ;
2003-04-04 17:42:28 +03:00
}
2011-03-22 23:36:57 +02:00
/**
2012-03-16 20:40:05 +03:00
* Run setup operations that must be run after slice header decoding .
* This includes finding the next displayed frame .
*
* @ param h h264 master context
* @ param setup_finished enough NALs have been read that we can call
* ff_thread_finish_setup ( )
*/
static void decode_postinit ( H264Context * h , int setup_finished )
{
MpegEncContext * const s = & h - > s ;
2011-03-22 23:36:57 +02:00
Picture * out = s - > current_picture_ptr ;
Picture * cur = s - > current_picture_ptr ;
int i , pics , out_of_order , out_idx ;
2011-07-06 21:08:30 +03:00
s - > current_picture_ptr - > f . qscale_type = FF_QSCALE_TYPE_H264 ;
s - > current_picture_ptr - > f . pict_type = s - > pict_type ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > next_output_pic )
return ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
if ( cur - > field_poc [ 0 ] = = INT_MAX | | cur - > field_poc [ 1 ] = = INT_MAX ) {
/* FIXME: if we have two PAFF fields in one packet, we can't start
* the next thread here . If we have one field per packet , we can .
* The check in decode_nal_units ( ) is not good enough to find this
* yet , so we assume the worst for now . */
// if (setup_finished)
2011-05-21 04:11:50 +03:00
// ff_thread_finish_setup(s->avctx);
2011-03-22 23:36:57 +02:00
return ;
}
2011-07-06 21:08:30 +03:00
cur - > f . interlaced_frame = 0 ;
cur - > f . repeat_pict = 0 ;
2011-03-22 23:36:57 +02:00
/* Signal interlacing information externally. */
2012-03-16 20:40:05 +03:00
/* Prioritize picture timing SEI information over used
* decoding process if it exists . */
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > sps . pic_struct_present_flag ) {
switch ( h - > sei_pic_struct ) {
2011-03-22 23:36:57 +02:00
case SEI_PIC_STRUCT_FRAME :
break ;
case SEI_PIC_STRUCT_TOP_FIELD :
case SEI_PIC_STRUCT_BOTTOM_FIELD :
2011-07-06 21:08:30 +03:00
cur - > f . interlaced_frame = 1 ;
2011-03-22 23:36:57 +02:00
break ;
case SEI_PIC_STRUCT_TOP_BOTTOM :
case SEI_PIC_STRUCT_BOTTOM_TOP :
if ( FIELD_OR_MBAFF_PICTURE )
2011-07-06 21:08:30 +03:00
cur - > f . interlaced_frame = 1 ;
2011-03-22 23:36:57 +02:00
else
// try to flag soft telecine progressive
2011-07-06 21:08:30 +03:00
cur - > f . interlaced_frame = h - > prev_interlaced_frame ;
2011-03-22 23:36:57 +02:00
break ;
case SEI_PIC_STRUCT_TOP_BOTTOM_TOP :
case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM :
2012-03-16 20:40:05 +03:00
/* Signal the possibility of telecined film externally
* ( pic_struct 5 , 6 ) . From these hints , let the applications
* decide if they apply deinterlacing . */
2011-07-06 21:08:30 +03:00
cur - > f . repeat_pict = 1 ;
2011-03-22 23:36:57 +02:00
break ;
case SEI_PIC_STRUCT_FRAME_DOUBLING :
2012-03-16 20:40:05 +03:00
// Force progressive here, doubling interlaced frame is a bad idea.
2011-07-06 21:08:30 +03:00
cur - > f . repeat_pict = 2 ;
2011-03-22 23:36:57 +02:00
break ;
case SEI_PIC_STRUCT_FRAME_TRIPLING :
2011-07-06 21:08:30 +03:00
cur - > f . repeat_pict = 4 ;
2011-03-22 23:36:57 +02:00
break ;
}
2012-03-16 20:40:05 +03:00
if ( ( h - > sei_ct_type & 3 ) & &
h - > sei_pic_struct < = SEI_PIC_STRUCT_BOTTOM_TOP )
2011-07-06 21:08:30 +03:00
cur - > f . interlaced_frame = ( h - > sei_ct_type & ( 1 < < 1 ) ) ! = 0 ;
2012-03-16 20:40:05 +03:00
} else {
2011-03-22 23:36:57 +02:00
/* Derive interlacing flag from used decoding process. */
2011-07-06 21:08:30 +03:00
cur - > f . interlaced_frame = FIELD_OR_MBAFF_PICTURE ;
2011-03-22 23:36:57 +02:00
}
2011-07-06 21:08:30 +03:00
h - > prev_interlaced_frame = cur - > f . interlaced_frame ;
2011-03-22 23:36:57 +02:00
2012-03-16 20:40:05 +03:00
if ( cur - > field_poc [ 0 ] ! = cur - > field_poc [ 1 ] ) {
2011-03-22 23:36:57 +02:00
/* Derive top_field_first from field pocs. */
2011-07-06 21:08:30 +03:00
cur - > f . top_field_first = cur - > field_poc [ 0 ] < cur - > field_poc [ 1 ] ;
2012-03-16 20:40:05 +03:00
} else {
2011-07-06 21:08:30 +03:00
if ( cur - > f . interlaced_frame | | h - > sps . pic_struct_present_flag ) {
2012-03-16 20:40:05 +03:00
/* Use picture timing SEI information. Even if it is a
* information of a past frame , better than nothing . */
if ( h - > sei_pic_struct = = SEI_PIC_STRUCT_TOP_BOTTOM | |
h - > sei_pic_struct = = SEI_PIC_STRUCT_TOP_BOTTOM_TOP )
2011-07-06 21:08:30 +03:00
cur - > f . top_field_first = 1 ;
2011-03-22 23:36:57 +02:00
else
2011-07-06 21:08:30 +03:00
cur - > f . top_field_first = 0 ;
2012-03-16 20:40:05 +03:00
} else {
2011-03-22 23:36:57 +02:00
/* Most likely progressive */
2011-07-06 21:08:30 +03:00
cur - > f . top_field_first = 0 ;
2011-03-22 23:36:57 +02:00
}
}
2011-12-10 19:33:54 +03:00
cur - > mmco_reset = h - > mmco_reset ;
h - > mmco_reset = 0 ;
2012-03-16 20:40:05 +03:00
// FIXME do something with unavailable reference frames
2011-03-22 23:36:57 +02:00
/* Sort B-frames into display order */
2012-03-16 20:40:05 +03:00
if ( h - > sps . bitstream_restriction_flag & &
s - > avctx - > has_b_frames < h - > sps . num_reorder_frames ) {
2011-03-22 23:36:57 +02:00
s - > avctx - > has_b_frames = h - > sps . num_reorder_frames ;
2012-03-16 20:40:05 +03:00
s - > low_delay = 0 ;
2011-03-22 23:36:57 +02:00
}
2012-03-16 20:40:05 +03:00
if ( s - > avctx - > strict_std_compliance > = FF_COMPLIANCE_STRICT & &
! h - > sps . bitstream_restriction_flag ) {
2011-12-01 23:45:10 +03:00
s - > avctx - > has_b_frames = MAX_DELAYED_PIC_COUNT - 1 ;
2012-03-16 20:40:05 +03:00
s - > low_delay = 0 ;
2011-03-22 23:36:57 +02:00
}
2011-12-10 19:33:54 +03:00
for ( i = 0 ; 1 ; i + + ) {
if ( i = = MAX_DELAYED_PIC_COUNT | | cur - > poc < h - > last_pocs [ i ] ) {
if ( i )
h - > last_pocs [ i - 1 ] = cur - > poc ;
break ;
} else if ( i ) {
h - > last_pocs [ i - 1 ] = h - > last_pocs [ i ] ;
}
}
out_of_order = MAX_DELAYED_PIC_COUNT - i ;
if ( cur - > f . pict_type = = AV_PICTURE_TYPE_B
| | ( h - > last_pocs [ MAX_DELAYED_PIC_COUNT - 2 ] > INT_MIN & & h - > last_pocs [ MAX_DELAYED_PIC_COUNT - 1 ] - h - > last_pocs [ MAX_DELAYED_PIC_COUNT - 2 ] > 2 ) )
out_of_order = FFMAX ( out_of_order , 1 ) ;
if ( s - > avctx - > has_b_frames < out_of_order & & ! h - > sps . bitstream_restriction_flag ) {
av_log ( s - > avctx , AV_LOG_WARNING , " Increasing reorder buffer to %d \n " , out_of_order ) ;
s - > avctx - > has_b_frames = out_of_order ;
s - > low_delay = 0 ;
}
2011-03-22 23:36:57 +02:00
pics = 0 ;
2012-03-16 20:40:05 +03:00
while ( h - > delayed_pic [ pics ] )
pics + + ;
2011-03-22 23:36:57 +02:00
2011-08-31 06:00:39 +03:00
av_assert0 ( pics < = MAX_DELAYED_PIC_COUNT ) ;
2011-03-22 23:36:57 +02:00
h - > delayed_pic [ pics + + ] = cur ;
2011-07-06 21:08:30 +03:00
if ( cur - > f . reference = = 0 )
cur - > f . reference = DELAYED_PIC_REF ;
2011-03-22 23:36:57 +02:00
out = h - > delayed_pic [ 0 ] ;
out_idx = 0 ;
2012-03-17 06:43:12 +03:00
for ( i = 1 ; h - > delayed_pic [ i ] & &
! h - > delayed_pic [ i ] - > f . key_frame & &
! h - > delayed_pic [ i ] - > mmco_reset ;
2012-03-16 20:40:05 +03:00
i + + )
if ( h - > delayed_pic [ i ] - > poc < out - > poc ) {
out = h - > delayed_pic [ i ] ;
2011-03-22 23:36:57 +02:00
out_idx = i ;
}
2012-03-16 20:40:05 +03:00
if ( s - > avctx - > has_b_frames = = 0 & &
2012-03-17 06:43:12 +03:00
( h - > delayed_pic [ 0 ] - > f . key_frame | | h - > delayed_pic [ 0 ] - > mmco_reset ) )
2011-11-30 09:22:44 +03:00
h - > next_outputed_poc = INT_MIN ;
2011-12-10 19:33:54 +03:00
out_of_order = out - > poc < h - > next_outputed_poc ;
2011-03-22 23:36:57 +02:00
2012-03-17 06:43:12 +03:00
if ( out_of_order | | pics > s - > avctx - > has_b_frames ) {
2011-07-06 21:08:30 +03:00
out - > f . reference & = ~ DELAYED_PIC_REF ;
2012-03-16 20:40:05 +03:00
// for frame threading, the owner must be the second field's thread or
// else the first thread can release the picture and reuse it unsafely
out - > owner2 = s ;
for ( i = out_idx ; h - > delayed_pic [ i ] ; i + + )
h - > delayed_pic [ i ] = h - > delayed_pic [ i + 1 ] ;
2011-03-22 23:36:57 +02:00
}
2012-03-16 20:40:05 +03:00
if ( ! out_of_order & & pics > s - > avctx - > has_b_frames ) {
2011-03-22 23:36:57 +02:00
h - > next_output_pic = out ;
2011-12-10 19:33:54 +03:00
if ( out_idx = = 0 & & h - > delayed_pic [ 0 ] & & ( h - > delayed_pic [ 0 ] - > f . key_frame | | h - > delayed_pic [ 0 ] - > mmco_reset ) ) {
h - > next_outputed_poc = INT_MIN ;
} else
2011-03-22 23:36:57 +02:00
h - > next_outputed_poc = out - > poc ;
2012-03-16 20:40:05 +03:00
} else {
2011-12-10 20:42:52 +03:00
av_log ( s - > avctx , AV_LOG_DEBUG , " no picture %s \n " , out_of_order ? " ooo " : " " ) ;
2011-03-22 23:36:57 +02:00
}
2011-09-18 20:02:37 +03:00
if ( h - > next_output_pic & & h - > next_output_pic - > sync ) {
2011-09-28 04:47:39 +03:00
h - > sync | = 2 ;
2011-09-18 20:02:37 +03:00
}
2011-05-21 04:11:50 +03:00
if ( setup_finished )
ff_thread_finish_setup ( s - > avctx ) ;
2011-03-22 23:36:57 +02:00
}
2011-08-16 18:05:44 +03:00
static av_always_inline void backup_mb_border ( H264Context * h , uint8_t * src_y ,
uint8_t * src_cb , uint8_t * src_cr ,
2012-03-16 20:40:05 +03:00
int linesize , int uvlinesize ,
int simple )
2011-08-16 18:05:44 +03:00
{
2012-03-16 20:40:05 +03:00
MpegEncContext * const s = & h - > s ;
2010-01-25 02:30:44 +02:00
uint8_t * top_border ;
2008-08-09 04:17:34 +03:00
int top_idx = 1 ;
2011-03-29 18:48:57 +03:00
const int pixel_shift = h - > pixel_shift ;
2011-08-15 01:39:55 +03:00
int chroma444 = CHROMA444 ;
int chroma422 = CHROMA422 ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
src_y - = linesize ;
2004-03-20 18:40:20 +02:00
src_cb - = uvlinesize ;
src_cr - = uvlinesize ;
2012-03-16 20:40:05 +03:00
if ( ! simple & & FRAME_MBAFF ) {
if ( s - > mb_y & 1 ) {
if ( ! MB_MBAFF ) {
2010-01-25 02:30:44 +02:00
top_border = h - > top_borders [ 0 ] [ s - > mb_x ] ;
2012-03-16 20:40:05 +03:00
AV_COPY128 ( top_border , src_y + 15 * linesize ) ;
2011-03-29 18:48:57 +03:00
if ( pixel_shift )
2012-03-16 20:40:05 +03:00
AV_COPY128 ( top_border + 16 , src_y + 15 * linesize + 16 ) ;
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
if ( chroma444 ) {
if ( pixel_shift ) {
AV_COPY128 ( top_border + 32 , src_cb + 15 * uvlinesize ) ;
AV_COPY128 ( top_border + 48 , src_cb + 15 * uvlinesize + 16 ) ;
AV_COPY128 ( top_border + 64 , src_cr + 15 * uvlinesize ) ;
AV_COPY128 ( top_border + 80 , src_cr + 15 * uvlinesize + 16 ) ;
2011-06-03 11:12:28 +03:00
} else {
2012-03-16 20:40:05 +03:00
AV_COPY128 ( top_border + 16 , src_cb + 15 * uvlinesize ) ;
AV_COPY128 ( top_border + 32 , src_cr + 15 * uvlinesize ) ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
} else if ( chroma422 ) {
2011-08-15 01:39:55 +03:00
if ( pixel_shift ) {
2012-03-16 20:40:05 +03:00
AV_COPY128 ( top_border + 32 , src_cb + 15 * uvlinesize ) ;
AV_COPY128 ( top_border + 48 , src_cr + 15 * uvlinesize ) ;
2011-08-15 01:39:55 +03:00
} else {
2012-03-16 20:40:05 +03:00
AV_COPY64 ( top_border + 16 , src_cb + 15 * uvlinesize ) ;
AV_COPY64 ( top_border + 24 , src_cr + 15 * uvlinesize ) ;
2011-08-15 01:39:55 +03:00
}
2011-03-29 18:48:57 +03:00
} else {
2011-06-03 11:12:28 +03:00
if ( pixel_shift ) {
2012-03-16 20:40:05 +03:00
AV_COPY128 ( top_border + 32 , src_cb + 7 * uvlinesize ) ;
AV_COPY128 ( top_border + 48 , src_cr + 7 * uvlinesize ) ;
2011-06-03 11:12:28 +03:00
} else {
2012-03-16 20:40:05 +03:00
AV_COPY64 ( top_border + 16 , src_cb + 7 * uvlinesize ) ;
AV_COPY64 ( top_border + 24 , src_cr + 7 * uvlinesize ) ;
2011-06-03 11:12:28 +03:00
}
2011-03-29 18:48:57 +03:00
}
2008-08-09 04:17:34 +03:00
}
}
2012-03-16 20:40:05 +03:00
} else if ( MB_MBAFF ) {
2010-01-17 22:35:55 +02:00
top_idx = 0 ;
2012-03-16 20:40:05 +03:00
} else
2010-01-17 22:35:55 +02:00
return ;
2008-08-09 04:17:34 +03:00
}
2010-01-25 02:30:44 +02:00
top_border = h - > top_borders [ top_idx ] [ s - > mb_x ] ;
2012-03-16 20:40:05 +03:00
/* There are two lines saved, the line above the the top macroblock
* of a pair , and the line above the bottom macroblock . */
AV_COPY128 ( top_border , src_y + 16 * linesize ) ;
2011-03-29 18:48:57 +03:00
if ( pixel_shift )
2012-03-16 20:40:05 +03:00
AV_COPY128 ( top_border + 16 , src_y + 16 * linesize + 16 ) ;
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
if ( chroma444 ) {
if ( pixel_shift ) {
AV_COPY128 ( top_border + 32 , src_cb + 16 * linesize ) ;
AV_COPY128 ( top_border + 48 , src_cb + 16 * linesize + 16 ) ;
AV_COPY128 ( top_border + 64 , src_cr + 16 * linesize ) ;
AV_COPY128 ( top_border + 80 , src_cr + 16 * linesize + 16 ) ;
2011-06-03 11:12:28 +03:00
} else {
2012-03-16 20:40:05 +03:00
AV_COPY128 ( top_border + 16 , src_cb + 16 * linesize ) ;
AV_COPY128 ( top_border + 32 , src_cr + 16 * linesize ) ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
} else if ( chroma422 ) {
2011-08-15 01:39:55 +03:00
if ( pixel_shift ) {
2012-03-16 20:40:05 +03:00
AV_COPY128 ( top_border + 32 , src_cb + 16 * uvlinesize ) ;
AV_COPY128 ( top_border + 48 , src_cr + 16 * uvlinesize ) ;
2011-08-15 01:39:55 +03:00
} else {
2012-03-16 20:40:05 +03:00
AV_COPY64 ( top_border + 16 , src_cb + 16 * uvlinesize ) ;
AV_COPY64 ( top_border + 24 , src_cr + 16 * uvlinesize ) ;
2011-08-15 01:39:55 +03:00
}
2011-03-29 18:48:57 +03:00
} else {
2011-06-03 11:12:28 +03:00
if ( pixel_shift ) {
2012-03-16 20:40:05 +03:00
AV_COPY128 ( top_border + 32 , src_cb + 8 * uvlinesize ) ;
AV_COPY128 ( top_border + 48 , src_cr + 8 * uvlinesize ) ;
2011-06-03 11:12:28 +03:00
} else {
2012-03-16 20:40:05 +03:00
AV_COPY64 ( top_border + 16 , src_cb + 8 * uvlinesize ) ;
AV_COPY64 ( top_border + 24 , src_cr + 8 * uvlinesize ) ;
2011-06-03 11:12:28 +03:00
}
2011-03-29 18:48:57 +03:00
}
2004-03-20 18:40:20 +02:00
}
}
2011-07-06 04:08:22 +03:00
static av_always_inline void xchg_mb_border ( H264Context * h , uint8_t * src_y ,
2012-03-16 20:40:05 +03:00
uint8_t * src_cb , uint8_t * src_cr ,
int linesize , int uvlinesize ,
int xchg , int chroma444 ,
int simple , int pixel_shift )
{
MpegEncContext * const s = & h - > s ;
2011-05-19 23:47:59 +03:00
int deblock_topleft ;
2007-06-21 10:52:06 +03:00
int deblock_top ;
2008-08-09 04:17:34 +03:00
int top_idx = 1 ;
2010-01-25 03:56:13 +02:00
uint8_t * top_border_m1 ;
uint8_t * top_border ;
2008-08-09 04:17:34 +03:00
2012-03-16 20:40:05 +03:00
if ( ! simple & & FRAME_MBAFF ) {
if ( s - > mb_y & 1 ) {
if ( ! MB_MBAFF )
2010-01-17 22:35:55 +02:00
return ;
2012-03-16 20:40:05 +03:00
} else {
2008-08-09 04:17:34 +03:00
top_idx = MB_MBAFF ? 0 : 1 ;
}
}
2007-06-21 10:52:06 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > deblocking_filter = = 2 ) {
2011-05-19 23:47:59 +03:00
deblock_topleft = h - > slice_table [ h - > mb_xy - 1 - s - > mb_stride ] = = h - > slice_num ;
deblock_top = h - > top_type ;
2007-06-21 10:52:06 +03:00
} else {
2011-05-19 23:47:59 +03:00
deblock_topleft = ( s - > mb_x > 0 ) ;
deblock_top = ( s - > mb_y > ! ! MB_FIELD ) ;
2007-06-21 10:52:06 +03:00
}
2004-03-20 18:40:20 +02:00
2012-03-16 20:40:05 +03:00
src_y - = linesize + 1 + pixel_shift ;
2011-04-10 21:44:14 +03:00
src_cb - = uvlinesize + 1 + pixel_shift ;
src_cr - = uvlinesize + 1 + pixel_shift ;
2004-03-20 18:40:20 +02:00
2012-03-16 20:40:05 +03:00
top_border_m1 = h - > top_borders [ top_idx ] [ s - > mb_x - 1 ] ;
2010-01-25 03:56:13 +02:00
top_border = h - > top_borders [ top_idx ] [ s - > mb_x ] ;
2012-03-16 20:40:05 +03:00
# define XCHG(a, b, xchg) \
if ( pixel_shift ) { \
if ( xchg ) { \
AV_SWAP64 ( b + 0 , a + 0 ) ; \
AV_SWAP64 ( b + 8 , a + 8 ) ; \
} else { \
AV_COPY128 ( b , a ) ; \
} \
} else if ( xchg ) \
AV_SWAP64 ( b , a ) ; \
else \
AV_COPY64 ( b , a ) ;
if ( deblock_top ) {
if ( deblock_topleft ) {
XCHG ( top_border_m1 + ( 8 < < pixel_shift ) ,
src_y - ( 7 < < pixel_shift ) , 1 ) ;
2010-01-17 22:35:55 +02:00
}
2011-03-29 18:48:57 +03:00
XCHG ( top_border + ( 0 < < pixel_shift ) , src_y + ( 1 < < pixel_shift ) , xchg ) ;
XCHG ( top_border + ( 8 < < pixel_shift ) , src_y + ( 9 < < pixel_shift ) , 1 ) ;
2012-03-16 20:40:05 +03:00
if ( s - > mb_x + 1 < s - > mb_width ) {
XCHG ( h - > top_borders [ top_idx ] [ s - > mb_x + 1 ] ,
src_y + ( 17 < < pixel_shift ) , 1 ) ;
2005-06-03 00:15:20 +03:00
}
2004-03-20 18:40:20 +02:00
}
2012-03-16 20:40:05 +03:00
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
if ( chroma444 ) {
if ( deblock_topleft ) {
2011-06-03 11:12:28 +03:00
XCHG ( top_border_m1 + ( 24 < < pixel_shift ) , src_cb - ( 7 < < pixel_shift ) , 1 ) ;
XCHG ( top_border_m1 + ( 40 < < pixel_shift ) , src_cr - ( 7 < < pixel_shift ) , 1 ) ;
}
XCHG ( top_border + ( 16 < < pixel_shift ) , src_cb + ( 1 < < pixel_shift ) , xchg ) ;
XCHG ( top_border + ( 24 < < pixel_shift ) , src_cb + ( 9 < < pixel_shift ) , 1 ) ;
XCHG ( top_border + ( 32 < < pixel_shift ) , src_cr + ( 1 < < pixel_shift ) , xchg ) ;
XCHG ( top_border + ( 40 < < pixel_shift ) , src_cr + ( 9 < < pixel_shift ) , 1 ) ;
2012-03-16 20:40:05 +03:00
if ( s - > mb_x + 1 < s - > mb_width ) {
XCHG ( h - > top_borders [ top_idx ] [ s - > mb_x + 1 ] + ( 16 < < pixel_shift ) , src_cb + ( 17 < < pixel_shift ) , 1 ) ;
XCHG ( h - > top_borders [ top_idx ] [ s - > mb_x + 1 ] + ( 32 < < pixel_shift ) , src_cr + ( 17 < < pixel_shift ) , 1 ) ;
2011-06-03 11:12:28 +03:00
}
} else {
2012-03-16 20:40:05 +03:00
if ( deblock_top ) {
if ( deblock_topleft ) {
2011-06-03 11:12:28 +03:00
XCHG ( top_border_m1 + ( 16 < < pixel_shift ) , src_cb - ( 7 < < pixel_shift ) , 1 ) ;
XCHG ( top_border_m1 + ( 24 < < pixel_shift ) , src_cr - ( 7 < < pixel_shift ) , 1 ) ;
}
2012-03-16 20:40:05 +03:00
XCHG ( top_border + ( 16 < < pixel_shift ) , src_cb + 1 + pixel_shift , 1 ) ;
XCHG ( top_border + ( 24 < < pixel_shift ) , src_cr + 1 + pixel_shift , 1 ) ;
2010-01-17 22:35:55 +02:00
}
2004-03-20 18:40:20 +02:00
}
}
}
2012-03-16 20:40:05 +03:00
static av_always_inline int dctcoef_get ( DCTELEM * mb , int high_bit_depth ,
int index )
{
2011-03-29 18:48:57 +03:00
if ( high_bit_depth ) {
2012-03-16 20:40:05 +03:00
return AV_RN32A ( ( ( int32_t * ) mb ) + index ) ;
2011-03-29 18:48:57 +03:00
} else
return AV_RN16A ( mb + index ) ;
2011-03-29 18:48:57 +03:00
}
2012-03-16 20:40:05 +03:00
static av_always_inline void dctcoef_set ( DCTELEM * mb , int high_bit_depth ,
int index , int value )
{
2011-03-29 18:48:57 +03:00
if ( high_bit_depth ) {
2012-03-16 20:40:05 +03:00
AV_WN32A ( ( ( int32_t * ) mb ) + index , value ) ;
2011-03-29 18:48:57 +03:00
} else
AV_WN16A ( mb + index , value ) ;
2011-03-29 18:48:57 +03:00
}
2012-03-16 20:40:05 +03:00
static av_always_inline void hl_decode_mb_predict_luma ( H264Context * h ,
int mb_type , int is_h264 ,
int simple ,
int transform_bypass ,
int pixel_shift ,
int * block_offset ,
int linesize ,
uint8_t * dest_y , int p )
2011-06-03 11:12:28 +03:00
{
2012-03-16 20:40:05 +03:00
MpegEncContext * const s = & h - > s ;
2011-06-03 11:12:28 +03:00
void ( * idct_add ) ( uint8_t * dst , DCTELEM * block , int stride ) ;
void ( * idct_dc_add ) ( uint8_t * dst , DCTELEM * block , int stride ) ;
int i ;
2012-03-16 20:40:05 +03:00
int qscale = p = = 0 ? s - > qscale : h - > chroma_qp [ p - 1 ] ;
block_offset + = 16 * p ;
if ( IS_INTRA4x4 ( mb_type ) ) {
if ( simple | | ! s - > encoding ) {
if ( IS_8x8DCT ( mb_type ) ) {
if ( transform_bypass ) {
idct_dc_add =
idct_add = s - > dsp . add_pixels8 ;
} else {
2011-06-03 11:12:28 +03:00
idct_dc_add = h - > h264dsp . h264_idct8_dc_add ;
idct_add = h - > h264dsp . h264_idct8_add ;
}
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 16 ; i + = 4 ) {
uint8_t * const ptr = dest_y + block_offset [ i ] ;
const int dir = h - > intra4x4_pred_mode_cache [ scan8 [ i ] ] ;
if ( transform_bypass & & h - > sps . profile_idc = = 244 & & dir < = 1 ) {
h - > hpc . pred8x8l_add [ dir ] ( ptr , h - > mb + ( i * 16 + p * 256 < < pixel_shift ) , linesize ) ;
} else {
const int nnz = h - > non_zero_count_cache [ scan8 [ i + p * 16 ] ] ;
h - > hpc . pred8x8l [ dir ] ( ptr , ( h - > topleft_samples_available < < i ) & 0x8000 ,
( h - > topright_samples_available < < i ) & 0x4000 , linesize ) ;
if ( nnz ) {
if ( nnz = = 1 & & dctcoef_get ( h - > mb , pixel_shift , i * 16 + p * 256 ) )
idct_dc_add ( ptr , h - > mb + ( i * 16 + p * 256 < < pixel_shift ) , linesize ) ;
2011-06-03 11:12:28 +03:00
else
2012-03-16 20:40:05 +03:00
idct_add ( ptr , h - > mb + ( i * 16 + p * 256 < < pixel_shift ) , linesize ) ;
2011-06-03 11:12:28 +03:00
}
}
}
2012-03-16 20:40:05 +03:00
} else {
if ( transform_bypass ) {
idct_dc_add =
idct_add = s - > dsp . add_pixels4 ;
} else {
2011-06-03 11:12:28 +03:00
idct_dc_add = h - > h264dsp . h264_idct_dc_add ;
idct_add = h - > h264dsp . h264_idct_add ;
}
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 16 ; i + + ) {
uint8_t * const ptr = dest_y + block_offset [ i ] ;
const int dir = h - > intra4x4_pred_mode_cache [ scan8 [ i ] ] ;
2011-06-03 11:12:28 +03:00
2012-03-16 20:40:05 +03:00
if ( transform_bypass & & h - > sps . profile_idc = = 244 & & dir < = 1 ) {
h - > hpc . pred4x4_add [ dir ] ( ptr , h - > mb + ( i * 16 + p * 256 < < pixel_shift ) , linesize ) ;
} else {
2011-06-03 11:12:28 +03:00
uint8_t * topright ;
int nnz , tr ;
uint64_t tr_high ;
2012-03-16 20:40:05 +03:00
if ( dir = = DIAG_DOWN_LEFT_PRED | | dir = = VERT_LEFT_PRED ) {
const int topright_avail = ( h - > topright_samples_available < < i ) & 0x8000 ;
2011-06-21 02:11:28 +03:00
assert ( s - > mb_y | | linesize < = block_offset [ i ] ) ;
2012-03-16 20:40:05 +03:00
if ( ! topright_avail ) {
2011-06-03 11:12:28 +03:00
if ( pixel_shift ) {
2012-03-16 20:40:05 +03:00
tr_high = ( ( uint16_t * ) ptr ) [ 3 - linesize / 2 ] * 0x0001000100010001ULL ;
topright = ( uint8_t * ) & tr_high ;
2011-06-03 11:12:28 +03:00
} else {
2012-03-16 20:40:05 +03:00
tr = ptr [ 3 - linesize ] * 0x01010101u ;
topright = ( uint8_t * ) & tr ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
} else
topright = ptr + ( 4 < < pixel_shift ) - linesize ;
} else
topright = NULL ;
h - > hpc . pred4x4 [ dir ] ( ptr , topright , linesize ) ;
nnz = h - > non_zero_count_cache [ scan8 [ i + p * 16 ] ] ;
if ( nnz ) {
if ( is_h264 ) {
if ( nnz = = 1 & & dctcoef_get ( h - > mb , pixel_shift , i * 16 + p * 256 ) )
idct_dc_add ( ptr , h - > mb + ( i * 16 + p * 256 < < pixel_shift ) , linesize ) ;
2011-06-03 11:12:28 +03:00
else
2012-03-16 20:40:05 +03:00
idct_add ( ptr , h - > mb + ( i * 16 + p * 256 < < pixel_shift ) , linesize ) ;
2012-01-06 03:34:16 +03:00
} else if ( CONFIG_SVQ3_DECODER )
2012-03-16 20:40:05 +03:00
ff_svq3_add_idct_c ( ptr , h - > mb + i * 16 + p * 256 , linesize , qscale , 0 ) ;
2011-06-03 11:12:28 +03:00
}
}
}
}
}
2012-03-16 20:40:05 +03:00
} else {
h - > hpc . pred16x16 [ h - > intra16x16_pred_mode ] ( dest_y , linesize ) ;
if ( is_h264 ) {
if ( h - > non_zero_count_cache [ scan8 [ LUMA_DC_BLOCK_INDEX + p ] ] ) {
if ( ! transform_bypass )
h - > h264dsp . h264_luma_dc_dequant_idct ( h - > mb + ( p * 256 < < pixel_shift ) ,
h - > mb_luma_dc [ p ] ,
h - > dequant4_coeff [ p ] [ qscale ] [ 0 ] ) ;
else {
static const uint8_t dc_mapping [ 16 ] = {
0 * 16 , 1 * 16 , 4 * 16 , 5 * 16 ,
2 * 16 , 3 * 16 , 6 * 16 , 7 * 16 ,
8 * 16 , 9 * 16 , 12 * 16 , 13 * 16 ,
10 * 16 , 11 * 16 , 14 * 16 , 15 * 16 } ;
for ( i = 0 ; i < 16 ; i + + )
dctcoef_set ( h - > mb + ( p * 256 < < pixel_shift ) ,
pixel_shift , dc_mapping [ i ] ,
dctcoef_get ( h - > mb_luma_dc [ p ] ,
pixel_shift , i ) ) ;
2011-06-03 11:12:28 +03:00
}
}
2012-01-06 03:34:16 +03:00
} else if ( CONFIG_SVQ3_DECODER )
2012-03-16 20:40:05 +03:00
ff_svq3_luma_dc_dequant_idct_c ( h - > mb + p * 256 ,
h - > mb_luma_dc [ p ] , qscale ) ;
2011-06-03 11:12:28 +03:00
}
}
2012-03-16 20:40:05 +03:00
static av_always_inline void hl_decode_mb_idct_luma ( H264Context * h , int mb_type ,
int is_h264 , int simple ,
int transform_bypass ,
int pixel_shift ,
int * block_offset ,
int linesize ,
uint8_t * dest_y , int p )
2011-06-03 11:12:28 +03:00
{
2012-03-16 20:40:05 +03:00
MpegEncContext * const s = & h - > s ;
2011-06-03 11:12:28 +03:00
void ( * idct_add ) ( uint8_t * dst , DCTELEM * block , int stride ) ;
int i ;
2012-03-16 20:40:05 +03:00
block_offset + = 16 * p ;
if ( ! IS_INTRA4x4 ( mb_type ) ) {
if ( is_h264 ) {
if ( IS_INTRA16x16 ( mb_type ) ) {
if ( transform_bypass ) {
if ( h - > sps . profile_idc = = 244 & &
( h - > intra16x16_pred_mode = = VERT_PRED8x8 | |
h - > intra16x16_pred_mode = = HOR_PRED8x8 ) ) {
h - > hpc . pred16x16_add [ h - > intra16x16_pred_mode ] ( dest_y , block_offset ,
h - > mb + ( p * 256 < < pixel_shift ) ,
linesize ) ;
} else {
for ( i = 0 ; i < 16 ; i + + )
if ( h - > non_zero_count_cache [ scan8 [ i + p * 16 ] ] | |
dctcoef_get ( h - > mb , pixel_shift , i * 16 + p * 256 ) )
s - > dsp . add_pixels4 ( dest_y + block_offset [ i ] ,
h - > mb + ( i * 16 + p * 256 < < pixel_shift ) ,
linesize ) ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
} else {
h - > h264dsp . h264_idct_add16intra ( dest_y , block_offset ,
h - > mb + ( p * 256 < < pixel_shift ) ,
linesize ,
h - > non_zero_count_cache + p * 5 * 8 ) ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
} else if ( h - > cbp & 15 ) {
if ( transform_bypass ) {
2011-06-03 11:12:28 +03:00
const int di = IS_8x8DCT ( mb_type ) ? 4 : 1 ;
2012-03-16 20:40:05 +03:00
idct_add = IS_8x8DCT ( mb_type ) ? s - > dsp . add_pixels8
: s - > dsp . add_pixels4 ;
for ( i = 0 ; i < 16 ; i + = di )
if ( h - > non_zero_count_cache [ scan8 [ i + p * 16 ] ] )
idct_add ( dest_y + block_offset [ i ] ,
h - > mb + ( i * 16 + p * 256 < < pixel_shift ) ,
linesize ) ;
} else {
if ( IS_8x8DCT ( mb_type ) )
h - > h264dsp . h264_idct8_add4 ( dest_y , block_offset ,
h - > mb + ( p * 256 < < pixel_shift ) ,
linesize ,
h - > non_zero_count_cache + p * 5 * 8 ) ;
else
h - > h264dsp . h264_idct_add16 ( dest_y , block_offset ,
h - > mb + ( p * 256 < < pixel_shift ) ,
linesize ,
h - > non_zero_count_cache + p * 5 * 8 ) ;
2011-06-03 11:12:28 +03:00
}
}
2012-01-06 03:34:16 +03:00
} else if ( CONFIG_SVQ3_DECODER ) {
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 16 ; i + + )
if ( h - > non_zero_count_cache [ scan8 [ i + p * 16 ] ] | | h - > mb [ i * 16 + p * 256 ] ) {
// FIXME benchmark weird rule, & below
uint8_t * const ptr = dest_y + block_offset [ i ] ;
ff_svq3_add_idct_c ( ptr , h - > mb + i * 16 + p * 256 , linesize ,
s - > qscale , IS_INTRA ( mb_type ) ? 1 : 0 ) ;
2011-06-03 11:12:28 +03:00
}
}
}
}
2012-03-16 20:40:05 +03:00
static av_always_inline void hl_decode_mb_internal ( H264Context * h , int simple ,
int pixel_shift )
2011-10-21 10:01:16 +03:00
{
2012-03-16 20:40:05 +03:00
MpegEncContext * const s = & h - > s ;
const int mb_x = s - > mb_x ;
const int mb_y = s - > mb_y ;
const int mb_xy = h - > mb_xy ;
2011-07-06 21:08:30 +03:00
const int mb_type = s - > current_picture . f . mb_type [ mb_xy ] ;
2012-03-16 20:40:05 +03:00
uint8_t * dest_y , * dest_cb , * dest_cr ;
2003-04-04 17:42:28 +03:00
int linesize , uvlinesize /*dct_offset*/ ;
2011-06-03 11:12:28 +03:00
int i , j ;
2005-03-07 01:02:25 +02:00
int * block_offset = & h - > block_offset [ 0 ] ;
2008-12-16 22:09:09 +02:00
const int transform_bypass = ! simple & & ( s - > qscale = = 0 & & h - > sps . transform_bypass ) ;
2009-01-07 03:58:04 +02:00
/* is_h264 should always be true if SVQ3 is disabled. */
2009-01-14 19:19:17 +02:00
const int is_h264 = ! CONFIG_SVQ3_DECODER | | simple | | s - > codec_id = = CODEC_ID_H264 ;
2005-06-17 11:24:35 +03:00
void ( * idct_add ) ( uint8_t * dst , DCTELEM * block , int stride ) ;
2012-03-16 20:40:05 +03:00
const int block_h = 16 > > s - > chroma_y_shift ;
2011-10-21 10:01:16 +03:00
const int chroma422 = CHROMA422 ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
dest_y = s - > current_picture . f . data [ 0 ] + ( ( mb_x < < pixel_shift ) + mb_y * s - > linesize ) * 16 ;
dest_cb = s - > current_picture . f . data [ 1 ] + ( mb_x < < pixel_shift ) * 8 + mb_y * s - > uvlinesize * block_h ;
dest_cr = s - > current_picture . f . data [ 2 ] + ( mb_x < < pixel_shift ) * 8 + mb_y * s - > uvlinesize * block_h ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
s - > dsp . prefetch ( dest_y + ( s - > mb_x & 3 ) * 4 * s - > linesize + ( 64 < < pixel_shift ) , s - > linesize , 4 ) ;
s - > dsp . prefetch ( dest_cb + ( s - > mb_x & 7 ) * s - > uvlinesize + ( 64 < < pixel_shift ) , dest_cr - dest_cb , 2 ) ;
2006-10-12 00:34:15 +03:00
2012-03-16 20:40:05 +03:00
h - > list_counts [ mb_xy ] = h - > list_count ;
2010-01-17 22:35:55 +02:00
2007-02-24 02:58:28 +02:00
if ( ! simple & & MB_FIELD ) {
2012-03-16 20:40:05 +03:00
linesize = h - > mb_linesize = s - > linesize * 2 ;
uvlinesize = h - > mb_uvlinesize = s - > uvlinesize * 2 ;
2011-06-03 11:12:28 +03:00
block_offset = & h - > block_offset [ 48 ] ;
2012-03-16 20:40:05 +03:00
if ( mb_y & 1 ) { // FIXME move out of this function?
dest_y - = s - > linesize * 15 ;
dest_cb - = s - > uvlinesize * ( block_h - 1 ) ;
dest_cr - = s - > uvlinesize * ( block_h - 1 ) ;
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
if ( FRAME_MBAFF ) {
2006-05-29 01:44:14 +03:00
int list ;
2012-03-16 20:40:05 +03:00
for ( list = 0 ; list < h - > list_count ; list + + ) {
if ( ! USES_LIST ( mb_type , list ) )
2006-05-29 01:44:14 +03:00
continue ;
2012-03-16 20:40:05 +03:00
if ( IS_16X16 ( mb_type ) ) {
2006-05-29 01:44:14 +03:00
int8_t * ref = & h - > ref_cache [ list ] [ scan8 [ 0 ] ] ;
2012-03-16 20:40:05 +03:00
fill_rectangle ( ref , 4 , 4 , 8 , ( 16 + * ref ) ^ ( s - > mb_y & 1 ) , 1 ) ;
} else {
for ( i = 0 ; i < 16 ; i + = 4 ) {
2006-05-29 01:44:14 +03:00
int ref = h - > ref_cache [ list ] [ scan8 [ i ] ] ;
2012-03-16 20:40:05 +03:00
if ( ref > = 0 )
fill_rectangle ( & h - > ref_cache [ list ] [ scan8 [ i ] ] , 2 , 2 ,
8 , ( 16 + ref ) ^ ( s - > mb_y & 1 ) , 1 ) ;
2006-05-29 01:44:14 +03:00
}
}
}
}
2003-04-04 17:42:28 +03:00
} else {
2006-05-29 01:44:14 +03:00
linesize = h - > mb_linesize = s - > linesize ;
uvlinesize = h - > mb_uvlinesize = s - > uvlinesize ;
2012-03-16 20:40:05 +03:00
// dct_offset = s->linesize * 16;
2003-04-04 17:42:28 +03:00
}
2005-12-17 20:14:38 +02:00
2007-02-24 02:58:28 +02:00
if ( ! simple & & IS_INTRA_PCM ( mb_type ) ) {
2011-07-05 20:20:06 +03:00
const int bit_depth = h - > sps . bit_depth_luma ;
2011-04-10 21:44:14 +03:00
if ( pixel_shift ) {
2011-03-29 18:48:57 +03:00
int j ;
GetBitContext gb ;
2012-04-02 19:25:19 +03:00
init_get_bits ( & gb , ( uint8_t * ) h - > mb ,
2012-04-04 15:53:25 +03:00
ff_h264_mb_sizes [ h - > sps . chroma_format_idc ] * bit_depth ) ;
2011-03-29 18:48:57 +03:00
for ( i = 0 ; i < 16 ; i + + ) {
2012-03-16 20:40:05 +03:00
uint16_t * tmp_y = ( uint16_t * ) ( dest_y + i * linesize ) ;
2011-03-29 18:48:57 +03:00
for ( j = 0 ; j < 16 ; j + + )
tmp_y [ j ] = get_bits ( & gb , bit_depth ) ;
}
2012-03-16 20:40:05 +03:00
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
2011-07-05 20:20:06 +03:00
if ( ! h - > sps . chroma_format_idc ) {
2011-10-12 18:55:37 +03:00
for ( i = 0 ; i < block_h ; i + + ) {
2012-03-16 20:40:05 +03:00
uint16_t * tmp_cb = ( uint16_t * ) ( dest_cb + i * uvlinesize ) ;
uint16_t * tmp_cr = ( uint16_t * ) ( dest_cr + i * uvlinesize ) ;
2011-07-05 20:20:06 +03:00
for ( j = 0 ; j < 8 ; j + + ) {
tmp_cb [ j ] = tmp_cr [ j ] = 1 < < ( bit_depth - 1 ) ;
}
}
} else {
2011-08-20 00:44:40 +03:00
for ( i = 0 ; i < block_h ; i + + ) {
2012-03-16 20:40:05 +03:00
uint16_t * tmp_cb = ( uint16_t * ) ( dest_cb + i * uvlinesize ) ;
2011-08-20 00:44:40 +03:00
for ( j = 0 ; j < 8 ; j + + )
tmp_cb [ j ] = get_bits ( & gb , bit_depth ) ;
}
for ( i = 0 ; i < block_h ; i + + ) {
2012-03-16 20:40:05 +03:00
uint16_t * tmp_cr = ( uint16_t * ) ( dest_cr + i * uvlinesize ) ;
2011-08-20 00:44:40 +03:00
for ( j = 0 ; j < 8 ; j + + )
tmp_cr [ j ] = get_bits ( & gb , bit_depth ) ;
}
2011-07-05 20:20:06 +03:00
}
2011-03-29 18:48:57 +03:00
}
} else {
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 16 ; i + + )
2012-04-02 19:25:19 +03:00
memcpy ( dest_y + i * linesize , ( uint8_t * ) h - > mb + i * 16 , 16 ) ;
2012-03-16 20:40:05 +03:00
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
2011-07-05 20:20:06 +03:00
if ( ! h - > sps . chroma_format_idc ) {
2012-03-17 06:43:12 +03:00
for ( i = 0 ; i < 8 ; i + + ) {
2011-10-22 02:03:27 +03:00
memset ( dest_cb + i * uvlinesize , 1 < < ( bit_depth - 1 ) , 8 ) ;
memset ( dest_cr + i * uvlinesize , 1 < < ( bit_depth - 1 ) , 8 ) ;
2011-07-05 20:20:06 +03:00
}
} else {
2012-04-02 19:25:19 +03:00
uint8_t * src_cb = ( uint8_t * ) h - > mb + 256 ;
uint8_t * src_cr = ( uint8_t * ) h - > mb + 256 + block_h * 8 ;
2011-08-16 18:05:44 +03:00
for ( i = 0 ; i < block_h ; i + + ) {
2012-04-02 19:25:19 +03:00
memcpy ( dest_cb + i * uvlinesize , src_cb + i * 8 , 8 ) ;
memcpy ( dest_cr + i * uvlinesize , src_cr + i * 8 , 8 ) ;
2011-08-20 00:44:40 +03:00
}
2011-07-05 20:20:06 +03:00
}
2011-06-10 02:17:41 +03:00
}
2011-03-29 18:48:57 +03:00
}
2005-02-17 01:18:06 +02:00
} else {
2012-03-16 20:40:05 +03:00
if ( IS_INTRA ( mb_type ) ) {
if ( h - > deblocking_filter )
xchg_mb_border ( h , dest_y , dest_cb , dest_cr , linesize ,
uvlinesize , 1 , 0 , simple , pixel_shift ) ;
if ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
2012-03-27 16:16:37 +03:00
if ( CHROMA ) {
h - > hpc . pred8x8 [ h - > chroma_pred_mode ] ( dest_cb , uvlinesize ) ;
h - > hpc . pred8x8 [ h - > chroma_pred_mode ] ( dest_cr , uvlinesize ) ;
}
2005-02-17 01:18:06 +02:00
}
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
hl_decode_mb_predict_luma ( h , mb_type , is_h264 , simple ,
transform_bypass , pixel_shift ,
block_offset , linesize , dest_y , 0 ) ;
2011-06-03 11:12:28 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > deblocking_filter )
xchg_mb_border ( h , dest_y , dest_cb , dest_cr , linesize ,
uvlinesize , 0 , 0 , simple , pixel_shift ) ;
} else if ( is_h264 ) {
2011-10-21 10:01:16 +03:00
if ( chroma422 ) {
hl_motion_422 ( h , dest_y , dest_cb , dest_cr ,
s - > me . qpel_put , s - > dsp . put_h264_chroma_pixels_tab ,
s - > me . qpel_avg , s - > dsp . avg_h264_chroma_pixels_tab ,
h - > h264dsp . weight_h264_pixels_tab ,
h - > h264dsp . biweight_h264_pixels_tab ,
pixel_shift ) ;
} else {
hl_motion_420 ( h , dest_y , dest_cb , dest_cr ,
s - > me . qpel_put , s - > dsp . put_h264_chroma_pixels_tab ,
s - > me . qpel_avg , s - > dsp . avg_h264_chroma_pixels_tab ,
h - > h264dsp . weight_h264_pixels_tab ,
h - > h264dsp . biweight_h264_pixels_tab ,
pixel_shift ) ;
}
2003-04-04 17:42:28 +03:00
}
2005-02-17 01:18:06 +02:00
2012-03-16 20:40:05 +03:00
hl_decode_mb_idct_luma ( h , mb_type , is_h264 , simple , transform_bypass ,
pixel_shift , block_offset , linesize , dest_y , 0 ) ;
if ( ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) & &
( h - > cbp & 0x30 ) ) {
uint8_t * dest [ 2 ] = { dest_cb , dest_cr } ;
if ( transform_bypass ) {
if ( IS_INTRA ( mb_type ) & & h - > sps . profile_idc = = 244 & &
( h - > chroma_pred_mode = = VERT_PRED8x8 | |
h - > chroma_pred_mode = = HOR_PRED8x8 ) ) {
h - > hpc . pred8x8_add [ h - > chroma_pred_mode ] ( dest [ 0 ] ,
block_offset + 16 ,
h - > mb + ( 16 * 16 * 1 < < pixel_shift ) ,
uvlinesize ) ;
h - > hpc . pred8x8_add [ h - > chroma_pred_mode ] ( dest [ 1 ] ,
block_offset + 32 ,
h - > mb + ( 16 * 16 * 2 < < pixel_shift ) ,
uvlinesize ) ;
} else {
2008-12-18 20:25:11 +02:00
idct_add = s - > dsp . add_pixels4 ;
2012-03-16 20:40:05 +03:00
for ( j = 1 ; j < 3 ; j + + ) {
for ( i = j * 16 ; i < j * 16 + 4 ; i + + )
if ( h - > non_zero_count_cache [ scan8 [ i ] ] | |
dctcoef_get ( h - > mb , pixel_shift , i * 16 ) )
idct_add ( dest [ j - 1 ] + block_offset [ i ] ,
h - > mb + ( i * 16 < < pixel_shift ) ,
uvlinesize ) ;
2011-10-21 10:01:16 +03:00
if ( chroma422 ) {
2012-03-16 20:40:05 +03:00
for ( i = j * 16 + 4 ; i < j * 16 + 8 ; i + + )
if ( h - > non_zero_count_cache [ scan8 [ i + 4 ] ] | |
dctcoef_get ( h - > mb , pixel_shift , i * 16 ) )
idct_add ( dest [ j - 1 ] + block_offset [ i + 4 ] ,
h - > mb + ( i * 16 < < pixel_shift ) ,
uvlinesize ) ;
2011-10-12 18:55:37 +03:00
}
2008-12-18 20:12:59 +02:00
}
}
2012-03-16 20:40:05 +03:00
} else {
if ( is_h264 ) {
2011-08-15 01:39:55 +03:00
int qp [ 2 ] ;
2011-10-21 10:01:16 +03:00
if ( chroma422 ) {
2011-08-16 18:05:44 +03:00
qp [ 0 ] = h - > chroma_qp [ 0 ] + 3 ;
qp [ 1 ] = h - > chroma_qp [ 1 ] + 3 ;
2011-08-15 01:39:55 +03:00
} else {
qp [ 0 ] = h - > chroma_qp [ 0 ] ;
qp [ 1 ] = h - > chroma_qp [ 1 ] ;
}
2012-03-16 20:40:05 +03:00
if ( h - > non_zero_count_cache [ scan8 [ CHROMA_DC_BLOCK_INDEX + 0 ] ] )
h - > h264dsp . h264_chroma_dc_dequant_idct ( h - > mb + ( 16 * 16 * 1 < < pixel_shift ) ,
h - > dequant4_coeff [ IS_INTRA ( mb_type ) ? 1 : 4 ] [ qp [ 0 ] ] [ 0 ] ) ;
if ( h - > non_zero_count_cache [ scan8 [ CHROMA_DC_BLOCK_INDEX + 1 ] ] )
h - > h264dsp . h264_chroma_dc_dequant_idct ( h - > mb + ( 16 * 16 * 2 < < pixel_shift ) ,
h - > dequant4_coeff [ IS_INTRA ( mb_type ) ? 2 : 5 ] [ qp [ 1 ] ] [ 0 ] ) ;
2010-09-14 16:36:26 +03:00
h - > h264dsp . h264_idct_add8 ( dest , block_offset ,
h - > mb , uvlinesize ,
h - > non_zero_count_cache ) ;
2012-01-06 03:34:16 +03:00
} else if ( CONFIG_SVQ3_DECODER ) {
2012-03-16 20:40:05 +03:00
h - > h264dsp . h264_chroma_dc_dequant_idct ( h - > mb + 16 * 16 * 1 ,
h - > dequant4_coeff [ IS_INTRA ( mb_type ) ? 1 : 4 ] [ h - > chroma_qp [ 0 ] ] [ 0 ] ) ;
h - > h264dsp . h264_chroma_dc_dequant_idct ( h - > mb + 16 * 16 * 2 ,
h - > dequant4_coeff [ IS_INTRA ( mb_type ) ? 2 : 5 ] [ h - > chroma_qp [ 1 ] ] [ 0 ] ) ;
for ( j = 1 ; j < 3 ; j + + ) {
for ( i = j * 16 ; i < j * 16 + 4 ; i + + )
if ( h - > non_zero_count_cache [ scan8 [ i ] ] | | h - > mb [ i * 16 ] ) {
uint8_t * const ptr = dest [ j - 1 ] + block_offset [ i ] ;
ff_svq3_add_idct_c ( ptr , h - > mb + i * 16 ,
uvlinesize ,
ff_h264_chroma_qp [ 0 ] [ s - > qscale + 12 ] - 12 , 2 ) ;
2011-06-03 11:12:28 +03:00
}
2005-02-17 01:18:06 +02:00
}
2003-05-13 03:46:42 +03:00
}
2003-04-04 17:42:28 +03:00
}
}
}
2012-03-16 20:40:05 +03:00
if ( h - > cbp | | IS_INTRA ( mb_type ) ) {
2011-06-03 11:12:28 +03:00
s - > dsp . clear_blocks ( h - > mb ) ;
2012-03-16 20:40:05 +03:00
s - > dsp . clear_blocks ( h - > mb + ( 24 * 16 < < pixel_shift ) ) ;
2011-06-03 11:12:28 +03:00
}
}
2012-03-16 20:40:05 +03:00
static av_always_inline void hl_decode_mb_444_internal ( H264Context * h ,
int simple ,
int pixel_shift )
{
MpegEncContext * const s = & h - > s ;
const int mb_x = s - > mb_x ;
const int mb_y = s - > mb_y ;
const int mb_xy = h - > mb_xy ;
2011-07-06 21:08:30 +03:00
const int mb_type = s - > current_picture . f . mb_type [ mb_xy ] ;
2012-03-16 20:40:05 +03:00
uint8_t * dest [ 3 ] ;
2011-06-03 11:12:28 +03:00
int linesize ;
int i , j , p ;
int * block_offset = & h - > block_offset [ 0 ] ;
const int transform_bypass = ! simple & & ( s - > qscale = = 0 & & h - > sps . transform_bypass ) ;
2012-03-16 20:40:05 +03:00
const int plane_count = ( simple | | ! CONFIG_GRAY | | ! ( s - > flags & CODEC_FLAG_GRAY ) ) ? 3 : 1 ;
2011-06-03 11:12:28 +03:00
2012-03-16 20:40:05 +03:00
for ( p = 0 ; p < plane_count ; p + + ) {
dest [ p ] = s - > current_picture . f . data [ p ] +
( ( mb_x < < pixel_shift ) + mb_y * s - > linesize ) * 16 ;
s - > dsp . prefetch ( dest [ p ] + ( s - > mb_x & 3 ) * 4 * s - > linesize + ( 64 < < pixel_shift ) ,
s - > linesize , 4 ) ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
h - > list_counts [ mb_xy ] = h - > list_count ;
2011-06-03 11:12:28 +03:00
if ( ! simple & & MB_FIELD ) {
2012-03-16 20:40:05 +03:00
linesize = h - > mb_linesize = h - > mb_uvlinesize = s - > linesize * 2 ;
2011-06-03 11:12:28 +03:00
block_offset = & h - > block_offset [ 48 ] ;
2012-03-16 20:40:05 +03:00
if ( mb_y & 1 ) // FIXME move out of this function?
2011-06-03 11:12:28 +03:00
for ( p = 0 ; p < 3 ; p + + )
2012-03-16 20:40:05 +03:00
dest [ p ] - = s - > linesize * 15 ;
if ( FRAME_MBAFF ) {
2011-06-03 11:12:28 +03:00
int list ;
2012-03-16 20:40:05 +03:00
for ( list = 0 ; list < h - > list_count ; list + + ) {
if ( ! USES_LIST ( mb_type , list ) )
2011-06-03 11:12:28 +03:00
continue ;
2012-03-16 20:40:05 +03:00
if ( IS_16X16 ( mb_type ) ) {
2011-06-03 11:12:28 +03:00
int8_t * ref = & h - > ref_cache [ list ] [ scan8 [ 0 ] ] ;
2012-03-16 20:40:05 +03:00
fill_rectangle ( ref , 4 , 4 , 8 , ( 16 + * ref ) ^ ( s - > mb_y & 1 ) , 1 ) ;
} else {
for ( i = 0 ; i < 16 ; i + = 4 ) {
2011-06-03 11:12:28 +03:00
int ref = h - > ref_cache [ list ] [ scan8 [ i ] ] ;
2012-03-16 20:40:05 +03:00
if ( ref > = 0 )
fill_rectangle ( & h - > ref_cache [ list ] [ scan8 [ i ] ] , 2 , 2 ,
8 , ( 16 + ref ) ^ ( s - > mb_y & 1 ) , 1 ) ;
2011-06-03 11:12:28 +03:00
}
}
}
}
} else {
2012-03-16 20:40:05 +03:00
linesize = h - > mb_linesize = h - > mb_uvlinesize = s - > linesize ;
2011-06-03 11:12:28 +03:00
}
if ( ! simple & & IS_INTRA_PCM ( mb_type ) ) {
if ( pixel_shift ) {
const int bit_depth = h - > sps . bit_depth_luma ;
GetBitContext gb ;
2012-03-16 20:40:05 +03:00
init_get_bits ( & gb , ( uint8_t * ) h - > mb , 768 * bit_depth ) ;
2011-06-03 11:12:28 +03:00
2012-03-16 20:40:05 +03:00
for ( p = 0 ; p < plane_count ; p + + )
2011-06-03 11:12:28 +03:00
for ( i = 0 ; i < 16 ; i + + ) {
2012-03-16 20:40:05 +03:00
uint16_t * tmp = ( uint16_t * ) ( dest [ p ] + i * linesize ) ;
2011-06-03 11:12:28 +03:00
for ( j = 0 ; j < 16 ; j + + )
tmp [ j ] = get_bits ( & gb , bit_depth ) ;
}
} else {
2012-03-16 20:40:05 +03:00
for ( p = 0 ; p < plane_count ; p + + )
for ( i = 0 ; i < 16 ; i + + )
2012-04-02 19:25:19 +03:00
memcpy ( dest [ p ] + i * linesize ,
( uint8_t * ) h - > mb + p * 256 + i * 16 , 16 ) ;
2011-06-03 11:12:28 +03:00
}
} else {
2012-03-16 20:40:05 +03:00
if ( IS_INTRA ( mb_type ) ) {
if ( h - > deblocking_filter )
xchg_mb_border ( h , dest [ 0 ] , dest [ 1 ] , dest [ 2 ] , linesize ,
linesize , 1 , 1 , simple , pixel_shift ) ;
2011-06-03 11:12:28 +03:00
2011-06-10 02:17:41 +03:00
for ( p = 0 ; p < plane_count ; p + + )
2012-03-16 20:40:05 +03:00
hl_decode_mb_predict_luma ( h , mb_type , 1 , simple ,
transform_bypass , pixel_shift ,
block_offset , linesize , dest [ p ] , p ) ;
2011-06-03 11:12:28 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > deblocking_filter )
xchg_mb_border ( h , dest [ 0 ] , dest [ 1 ] , dest [ 2 ] , linesize ,
linesize , 0 , 1 , simple , pixel_shift ) ;
} else {
2011-07-06 22:26:04 +03:00
hl_motion ( h , dest [ 0 ] , dest [ 1 ] , dest [ 2 ] ,
s - > me . qpel_put , s - > dsp . put_h264_chroma_pixels_tab ,
s - > me . qpel_avg , s - > dsp . avg_h264_chroma_pixels_tab ,
h - > h264dsp . weight_h264_pixels_tab ,
2011-10-21 10:01:16 +03:00
h - > h264dsp . biweight_h264_pixels_tab , pixel_shift , 3 ) ;
2011-06-03 11:12:28 +03:00
}
2011-06-10 02:17:41 +03:00
for ( p = 0 ; p < plane_count ; p + + )
2012-03-16 20:40:05 +03:00
hl_decode_mb_idct_luma ( h , mb_type , 1 , simple , transform_bypass ,
pixel_shift , block_offset , linesize ,
dest [ p ] , p ) ;
2011-06-03 11:12:28 +03:00
}
2012-03-16 20:40:05 +03:00
if ( h - > cbp | | IS_INTRA ( mb_type ) ) {
2008-12-21 17:58:42 +02:00
s - > dsp . clear_blocks ( h - > mb ) ;
2012-03-16 20:40:05 +03:00
s - > dsp . clear_blocks ( h - > mb + ( 24 * 16 < < pixel_shift ) ) ;
2011-06-03 11:12:28 +03:00
}
2003-04-04 17:42:28 +03:00
}
2007-02-24 02:58:28 +02:00
/**
* Process a macroblock ; this case avoids checks for expensive uncommon cases .
*/
2012-03-16 20:40:05 +03:00
# define hl_decode_mb_simple(sh, bits) \
static void hl_decode_mb_simple_ # # bits ( H264Context * h ) \
{ \
hl_decode_mb_internal ( h , 1 , sh ) ; \
2007-02-24 02:58:28 +02:00
}
2012-03-16 20:40:05 +03:00
2011-12-11 20:07:04 +03:00
hl_decode_mb_simple ( 0 , 8 )
hl_decode_mb_simple ( 1 , 16 )
2007-02-24 02:58:28 +02:00
/**
* Process a macroblock ; this handles edge cases , such as interlacing .
*/
2012-03-31 00:34:22 +03:00
static av_noinline void hl_decode_mb_complex ( H264Context * h )
2012-03-16 20:40:05 +03:00
{
2011-04-10 21:44:14 +03:00
hl_decode_mb_internal ( h , 0 , h - > pixel_shift ) ;
2007-02-24 02:58:28 +02:00
}
2012-03-31 00:34:22 +03:00
static av_noinline void hl_decode_mb_444_complex ( H264Context * h )
2012-03-16 20:40:05 +03:00
{
2011-06-03 11:12:28 +03:00
hl_decode_mb_444_internal ( h , 0 , h - > pixel_shift ) ;
}
2012-03-31 00:34:22 +03:00
static av_noinline void hl_decode_mb_444_simple ( H264Context * h )
2012-03-16 20:40:05 +03:00
{
2011-06-03 11:12:28 +03:00
hl_decode_mb_444_internal ( h , 1 , 0 ) ;
}
2012-03-16 20:40:05 +03:00
void ff_h264_hl_decode_mb ( H264Context * h )
{
MpegEncContext * const s = & h - > s ;
const int mb_xy = h - > mb_xy ;
2011-07-06 21:08:30 +03:00
const int mb_type = s - > current_picture . f . mb_type [ mb_xy ] ;
2012-03-16 20:40:05 +03:00
int is_complex = CONFIG_SMALL | | h - > is_complex | | IS_INTRA_PCM ( mb_type ) | | s - > qscale = = 0 ;
2007-02-24 02:58:28 +02:00
2011-06-03 11:12:28 +03:00
if ( CHROMA444 ) {
2012-03-16 20:40:05 +03:00
if ( is_complex | | h - > pixel_shift )
2011-06-03 11:12:28 +03:00
hl_decode_mb_444_complex ( h ) ;
else
hl_decode_mb_444_simple ( h ) ;
} else if ( is_complex ) {
2007-02-24 02:58:28 +02:00
hl_decode_mb_complex ( h ) ;
2011-03-29 18:48:57 +03:00
} else if ( h - > pixel_shift ) {
hl_decode_mb_simple_16 ( h ) ;
} else
hl_decode_mb_simple_8 ( h ) ;
2007-02-24 02:58:28 +02:00
}
2012-03-16 20:40:05 +03:00
static int pred_weight_table ( H264Context * h )
{
MpegEncContext * const s = & h - > s ;
2003-04-04 17:42:28 +03:00
int list , i ;
2005-01-07 07:56:07 +02:00
int luma_def , chroma_def ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
h - > use_weight = 0 ;
h - > use_weight_chroma = 0 ;
h - > luma_log2_weight_denom = get_ue_golomb ( & s - > gb ) ;
if ( h - > sps . chroma_format_idc )
h - > chroma_log2_weight_denom = get_ue_golomb ( & s - > gb ) ;
luma_def = 1 < < h - > luma_log2_weight_denom ;
chroma_def = 1 < < h - > chroma_log2_weight_denom ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
for ( list = 0 ; list < 2 ; list + + ) {
2009-02-03 22:49:02 +02:00
h - > luma_weight_flag [ list ] = 0 ;
h - > chroma_weight_flag [ list ] = 0 ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < h - > ref_count [ list ] ; i + + ) {
2003-04-04 17:42:28 +03:00
int luma_weight_flag , chroma_weight_flag ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
luma_weight_flag = get_bits1 ( & s - > gb ) ;
if ( luma_weight_flag ) {
h - > luma_weight [ i ] [ list ] [ 0 ] = get_se_golomb ( & s - > gb ) ;
h - > luma_weight [ i ] [ list ] [ 1 ] = get_se_golomb ( & s - > gb ) ;
if ( h - > luma_weight [ i ] [ list ] [ 0 ] ! = luma_def | |
h - > luma_weight [ i ] [ list ] [ 1 ] ! = 0 ) {
h - > use_weight = 1 ;
h - > luma_weight_flag [ list ] = 1 ;
2009-02-03 22:49:02 +02:00
}
2012-03-16 20:40:05 +03:00
} else {
h - > luma_weight [ i ] [ list ] [ 0 ] = luma_def ;
h - > luma_weight [ i ] [ list ] [ 1 ] = 0 ;
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
if ( h - > sps . chroma_format_idc ) {
chroma_weight_flag = get_bits1 ( & s - > gb ) ;
if ( chroma_weight_flag ) {
2008-07-26 05:31:19 +03:00
int j ;
2012-03-16 20:40:05 +03:00
for ( j = 0 ; j < 2 ; j + + ) {
h - > chroma_weight [ i ] [ list ] [ j ] [ 0 ] = get_se_golomb ( & s - > gb ) ;
h - > chroma_weight [ i ] [ list ] [ j ] [ 1 ] = get_se_golomb ( & s - > gb ) ;
if ( h - > chroma_weight [ i ] [ list ] [ j ] [ 0 ] ! = chroma_def | |
h - > chroma_weight [ i ] [ list ] [ j ] [ 1 ] ! = 0 ) {
h - > use_weight_chroma = 1 ;
h - > chroma_weight_flag [ list ] = 1 ;
2009-02-03 22:49:02 +02:00
}
2008-07-26 05:31:19 +03:00
}
2012-03-16 20:40:05 +03:00
} else {
2008-07-26 05:31:19 +03:00
int j ;
2012-03-16 20:40:05 +03:00
for ( j = 0 ; j < 2 ; j + + ) {
h - > chroma_weight [ i ] [ list ] [ j ] [ 0 ] = chroma_def ;
h - > chroma_weight [ i ] [ list ] [ j ] [ 1 ] = 0 ;
2008-07-26 05:31:19 +03:00
}
2003-04-04 17:42:28 +03:00
}
}
}
2012-03-16 20:40:05 +03:00
if ( h - > slice_type_nos ! = AV_PICTURE_TYPE_B )
break ;
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
h - > use_weight = h - > use_weight | | h - > use_weight_chroma ;
2003-04-04 17:42:28 +03:00
return 0 ;
}
2010-03-31 00:05:11 +03:00
/**
* Initialize implicit_weight table .
2010-07-02 14:54:34 +03:00
* @ param field 0 / 1 initialize the weight for interlaced MBAFF
2010-03-31 00:05:11 +03:00
* - 1 initializes the rest
*/
2012-03-16 20:40:05 +03:00
static void implicit_weight_table ( H264Context * h , int field )
{
MpegEncContext * const s = & h - > s ;
2010-03-31 00:05:11 +03:00
int ref0 , ref1 , i , cur_poc , ref_start , ref_count0 , ref_count1 ;
2005-01-07 07:56:07 +02:00
2009-02-17 15:41:27 +02:00
for ( i = 0 ; i < 2 ; i + + ) {
h - > luma_weight_flag [ i ] = 0 ;
h - > chroma_weight_flag [ i ] = 0 ;
}
2012-03-16 20:40:05 +03:00
if ( field < 0 ) {
2011-10-03 18:41:51 +03:00
if ( s - > picture_structure = = PICT_FRAME ) {
cur_poc = s - > current_picture_ptr - > poc ;
} else {
cur_poc = s - > current_picture_ptr - > field_poc [ s - > picture_structure - 1 ] ;
}
2012-03-16 20:40:05 +03:00
if ( h - > ref_count [ 0 ] = = 1 & & h - > ref_count [ 1 ] = = 1 & & ! FRAME_MBAFF & &
h - > ref_list [ 0 ] [ 0 ] . poc + h - > ref_list [ 1 ] [ 0 ] . poc = = 2 * cur_poc ) {
h - > use_weight = 0 ;
h - > use_weight_chroma = 0 ;
return ;
}
ref_start = 0 ;
ref_count0 = h - > ref_count [ 0 ] ;
ref_count1 = h - > ref_count [ 1 ] ;
} else {
cur_poc = s - > current_picture_ptr - > field_poc [ field ] ;
ref_start = 16 ;
ref_count0 = 16 + 2 * h - > ref_count [ 0 ] ;
ref_count1 = 16 + 2 * h - > ref_count [ 1 ] ;
2010-03-31 00:05:11 +03:00
}
2005-01-07 07:56:07 +02:00
2012-03-16 20:40:05 +03:00
h - > use_weight = 2 ;
h - > use_weight_chroma = 2 ;
h - > luma_log2_weight_denom = 5 ;
h - > chroma_log2_weight_denom = 5 ;
2005-01-07 07:56:07 +02:00
2012-03-16 20:40:05 +03:00
for ( ref0 = ref_start ; ref0 < ref_count0 ; ref0 + + ) {
2005-01-07 07:56:07 +02:00
int poc0 = h - > ref_list [ 0 ] [ ref0 ] . poc ;
2012-03-16 20:40:05 +03:00
for ( ref1 = ref_start ; ref1 < ref_count1 ; ref1 + + ) {
2011-07-06 18:54:36 +03:00
int w = 32 ;
if ( ! h - > ref_list [ 0 ] [ ref0 ] . long_ref & & ! h - > ref_list [ 1 ] [ ref1 ] . long_ref ) {
int poc1 = h - > ref_list [ 1 ] [ ref1 ] . poc ;
2012-03-16 20:40:05 +03:00
int td = av_clip ( poc1 - poc0 , - 128 , 127 ) ;
if ( td ) {
2011-07-06 18:54:36 +03:00
int tb = av_clip ( cur_poc - poc0 , - 128 , 127 ) ;
int tx = ( 16384 + ( FFABS ( td ) > > 1 ) ) / td ;
2012-03-16 20:40:05 +03:00
int dist_scale_factor = ( tb * tx + 32 ) > > 8 ;
if ( dist_scale_factor > = - 64 & & dist_scale_factor < = 128 )
2011-07-06 18:54:36 +03:00
w = 64 - dist_scale_factor ;
}
2011-07-06 18:54:36 +03:00
}
2012-03-16 20:40:05 +03:00
if ( field < 0 ) {
h - > implicit_weight [ ref0 ] [ ref1 ] [ 0 ] =
h - > implicit_weight [ ref0 ] [ ref1 ] [ 1 ] = w ;
} else {
h - > implicit_weight [ ref0 ] [ ref1 ] [ field ] = w ;
2010-03-03 12:57:38 +02:00
}
2005-01-07 07:56:07 +02:00
}
}
}
2003-04-04 17:42:28 +03:00
/**
2004-12-18 05:49:07 +02:00
* instantaneous decoder refresh .
2003-04-04 17:42:28 +03:00
*/
2012-03-16 20:40:05 +03:00
static void idr ( H264Context * h )
{
2011-11-17 01:57:17 +03:00
int i ;
2010-01-12 22:59:00 +02:00
ff_h264_remove_all_refs ( h ) ;
2012-03-16 20:40:05 +03:00
h - > prev_frame_num = 0 ;
h - > prev_frame_num_offset = 0 ;
2012-03-17 06:43:12 +03:00
h - > prev_poc_msb = 1 < < 16 ;
2012-03-16 20:40:05 +03:00
h - > prev_poc_lsb = 0 ;
2011-11-17 01:57:17 +03:00
for ( i = 0 ; i < MAX_DELAYED_PIC_COUNT ; i + + )
h - > last_pocs [ i ] = INT_MIN ;
2003-04-04 17:42:28 +03:00
}
2005-05-03 09:53:59 +03:00
/* forget old pics after a seek */
2012-03-16 20:40:05 +03:00
static void flush_dpb ( AVCodecContext * avctx )
{
H264Context * h = avctx - > priv_data ;
2005-05-03 09:53:59 +03:00
int i ;
2012-03-17 06:43:12 +03:00
for ( i = 0 ; i < = MAX_DELAYED_PIC_COUNT ; i + + ) {
2012-03-16 20:40:05 +03:00
if ( h - > delayed_pic [ i ] )
2011-07-06 21:08:30 +03:00
h - > delayed_pic [ i ] - > f . reference = 0 ;
2012-03-16 20:40:05 +03:00
h - > delayed_pic [ i ] = NULL ;
2006-02-26 00:15:24 +02:00
}
2012-03-16 20:40:05 +03:00
h - > outputed_poc = h - > next_outputed_poc = INT_MIN ;
2009-06-10 00:16:40 +03:00
h - > prev_interlaced_frame = 1 ;
2005-05-03 09:53:59 +03:00
idr ( h ) ;
2012-03-17 06:43:12 +03:00
h - > prev_frame_num = - 1 ;
2012-03-16 20:40:05 +03:00
if ( h - > s . current_picture_ptr )
2011-07-06 21:08:30 +03:00
h - > s . current_picture_ptr - > f . reference = 0 ;
2012-03-16 20:40:05 +03:00
h - > s . first_field = 0 ;
2010-01-12 20:54:40 +02:00
ff_h264_reset_sei ( h ) ;
2007-11-17 05:04:21 +02:00
ff_mpeg_flush ( avctx ) ;
2011-09-20 03:37:37 +03:00
h - > recovery_frame = - 1 ;
2011-09-17 20:59:48 +03:00
h - > sync = 0 ;
2005-05-03 09:53:59 +03:00
}
2012-03-16 20:40:05 +03:00
static int init_poc ( H264Context * h )
{
MpegEncContext * const s = & h - > s ;
const int max_frame_num = 1 < < h - > sps . log2_max_frame_num ;
2003-04-04 17:42:28 +03:00
int field_poc [ 2 ] ;
2008-07-25 02:43:44 +03:00
Picture * cur = s - > current_picture_ptr ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
h - > frame_num_offset = h - > prev_frame_num_offset ;
if ( h - > frame_num < h - > prev_frame_num )
2008-07-25 01:29:38 +03:00
h - > frame_num_offset + = max_frame_num ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > sps . poc_type = = 0 ) {
const int max_poc_lsb = 1 < < h - > sps . log2_max_poc_lsb ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > poc_lsb < h - > prev_poc_lsb & & h - > prev_poc_lsb - h - > poc_lsb > = max_poc_lsb / 2 )
2003-04-04 17:42:28 +03:00
h - > poc_msb = h - > prev_poc_msb + max_poc_lsb ;
2012-03-16 20:40:05 +03:00
else if ( h - > poc_lsb > h - > prev_poc_lsb & & h - > prev_poc_lsb - h - > poc_lsb < - max_poc_lsb / 2 )
2003-04-04 17:42:28 +03:00
h - > poc_msb = h - > prev_poc_msb - max_poc_lsb ;
else
h - > poc_msb = h - > prev_poc_msb ;
2012-03-16 20:40:05 +03:00
// printf("poc: %d %d\n", h->poc_msb, h->poc_lsb);
2005-12-17 20:14:38 +02:00
field_poc [ 0 ] =
2003-04-04 17:42:28 +03:00
field_poc [ 1 ] = h - > poc_msb + h - > poc_lsb ;
2012-03-16 20:40:05 +03:00
if ( s - > picture_structure = = PICT_FRAME )
2003-04-04 17:42:28 +03:00
field_poc [ 1 ] + = h - > delta_poc_bottom ;
2012-03-16 20:40:05 +03:00
} else if ( h - > sps . poc_type = = 1 ) {
2003-04-04 17:42:28 +03:00
int abs_frame_num , expected_delta_per_poc_cycle , expectedpoc ;
int i ;
2012-03-16 20:40:05 +03:00
if ( h - > sps . poc_cycle_length ! = 0 )
2003-04-04 17:42:28 +03:00
abs_frame_num = h - > frame_num_offset + h - > frame_num ;
else
abs_frame_num = 0 ;
2012-03-16 20:40:05 +03:00
if ( h - > nal_ref_idc = = 0 & & abs_frame_num > 0 )
2003-04-04 17:42:28 +03:00
abs_frame_num - - ;
2005-12-17 20:14:38 +02:00
2003-04-04 17:42:28 +03:00
expected_delta_per_poc_cycle = 0 ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < h - > sps . poc_cycle_length ; i + + )
// FIXME integrate during sps parse
expected_delta_per_poc_cycle + = h - > sps . offset_for_ref_frame [ i ] ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( abs_frame_num > 0 ) {
2003-04-04 17:42:28 +03:00
int poc_cycle_cnt = ( abs_frame_num - 1 ) / h - > sps . poc_cycle_length ;
int frame_num_in_poc_cycle = ( abs_frame_num - 1 ) % h - > sps . poc_cycle_length ;
expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < = frame_num_in_poc_cycle ; i + + )
expectedpoc = expectedpoc + h - > sps . offset_for_ref_frame [ i ] ;
2003-04-04 17:42:28 +03:00
} else
expectedpoc = 0 ;
2012-03-16 20:40:05 +03:00
if ( h - > nal_ref_idc = = 0 )
2003-04-04 17:42:28 +03:00
expectedpoc = expectedpoc + h - > sps . offset_for_non_ref_pic ;
2005-12-17 20:14:38 +02:00
2003-04-04 17:42:28 +03:00
field_poc [ 0 ] = expectedpoc + h - > delta_poc [ 0 ] ;
field_poc [ 1 ] = field_poc [ 0 ] + h - > sps . offset_for_top_to_bottom_field ;
2012-03-16 20:40:05 +03:00
if ( s - > picture_structure = = PICT_FRAME )
2003-04-04 17:42:28 +03:00
field_poc [ 1 ] + = h - > delta_poc [ 1 ] ;
2012-03-16 20:40:05 +03:00
} else {
int poc = 2 * ( h - > frame_num_offset + h - > frame_num ) ;
2008-07-25 01:05:58 +03:00
2012-03-16 20:40:05 +03:00
if ( ! h - > nal_ref_idc )
2008-07-25 01:29:38 +03:00
poc - - ;
2008-07-25 01:05:58 +03:00
2012-03-16 20:40:05 +03:00
field_poc [ 0 ] = poc ;
field_poc [ 1 ] = poc ;
2003-04-04 17:42:28 +03:00
}
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( s - > picture_structure ! = PICT_BOTTOM_FIELD )
s - > current_picture_ptr - > field_poc [ 0 ] = field_poc [ 0 ] ;
if ( s - > picture_structure ! = PICT_TOP_FIELD )
s - > current_picture_ptr - > field_poc [ 1 ] = field_poc [ 1 ] ;
cur - > poc = FFMIN ( cur - > field_poc [ 0 ] , cur - > field_poc [ 1 ] ) ;
2003-04-04 17:42:28 +03:00
return 0 ;
}
2007-06-16 22:54:04 +03:00
/**
* initialize scan tables
*/
2012-03-16 20:40:05 +03:00
static void init_scan_tables ( H264Context * h )
{
2007-06-16 22:54:04 +03:00
int i ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 16 ; i + + ) {
# define T(x) (x >> 2) | ((x << 2) & 0xF)
2011-01-14 21:04:59 +02:00
h - > zigzag_scan [ i ] = T ( zigzag_scan [ i ] ) ;
2012-03-16 20:40:05 +03:00
h - > field_scan [ i ] = T ( field_scan [ i ] ) ;
2007-06-16 22:54:04 +03:00
# undef T
}
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < 64 ; i + + ) {
# define T(x) (x >> 3) | ((x & 7) << 3)
2011-01-14 21:04:59 +02:00
h - > zigzag_scan8x8 [ i ] = T ( ff_zigzag_direct [ i ] ) ;
h - > zigzag_scan8x8_cavlc [ i ] = T ( zigzag_scan8x8_cavlc [ i ] ) ;
h - > field_scan8x8 [ i ] = T ( field_scan8x8 [ i ] ) ;
h - > field_scan8x8_cavlc [ i ] = T ( field_scan8x8_cavlc [ i ] ) ;
2007-06-16 22:54:04 +03:00
# undef T
}
2012-03-16 20:40:05 +03:00
if ( h - > sps . transform_bypass ) { // FIXME same ugly
2007-06-16 22:54:04 +03:00
h - > zigzag_scan_q0 = zigzag_scan ;
2009-01-24 16:30:15 +02:00
h - > zigzag_scan8x8_q0 = ff_zigzag_direct ;
2007-06-16 22:54:04 +03:00
h - > zigzag_scan8x8_cavlc_q0 = zigzag_scan8x8_cavlc ;
h - > field_scan_q0 = field_scan ;
h - > field_scan8x8_q0 = field_scan8x8 ;
h - > field_scan8x8_cavlc_q0 = field_scan8x8_cavlc ;
2012-03-16 20:40:05 +03:00
} else {
2007-06-16 22:54:04 +03:00
h - > zigzag_scan_q0 = h - > zigzag_scan ;
h - > zigzag_scan8x8_q0 = h - > zigzag_scan8x8 ;
h - > zigzag_scan8x8_cavlc_q0 = h - > zigzag_scan8x8_cavlc ;
h - > field_scan_q0 = h - > field_scan ;
h - > field_scan8x8_q0 = h - > field_scan8x8 ;
h - > field_scan8x8_cavlc_q0 = h - > field_scan8x8_cavlc ;
}
}
2007-09-05 19:18:15 +03:00
2012-03-16 20:40:05 +03:00
static int field_end ( H264Context * h , int in_setup )
{
MpegEncContext * const s = & h - > s ;
AVCodecContext * const avctx = s - > avctx ;
2011-08-05 00:47:16 +03:00
int err = 0 ;
2012-03-16 20:40:05 +03:00
s - > mb_y = 0 ;
2009-04-12 23:21:23 +03:00
2011-03-22 23:36:57 +02:00
if ( ! in_setup & & ! s - > dropable )
2012-03-17 01:24:08 +03:00
ff_thread_report_progress ( & s - > current_picture_ptr - > f , INT_MAX ,
2012-02-28 00:02:45 +03:00
s - > picture_structure = = PICT_BOTTOM_FIELD ) ;
2009-04-12 23:21:23 +03:00
2012-03-16 20:40:05 +03:00
if ( CONFIG_H264_VDPAU_DECODER & &
s - > avctx - > codec - > capabilities & CODEC_CAP_HWACCEL_VDPAU )
2009-04-12 23:21:23 +03:00
ff_vdpau_h264_set_reference_frames ( s ) ;
2012-03-16 20:40:05 +03:00
if ( in_setup | | ! ( avctx - > active_thread_type & FF_THREAD_FRAME ) ) {
if ( ! s - > dropable ) {
2011-08-05 00:47:16 +03:00
err = ff_h264_execute_ref_pic_marking ( h , h - > mmco , h - > mmco_index ) ;
2012-03-16 20:40:05 +03:00
h - > prev_poc_msb = h - > poc_msb ;
h - > prev_poc_lsb = h - > poc_lsb ;
2011-03-22 23:36:57 +02:00
}
2012-03-16 20:40:05 +03:00
h - > prev_frame_num_offset = h - > frame_num_offset ;
h - > prev_frame_num = h - > frame_num ;
h - > outputed_poc = h - > next_outputed_poc ;
2009-04-12 23:21:23 +03:00
}
if ( avctx - > hwaccel ) {
if ( avctx - > hwaccel - > end_frame ( avctx ) < 0 )
2012-03-16 20:40:05 +03:00
av_log ( avctx , AV_LOG_ERROR ,
" hardware accelerator failed to decode picture \n " ) ;
2009-04-12 23:21:23 +03:00
}
2012-03-16 20:40:05 +03:00
if ( CONFIG_H264_VDPAU_DECODER & &
s - > avctx - > codec - > capabilities & CODEC_CAP_HWACCEL_VDPAU )
2009-04-12 23:21:23 +03:00
ff_vdpau_h264_picture_complete ( s ) ;
/*
* FIXME : Error handling code does not seem to support interlaced
* when slices span multiple rows
* The ff_er_add_slice calls don ' t work right for bottom
* fields ; they cause massive erroneous error concealing
* Error marking covers both fields ( top and bottom ) .
* This causes a mismatched s - > error_count
* and a bad error table . Further , the error count goes to
* INT_MAX when called for bottom field , because mb_y is
* past end by one ( callers fault ) and resync_mb_y ! = 0
* causes problems for the first MB line , too .
*/
if ( ! FIELD_PICTURE )
ff_er_frame_end ( s ) ;
2012-02-15 15:10:33 +03:00
ff_MPV_frame_end ( s ) ;
2009-04-12 23:43:52 +03:00
2012-03-16 20:40:05 +03:00
h - > current_slice = 0 ;
2011-08-05 00:47:16 +03:00
return err ;
2009-04-12 23:21:23 +03:00
}
2007-09-05 19:18:15 +03:00
/**
2010-06-30 18:38:06 +03:00
* Replicate H264 " master " context to thread contexts .
2007-09-05 19:18:15 +03:00
*/
static void clone_slice ( H264Context * dst , H264Context * src )
{
2012-03-16 20:40:05 +03:00
memcpy ( dst - > block_offset , src - > block_offset , sizeof ( dst - > block_offset ) ) ;
dst - > s . current_picture_ptr = src - > s . current_picture_ptr ;
dst - > s . current_picture = src - > s . current_picture ;
dst - > s . linesize = src - > s . linesize ;
dst - > s . uvlinesize = src - > s . uvlinesize ;
dst - > s . first_field = src - > s . first_field ;
dst - > prev_poc_msb = src - > prev_poc_msb ;
dst - > prev_poc_lsb = src - > prev_poc_lsb ;
dst - > prev_frame_num_offset = src - > prev_frame_num_offset ;
dst - > prev_frame_num = src - > prev_frame_num ;
dst - > short_ref_count = src - > short_ref_count ;
2007-09-05 19:18:15 +03:00
memcpy ( dst - > short_ref , src - > short_ref , sizeof ( dst - > short_ref ) ) ;
memcpy ( dst - > long_ref , src - > long_ref , sizeof ( dst - > long_ref ) ) ;
memcpy ( dst - > default_ref_list , src - > default_ref_list , sizeof ( dst - > default_ref_list ) ) ;
memcpy ( dst - > ref_list , src - > ref_list , sizeof ( dst - > ref_list ) ) ;
2007-09-16 13:37:07 +03:00
memcpy ( dst - > dequant4_coeff , src - > dequant4_coeff , sizeof ( src - > dequant4_coeff ) ) ;
memcpy ( dst - > dequant8_coeff , src - > dequant8_coeff , sizeof ( src - > dequant8_coeff ) ) ;
2007-09-05 19:18:15 +03:00
}
2011-01-28 23:15:47 +02:00
/**
2011-12-07 15:03:53 +03:00
* Compute profile from profile_idc and constraint_set ? _flags .
2011-01-28 23:15:47 +02:00
*
* @ param sps SPS
*
* @ return profile as defined by FF_PROFILE_H264_ *
*/
int ff_h264_get_profile ( SPS * sps )
{
int profile = sps - > profile_idc ;
2012-03-16 20:40:05 +03:00
switch ( sps - > profile_idc ) {
2011-01-28 23:15:47 +02:00
case FF_PROFILE_H264_BASELINE :
// constraint_set1_flag set to 1
2012-03-16 20:40:05 +03:00
profile | = ( sps - > constraint_set_flags & 1 < < 1 ) ? FF_PROFILE_H264_CONSTRAINED : 0 ;
2011-01-28 23:15:47 +02:00
break ;
case FF_PROFILE_H264_HIGH_10 :
case FF_PROFILE_H264_HIGH_422 :
case FF_PROFILE_H264_HIGH_444_PREDICTIVE :
// constraint_set3_flag set to 1
2012-03-16 20:40:05 +03:00
profile | = ( sps - > constraint_set_flags & 1 < < 3 ) ? FF_PROFILE_H264_INTRA : 0 ;
2011-01-28 23:15:47 +02:00
break ;
}
return profile ;
}
2003-04-04 17:42:28 +03:00
/**
2011-12-07 15:03:53 +03:00
* Decode a slice header .
2012-02-15 15:10:33 +03:00
* This will also call ff_MPV_common_init ( ) and frame_start ( ) as needed .
2007-09-05 19:18:15 +03:00
*
* @ param h h264context
2012-03-16 20:40:05 +03:00
* @ param h0 h264 master context ( differs from ' h ' when doing sliced based
* parallel decoding )
2007-09-05 19:18:15 +03:00
*
2008-03-22 03:06:57 +02:00
* @ return 0 if okay , < 0 if an error occurred , 1 if decoding must not be multithreaded
2003-04-04 17:42:28 +03:00
*/
2012-03-16 20:40:05 +03:00
static int decode_slice_header ( H264Context * h , H264Context * h0 )
{
MpegEncContext * const s = & h - > s ;
MpegEncContext * const s0 = & h0 - > s ;
2007-01-20 15:50:00 +02:00
unsigned int first_mb_in_slice ;
2007-01-19 11:37:04 +02:00
unsigned int pps_id ;
2003-04-04 17:42:28 +03:00
int num_ref_idx_active_override_flag ;
2008-07-20 21:06:41 +03:00
unsigned int slice_type , tmp , i , j ;
2005-02-04 04:47:45 +02:00
int default_ref_list_done = 0 ;
2012-03-17 01:24:08 +03:00
int last_pic_structure , last_pic_dropable ;
2012-03-24 18:23:40 +03:00
int must_reinit ;
2003-04-04 17:42:28 +03:00
2011-06-26 10:21:54 +03:00
/* FIXME: 2tap qpel isn't implemented for high bit depth. */
2012-03-16 20:40:05 +03:00
if ( ( s - > avctx - > flags2 & CODEC_FLAG2_FAST ) & &
! h - > nal_ref_idc & & ! h - > pixel_shift ) {
s - > me . qpel_put = s - > dsp . put_2tap_qpel_pixels_tab ;
s - > me . qpel_avg = s - > dsp . avg_2tap_qpel_pixels_tab ;
} else {
s - > me . qpel_put = s - > dsp . put_h264_qpel_pixels_tab ;
s - > me . qpel_avg = s - > dsp . avg_h264_qpel_pixels_tab ;
2007-12-05 07:24:54 +02:00
}
2012-03-17 06:43:12 +03:00
first_mb_in_slice = get_ue_golomb_long ( & s - > gb ) ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( first_mb_in_slice = = 0 ) { // FIXME better field boundary detection
if ( h0 - > current_slice & & FIELD_PICTURE ) {
2011-03-22 23:36:57 +02:00
field_end ( h , 1 ) ;
2009-04-12 23:43:52 +03:00
}
2007-09-05 19:18:15 +03:00
h0 - > current_slice = 0 ;
2012-03-17 01:24:08 +03:00
if ( ! s0 - > first_field ) {
if ( s - > current_picture_ptr & & ! s - > dropable & &
s - > current_picture_ptr - > owner2 = = s ) {
ff_thread_report_progress ( & s - > current_picture_ptr - > f , INT_MAX ,
s - > picture_structure = = PICT_BOTTOM_FIELD ) ;
}
2012-03-16 20:40:05 +03:00
s - > current_picture_ptr = NULL ;
2012-03-17 01:24:08 +03:00
}
2007-03-03 01:35:26 +02:00
}
2012-03-16 20:40:05 +03:00
slice_type = get_ue_golomb_31 ( & s - > gb ) ;
if ( slice_type > 9 ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" slice type too large (%d) at %d %d \n " ,
h - > slice_type , s - > mb_x , s - > mb_y ) ;
2004-12-18 05:49:07 +02:00
return - 1 ;
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
if ( slice_type > 4 ) {
2005-02-04 04:47:45 +02:00
slice_type - = 5 ;
2012-03-16 20:40:05 +03:00
h - > slice_type_fixed = 1 ;
} else
h - > slice_type_fixed = 0 ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
slice_type = golomb_to_pict_type [ slice_type ] ;
if ( slice_type = = AV_PICTURE_TYPE_I | |
( h0 - > current_slice ! = 0 & & slice_type = = h0 - > last_slice_type ) ) {
2005-02-04 04:47:45 +02:00
default_ref_list_done = 1 ;
}
2012-03-16 20:40:05 +03:00
h - > slice_type = slice_type ;
h - > slice_type_nos = slice_type & 3 ;
2005-02-04 04:47:45 +02:00
2012-03-16 20:40:05 +03:00
// to make a few old functions happy, it's wrong though
s - > pict_type = h - > slice_type ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
pps_id = get_ue_golomb ( & s - > gb ) ;
if ( pps_id > = MAX_PPS_COUNT ) {
2012-03-19 03:43:44 +03:00
av_log ( h - > s . avctx , AV_LOG_ERROR , " pps_id %d out of range \n " , pps_id ) ;
2003-04-04 17:42:28 +03:00
return - 1 ;
}
2012-03-16 20:40:05 +03:00
if ( ! h0 - > pps_buffers [ pps_id ] ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" non-existing PPS %u referenced \n " ,
pps_id ) ;
2003-04-07 22:23:21 +03:00
return - 1 ;
}
2012-03-16 20:40:05 +03:00
h - > pps = * h0 - > pps_buffers [ pps_id ] ;
2003-04-07 22:23:21 +03:00
2012-03-16 20:40:05 +03:00
if ( ! h0 - > sps_buffers [ h - > pps . sps_id ] ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" non-existing SPS %u referenced \n " ,
h - > pps . sps_id ) ;
2003-04-07 22:23:21 +03:00
return - 1 ;
}
2007-09-05 19:18:15 +03:00
h - > sps = * h0 - > sps_buffers [ h - > pps . sps_id ] ;
2005-10-25 04:17:20 +03:00
2011-01-28 23:15:47 +02:00
s - > avctx - > profile = ff_h264_get_profile ( & h - > sps ) ;
2010-04-15 11:30:48 +03:00
s - > avctx - > level = h - > sps . level_idc ;
2010-04-15 16:16:37 +03:00
s - > avctx - > refs = h - > sps . ref_frame_count ;
2010-04-15 11:27:06 +03:00
2012-03-24 18:23:40 +03:00
must_reinit = ( s - > context_initialized & &
( 16 * h - > sps . mb_width ! = s - > avctx - > coded_width
| | 16 * h - > sps . mb_height * ( 2 - h - > sps . frame_mbs_only_flag ) ! = s - > avctx - > coded_height
| | s - > avctx - > bits_per_raw_sample ! = h - > sps . bit_depth_luma
| | h - > cur_chroma_format_idc ! = h - > sps . chroma_format_idc
| | av_cmp_q ( h - > sps . sar , s - > avctx - > sample_aspect_ratio ) ) ) ;
if ( must_reinit & & ( h ! = h0 | | ( s - > avctx - > active_thread_type & FF_THREAD_FRAME ) ) ) {
av_log_missing_feature ( s - > avctx ,
" Width/height/bit depth/chroma idc changing with threads is " , 0 ) ;
2012-05-03 22:02:32 +03:00
return AVERROR_PATCHWELCOME ; // width / height changed during parallelized decoding
2012-03-24 18:23:40 +03:00
}
2012-03-16 20:40:05 +03:00
s - > mb_width = h - > sps . mb_width ;
s - > mb_height = h - > sps . mb_height * ( 2 - h - > sps . frame_mbs_only_flag ) ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
h - > b_stride = s - > mb_width * 4 ;
2003-04-04 17:42:28 +03:00
2011-08-15 01:39:55 +03:00
s - > chroma_y_shift = h - > sps . chroma_format_idc < = 1 ; // 400 uses yuv420p
2012-03-17 06:43:12 +03:00
s - > width = 16 * s - > mb_width ;
s - > height = 16 * s - > mb_height ;
2005-12-17 20:14:38 +02:00
2012-03-24 18:23:40 +03:00
if ( must_reinit ) {
2011-01-22 16:42:56 +02:00
free_tables ( h , 0 ) ;
2008-12-01 01:51:02 +02:00
flush_dpb ( s - > avctx ) ;
2012-02-15 15:10:33 +03:00
ff_MPV_common_end ( s ) ;
2011-10-04 23:13:58 +03:00
h - > list_count = 0 ;
2012-04-18 16:16:36 +03:00
h - > current_slice = 0 ;
2003-04-04 17:42:28 +03:00
}
if ( ! s - > context_initialized ) {
2011-04-02 18:57:53 +03:00
if ( h ! = h0 ) {
2012-03-16 20:40:05 +03:00
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" Cannot (re-)initialize context during parallel decoding. \n " ) ;
2011-04-02 18:57:53 +03:00
return - 1 ;
}
2009-11-24 17:13:47 +02:00
avcodec_set_dimensions ( s - > avctx , s - > width , s - > height ) ;
2011-11-06 02:59:37 +03:00
s - > avctx - > width - = ( 2 > > CHROMA444 ) * FFMIN ( h - > sps . crop_right , ( 8 < < CHROMA444 ) - 1 ) ;
s - > avctx - > height - = ( 1 < < s - > chroma_y_shift ) * FFMIN ( h - > sps . crop_bottom , ( 16 > > s - > chroma_y_shift ) - 1 ) * ( 2 - h - > sps . frame_mbs_only_flag ) ;
2012-03-16 20:40:05 +03:00
s - > avctx - > sample_aspect_ratio = h - > sps . sar ;
2010-10-05 04:43:25 +03:00
av_assert0 ( s - > avctx - > sample_aspect_ratio . den ) ;
2009-11-24 17:13:47 +02:00
2011-10-04 23:13:57 +03:00
if ( s - > avctx - > bits_per_raw_sample ! = h - > sps . bit_depth_luma | |
h - > cur_chroma_format_idc ! = h - > sps . chroma_format_idc ) {
2011-10-06 22:55:43 +03:00
if ( h - > sps . bit_depth_luma > = 8 & & h - > sps . bit_depth_luma < = 10 & &
( h - > sps . bit_depth_luma ! = 9 | | ! CHROMA422 ) ) {
2011-10-04 23:13:57 +03:00
s - > avctx - > bits_per_raw_sample = h - > sps . bit_depth_luma ;
h - > cur_chroma_format_idc = h - > sps . chroma_format_idc ;
h - > pixel_shift = h - > sps . bit_depth_luma > 8 ;
ff_h264dsp_init ( & h - > h264dsp , h - > sps . bit_depth_luma , h - > sps . chroma_format_idc ) ;
ff_h264_pred_init ( & h - > hpc , s - > codec_id , h - > sps . bit_depth_luma , h - > sps . chroma_format_idc ) ;
s - > dsp . dct_bits = h - > sps . bit_depth_luma > 8 ? 32 : 16 ;
2012-02-16 02:49:16 +03:00
ff_dsputil_init ( & s - > dsp , s - > avctx ) ;
2011-10-04 23:13:57 +03:00
} else {
2011-10-30 00:39:02 +03:00
av_log ( s - > avctx , AV_LOG_ERROR , " Unsupported bit depth: %d chroma_idc: %d \n " ,
2011-10-06 22:55:43 +03:00
h - > sps . bit_depth_luma , h - > sps . chroma_format_idc ) ;
2011-10-04 23:13:57 +03:00
return - 1 ;
}
}
2012-03-16 20:40:05 +03:00
if ( h - > sps . video_signal_type_present_flag ) {
2012-03-17 06:43:12 +03:00
s - > avctx - > color_range = h - > sps . full_range > 0 ? AVCOL_RANGE_JPEG
2012-03-16 20:40:05 +03:00
: AVCOL_RANGE_MPEG ;
if ( h - > sps . colour_description_present_flag ) {
2010-01-11 02:31:39 +02:00
s - > avctx - > color_primaries = h - > sps . color_primaries ;
s - > avctx - > color_trc = h - > sps . color_trc ;
s - > avctx - > colorspace = h - > sps . colorspace ;
}
}
2012-03-16 20:40:05 +03:00
if ( h - > sps . timing_info_present_flag ) {
int64_t den = h - > sps . time_scale ;
if ( h - > x264_build < 44U )
2010-02-04 17:30:37 +02:00
den * = 2 ;
2009-11-24 17:13:47 +02:00
av_reduce ( & s - > avctx - > time_base . num , & s - > avctx - > time_base . den ,
2012-03-16 20:40:05 +03:00
h - > sps . num_units_in_tick , den , 1 < < 30 ) ;
2009-11-24 17:13:47 +02:00
}
2011-03-29 18:49:00 +03:00
switch ( h - > sps . bit_depth_luma ) {
2012-03-16 20:40:05 +03:00
case 9 :
if ( CHROMA444 ) {
if ( s - > avctx - > colorspace = = AVCOL_SPC_RGB ) {
s - > avctx - > pix_fmt = PIX_FMT_GBRP9 ;
} else
s - > avctx - > pix_fmt = PIX_FMT_YUV444P9 ;
} else if ( CHROMA422 )
s - > avctx - > pix_fmt = PIX_FMT_YUV422P9 ;
else
s - > avctx - > pix_fmt = PIX_FMT_YUV420P9 ;
break ;
case 10 :
if ( CHROMA444 ) {
if ( s - > avctx - > colorspace = = AVCOL_SPC_RGB ) {
s - > avctx - > pix_fmt = PIX_FMT_GBRP10 ;
} else
s - > avctx - > pix_fmt = PIX_FMT_YUV444P10 ;
} else if ( CHROMA422 )
s - > avctx - > pix_fmt = PIX_FMT_YUV422P10 ;
else
s - > avctx - > pix_fmt = PIX_FMT_YUV420P10 ;
break ;
case 8 :
if ( CHROMA444 ) {
s - > avctx - > pix_fmt = s - > avctx - > color_range = = AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ444P
: PIX_FMT_YUV444P ;
2011-10-08 22:54:20 +03:00
if ( s - > avctx - > colorspace = = AVCOL_SPC_RGB ) {
2012-03-17 06:43:12 +03:00
s - > avctx - > pix_fmt = PIX_FMT_GBR24P ;
av_log ( h - > s . avctx , AV_LOG_DEBUG , " Detected GBR colorspace. \n " ) ;
2011-10-29 14:11:01 +03:00
} else if ( s - > avctx - > colorspace = = AVCOL_SPC_YCGCO ) {
av_log ( h - > s . avctx , AV_LOG_WARNING , " Detected unsupported YCgCo colorspace. \n " ) ;
2011-10-08 22:54:20 +03:00
}
2012-03-16 20:40:05 +03:00
} else if ( CHROMA422 ) {
s - > avctx - > pix_fmt = s - > avctx - > color_range = = AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ422P
: PIX_FMT_YUV422P ;
} else {
s - > avctx - > pix_fmt = s - > avctx - > get_format ( s - > avctx ,
s - > avctx - > codec - > pix_fmts ?
s - > avctx - > codec - > pix_fmts :
s - > avctx - > color_range = = AVCOL_RANGE_JPEG ?
hwaccel_pixfmt_list_h264_jpeg_420 :
ff_hwaccel_pixfmt_list_420 ) ;
}
break ;
default :
av_log ( s - > avctx , AV_LOG_ERROR ,
" Unsupported bit depth: %d \n " , h - > sps . bit_depth_luma ) ;
return AVERROR_INVALIDDATA ;
2011-03-29 18:49:00 +03:00
}
2012-03-16 20:40:05 +03:00
s - > avctx - > hwaccel = ff_find_hwaccel ( s - > avctx - > codec - > id ,
s - > avctx - > pix_fmt ) ;
2009-11-24 17:13:47 +02:00
2012-02-15 15:10:33 +03:00
if ( ff_MPV_common_init ( s ) < 0 ) {
av_log ( h - > s . avctx , AV_LOG_ERROR , " ff_MPV_common_init() failed. \n " ) ;
2003-04-04 17:42:28 +03:00
return - 1 ;
2011-04-02 18:57:53 +03:00
}
2007-10-08 20:44:38 +03:00
s - > first_field = 0 ;
2009-06-10 00:16:40 +03:00
h - > prev_interlaced_frame = 1 ;
2005-12-17 20:14:38 +02:00
2007-06-16 22:54:04 +03:00
init_scan_tables ( h ) ;
2011-08-11 15:57:58 +03:00
if ( ff_h264_alloc_tables ( h ) < 0 ) {
2012-03-16 20:40:05 +03:00
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" Could not allocate memory for h264 \n " ) ;
2011-08-11 15:57:58 +03:00
return AVERROR ( ENOMEM ) ;
}
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( ! HAVE_THREADS | | ! ( s - > avctx - > active_thread_type & FF_THREAD_SLICE ) ) {
2011-04-02 18:57:53 +03:00
if ( context_init ( h ) < 0 ) {
av_log ( h - > s . avctx , AV_LOG_ERROR , " context_init() failed. \n " ) ;
2007-09-05 19:18:15 +03:00
return - 1 ;
2011-04-02 18:57:53 +03:00
}
2011-03-22 23:36:57 +02:00
} else {
2012-03-16 20:40:05 +03:00
for ( i = 1 ; i < s - > slice_context_count ; i + + ) {
2011-03-22 23:36:57 +02:00
H264Context * c ;
c = h - > thread_context [ i ] = av_malloc ( sizeof ( H264Context ) ) ;
memcpy ( c , h - > s . thread_context [ i ] , sizeof ( MpegEncContext ) ) ;
memset ( & c - > s + 1 , 0 , sizeof ( H264Context ) - sizeof ( MpegEncContext ) ) ;
2012-03-16 20:40:05 +03:00
c - > h264dsp = h - > h264dsp ;
c - > sps = h - > sps ;
c - > pps = h - > pps ;
2011-05-19 06:12:45 +03:00
c - > pixel_shift = h - > pixel_shift ;
2011-11-17 07:42:18 +03:00
c - > cur_chroma_format_idc = h - > cur_chroma_format_idc ;
2011-03-22 23:36:57 +02:00
init_scan_tables ( c ) ;
clone_tables ( c , h , i ) ;
}
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < s - > slice_context_count ; i + + )
2011-04-02 18:57:53 +03:00
if ( context_init ( h - > thread_context [ i ] ) < 0 ) {
2012-03-16 20:40:05 +03:00
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" context_init() failed. \n " ) ;
2011-03-22 23:36:57 +02:00
return - 1 ;
2011-04-02 18:57:53 +03:00
}
2011-03-22 23:36:57 +02:00
}
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
if ( h = = h0 & & h - > dequant_coeff_pps ! = pps_id ) {
2012-03-01 22:56:05 +03:00
h - > dequant_coeff_pps = pps_id ;
init_dequant_tables ( h ) ;
}
2012-03-16 20:40:05 +03:00
h - > frame_num = get_bits ( & s - > gb , h - > sps . log2_max_frame_num ) ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
h - > mb_mbaff = 0 ;
h - > mb_aff_frame = 0 ;
2007-10-08 20:44:38 +03:00
last_pic_structure = s0 - > picture_structure ;
2012-03-17 01:24:08 +03:00
last_pic_dropable = s - > dropable ;
s - > dropable = h - > nal_ref_idc = = 0 ;
2012-03-16 20:40:05 +03:00
if ( h - > sps . frame_mbs_only_flag ) {
s - > picture_structure = PICT_FRAME ;
} else {
2012-03-17 06:43:12 +03:00
if ( ! h - > sps . direct_8x8_inference_flag & & slice_type = = AV_PICTURE_TYPE_B ) {
2011-10-15 16:32:34 +03:00
av_log ( h - > s . avctx , AV_LOG_ERROR , " This stream was generated by a broken encoder, invalid 8x8 inference \n " ) ;
return - 1 ;
}
2012-03-16 20:40:05 +03:00
if ( get_bits1 ( & s - > gb ) ) { // field_pic_flag
s - > picture_structure = PICT_TOP_FIELD + get_bits1 ( & s - > gb ) ; // bottom_field_flag
2005-03-27 03:44:11 +03:00
} else {
2012-03-16 20:40:05 +03:00
s - > picture_structure = PICT_FRAME ;
h - > mb_aff_frame = h - > sps . mb_aff ;
2005-03-07 01:02:25 +02:00
}
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
h - > mb_field_decoding_flag = s - > picture_structure ! = PICT_FRAME ;
2007-09-26 16:28:13 +03:00
2012-03-17 01:24:08 +03:00
if ( h0 - > current_slice ! = 0 ) {
if ( last_pic_structure ! = s - > picture_structure | |
last_pic_dropable ! = s - > dropable ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" Changing field mode (%d -> %d) between slices is not allowed \n " ,
last_pic_structure , s - > picture_structure ) ;
s - > picture_structure = last_pic_structure ;
s - > dropable = last_pic_dropable ;
return AVERROR_INVALIDDATA ;
}
} else {
2012-03-16 20:40:05 +03:00
/* Shorten frame num gaps so we don't have to allocate reference
* frames just to throw them away */
2012-03-17 06:43:12 +03:00
if ( h - > frame_num ! = h - > prev_frame_num & & h - > prev_frame_num > = 0 ) {
2012-03-16 20:40:05 +03:00
int unwrap_prev_frame_num = h - > prev_frame_num ;
int max_frame_num = 1 < < h - > sps . log2_max_frame_num ;
2011-06-02 11:39:56 +03:00
2012-03-16 20:40:05 +03:00
if ( unwrap_prev_frame_num > h - > frame_num )
unwrap_prev_frame_num - = max_frame_num ;
2011-06-02 11:39:56 +03:00
if ( ( h - > frame_num - unwrap_prev_frame_num ) > h - > sps . ref_frame_count ) {
unwrap_prev_frame_num = ( h - > frame_num - h - > sps . ref_frame_count ) - 1 ;
if ( unwrap_prev_frame_num < 0 )
unwrap_prev_frame_num + = max_frame_num ;
h - > prev_frame_num = unwrap_prev_frame_num ;
}
}
2011-03-22 23:36:57 +02:00
2012-03-17 01:24:08 +03:00
/* See if we have a decoded first field looking for a pair...
* Here , we ' re using that to see if we should mark previously
* decode frames as " finished " .
* We have to do that before the " dummy " in - between frame allocation ,
* since that can modify s - > current_picture_ptr . */
if ( s0 - > first_field ) {
assert ( s0 - > current_picture_ptr ) ;
assert ( s0 - > current_picture_ptr - > f . data [ 0 ] ) ;
assert ( s0 - > current_picture_ptr - > f . reference ! = DELAYED_PIC_REF ) ;
/* Mark old field/frame as completed */
if ( ! last_pic_dropable & & s0 - > current_picture_ptr - > owner2 = = s0 ) {
ff_thread_report_progress ( & s0 - > current_picture_ptr - > f , INT_MAX ,
last_pic_structure = = PICT_BOTTOM_FIELD ) ;
}
/* figure out if we have a complementary field pair */
if ( ! FIELD_PICTURE | | s - > picture_structure = = last_pic_structure ) {
/* Previous field is unmatched. Don't display it, but let it
* remain for reference if marked as such . */
if ( ! last_pic_dropable & & last_pic_structure ! = PICT_FRAME ) {
ff_thread_report_progress ( & s0 - > current_picture_ptr - > f , INT_MAX ,
last_pic_structure = = PICT_TOP_FIELD ) ;
}
} else {
if ( s0 - > current_picture_ptr - > frame_num ! = h - > frame_num ) {
/* This and previous field were reference, but had
* different frame_nums . Consider this field first in
* pair . Throw away previous field except for reference
* purposes . */
if ( ! last_pic_dropable & & last_pic_structure ! = PICT_FRAME ) {
ff_thread_report_progress ( & s0 - > current_picture_ptr - > f , INT_MAX ,
last_pic_structure = = PICT_TOP_FIELD ) ;
}
} else {
/* Second field in complementary pair */
if ( ! ( ( last_pic_structure = = PICT_TOP_FIELD & &
s - > picture_structure = = PICT_BOTTOM_FIELD ) | |
( last_pic_structure = = PICT_BOTTOM_FIELD & &
s - > picture_structure = = PICT_TOP_FIELD ) ) ) {
av_log ( s - > avctx , AV_LOG_ERROR ,
" Invalid field mode combination %d/%d \n " ,
last_pic_structure , s - > picture_structure ) ;
s - > picture_structure = last_pic_structure ;
s - > dropable = last_pic_dropable ;
return AVERROR_INVALIDDATA ;
} else if ( last_pic_dropable ! = s - > dropable ) {
av_log ( s - > avctx , AV_LOG_ERROR ,
" Cannot combine reference and non-reference fields in the same frame \n " ) ;
av_log_ask_for_sample ( s - > avctx , NULL ) ;
s - > picture_structure = last_pic_structure ;
s - > dropable = last_pic_dropable ;
return AVERROR_INVALIDDATA ;
}
/* Take ownership of this buffer. Note that if another thread owned
* the first field of this buffer , we ' re not operating on that pointer ,
* so the original thread is still responsible for reporting progress
* on that first field ( or if that was us , we just did that above ) .
* By taking ownership , we assign responsibility to ourselves to
* report progress on the second field . */
s0 - > current_picture_ptr - > owner2 = s0 ;
}
}
}
2012-03-17 06:43:12 +03:00
while ( h - > frame_num ! = h - > prev_frame_num & & h - > prev_frame_num > = 0 & &
2012-03-16 20:40:05 +03:00
h - > frame_num ! = ( h - > prev_frame_num + 1 ) % ( 1 < < h - > sps . log2_max_frame_num ) ) {
2010-09-28 12:06:22 +03:00
Picture * prev = h - > short_ref_count ? h - > short_ref [ 0 ] : NULL ;
2012-03-16 20:40:05 +03:00
av_log ( h - > s . avctx , AV_LOG_DEBUG , " Frame num gap %d %d \n " ,
h - > frame_num , h - > prev_frame_num ) ;
2010-01-12 07:30:31 +02:00
if ( ff_h264_frame_start ( h ) < 0 )
2009-02-22 11:51:58 +02:00
return - 1 ;
2008-07-23 05:12:54 +03:00
h - > prev_frame_num + + ;
2012-03-16 20:40:05 +03:00
h - > prev_frame_num % = 1 < < h - > sps . log2_max_frame_num ;
s - > current_picture_ptr - > frame_num = h - > prev_frame_num ;
2012-02-28 00:02:45 +03:00
ff_thread_report_progress ( & s - > current_picture_ptr - > f , INT_MAX , 0 ) ;
ff_thread_report_progress ( & s - > current_picture_ptr - > f , INT_MAX , 1 ) ;
2010-07-05 17:36:03 +03:00
ff_generate_sliding_window_mmcos ( h ) ;
2011-08-05 00:47:16 +03:00
if ( ff_h264_execute_ref_pic_marking ( h , h - > mmco , h - > mmco_index ) < 0 & &
2011-10-22 15:44:16 +03:00
( s - > avctx - > err_recognition & AV_EF_EXPLODE ) )
2011-08-05 00:47:16 +03:00
return AVERROR_INVALIDDATA ;
2010-09-27 07:43:41 +03:00
/* Error concealment: if a ref is missing, copy the previous ref in its place.
* FIXME : avoiding a memcpy would be nice , but ref handling makes many assumptions
* about there being no actual duplicates .
* FIXME : this doesn ' t copy padding for out - of - frame motion vectors . Given we ' re
2011-10-05 15:12:42 +03:00
* concealing a lost frame , this probably isn ' t noticeable by comparison , but it should
2010-09-27 07:43:41 +03:00
* be fixed . */
2010-09-28 12:06:22 +03:00
if ( h - > short_ref_count ) {
if ( prev ) {
2011-07-06 21:08:30 +03:00
av_image_copy ( h - > short_ref [ 0 ] - > f . data , h - > short_ref [ 0 ] - > f . linesize ,
2012-03-16 20:40:05 +03:00
( const uint8_t * * ) prev - > f . data , prev - > f . linesize ,
s - > avctx - > pix_fmt , s - > mb_width * 16 , s - > mb_height * 16 ) ;
h - > short_ref [ 0 ] - > poc = prev - > poc + 2 ;
2010-09-28 12:06:22 +03:00
}
h - > short_ref [ 0 ] - > frame_num = h - > prev_frame_num ;
}
2008-07-23 05:12:54 +03:00
}
2012-03-17 01:24:08 +03:00
/* See if we have a decoded first field looking for a pair...
* We ' re using that to see whether to continue decoding in that
* frame , or to allocate a new one . */
2007-10-08 20:44:38 +03:00
if ( s0 - > first_field ) {
assert ( s0 - > current_picture_ptr ) ;
2011-07-06 21:08:30 +03:00
assert ( s0 - > current_picture_ptr - > f . data [ 0 ] ) ;
2011-09-13 18:00:41 +03:00
assert ( s0 - > current_picture_ptr - > f . reference ! = DELAYED_PIC_REF ) ;
2007-10-08 20:44:38 +03:00
/* figure out if we have a complementary field pair */
if ( ! FIELD_PICTURE | | s - > picture_structure = = last_pic_structure ) {
2012-03-16 20:40:05 +03:00
/* Previous field is unmatched. Don't display it, but let it
* remain for reference if marked as such . */
2007-10-08 20:44:38 +03:00
s0 - > current_picture_ptr = NULL ;
2012-03-16 20:40:05 +03:00
s0 - > first_field = FIELD_PICTURE ;
2007-10-08 20:44:38 +03:00
} else {
2011-11-12 23:10:15 +03:00
if ( s0 - > current_picture_ptr - > frame_num ! = h - > frame_num ) {
2012-02-11 22:11:18 +03:00
ff_thread_report_progress ( ( AVFrame * ) s0 - > current_picture_ptr , INT_MAX ,
s0 - > picture_structure = = PICT_BOTTOM_FIELD ) ;
2012-03-17 01:24:08 +03:00
/* This and the previous field had different frame_nums.
* Consider this field first in pair . Throw away previous
* one except for reference purposes . */
2012-03-16 20:40:05 +03:00
s0 - > first_field = 1 ;
2007-10-08 20:44:38 +03:00
s0 - > current_picture_ptr = NULL ;
} else {
/* Second field in complementary pair */
s0 - > first_field = 0 ;
}
}
} else {
/* Frame or first field in a potentially complementary pair */
assert ( ! s0 - > current_picture_ptr ) ;
s0 - > first_field = FIELD_PICTURE ;
}
2012-03-16 20:40:05 +03:00
if ( ! FIELD_PICTURE | | s0 - > first_field ) {
2011-04-18 01:47:35 +03:00
if ( ff_h264_frame_start ( h ) < 0 ) {
s0 - > first_field = 0 ;
return - 1 ;
}
} else {
ff_release_unused_pictures ( s , 0 ) ;
2007-10-08 20:44:38 +03:00
}
2007-09-26 16:28:13 +03:00
}
2012-03-16 20:40:05 +03:00
if ( h ! = h0 )
2007-09-26 16:28:13 +03:00
clone_slice ( h , h0 ) ;
2012-03-16 20:40:05 +03:00
s - > current_picture_ptr - > frame_num = h - > frame_num ; // FIXME frame_num cleanup
2007-09-26 16:28:13 +03:00
2007-01-20 15:50:00 +02:00
assert ( s - > mb_num = = s - > mb_width * s - > mb_height ) ;
2012-03-16 20:40:05 +03:00
if ( first_mb_in_slice < < FIELD_OR_MBAFF_PICTURE > = s - > mb_num | |
first_mb_in_slice > = s - > mb_num ) {
2007-01-20 15:50:00 +02:00
av_log ( h - > s . avctx , AV_LOG_ERROR , " first_mb_in_slice overflow \n " ) ;
2005-06-28 02:13:10 +03:00
return - 1 ;
}
2012-03-16 20:40:05 +03:00
s - > resync_mb_x = s - > mb_x = first_mb_in_slice % s - > mb_width ;
2007-10-06 08:59:14 +03:00
s - > resync_mb_y = s - > mb_y = ( first_mb_in_slice / s - > mb_width ) < < FIELD_OR_MBAFF_PICTURE ;
if ( s - > picture_structure = = PICT_BOTTOM_FIELD )
s - > resync_mb_y = s - > mb_y = s - > mb_y + 1 ;
2007-01-20 15:50:00 +02:00
assert ( s - > mb_y < s - > mb_height ) ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( s - > picture_structure = = PICT_FRAME ) {
h - > curr_pic_num = h - > frame_num ;
h - > max_pic_num = 1 < < h - > sps . log2_max_frame_num ;
} else {
h - > curr_pic_num = 2 * h - > frame_num + 1 ;
h - > max_pic_num = 1 < < ( h - > sps . log2_max_frame_num + 1 ) ;
2003-04-04 17:42:28 +03:00
}
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > nal_unit_type = = NAL_IDR_SLICE )
2003-09-10 01:50:44 +03:00
get_ue_golomb ( & s - > gb ) ; /* idr_pic_id */
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > sps . poc_type = = 0 ) {
h - > poc_lsb = get_bits ( & s - > gb , h - > sps . log2_max_poc_lsb ) ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > pps . pic_order_present = = 1 & & s - > picture_structure = = PICT_FRAME )
h - > delta_poc_bottom = get_se_golomb ( & s - > gb ) ;
2003-04-04 17:42:28 +03:00
}
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > sps . poc_type = = 1 & & ! h - > sps . delta_pic_order_always_zero_flag ) {
h - > delta_poc [ 0 ] = get_se_golomb ( & s - > gb ) ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > pps . pic_order_present = = 1 & & s - > picture_structure = = PICT_FRAME )
h - > delta_poc [ 1 ] = get_se_golomb ( & s - > gb ) ;
2003-04-04 17:42:28 +03:00
}
2005-12-17 20:14:38 +02:00
2003-04-04 17:42:28 +03:00
init_poc ( h ) ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > pps . redundant_pic_cnt_present )
h - > redundant_pic_count = get_ue_golomb ( & s - > gb ) ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
// set defaults, might be overridden a few lines later
h - > ref_count [ 0 ] = h - > pps . ref_count [ 0 ] ;
h - > ref_count [ 1 ] = h - > pps . ref_count [ 1 ] ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > slice_type_nos ! = AV_PICTURE_TYPE_I ) {
2012-03-17 06:43:12 +03:00
unsigned max = s - > picture_structure = = PICT_FRAME ? 15 : 31 ;
2012-03-14 02:26:44 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > slice_type_nos = = AV_PICTURE_TYPE_B )
h - > direct_spatial_mv_pred = get_bits1 ( & s - > gb ) ;
num_ref_idx_active_override_flag = get_bits1 ( & s - > gb ) ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( num_ref_idx_active_override_flag ) {
h - > ref_count [ 0 ] = get_ue_golomb ( & s - > gb ) + 1 ;
if ( h - > slice_type_nos = = AV_PICTURE_TYPE_B )
h - > ref_count [ 1 ] = get_ue_golomb ( & s - > gb ) + 1 ;
2011-09-28 23:22:56 +03:00
}
2003-04-04 17:42:28 +03:00
2012-03-15 03:21:16 +03:00
if ( h - > ref_count [ 0 ] - 1 > max | | h - > ref_count [ 1 ] - 1 > max ) {
2011-09-28 23:22:56 +03:00
av_log ( h - > s . avctx , AV_LOG_ERROR , " reference overflow \n " ) ;
2012-03-14 02:26:44 +03:00
h - > ref_count [ 0 ] = h - > ref_count [ 1 ] = 1 ;
return AVERROR_INVALIDDATA ;
2003-04-04 17:42:28 +03:00
}
2012-03-14 02:26:44 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > slice_type_nos = = AV_PICTURE_TYPE_B )
h - > list_count = 2 ;
2007-02-16 23:34:21 +02:00
else
2012-03-16 20:40:05 +03:00
h - > list_count = 1 ;
} else
2011-10-02 01:45:41 +03:00
h - > ref_count [ 1 ] = h - > ref_count [ 0 ] = h - > list_count = 0 ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( ! default_ref_list_done )
2010-01-12 22:59:00 +02:00
ff_h264_fill_default_ref_list ( h ) ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > slice_type_nos ! = AV_PICTURE_TYPE_I & &
ff_h264_decode_ref_pic_list_reordering ( h ) < 0 ) {
h - > ref_count [ 1 ] = h - > ref_count [ 0 ] = 0 ;
2005-06-20 02:33:09 +03:00
return - 1 ;
2011-10-02 17:06:37 +03:00
}
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > slice_type_nos ! = AV_PICTURE_TYPE_I ) {
s - > last_picture_ptr = & h - > ref_list [ 0 ] [ 0 ] ;
2008-10-02 03:27:09 +03:00
ff_copy_picture ( & s - > last_picture , s - > last_picture_ptr ) ;
2008-09-25 17:29:35 +03:00
}
2012-03-16 20:40:05 +03:00
if ( h - > slice_type_nos = = AV_PICTURE_TYPE_B ) {
s - > next_picture_ptr = & h - > ref_list [ 1 ] [ 0 ] ;
2008-10-02 03:27:09 +03:00
ff_copy_picture ( & s - > next_picture , s - > next_picture_ptr ) ;
2008-09-25 17:29:35 +03:00
}
2012-03-16 20:40:05 +03:00
if ( ( h - > pps . weighted_pred & & h - > slice_type_nos = = AV_PICTURE_TYPE_P ) | |
( h - > pps . weighted_bipred_idc = = 1 & &
h - > slice_type_nos = = AV_PICTURE_TYPE_B ) )
2003-04-04 17:42:28 +03:00
pred_weight_table ( h ) ;
2012-03-16 20:40:05 +03:00
else if ( h - > pps . weighted_bipred_idc = = 2 & &
h - > slice_type_nos = = AV_PICTURE_TYPE_B ) {
2010-03-31 00:05:11 +03:00
implicit_weight_table ( h , - 1 ) ;
2012-03-16 20:40:05 +03:00
} else {
2005-01-07 07:56:07 +02:00
h - > use_weight = 0 ;
2009-02-03 22:49:02 +02:00
for ( i = 0 ; i < 2 ; i + + ) {
h - > luma_weight_flag [ i ] = 0 ;
h - > chroma_weight_flag [ i ] = 0 ;
}
}
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > nal_ref_idc & & ff_h264_decode_ref_pic_marking ( h0 , & s - > gb ) < 0 & &
( s - > avctx - > err_recognition & AV_EF_EXPLODE ) )
2011-08-05 00:47:16 +03:00
return AVERROR_INVALIDDATA ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( FRAME_MBAFF ) {
2010-01-12 22:59:00 +02:00
ff_h264_fill_mbaff_ref_list ( h ) ;
2006-05-29 01:44:14 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > pps . weighted_bipred_idc = = 2 & & h - > slice_type_nos = = AV_PICTURE_TYPE_B ) {
2010-03-31 00:05:11 +03:00
implicit_weight_table ( h , 0 ) ;
implicit_weight_table ( h , 1 ) ;
}
}
2012-03-16 20:40:05 +03:00
if ( h - > slice_type_nos = = AV_PICTURE_TYPE_B & & ! h - > direct_spatial_mv_pred )
2010-01-12 16:32:58 +02:00
ff_h264_direct_dist_scale_factor ( h ) ;
ff_h264_direct_ref_list_init ( h ) ;
2008-09-21 05:23:51 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > slice_type_nos ! = AV_PICTURE_TYPE_I & & h - > pps . cabac ) {
2008-12-23 23:12:19 +02:00
tmp = get_ue_golomb_31 ( & s - > gb ) ;
2012-03-16 20:40:05 +03:00
if ( tmp > 2 ) {
2007-01-20 15:50:00 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " cabac_init_idc overflow \n " ) ;
return - 1 ;
}
2012-03-16 20:40:05 +03:00
h - > cabac_init_idc = tmp ;
2007-01-20 15:50:00 +02:00
}
2004-03-26 21:35:53 +02:00
h - > last_qscale_diff = 0 ;
2007-01-20 15:50:00 +02:00
tmp = h - > pps . init_qp + get_se_golomb ( & s - > gb ) ;
2012-03-16 20:40:05 +03:00
if ( tmp > 51 + 6 * ( h - > sps . bit_depth_luma - 8 ) ) {
2007-01-20 15:50:00 +02:00
av_log ( s - > avctx , AV_LOG_ERROR , " QP %u out of range \n " , tmp ) ;
2004-03-20 02:18:52 +02:00
return - 1 ;
}
2012-03-16 20:40:05 +03:00
s - > qscale = tmp ;
2007-07-06 17:21:37 +03:00
h - > chroma_qp [ 0 ] = get_chroma_qp ( h , 0 , s - > qscale ) ;
h - > chroma_qp [ 1 ] = get_chroma_qp ( h , 1 , s - > qscale ) ;
2012-03-16 20:40:05 +03:00
// FIXME qscale / qp ... stuff
if ( h - > slice_type = = AV_PICTURE_TYPE_SP )
2003-09-10 01:50:44 +03:00
get_bits1 ( & s - > gb ) ; /* sp_for_switch_flag */
2012-03-16 20:40:05 +03:00
if ( h - > slice_type = = AV_PICTURE_TYPE_SP | |
h - > slice_type = = AV_PICTURE_TYPE_SI )
2003-09-10 01:50:44 +03:00
get_se_golomb ( & s - > gb ) ; /* slice_qs_delta */
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
h - > deblocking_filter = 1 ;
2010-01-23 20:05:30 +02:00
h - > slice_alpha_c0_offset = 52 ;
2012-03-16 20:40:05 +03:00
h - > slice_beta_offset = 52 ;
if ( h - > pps . deblocking_filter_parameters_present ) {
tmp = get_ue_golomb_31 ( & s - > gb ) ;
if ( tmp > 2 ) {
av_log ( s - > avctx , AV_LOG_ERROR ,
" deblocking_filter_idc %u out of range \n " , tmp ) ;
2007-01-20 15:50:00 +02:00
return - 1 ;
}
2012-03-16 20:40:05 +03:00
h - > deblocking_filter = tmp ;
if ( h - > deblocking_filter < 2 )
h - > deblocking_filter ^ = 1 ; // 1<->0
2004-03-20 18:40:20 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > deblocking_filter ) {
2010-01-23 20:05:30 +02:00
h - > slice_alpha_c0_offset + = get_se_golomb ( & s - > gb ) < < 1 ;
h - > slice_beta_offset + = get_se_golomb ( & s - > gb ) < < 1 ;
2012-03-16 20:40:05 +03:00
if ( h - > slice_alpha_c0_offset > 104U | |
h - > slice_beta_offset > 104U ) {
av_log ( s - > avctx , AV_LOG_ERROR ,
" deblocking filter parameters %d %d out of range \n " ,
h - > slice_alpha_c0_offset , h - > slice_beta_offset ) ;
2010-01-23 20:05:30 +02:00
return - 1 ;
}
2003-04-04 17:42:28 +03:00
}
2004-03-19 23:21:17 +02:00
}
2007-09-05 19:18:15 +03:00
2012-03-16 20:40:05 +03:00
if ( s - > avctx - > skip_loop_filter > = AVDISCARD_ALL | |
( s - > avctx - > skip_loop_filter > = AVDISCARD_NONKEY & &
h - > slice_type_nos ! = AV_PICTURE_TYPE_I ) | |
( s - > avctx - > skip_loop_filter > = AVDISCARD_BIDIR & &
h - > slice_type_nos = = AV_PICTURE_TYPE_B ) | |
( s - > avctx - > skip_loop_filter > = AVDISCARD_NONREF & &
h - > nal_ref_idc = = 0 ) )
h - > deblocking_filter = 0 ;
2007-09-22 13:28:22 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > deblocking_filter = = 1 & & h0 - > max_contexts > 1 ) {
if ( s - > avctx - > flags2 & CODEC_FLAG2_FAST ) {
2007-09-07 21:27:13 +03:00
/* Cheat slightly for speed:
2012-03-16 20:40:05 +03:00
* Do not bother to deblock across slices . */
2007-09-07 21:27:13 +03:00
h - > deblocking_filter = 2 ;
} else {
2007-09-07 22:19:49 +03:00
h0 - > max_contexts = 1 ;
2012-03-16 20:40:05 +03:00
if ( ! h0 - > single_decode_warning ) {
av_log ( s - > avctx , AV_LOG_INFO ,
" Cannot parallelize deblocking type 1, decoding such frames in sequential order \n " ) ;
2007-09-07 22:19:49 +03:00
h0 - > single_decode_warning = 1 ;
}
2011-04-02 18:57:53 +03:00
if ( h ! = h0 ) {
2012-03-16 20:40:05 +03:00
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" Deblocking switched inside frame. \n " ) ;
2011-04-02 18:57:53 +03:00
return 1 ;
}
2007-09-07 21:27:13 +03:00
}
2007-09-05 19:18:15 +03:00
}
2012-03-16 20:40:05 +03:00
h - > qp_thresh = 15 + 52 -
FFMIN ( h - > slice_alpha_c0_offset , h - > slice_beta_offset ) -
FFMAX3 ( 0 ,
h - > pps . chroma_qp_index_offset [ 0 ] ,
h - > pps . chroma_qp_index_offset [ 1 ] ) +
6 * ( h - > sps . bit_depth_luma - 8 ) ;
2003-04-04 17:42:28 +03:00
2007-09-05 19:18:15 +03:00
h0 - > last_slice_type = slice_type ;
h - > slice_num = + + h0 - > current_slice ;
2011-09-12 07:06:43 +03:00
2012-03-17 06:43:12 +03:00
if ( h - > slice_num )
2011-09-12 07:06:43 +03:00
h0 - > slice_row [ ( h - > slice_num - 1 ) & ( MAX_SLICES - 1 ) ] = s - > resync_mb_y ;
if ( h0 - > slice_row [ h - > slice_num & ( MAX_SLICES - 1 ) ] + 3 > = s - > resync_mb_y
& & h0 - > slice_row [ h - > slice_num & ( MAX_SLICES - 1 ) ] < = s - > resync_mb_y
& & h - > slice_num > = MAX_SLICES ) {
//in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case
2011-07-28 12:30:44 +03:00
av_log ( s - > avctx , AV_LOG_WARNING , " Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts \n " , h - > slice_num , MAX_SLICES ) ;
2008-10-29 00:50:16 +02:00
}
2004-12-18 05:49:07 +02:00
2012-03-16 20:40:05 +03:00
for ( j = 0 ; j < 2 ; j + + ) {
2010-01-18 07:15:31 +02:00
int id_list [ 16 ] ;
2012-03-16 20:40:05 +03:00
int * ref2frm = h - > ref2frm [ h - > slice_num & ( MAX_SLICES - 1 ) ] [ j ] ;
for ( i = 0 ; i < 16 ; i + + ) {
id_list [ i ] = 60 ;
2011-07-06 21:08:30 +03:00
if ( h - > ref_list [ j ] [ i ] . f . data [ 0 ] ) {
2010-01-18 07:15:31 +02:00
int k ;
2011-07-06 21:08:30 +03:00
uint8_t * base = h - > ref_list [ j ] [ i ] . f . base [ 0 ] ;
2012-03-16 20:40:05 +03:00
for ( k = 0 ; k < h - > short_ref_count ; k + + )
2011-07-06 21:08:30 +03:00
if ( h - > short_ref [ k ] - > f . base [ 0 ] = = base ) {
2012-03-16 20:40:05 +03:00
id_list [ i ] = k ;
2010-01-18 07:15:31 +02:00
break ;
}
2012-03-16 20:40:05 +03:00
for ( k = 0 ; k < h - > long_ref_count ; k + + )
2011-07-06 21:08:30 +03:00
if ( h - > long_ref [ k ] & & h - > long_ref [ k ] - > f . base [ 0 ] = = base ) {
2012-03-16 20:40:05 +03:00
id_list [ i ] = h - > short_ref_count + k ;
2010-01-18 07:15:31 +02:00
break ;
}
}
}
2012-03-16 20:40:05 +03:00
ref2frm [ 0 ] =
ref2frm [ 1 ] = - 1 ;
for ( i = 0 ; i < 16 ; i + + )
ref2frm [ i + 2 ] = 4 * id_list [ i ] +
( h - > ref_list [ j ] [ i ] . f . reference & 3 ) ;
ref2frm [ 18 + 0 ] =
ref2frm [ 18 + 1 ] = - 1 ;
for ( i = 16 ; i < 48 ; i + + )
ref2frm [ i + 4 ] = 4 * id_list [ ( i - 16 ) > > 1 ] +
( h - > ref_list [ j ] [ i ] . f . reference & 3 ) ;
}
// FIXME: fix draw_edges + PAFF + frame threads
h - > emu_edge_width = ( s - > flags & CODEC_FLAG_EMU_EDGE | |
( ! h - > sps . frame_mbs_only_flag & &
s - > avctx - > active_thread_type ) )
? 0 : 16 ;
h - > emu_edge_height = ( FRAME_MBAFF | | FIELD_PICTURE ) ? 0 : h - > emu_edge_width ;
if ( s - > avctx - > debug & FF_DEBUG_PICT_INFO ) {
av_log ( h - > s . avctx , AV_LOG_DEBUG ,
" slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s \n " ,
2005-03-07 01:02:25 +02:00
h - > slice_num ,
2012-03-16 20:40:05 +03:00
( s - > picture_structure = = PICT_FRAME ? " F " : s - > picture_structure = = PICT_TOP_FIELD ? " T " : " B " ) ,
2005-12-17 20:14:38 +02:00
first_mb_in_slice ,
2012-03-16 20:40:05 +03:00
av_get_picture_type_char ( h - > slice_type ) ,
h - > slice_type_fixed ? " fix " : " " ,
h - > nal_unit_type = = NAL_IDR_SLICE ? " IDR " : " " ,
2003-04-04 17:42:28 +03:00
pps_id , h - > frame_num ,
2012-03-16 20:40:05 +03:00
s - > current_picture_ptr - > field_poc [ 0 ] ,
s - > current_picture_ptr - > field_poc [ 1 ] ,
2003-04-04 17:42:28 +03:00
h - > ref_count [ 0 ] , h - > ref_count [ 1 ] ,
s - > qscale ,
2012-03-16 20:40:05 +03:00
h - > deblocking_filter ,
h - > slice_alpha_c0_offset / 2 - 26 , h - > slice_beta_offset / 2 - 26 ,
2005-01-07 07:56:07 +02:00
h - > use_weight ,
2012-03-16 20:40:05 +03:00
h - > use_weight = = 1 & & h - > use_weight_chroma ? " c " : " " ,
h - > slice_type = = AV_PICTURE_TYPE_B ? ( h - > direct_spatial_mv_pred ? " SPAT " : " TEMP " ) : " " ) ;
2003-04-04 17:42:28 +03:00
}
return 0 ;
}
2010-01-24 18:37:12 +02:00
int ff_h264_get_slice_type ( const H264Context * h )
2010-01-09 18:20:41 +02:00
{
switch ( h - > slice_type ) {
2012-03-16 20:40:05 +03:00
case AV_PICTURE_TYPE_P :
return 0 ;
case AV_PICTURE_TYPE_B :
return 1 ;
case AV_PICTURE_TYPE_I :
return 2 ;
case AV_PICTURE_TYPE_SP :
return 3 ;
case AV_PICTURE_TYPE_SI :
return 4 ;
default :
return - 1 ;
2010-01-09 18:20:41 +02:00
}
}
2012-03-16 20:40:05 +03:00
static av_always_inline void fill_filter_caches_inter ( H264Context * h ,
MpegEncContext * const s ,
int mb_type , int top_xy ,
int left_xy [ LEFT_MBS ] ,
int top_type ,
int left_type [ LEFT_MBS ] ,
int mb_xy , int list )
2011-06-28 03:41:28 +03:00
{
int b_stride = h - > b_stride ;
2012-03-16 20:40:05 +03:00
int16_t ( * mv_dst ) [ 2 ] = & h - > mv_cache [ list ] [ scan8 [ 0 ] ] ;
2011-06-28 03:41:28 +03:00
int8_t * ref_cache = & h - > ref_cache [ list ] [ scan8 [ 0 ] ] ;
2012-03-16 20:40:05 +03:00
if ( IS_INTER ( mb_type ) | | IS_DIRECT ( mb_type ) ) {
if ( USES_LIST ( top_type , list ) ) {
const int b_xy = h - > mb2b_xy [ top_xy ] + 3 * b_stride ;
const int b8_xy = 4 * top_xy + 2 ;
2012-04-02 23:05:42 +03:00
int ( * ref2frm ) [ 64 ] = ( void * ) ( h - > ref2frm [ h - > slice_table [ top_xy ] & ( MAX_SLICES - 1 ) ] [ 0 ] + ( MB_MBAFF ? 20 : 2 ) ) ;
2012-03-16 20:40:05 +03:00
AV_COPY128 ( mv_dst - 1 * 8 , s - > current_picture . f . motion_val [ list ] [ b_xy + 0 ] ) ;
ref_cache [ 0 - 1 * 8 ] =
ref_cache [ 1 - 1 * 8 ] = ref2frm [ list ] [ s - > current_picture . f . ref_index [ list ] [ b8_xy + 0 ] ] ;
ref_cache [ 2 - 1 * 8 ] =
ref_cache [ 3 - 1 * 8 ] = ref2frm [ list ] [ s - > current_picture . f . ref_index [ list ] [ b8_xy + 1 ] ] ;
} else {
AV_ZERO128 ( mv_dst - 1 * 8 ) ;
AV_WN32A ( & ref_cache [ 0 - 1 * 8 ] , ( ( LIST_NOT_USED ) & 0xFF ) * 0x01010101u ) ;
2011-06-28 03:41:28 +03:00
}
2012-03-16 20:40:05 +03:00
if ( ! IS_INTERLACED ( mb_type ^ left_type [ LTOP ] ) ) {
if ( USES_LIST ( left_type [ LTOP ] , list ) ) {
const int b_xy = h - > mb2b_xy [ left_xy [ LTOP ] ] + 3 ;
const int b8_xy = 4 * left_xy [ LTOP ] + 1 ;
2012-04-02 23:05:42 +03:00
int ( * ref2frm ) [ 64 ] = ( void * ) ( h - > ref2frm [ h - > slice_table [ left_xy [ LTOP ] ] & ( MAX_SLICES - 1 ) ] [ 0 ] + ( MB_MBAFF ? 20 : 2 ) ) ;
2012-03-16 20:40:05 +03:00
AV_COPY32 ( mv_dst - 1 + 0 , s - > current_picture . f . motion_val [ list ] [ b_xy + b_stride * 0 ] ) ;
AV_COPY32 ( mv_dst - 1 + 8 , s - > current_picture . f . motion_val [ list ] [ b_xy + b_stride * 1 ] ) ;
AV_COPY32 ( mv_dst - 1 + 16 , s - > current_picture . f . motion_val [ list ] [ b_xy + b_stride * 2 ] ) ;
AV_COPY32 ( mv_dst - 1 + 24 , s - > current_picture . f . motion_val [ list ] [ b_xy + b_stride * 3 ] ) ;
ref_cache [ - 1 + 0 ] =
ref_cache [ - 1 + 8 ] = ref2frm [ list ] [ s - > current_picture . f . ref_index [ list ] [ b8_xy + 2 * 0 ] ] ;
ref_cache [ - 1 + 16 ] =
ref_cache [ - 1 + 24 ] = ref2frm [ list ] [ s - > current_picture . f . ref_index [ list ] [ b8_xy + 2 * 1 ] ] ;
} else {
AV_ZERO32 ( mv_dst - 1 + 0 ) ;
AV_ZERO32 ( mv_dst - 1 + 8 ) ;
AV_ZERO32 ( mv_dst - 1 + 16 ) ;
AV_ZERO32 ( mv_dst - 1 + 24 ) ;
ref_cache [ - 1 + 0 ] =
ref_cache [ - 1 + 8 ] =
ref_cache [ - 1 + 16 ] =
ref_cache [ - 1 + 24 ] = LIST_NOT_USED ;
2011-06-28 03:41:28 +03:00
}
}
}
2012-03-16 20:40:05 +03:00
if ( ! USES_LIST ( mb_type , list ) ) {
fill_rectangle ( mv_dst , 4 , 4 , 8 , pack16to32 ( 0 , 0 ) , 4 ) ;
AV_WN32A ( & ref_cache [ 0 * 8 ] , ( ( LIST_NOT_USED ) & 0xFF ) * 0x01010101u ) ;
AV_WN32A ( & ref_cache [ 1 * 8 ] , ( ( LIST_NOT_USED ) & 0xFF ) * 0x01010101u ) ;
AV_WN32A ( & ref_cache [ 2 * 8 ] , ( ( LIST_NOT_USED ) & 0xFF ) * 0x01010101u ) ;
AV_WN32A ( & ref_cache [ 3 * 8 ] , ( ( LIST_NOT_USED ) & 0xFF ) * 0x01010101u ) ;
2011-06-28 03:41:28 +03:00
return ;
}
{
2012-03-16 20:40:05 +03:00
int8_t * ref = & s - > current_picture . f . ref_index [ list ] [ 4 * mb_xy ] ;
2012-04-02 23:05:42 +03:00
int ( * ref2frm ) [ 64 ] = ( void * ) ( h - > ref2frm [ h - > slice_num & ( MAX_SLICES - 1 ) ] [ 0 ] + ( MB_MBAFF ? 20 : 2 ) ) ;
2012-03-16 20:40:05 +03:00
uint32_t ref01 = ( pack16to32 ( ref2frm [ list ] [ ref [ 0 ] ] , ref2frm [ list ] [ ref [ 1 ] ] ) & 0x00FF00FF ) * 0x0101 ;
uint32_t ref23 = ( pack16to32 ( ref2frm [ list ] [ ref [ 2 ] ] , ref2frm [ list ] [ ref [ 3 ] ] ) & 0x00FF00FF ) * 0x0101 ;
AV_WN32A ( & ref_cache [ 0 * 8 ] , ref01 ) ;
AV_WN32A ( & ref_cache [ 1 * 8 ] , ref01 ) ;
AV_WN32A ( & ref_cache [ 2 * 8 ] , ref23 ) ;
AV_WN32A ( & ref_cache [ 3 * 8 ] , ref23 ) ;
2011-06-28 03:41:28 +03:00
}
{
2012-03-16 20:40:05 +03:00
int16_t ( * mv_src ) [ 2 ] = & s - > current_picture . f . motion_val [ list ] [ 4 * s - > mb_x + 4 * s - > mb_y * b_stride ] ;
AV_COPY128 ( mv_dst + 8 * 0 , mv_src + 0 * b_stride ) ;
AV_COPY128 ( mv_dst + 8 * 1 , mv_src + 1 * b_stride ) ;
AV_COPY128 ( mv_dst + 8 * 2 , mv_src + 2 * b_stride ) ;
AV_COPY128 ( mv_dst + 8 * 3 , mv_src + 3 * b_stride ) ;
2011-06-28 03:41:28 +03:00
}
}
2010-04-14 01:15:49 +03:00
/**
*
2011-10-05 15:12:42 +03:00
* @ return non zero if the loop filter can be skipped
2010-04-14 01:15:49 +03:00
*/
2012-03-16 20:40:05 +03:00
static int fill_filter_caches ( H264Context * h , int mb_type )
{
MpegEncContext * const s = & h - > s ;
const int mb_xy = h - > mb_xy ;
2011-06-30 01:38:39 +03:00
int top_xy , left_xy [ LEFT_MBS ] ;
int top_type , left_type [ LEFT_MBS ] ;
2011-06-28 03:41:28 +03:00
uint8_t * nnz ;
uint8_t * nnz_cache ;
2010-04-14 01:15:49 +03:00
2012-03-16 20:40:05 +03:00
top_xy = mb_xy - ( s - > mb_stride < < MB_FIELD ) ;
2010-04-14 01:15:49 +03:00
/* Wow, what a mess, why didn't they simplify the interlacing & intra
* stuff , I can ' t imagine that these complex rules are worth it . */
2012-03-16 20:40:05 +03:00
left_xy [ LBOT ] = left_xy [ LTOP ] = mb_xy - 1 ;
if ( FRAME_MBAFF ) {
const int left_mb_field_flag = IS_INTERLACED ( s - > current_picture . f . mb_type [ mb_xy - 1 ] ) ;
const int curr_mb_field_flag = IS_INTERLACED ( mb_type ) ;
if ( s - > mb_y & 1 ) {
if ( left_mb_field_flag ! = curr_mb_field_flag )
2011-06-30 01:38:39 +03:00
left_xy [ LTOP ] - = s - > mb_stride ;
2012-03-16 20:40:05 +03:00
} else {
if ( curr_mb_field_flag )
top_xy + = s - > mb_stride &
( ( ( s - > current_picture . f . mb_type [ top_xy ] > > 7 ) & 1 ) - 1 ) ;
if ( left_mb_field_flag ! = curr_mb_field_flag )
2011-06-30 01:38:39 +03:00
left_xy [ LBOT ] + = s - > mb_stride ;
2010-04-14 01:15:49 +03:00
}
}
2012-03-16 20:40:05 +03:00
h - > top_mb_xy = top_xy ;
2011-06-30 01:38:39 +03:00
h - > left_mb_xy [ LTOP ] = left_xy [ LTOP ] ;
h - > left_mb_xy [ LBOT ] = left_xy [ LBOT ] ;
2010-04-14 01:15:49 +03:00
{
2012-03-16 20:40:05 +03:00
/* For sufficiently low qp, filtering wouldn't do anything.
* This is a conservative estimate : could also check beta_offset
* and more accurate chroma_qp . */
int qp_thresh = h - > qp_thresh ; // FIXME strictly we should store qp_thresh for each mb of a slice
int qp = s - > current_picture . f . qscale_table [ mb_xy ] ;
if ( qp < = qp_thresh & &
( left_xy [ LTOP ] < 0 | |
( ( qp + s - > current_picture . f . qscale_table [ left_xy [ LTOP ] ] + 1 ) > > 1 ) < = qp_thresh ) & &
( top_xy < 0 | |
( ( qp + s - > current_picture . f . qscale_table [ top_xy ] + 1 ) > > 1 ) < = qp_thresh ) ) {
if ( ! FRAME_MBAFF )
2010-04-14 01:15:49 +03:00
return 1 ;
2012-03-16 20:40:05 +03:00
if ( ( left_xy [ LTOP ] < 0 | |
( ( qp + s - > current_picture . f . qscale_table [ left_xy [ LBOT ] ] + 1 ) > > 1 ) < = qp_thresh ) & &
( top_xy < s - > mb_stride | |
( ( qp + s - > current_picture . f . qscale_table [ top_xy - s - > mb_stride ] + 1 ) > > 1 ) < = qp_thresh ) )
2010-04-14 01:15:49 +03:00
return 1 ;
}
}
2011-07-06 21:08:30 +03:00
top_type = s - > current_picture . f . mb_type [ top_xy ] ;
left_type [ LTOP ] = s - > current_picture . f . mb_type [ left_xy [ LTOP ] ] ;
left_type [ LBOT ] = s - > current_picture . f . mb_type [ left_xy [ LBOT ] ] ;
2012-03-16 20:40:05 +03:00
if ( h - > deblocking_filter = = 2 ) {
if ( h - > slice_table [ top_xy ] ! = h - > slice_num )
top_type = 0 ;
if ( h - > slice_table [ left_xy [ LBOT ] ] ! = h - > slice_num )
left_type [ LTOP ] = left_type [ LBOT ] = 0 ;
} else {
if ( h - > slice_table [ top_xy ] = = 0xFFFF )
top_type = 0 ;
if ( h - > slice_table [ left_xy [ LBOT ] ] = = 0xFFFF )
left_type [ LTOP ] = left_type [ LBOT ] = 0 ;
2010-04-14 01:15:49 +03:00
}
2012-03-16 20:40:05 +03:00
h - > top_type = top_type ;
h - > left_type [ LTOP ] = left_type [ LTOP ] ;
h - > left_type [ LBOT ] = left_type [ LBOT ] ;
2010-04-14 01:15:49 +03:00
2012-03-16 20:40:05 +03:00
if ( IS_INTRA ( mb_type ) )
2010-04-14 01:15:49 +03:00
return 0 ;
2012-03-16 20:40:05 +03:00
fill_filter_caches_inter ( h , s , mb_type , top_xy , left_xy ,
top_type , left_type , mb_xy , 0 ) ;
if ( h - > list_count = = 2 )
fill_filter_caches_inter ( h , s , mb_type , top_xy , left_xy ,
top_type , left_type , mb_xy , 1 ) ;
2010-04-14 01:15:49 +03:00
2012-03-16 20:40:05 +03:00
nnz = h - > non_zero_count [ mb_xy ] ;
2011-06-28 03:41:28 +03:00
nnz_cache = h - > non_zero_count_cache ;
2012-03-16 20:40:05 +03:00
AV_COPY32 ( & nnz_cache [ 4 + 8 * 1 ] , & nnz [ 0 ] ) ;
AV_COPY32 ( & nnz_cache [ 4 + 8 * 2 ] , & nnz [ 4 ] ) ;
AV_COPY32 ( & nnz_cache [ 4 + 8 * 3 ] , & nnz [ 8 ] ) ;
AV_COPY32 ( & nnz_cache [ 4 + 8 * 4 ] , & nnz [ 12 ] ) ;
h - > cbp = h - > cbp_table [ mb_xy ] ;
2010-04-14 01:15:49 +03:00
2012-03-16 20:40:05 +03:00
if ( top_type ) {
2011-06-28 03:41:28 +03:00
nnz = h - > non_zero_count [ top_xy ] ;
2012-03-16 20:40:05 +03:00
AV_COPY32 ( & nnz_cache [ 4 + 8 * 0 ] , & nnz [ 3 * 4 ] ) ;
2010-04-14 01:15:49 +03:00
}
2012-03-16 20:40:05 +03:00
if ( left_type [ LTOP ] ) {
2011-06-30 01:38:39 +03:00
nnz = h - > non_zero_count [ left_xy [ LTOP ] ] ;
2012-03-16 20:40:05 +03:00
nnz_cache [ 3 + 8 * 1 ] = nnz [ 3 + 0 * 4 ] ;
nnz_cache [ 3 + 8 * 2 ] = nnz [ 3 + 1 * 4 ] ;
nnz_cache [ 3 + 8 * 3 ] = nnz [ 3 + 2 * 4 ] ;
nnz_cache [ 3 + 8 * 4 ] = nnz [ 3 + 3 * 4 ] ;
}
/* CAVLC 8x8dct requires NNZ values for residual decoding that differ
* from what the loop filter needs */
if ( ! CABAC & & h - > pps . transform_8x8_mode ) {
if ( IS_8x8DCT ( top_type ) ) {
nnz_cache [ 4 + 8 * 0 ] =
nnz_cache [ 5 + 8 * 0 ] = ( h - > cbp_table [ top_xy ] & 0x4000 ) > > 12 ;
nnz_cache [ 6 + 8 * 0 ] =
nnz_cache [ 7 + 8 * 0 ] = ( h - > cbp_table [ top_xy ] & 0x8000 ) > > 12 ;
2010-04-14 01:15:49 +03:00
}
2012-03-16 20:40:05 +03:00
if ( IS_8x8DCT ( left_type [ LTOP ] ) ) {
nnz_cache [ 3 + 8 * 1 ] =
nnz_cache [ 3 + 8 * 2 ] = ( h - > cbp_table [ left_xy [ LTOP ] ] & 0x2000 ) > > 12 ; // FIXME check MBAFF
2010-04-14 01:15:49 +03:00
}
2012-03-16 20:40:05 +03:00
if ( IS_8x8DCT ( left_type [ LBOT ] ) ) {
nnz_cache [ 3 + 8 * 3 ] =
nnz_cache [ 3 + 8 * 4 ] = ( h - > cbp_table [ left_xy [ LBOT ] ] & 0x8000 ) > > 12 ; // FIXME check MBAFF
2010-04-14 01:15:49 +03:00
}
2012-03-16 20:40:05 +03:00
if ( IS_8x8DCT ( mb_type ) ) {
nnz_cache [ scan8 [ 0 ] ] =
nnz_cache [ scan8 [ 1 ] ] =
nnz_cache [ scan8 [ 2 ] ] =
nnz_cache [ scan8 [ 3 ] ] = ( h - > cbp & 0x1000 ) > > 12 ;
nnz_cache [ scan8 [ 0 + 4 ] ] =
nnz_cache [ scan8 [ 1 + 4 ] ] =
nnz_cache [ scan8 [ 2 + 4 ] ] =
nnz_cache [ scan8 [ 3 + 4 ] ] = ( h - > cbp & 0x2000 ) > > 12 ;
nnz_cache [ scan8 [ 0 + 8 ] ] =
nnz_cache [ scan8 [ 1 + 8 ] ] =
nnz_cache [ scan8 [ 2 + 8 ] ] =
nnz_cache [ scan8 [ 3 + 8 ] ] = ( h - > cbp & 0x4000 ) > > 12 ;
nnz_cache [ scan8 [ 0 + 12 ] ] =
nnz_cache [ scan8 [ 1 + 12 ] ] =
nnz_cache [ scan8 [ 2 + 12 ] ] =
nnz_cache [ scan8 [ 3 + 12 ] ] = ( h - > cbp & 0x8000 ) > > 12 ;
2010-04-14 01:15:49 +03:00
}
}
return 0 ;
}
2012-03-16 20:40:05 +03:00
static void loop_filter ( H264Context * h , int start_x , int end_x )
{
MpegEncContext * const s = & h - > s ;
uint8_t * dest_y , * dest_cb , * dest_cr ;
2010-01-17 22:35:55 +02:00
int linesize , uvlinesize , mb_x , mb_y ;
2012-03-16 20:40:05 +03:00
const int end_mb_y = s - > mb_y + FRAME_MBAFF ;
const int old_slice_type = h - > slice_type ;
const int pixel_shift = h - > pixel_shift ;
const int block_h = 16 > > s - > chroma_y_shift ;
2010-01-17 22:35:55 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > deblocking_filter ) {
for ( mb_x = start_x ; mb_x < end_x ; mb_x + + )
for ( mb_y = end_mb_y - FRAME_MBAFF ; mb_y < = end_mb_y ; mb_y + + ) {
2010-02-13 23:09:38 +02:00
int mb_xy , mb_type ;
2012-03-16 20:40:05 +03:00
mb_xy = h - > mb_xy = mb_x + mb_y * s - > mb_stride ;
h - > slice_num = h - > slice_table [ mb_xy ] ;
mb_type = s - > current_picture . f . mb_type [ mb_xy ] ;
h - > list_count = h - > list_counts [ mb_xy ] ;
if ( FRAME_MBAFF )
h - > mb_mbaff =
h - > mb_field_decoding_flag = ! ! IS_INTERLACED ( mb_type ) ;
s - > mb_x = mb_x ;
s - > mb_y = mb_y ;
dest_y = s - > current_picture . f . data [ 0 ] +
( ( mb_x < < pixel_shift ) + mb_y * s - > linesize ) * 16 ;
dest_cb = s - > current_picture . f . data [ 1 ] +
( mb_x < < pixel_shift ) * ( 8 < < CHROMA444 ) +
mb_y * s - > uvlinesize * block_h ;
dest_cr = s - > current_picture . f . data [ 2 ] +
( mb_x < < pixel_shift ) * ( 8 < < CHROMA444 ) +
mb_y * s - > uvlinesize * block_h ;
// FIXME simplify above
2010-01-17 22:35:55 +02:00
if ( MB_FIELD ) {
2012-03-16 20:40:05 +03:00
linesize = h - > mb_linesize = s - > linesize * 2 ;
2010-01-17 22:35:55 +02:00
uvlinesize = h - > mb_uvlinesize = s - > uvlinesize * 2 ;
2012-03-16 20:40:05 +03:00
if ( mb_y & 1 ) { // FIXME move out of this function?
dest_y - = s - > linesize * 15 ;
dest_cb - = s - > uvlinesize * ( block_h - 1 ) ;
dest_cr - = s - > uvlinesize * ( block_h - 1 ) ;
2010-01-17 22:35:55 +02:00
}
} else {
linesize = h - > mb_linesize = s - > linesize ;
uvlinesize = h - > mb_uvlinesize = s - > uvlinesize ;
}
2012-03-16 20:40:05 +03:00
backup_mb_border ( h , dest_y , dest_cb , dest_cr , linesize ,
uvlinesize , 0 ) ;
if ( fill_filter_caches ( h , mb_type ) )
2010-01-18 02:20:44 +02:00
continue ;
2011-07-06 21:08:30 +03:00
h - > chroma_qp [ 0 ] = get_chroma_qp ( h , 0 , s - > current_picture . f . qscale_table [ mb_xy ] ) ;
h - > chroma_qp [ 1 ] = get_chroma_qp ( h , 1 , s - > current_picture . f . qscale_table [ mb_xy ] ) ;
2010-01-17 22:35:55 +02:00
2010-01-24 19:02:44 +02:00
if ( FRAME_MBAFF ) {
2012-03-16 20:40:05 +03:00
ff_h264_filter_mb ( h , mb_x , mb_y , dest_y , dest_cb , dest_cr ,
linesize , uvlinesize ) ;
2010-01-17 22:35:55 +02:00
} else {
2012-03-16 20:40:05 +03:00
ff_h264_filter_mb_fast ( h , mb_x , mb_y , dest_y , dest_cb ,
dest_cr , linesize , uvlinesize ) ;
2010-01-17 22:35:55 +02:00
}
}
}
2012-03-16 20:40:05 +03:00
h - > slice_type = old_slice_type ;
s - > mb_x = end_x ;
s - > mb_y = end_mb_y - FRAME_MBAFF ;
2010-02-15 01:06:25 +02:00
h - > chroma_qp [ 0 ] = get_chroma_qp ( h , 0 , s - > qscale ) ;
h - > chroma_qp [ 1 ] = get_chroma_qp ( h , 1 , s - > qscale ) ;
2010-01-17 22:35:55 +02:00
}
2012-03-16 20:40:05 +03:00
static void predict_field_decoding_flag ( H264Context * h )
{
MpegEncContext * const s = & h - > s ;
const int mb_xy = s - > mb_x + s - > mb_y * s - > mb_stride ;
int mb_type = ( h - > slice_table [ mb_xy - 1 ] = = h - > slice_num ) ?
s - > current_picture . f . mb_type [ mb_xy - 1 ] :
( h - > slice_table [ mb_xy - s - > mb_stride ] = = h - > slice_num ) ?
s - > current_picture . f . mb_type [ mb_xy - s - > mb_stride ] : 0 ;
h - > mb_mbaff = h - > mb_field_decoding_flag = IS_INTERLACED ( mb_type ) ? 1 : 0 ;
2010-02-17 04:25:05 +02:00
}
2011-03-22 23:36:57 +02:00
/**
* Draw edges and report progress for the last MB row .
*/
2012-03-16 20:40:05 +03:00
static void decode_finish_row ( H264Context * h )
{
MpegEncContext * const s = & h - > s ;
int top = 16 * ( s - > mb_y > > FIELD_PICTURE ) ;
int pic_height = 16 * s - > mb_height > > FIELD_PICTURE ;
int height = 16 < < FRAME_MBAFF ;
2011-03-22 23:36:57 +02:00
int deblock_border = ( 16 + 4 ) < < FRAME_MBAFF ;
if ( h - > deblocking_filter ) {
2012-03-16 20:40:05 +03:00
if ( ( top + height ) > = pic_height )
2011-03-22 23:36:57 +02:00
height + = deblock_border ;
top - = deblock_border ;
}
if ( top > = pic_height | | ( top + height ) < h - > emu_edge_height )
return ;
height = FFMIN ( height , pic_height - top ) ;
if ( top < h - > emu_edge_height ) {
2012-03-16 20:40:05 +03:00
height = top + height ;
top = 0 ;
2011-03-22 23:36:57 +02:00
}
ff_draw_horiz_band ( s , top , height ) ;
2012-03-16 20:40:05 +03:00
if ( s - > dropable )
return ;
2011-03-22 23:36:57 +02:00
2012-02-28 00:02:45 +03:00
ff_thread_report_progress ( & s - > current_picture_ptr - > f , top + height - 1 ,
s - > picture_structure = = PICT_BOTTOM_FIELD ) ;
2011-03-22 23:36:57 +02:00
}
2012-03-16 20:40:05 +03:00
static int decode_slice ( struct AVCodecContext * avctx , void * arg )
{
H264Context * h = * ( void * * ) arg ;
MpegEncContext * const s = & h - > s ;
const int part_mask = s - > partitioned_frame ? ( ER_AC_END | ER_AC_ERROR )
: 0x7F ;
2011-05-18 15:10:49 +03:00
int lf_x_start = s - > mb_x ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
s - > mb_skip_run = - 1 ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
h - > is_complex = FRAME_MBAFF | | s - > picture_structure ! = PICT_FRAME | |
s - > codec_id ! = CODEC_ID_H264 | |
( CONFIG_GRAY & & ( s - > flags & CODEC_FLAG_GRAY ) ) ;
2008-12-16 22:26:22 +02:00
2012-03-16 20:40:05 +03:00
if ( h - > pps . cabac ) {
2004-03-26 21:35:53 +02:00
/* realign */
2012-03-16 20:40:05 +03:00
align_get_bits ( & s - > gb ) ;
2004-03-26 21:35:53 +02:00
/* init cabac */
2012-03-16 20:40:05 +03:00
ff_init_cabac_states ( & h - > cabac ) ;
ff_init_cabac_decoder ( & h - > cabac ,
s - > gb . buffer + get_bits_count ( & s - > gb ) / 8 ,
( get_bits_left ( & s - > gb ) + 7 ) / 8 ) ;
2010-01-13 04:35:36 +02:00
ff_h264_init_cabac_states ( h ) ;
2003-04-05 13:08:48 +03:00
2012-03-16 20:40:05 +03:00
for ( ; ; ) {
// START_TIMER
2010-01-13 04:35:36 +02:00
int ret = ff_h264_decode_mb_cabac ( h ) ;
2005-03-07 01:02:25 +02:00
int eos ;
2012-03-16 20:40:05 +03:00
// STOP_TIMER("decode_mb_cabac")
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( ret > = 0 )
ff_h264_hl_decode_mb ( h ) ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
// FIXME optimal? or let mb_decode decode 16x32 ?
if ( ret > = 0 & & FRAME_MBAFF ) {
2004-03-26 21:35:53 +02:00
s - > mb_y + + ;
2010-01-13 04:35:36 +02:00
ret = ff_h264_decode_mb_cabac ( h ) ;
2004-03-26 21:35:53 +02:00
2012-03-16 20:40:05 +03:00
if ( ret > = 0 )
ff_h264_hl_decode_mb ( h ) ;
2004-03-26 21:35:53 +02:00
s - > mb_y - - ;
}
2012-03-16 20:40:05 +03:00
eos = get_cabac_terminate ( & h - > cabac ) ;
if ( ( s - > workaround_bugs & FF_BUG_TRUNCATED ) & &
h - > cabac . bytestream > h - > cabac . bytestream_end + 2 ) {
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x - 1 ,
s - > mb_y , ER_MB_END & part_mask ) ;
if ( s - > mb_x > = lf_x_start )
loop_filter ( h , lf_x_start , s - > mb_x + 1 ) ;
2010-02-12 21:25:23 +02:00
return 0 ;
}
2012-03-16 20:40:05 +03:00
if ( ret < 0 | | h - > cabac . bytestream > h - > cabac . bytestream_end + 2 ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" error while decoding MB %d %d, bytestream (%td) \n " ,
s - > mb_x , s - > mb_y ,
h - > cabac . bytestream_end - h - > cabac . bytestream ) ;
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x ,
s - > mb_y , ER_MB_ERROR & part_mask ) ;
2004-03-26 21:35:53 +02:00
return - 1 ;
}
2012-03-16 20:40:05 +03:00
if ( + + s - > mb_x > = s - > mb_width ) {
2011-05-18 15:10:49 +03:00
loop_filter ( h , lf_x_start , s - > mb_x ) ;
s - > mb_x = lf_x_start = 0 ;
2011-03-22 23:36:57 +02:00
decode_finish_row ( h ) ;
2004-12-18 05:49:07 +02:00
+ + s - > mb_y ;
2012-03-16 20:40:05 +03:00
if ( FIELD_OR_MBAFF_PICTURE ) {
2005-03-07 01:02:25 +02:00
+ + s - > mb_y ;
2012-03-16 20:40:05 +03:00
if ( FRAME_MBAFF & & s - > mb_y < s - > mb_height )
2010-02-17 04:14:02 +02:00
predict_field_decoding_flag ( h ) ;
2005-03-07 01:02:25 +02:00
}
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
if ( eos | | s - > mb_y > = s - > mb_height ) {
tprintf ( s - > avctx , " slice end %d %d \n " ,
get_bits_count ( & s - > gb ) , s - > gb . size_in_bits ) ;
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x - 1 ,
s - > mb_y , ER_MB_END & part_mask ) ;
if ( s - > mb_x > lf_x_start )
loop_filter ( h , lf_x_start , s - > mb_x ) ;
2003-04-04 17:42:28 +03:00
return 0 ;
2004-03-26 21:35:53 +02:00
}
}
} else {
2012-03-16 20:40:05 +03:00
for ( ; ; ) {
2010-01-13 03:59:19 +02:00
int ret = ff_h264_decode_mb_cavlc ( h ) ;
2004-03-26 21:35:53 +02:00
2012-03-16 20:40:05 +03:00
if ( ret > = 0 )
ff_h264_hl_decode_mb ( h ) ;
2004-03-26 21:35:53 +02:00
2012-03-16 20:40:05 +03:00
// FIXME optimal? or let mb_decode decode 16x32 ?
if ( ret > = 0 & & FRAME_MBAFF ) {
2004-03-26 21:35:53 +02:00
s - > mb_y + + ;
2010-01-13 03:59:19 +02:00
ret = ff_h264_decode_mb_cavlc ( h ) ;
2004-03-26 21:35:53 +02:00
2012-03-16 20:40:05 +03:00
if ( ret > = 0 )
ff_h264_hl_decode_mb ( h ) ;
2004-03-26 21:35:53 +02:00
s - > mb_y - - ;
}
2012-03-16 20:40:05 +03:00
if ( ret < 0 ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" error while decoding MB %d %d \n " , s - > mb_x , s - > mb_y ) ;
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x ,
s - > mb_y , ER_MB_ERROR & part_mask ) ;
2003-04-04 17:42:28 +03:00
return - 1 ;
}
2004-03-26 21:35:53 +02:00
2012-03-16 20:40:05 +03:00
if ( + + s - > mb_x > = s - > mb_width ) {
2011-05-18 15:10:49 +03:00
loop_filter ( h , lf_x_start , s - > mb_x ) ;
s - > mb_x = lf_x_start = 0 ;
2011-03-22 23:36:57 +02:00
decode_finish_row ( h ) ;
2005-03-07 01:02:25 +02:00
+ + s - > mb_y ;
2012-03-16 20:40:05 +03:00
if ( FIELD_OR_MBAFF_PICTURE ) {
2005-03-07 01:02:25 +02:00
+ + s - > mb_y ;
2012-03-16 20:40:05 +03:00
if ( FRAME_MBAFF & & s - > mb_y < s - > mb_height )
2010-02-17 04:14:02 +02:00
predict_field_decoding_flag ( h ) ;
2005-03-07 01:02:25 +02:00
}
2012-03-16 20:40:05 +03:00
if ( s - > mb_y > = s - > mb_height ) {
tprintf ( s - > avctx , " slice end %d %d \n " ,
get_bits_count ( & s - > gb ) , s - > gb . size_in_bits ) ;
2004-03-26 21:35:53 +02:00
2012-03-06 05:56:25 +03:00
if ( get_bits_left ( & s - > gb ) = = 0
| | get_bits_left ( & s - > gb ) > 0 & & ! ( s - > avctx - > err_recognition & AV_EF_AGGRESSIVE ) ) {
2012-03-16 20:40:05 +03:00
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y ,
s - > mb_x - 1 , s - > mb_y ,
ER_MB_END & part_mask ) ;
2004-03-26 21:35:53 +02:00
return 0 ;
2012-03-16 20:40:05 +03:00
} else {
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y ,
s - > mb_x , s - > mb_y ,
ER_MB_END & part_mask ) ;
2004-03-26 21:35:53 +02:00
return - 1 ;
}
}
}
2012-03-16 20:40:05 +03:00
if ( get_bits_left ( & s - > gb ) < = 0 & & s - > mb_skip_run < = 0 ) {
tprintf ( s - > avctx , " slice end %d %d \n " ,
get_bits_count ( & s - > gb ) , s - > gb . size_in_bits ) ;
2012-03-05 04:53:50 +03:00
if ( get_bits_left ( & s - > gb ) = = 0 ) {
2012-03-16 20:40:05 +03:00
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y ,
s - > mb_x - 1 , s - > mb_y ,
ER_MB_END & part_mask ) ;
if ( s - > mb_x > lf_x_start )
loop_filter ( h , lf_x_start , s - > mb_x ) ;
2004-03-26 21:35:53 +02:00
return 0 ;
2012-03-16 20:40:05 +03:00
} else {
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x ,
s - > mb_y , ER_MB_ERROR & part_mask ) ;
2004-03-26 21:35:53 +02:00
return - 1 ;
}
}
2003-04-04 17:42:28 +03:00
}
}
}
2007-09-05 19:18:15 +03:00
/**
* Call decode_slice ( ) for each context .
*
* @ param h h264 master context
* @ param context_count number of contexts to execute
*/
2012-03-16 20:40:05 +03:00
static int execute_decode_slices ( H264Context * h , int context_count )
{
MpegEncContext * const s = & h - > s ;
AVCodecContext * const avctx = s - > avctx ;
2007-09-05 19:18:15 +03:00
H264Context * hx ;
int i ;
2012-03-16 20:40:05 +03:00
if ( s - > avctx - > hwaccel | |
s - > avctx - > codec - > capabilities & CODEC_CAP_HWACCEL_VDPAU )
2011-08-05 00:47:16 +03:00
return 0 ;
2012-03-16 20:40:05 +03:00
if ( context_count = = 1 ) {
2011-08-05 00:47:16 +03:00
return decode_slice ( avctx , & h ) ;
2007-09-05 19:18:15 +03:00
} else {
2012-03-16 20:40:05 +03:00
for ( i = 1 ; i < context_count ; i + + ) {
hx = h - > thread_context [ i ] ;
2011-12-07 16:51:36 +03:00
hx - > s . err_recognition = avctx - > err_recognition ;
2012-03-16 20:40:05 +03:00
hx - > s . error_count = 0 ;
2012-03-17 06:43:12 +03:00
hx - > x264_build = h - > x264_build ;
2007-09-05 19:18:15 +03:00
}
2012-03-16 20:40:05 +03:00
avctx - > execute ( avctx , decode_slice , h - > thread_context ,
NULL , context_count , sizeof ( void * ) ) ;
2007-09-05 19:18:15 +03:00
/* pull back stuff from slices to master context */
2012-03-16 20:40:05 +03:00
hx = h - > thread_context [ context_count - 1 ] ;
s - > mb_x = hx - > s . mb_x ;
s - > mb_y = hx - > s . mb_y ;
s - > dropable = hx - > s . dropable ;
2007-10-08 20:44:38 +03:00
s - > picture_structure = hx - > s . picture_structure ;
2012-03-16 20:40:05 +03:00
for ( i = 1 ; i < context_count ; i + + )
2007-09-05 19:18:15 +03:00
h - > s . error_count + = h - > thread_context [ i ] - > s . error_count ;
}
2011-08-05 00:47:16 +03:00
return 0 ;
2007-09-05 19:18:15 +03:00
}
2012-03-16 20:40:05 +03:00
static int decode_nal_units ( H264Context * h , const uint8_t * buf , int buf_size )
{
MpegEncContext * const s = & h - > s ;
AVCodecContext * const avctx = s - > avctx ;
2007-09-05 19:18:15 +03:00
H264Context * hx ; ///< thread context
2011-05-21 04:11:50 +03:00
int buf_index ;
int context_count ;
int next_avc ;
int pass = ! ( avctx - > active_thread_type & FF_THREAD_FRAME ) ;
2012-03-16 20:40:05 +03:00
int nals_needed = 0 ; ///< number of NALs that need decoding before the next frame thread starts
2011-05-21 04:11:50 +03:00
int nal_index ;
2007-09-05 19:18:15 +03:00
2011-12-16 20:52:56 +03:00
h - > nal_unit_type = 0 ;
2012-01-03 04:25:56 +03:00
if ( ! s - > slice_context_count )
s - > slice_context_count = 1 ;
2012-01-01 22:24:24 +03:00
h - > max_contexts = s - > slice_context_count ;
2012-03-16 20:40:05 +03:00
if ( ! ( s - > flags2 & CODEC_FLAG2_CHUNKS ) ) {
2007-09-05 19:18:15 +03:00
h - > current_slice = 0 ;
2007-10-08 20:44:38 +03:00
if ( ! s - > first_field )
2012-03-16 20:40:05 +03:00
s - > current_picture_ptr = NULL ;
2010-01-12 20:54:40 +02:00
ff_h264_reset_sei ( h ) ;
2007-03-03 01:35:26 +02:00
}
2012-03-16 20:40:05 +03:00
for ( ; pass < = 1 ; pass + + ) {
buf_index = 0 ;
2011-05-21 04:11:50 +03:00
context_count = 0 ;
2012-03-16 20:40:05 +03:00
next_avc = h - > is_avc ? 0 : buf_size ;
nal_index = 0 ;
for ( ; ; ) {
int consumed ;
int dst_length ;
int bit_length ;
const uint8_t * ptr ;
int i , nalsize = 0 ;
int err ;
if ( buf_index > = next_avc ) {
if ( buf_index > = buf_size - h - > nal_length_size )
2007-06-18 11:48:26 +03:00
break ;
2012-03-16 20:40:05 +03:00
nalsize = 0 ;
for ( i = 0 ; i < h - > nal_length_size ; i + + )
nalsize = ( nalsize < < 8 ) | buf [ buf_index + + ] ;
if ( nalsize < = 0 | | nalsize > buf_size - buf_index ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
" AVC: nal size %d \n " , nalsize ) ;
break ;
}
next_avc = buf_index + nalsize ;
} else {
// start code prefix search
for ( ; buf_index + 3 < next_avc ; buf_index + + )
// This should always succeed in the first iteration.
if ( buf [ buf_index ] = = 0 & &
buf [ buf_index + 1 ] = = 0 & &
buf [ buf_index + 2 ] = = 1 )
break ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( buf_index + 3 > = buf_size )
break ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
buf_index + = 3 ;
if ( buf_index > = next_avc )
continue ;
}
2004-09-14 00:20:55 +03:00
2012-03-16 20:40:05 +03:00
hx = h - > thread_context [ context_count ] ;
2011-05-21 04:11:50 +03:00
2012-03-16 20:40:05 +03:00
ptr = ff_h264_decode_nal ( hx , buf + buf_index , & dst_length ,
& consumed , next_avc - buf_index ) ;
2012-03-17 01:24:08 +03:00
if ( ptr = = NULL | | dst_length < 0 ) {
buf_index = - 1 ;
goto end ;
}
2012-03-16 20:40:05 +03:00
i = buf_index + consumed ;
if ( ( s - > workaround_bugs & FF_BUG_AUTODETECT ) & & i + 3 < next_avc & &
buf [ i ] = = 0x00 & & buf [ i + 1 ] = = 0x00 & &
buf [ i + 2 ] = = 0x01 & & buf [ i + 3 ] = = 0xE0 )
s - > workaround_bugs | = FF_BUG_TRUNCATED ;
if ( ! ( s - > workaround_bugs & FF_BUG_TRUNCATED ) )
2012-03-17 06:43:12 +03:00
while ( dst_length > 0 & & ptr [ dst_length - 1 ] = = 0 )
2012-03-16 20:40:05 +03:00
dst_length - - ;
bit_length = ! dst_length ? 0
: ( 8 * dst_length -
2012-03-29 15:15:16 +03:00
decode_rbsp_trailing ( h , ptr + dst_length - 1 ) ) ;
2012-03-16 20:40:05 +03:00
if ( s - > avctx - > debug & FF_DEBUG_STARTCODE )
2012-03-17 06:43:12 +03:00
av_log ( h - > s . avctx , AV_LOG_DEBUG , " NAL %d/%d at %d/%d length %d pass %d \n " , hx - > nal_unit_type , hx - > nal_ref_idc , buf_index , buf_size , dst_length , pass ) ;
2012-03-16 20:40:05 +03:00
if ( h - > is_avc & & ( nalsize ! = consumed ) & & nalsize )
av_log ( h - > s . avctx , AV_LOG_DEBUG ,
" AVC: Consumed only %d bytes instead of %d \n " ,
consumed , nalsize ) ;
buf_index + = consumed ;
nal_index + + ;
if ( pass = = 0 ) {
/* packets can sometimes contain multiple PPS/SPS,
* e . g . two PAFF field pictures in one packet , or a demuxer
* which splits NALs strangely if so , when frame threading we
* can ' t start the next thread until we ' ve read all of them */
switch ( hx - > nal_unit_type ) {
2011-05-21 04:11:50 +03:00
case NAL_SPS :
case NAL_PPS :
2011-10-04 01:14:48 +03:00
nals_needed = nal_index ;
break ;
2011-06-20 17:24:33 +03:00
case NAL_IDR_SLICE :
case NAL_SLICE :
2011-10-04 01:14:48 +03:00
init_get_bits ( & hx - > s . gb , ptr , bit_length ) ;
2011-10-04 01:14:48 +03:00
if ( ! get_ue_golomb ( & hx - > s . gb ) )
2011-10-04 01:14:48 +03:00
nals_needed = nal_index ;
2012-03-16 20:40:05 +03:00
}
continue ;
2011-05-21 04:11:50 +03:00
}
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
// FIXME do not discard SEI id
if ( avctx - > skip_frame > = AVDISCARD_NONREF & & h - > nal_ref_idc = = 0 )
continue ;
2011-09-18 23:10:52 +03:00
2012-03-16 20:40:05 +03:00
again :
err = 0 ;
switch ( hx - > nal_unit_type ) {
case NAL_IDR_SLICE :
if ( h - > nal_unit_type ! = NAL_IDR_SLICE ) {
av_log ( h - > s . avctx , AV_LOG_ERROR ,
2012-03-17 06:43:12 +03:00
" Invalid mix of idr and non-idr slices \n " ) ;
2012-03-17 01:24:08 +03:00
buf_index = - 1 ;
goto end ;
2012-03-16 20:40:05 +03:00
}
idr ( h ) ; // FIXME ensure we don't lose some frames if there is reordering
case NAL_SLICE :
init_get_bits ( & hx - > s . gb , ptr , bit_length ) ;
hx - > intra_gb_ptr =
hx - > inter_gb_ptr = & hx - > s . gb ;
hx - > s . data_partitioning = 0 ;
if ( ( err = decode_slice_header ( hx , h ) ) )
break ;
2011-09-18 23:10:52 +03:00
2012-03-17 06:43:12 +03:00
if ( h - > sei_recovery_frame_cnt > = 0
& & ( h - > recovery_frame < 0
| | ( ( h - > recovery_frame - h - > frame_num ) & ( ( 1 < < h - > sps . log2_max_frame_num ) - 1 ) ) > h - > sei_recovery_frame_cnt ) ) {
h - > recovery_frame = ( h - > frame_num + h - > sei_recovery_frame_cnt ) %
( 1 < < h - > sps . log2_max_frame_num ) ;
}
2011-09-18 23:10:52 +03:00
2012-03-16 20:40:05 +03:00
s - > current_picture_ptr - > f . key_frame | =
2012-03-17 06:43:12 +03:00
( hx - > nal_unit_type = = NAL_IDR_SLICE ) ;
2011-03-22 23:36:57 +02:00
2012-03-17 06:43:12 +03:00
if ( h - > recovery_frame = = h - > frame_num ) {
s - > current_picture_ptr - > sync | = 1 ;
h - > recovery_frame = - 1 ;
2011-03-22 23:36:57 +02:00
}
2012-03-17 06:43:12 +03:00
h - > sync | = ! ! s - > current_picture_ptr - > f . key_frame ;
h - > sync | = 3 * ! ! ( s - > flags2 & CODEC_FLAG2_SHOW_ALL ) ;
s - > current_picture_ptr - > sync | = h - > sync ;
2011-06-02 20:15:58 +03:00
2012-03-16 20:40:05 +03:00
if ( h - > current_slice = = 1 ) {
if ( ! ( s - > flags2 & CODEC_FLAG2_CHUNKS ) )
decode_postinit ( h , nal_index > = nals_needed ) ;
2009-02-27 17:45:55 +02:00
2012-03-16 20:40:05 +03:00
if ( s - > avctx - > hwaccel & &
s - > avctx - > hwaccel - > start_frame ( s - > avctx , NULL , 0 ) < 0 )
2009-02-25 21:39:42 +02:00
return - 1 ;
2012-03-16 20:40:05 +03:00
if ( CONFIG_H264_VDPAU_DECODER & &
s - > avctx - > codec - > capabilities & CODEC_CAP_HWACCEL_VDPAU )
ff_vdpau_h264_picture_start ( s ) ;
}
2009-07-03 08:52:00 +03:00
2012-03-16 20:40:05 +03:00
if ( hx - > redundant_pic_count = = 0 & &
( avctx - > skip_frame < AVDISCARD_NONREF | |
hx - > nal_ref_idc ) & &
( avctx - > skip_frame < AVDISCARD_BIDIR | |
hx - > slice_type_nos ! = AV_PICTURE_TYPE_B ) & &
( avctx - > skip_frame < AVDISCARD_NONKEY | |
hx - > slice_type_nos = = AV_PICTURE_TYPE_I ) & &
avctx - > skip_frame < AVDISCARD_ALL ) {
if ( avctx - > hwaccel ) {
if ( avctx - > hwaccel - > decode_slice ( avctx ,
& buf [ buf_index - consumed ] ,
consumed ) < 0 )
return - 1 ;
} else if ( CONFIG_H264_VDPAU_DECODER & &
s - > avctx - > codec - > capabilities & CODEC_CAP_HWACCEL_VDPAU ) {
static const uint8_t start_code [ ] = {
0x00 , 0x00 , 0x01 } ;
ff_vdpau_add_data_chunk ( s , start_code ,
sizeof ( start_code ) ) ;
ff_vdpau_add_data_chunk ( s , & buf [ buf_index - consumed ] ,
consumed ) ;
} else
context_count + + ;
}
2009-07-03 08:52:00 +03:00
break ;
2012-03-16 20:40:05 +03:00
case NAL_DPA :
init_get_bits ( & hx - > s . gb , ptr , bit_length ) ;
hx - > intra_gb_ptr =
hx - > inter_gb_ptr = NULL ;
2009-07-03 08:52:00 +03:00
2012-03-16 20:40:05 +03:00
if ( ( err = decode_slice_header ( hx , h ) ) < 0 )
break ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
hx - > s . data_partitioning = 1 ;
break ;
case NAL_DPB :
init_get_bits ( & hx - > intra_gb , ptr , bit_length ) ;
hx - > intra_gb_ptr = & hx - > intra_gb ;
break ;
case NAL_DPC :
init_get_bits ( & hx - > inter_gb , ptr , bit_length ) ;
hx - > inter_gb_ptr = & hx - > inter_gb ;
if ( hx - > redundant_pic_count = = 0 & &
hx - > intra_gb_ptr & &
hx - > s . data_partitioning & &
s - > context_initialized & &
( avctx - > skip_frame < AVDISCARD_NONREF | | hx - > nal_ref_idc ) & &
( avctx - > skip_frame < AVDISCARD_BIDIR | |
hx - > slice_type_nos ! = AV_PICTURE_TYPE_B ) & &
( avctx - > skip_frame < AVDISCARD_NONKEY | |
hx - > slice_type_nos = = AV_PICTURE_TYPE_I ) & &
avctx - > skip_frame < AVDISCARD_ALL )
context_count + + ;
break ;
case NAL_SEI :
init_get_bits ( & s - > gb , ptr , bit_length ) ;
ff_h264_decode_sei ( h ) ;
break ;
case NAL_SPS :
init_get_bits ( & s - > gb , ptr , bit_length ) ;
2012-03-17 06:43:12 +03:00
if ( ff_h264_decode_seq_parameter_set ( h ) < 0 & & ( h - > is_avc ? ( nalsize ! = consumed ) & & nalsize : 1 ) ) {
2012-03-16 20:40:05 +03:00
av_log ( h - > s . avctx , AV_LOG_DEBUG ,
2012-03-17 06:43:12 +03:00
" SPS decoding failure, trying alternative mode \n " ) ;
if ( h - > is_avc )
av_assert0 ( next_avc - buf_index + consumed = = nalsize ) ;
init_get_bits ( & s - > gb , & buf [ buf_index + 1 - consumed ] ,
8 * ( next_avc - buf_index + consumed - 1 ) ) ;
2012-03-16 20:40:05 +03:00
ff_h264_decode_seq_parameter_set ( h ) ;
}
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
if ( s - > flags & CODEC_FLAG_LOW_DELAY | |
( h - > sps . bitstream_restriction_flag & &
! h - > sps . num_reorder_frames ) )
s - > low_delay = 1 ;
if ( avctx - > has_b_frames < 2 )
avctx - > has_b_frames = ! s - > low_delay ;
break ;
case NAL_PPS :
init_get_bits ( & s - > gb , ptr , bit_length ) ;
ff_h264_decode_picture_parameter_set ( h , bit_length ) ;
break ;
case NAL_AUD :
case NAL_END_SEQUENCE :
case NAL_END_STREAM :
case NAL_FILLER_DATA :
case NAL_SPS_EXT :
case NAL_AUXILIARY_SLICE :
break ;
default :
av_log ( avctx , AV_LOG_DEBUG , " Unknown NAL code: %d (%d bits) \n " ,
hx - > nal_unit_type , bit_length ) ;
2011-03-29 18:48:59 +03:00
}
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
if ( context_count = = h - > max_contexts ) {
execute_decode_slices ( h , context_count ) ;
context_count = 0 ;
}
2007-09-05 19:18:15 +03:00
2012-03-16 20:40:05 +03:00
if ( err < 0 )
av_log ( h - > s . avctx , AV_LOG_ERROR , " decode_slice_header error \n " ) ;
else if ( err = = 1 ) {
/* Slice could not be decoded in parallel mode, copy down
* NAL unit stuff to context 0 and restart . Note that
* rbsp_buffer is not transferred , but since we no longer
* run in parallel mode this should not be an issue . */
h - > nal_unit_type = hx - > nal_unit_type ;
h - > nal_ref_idc = hx - > nal_ref_idc ;
hx = h ;
goto again ;
}
2007-09-05 19:18:15 +03:00
}
}
2012-03-16 20:40:05 +03:00
if ( context_count )
2007-09-05 19:18:15 +03:00
execute_decode_slices ( h , context_count ) ;
2012-03-17 01:24:08 +03:00
end :
/* clean up */
if ( s - > current_picture_ptr & & s - > current_picture_ptr - > owner2 = = s & &
! s - > dropable ) {
ff_thread_report_progress ( & s - > current_picture_ptr - > f , INT_MAX ,
s - > picture_structure = = PICT_BOTTOM_FIELD ) ;
}
2003-04-04 17:42:28 +03:00
return buf_index ;
}
/**
2011-12-07 15:03:53 +03:00
* Return the number of bytes consumed for building the current frame .
2003-04-04 17:42:28 +03:00
*/
2012-03-16 20:40:05 +03:00
static int get_consumed_bytes ( MpegEncContext * s , int pos , int buf_size )
{
if ( pos = = 0 )
pos = 1 ; // avoid infinite loops (i doubt that is needed but ...)
if ( pos + 10 > buf_size )
pos = buf_size ; // oops ;)
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
return pos ;
2003-04-04 17:42:28 +03:00
}
2012-03-16 20:40:05 +03:00
static int decode_frame ( AVCodecContext * avctx , void * data ,
int * data_size , AVPacket * avpkt )
2003-04-04 17:42:28 +03:00
{
2009-04-07 18:59:50 +03:00
const uint8_t * buf = avpkt - > data ;
2012-03-16 20:40:05 +03:00
int buf_size = avpkt - > size ;
H264Context * h = avctx - > priv_data ;
MpegEncContext * s = & h - > s ;
AVFrame * pict = data ;
int buf_index = 0 ;
2011-12-16 20:55:04 +03:00
Picture * out ;
int i , out_idx ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
s - > flags = avctx - > flags ;
s - > flags2 = avctx - > flags2 ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
/* end of stream, output what is still in the buffers */
2003-04-04 17:42:28 +03:00
if ( buf_size = = 0 ) {
2011-12-16 20:55:04 +03:00
out :
2007-02-21 23:16:07 +02:00
2011-03-22 23:36:57 +02:00
s - > current_picture_ptr = NULL ;
2012-03-16 20:40:05 +03:00
// FIXME factorize this with the output code below
out = h - > delayed_pic [ 0 ] ;
2007-02-21 23:16:07 +02:00
out_idx = 0 ;
2012-03-16 20:40:05 +03:00
for ( i = 1 ;
h - > delayed_pic [ i ] & &
! h - > delayed_pic [ i ] - > f . key_frame & &
! h - > delayed_pic [ i ] - > mmco_reset ;
i + + )
if ( h - > delayed_pic [ i ] - > poc < out - > poc ) {
out = h - > delayed_pic [ i ] ;
2007-02-21 23:16:07 +02:00
out_idx = i ;
}
2012-03-16 20:40:05 +03:00
for ( i = out_idx ; h - > delayed_pic [ i ] ; i + + )
h - > delayed_pic [ i ] = h - > delayed_pic [ i + 1 ] ;
2007-02-21 23:16:07 +02:00
2012-03-16 20:40:05 +03:00
if ( out ) {
2007-02-21 23:16:07 +02:00
* data_size = sizeof ( AVFrame ) ;
2012-02-28 00:08:41 +03:00
* pict = out - > f ;
2007-02-21 23:16:07 +02:00
}
2011-12-31 20:12:53 +03:00
return buf_index ;
2003-04-04 17:42:28 +03:00
}
2011-12-15 19:23:39 +03:00
if ( h - > is_avc & & buf_size > = 9 & & buf [ 0 ] = = 1 & & buf [ 2 ] = = 0 & & ( buf [ 4 ] & 0xFC ) = = 0xFC & & ( buf [ 5 ] & 0x1F ) & & buf [ 8 ] = = 0x67 ) {
int cnt = buf [ 5 ] & 0x1f ;
2012-03-07 02:32:02 +03:00
const uint8_t * p = buf + 6 ;
2011-12-15 19:23:39 +03:00
while ( cnt - - ) {
int nalsize = AV_RB16 ( p ) + 2 ;
if ( nalsize > buf_size - ( p - buf ) | | p [ 2 ] ! = 0x67 )
goto not_extra ;
p + = nalsize ;
}
cnt = * ( p + + ) ;
if ( ! cnt )
goto not_extra ;
while ( cnt - - ) {
int nalsize = AV_RB16 ( p ) + 2 ;
if ( nalsize > buf_size - ( p - buf ) | | p [ 2 ] ! = 0x68 )
goto not_extra ;
p + = nalsize ;
}
2011-09-23 06:43:32 +03:00
return ff_h264_decode_extradata ( h , buf , buf_size ) ;
2011-12-15 19:23:39 +03:00
}
not_extra :
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
buf_index = decode_nal_units ( h , buf , buf_size ) ;
if ( buf_index < 0 )
2003-04-04 17:42:28 +03:00
return - 1 ;
2010-11-23 03:16:37 +02:00
if ( ! s - > current_picture_ptr & & h - > nal_unit_type = = NAL_END_SEQUENCE ) {
2011-12-16 20:55:04 +03:00
av_assert0 ( buf_index < = buf_size ) ;
2010-11-23 03:16:37 +02:00
goto out ;
}
2012-03-16 20:40:05 +03:00
if ( ! ( s - > flags2 & CODEC_FLAG2_CHUNKS ) & & ! s - > current_picture_ptr ) {
2011-12-03 05:31:24 +03:00
if ( avctx - > skip_frame > = AVDISCARD_NONREF | |
buf_size > = 4 & & ! memcmp ( " Q264 " , buf , 4 ) )
2011-12-16 20:55:52 +03:00
return buf_size ;
2007-03-03 23:33:33 +02:00
av_log ( avctx , AV_LOG_ERROR , " no frame! \n " ) ;
return - 1 ;
}
2012-03-16 20:40:05 +03:00
if ( ! ( s - > flags2 & CODEC_FLAG2_CHUNKS ) | |
( s - > mb_y > = s - > mb_height & & s - > mb_height ) ) {
if ( s - > flags2 & CODEC_FLAG2_CHUNKS )
decode_postinit ( h , 1 ) ;
2007-03-03 01:35:26 +02:00
2011-03-22 23:36:57 +02:00
field_end ( h , 0 ) ;
2012-03-17 06:43:12 +03:00
/* Wait for second field. */
* data_size = 0 ;
2012-01-01 00:16:57 +03:00
if ( h - > next_output_pic & & ( h - > next_output_pic - > sync | | h - > sync > 1 ) ) {
2011-06-02 20:15:58 +03:00
* data_size = sizeof ( AVFrame ) ;
2012-02-28 00:08:41 +03:00
* pict = h - > next_output_pic - > f ;
2007-10-08 20:44:38 +03:00
}
2005-01-04 03:12:48 +02:00
}
2005-11-10 06:40:49 +02:00
assert ( pict - > data [ 0 ] | | ! * data_size ) ;
2005-03-11 04:14:44 +02:00
ff_print_debug_info ( s , pict ) ;
2012-03-16 20:40:05 +03:00
// printf("out %d\n", (int)pict->data[0]);
2003-04-04 17:42:28 +03:00
return get_consumed_bytes ( s , buf_index , buf_size ) ;
}
2009-04-10 14:31:55 +03:00
av_cold void ff_h264_free_context ( H264Context * h )
2003-04-04 17:42:28 +03:00
{
2008-09-25 22:01:39 +03:00
int i ;
2005-12-17 20:14:38 +02:00
2012-03-16 20:40:05 +03:00
free_tables ( h , 1 ) ; // FIXME cleanup init stuff perhaps
2008-09-25 22:01:39 +03:00
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < MAX_SPS_COUNT ; i + + )
2008-09-25 22:01:39 +03:00
av_freep ( h - > sps_buffers + i ) ;
2012-03-16 20:40:05 +03:00
for ( i = 0 ; i < MAX_PPS_COUNT ; i + + )
2008-09-25 22:01:39 +03:00
av_freep ( h - > pps_buffers + i ) ;
2009-04-10 10:01:55 +03:00
}
2012-03-29 14:52:21 +03:00
static av_cold int h264_decode_end ( AVCodecContext * avctx )
2009-04-10 10:01:55 +03:00
{
2012-03-16 20:40:05 +03:00
H264Context * h = avctx - > priv_data ;
2009-04-10 10:01:55 +03:00
MpegEncContext * s = & h - > s ;
2011-12-07 00:40:43 +03:00
ff_h264_remove_all_refs ( h ) ;
2009-04-10 10:01:55 +03:00
ff_h264_free_context ( h ) ;
2008-09-25 22:01:39 +03:00
2012-02-15 15:10:33 +03:00
ff_MPV_common_end ( s ) ;
2003-04-04 17:42:28 +03:00
2012-03-16 20:40:05 +03:00
// memset(h, 0, sizeof(H264Context));
2005-12-17 20:14:38 +02:00
2003-04-04 17:42:28 +03:00
return 0 ;
}
2011-01-22 00:58:52 +02:00
static const AVProfile profiles [ ] = {
{ FF_PROFILE_H264_BASELINE , " Baseline " } ,
{ FF_PROFILE_H264_CONSTRAINED_BASELINE , " Constrained Baseline " } ,
{ FF_PROFILE_H264_MAIN , " Main " } ,
{ FF_PROFILE_H264_EXTENDED , " Extended " } ,
{ FF_PROFILE_H264_HIGH , " High " } ,
{ FF_PROFILE_H264_HIGH_10 , " High 10 " } ,
{ FF_PROFILE_H264_HIGH_10_INTRA , " High 10 Intra " } ,
{ FF_PROFILE_H264_HIGH_422 , " High 4:2:2 " } ,
{ FF_PROFILE_H264_HIGH_422_INTRA , " High 4:2:2 Intra " } ,
2011-02-01 22:56:13 +02:00
{ FF_PROFILE_H264_HIGH_444 , " High 4:4:4 " } ,
2011-01-22 00:58:52 +02:00
{ FF_PROFILE_H264_HIGH_444_PREDICTIVE , " High 4:4:4 Predictive " } ,
{ FF_PROFILE_H264_HIGH_444_INTRA , " High 4:4:4 Intra " } ,
{ FF_PROFILE_H264_CAVLC_444 , " CAVLC 4:4:4 " } ,
{ FF_PROFILE_UNKNOWN } ,
} ;
2003-04-04 17:42:28 +03:00
2011-11-02 20:39:42 +03:00
static const AVOption h264_options [ ] = {
{ " is_avc " , " is avc " , offsetof ( H264Context , is_avc ) , FF_OPT_TYPE_INT , { . dbl = 0 } , 0 , 1 , 0 } ,
{ " nal_length_size " , " nal_length_size " , offsetof ( H264Context , nal_length_size ) , FF_OPT_TYPE_INT , { . dbl = 0 } , 0 , 4 , 0 } ,
{ NULL }
} ;
static const AVClass h264_class = {
" H264 Decoder " ,
av_default_item_name ,
h264_options ,
LIBAVUTIL_VERSION_INT ,
} ;
static const AVClass h264_vdpau_class = {
" H264 VDPAU Decoder " ,
av_default_item_name ,
h264_options ,
LIBAVUTIL_VERSION_INT ,
} ;
2011-01-25 23:40:11 +02:00
AVCodec ff_h264_decoder = {
2012-03-16 20:40:05 +03:00
. name = " h264 " ,
. type = AVMEDIA_TYPE_VIDEO ,
. id = CODEC_ID_H264 ,
. priv_data_size = sizeof ( H264Context ) ,
. init = ff_h264_decode_init ,
2012-03-29 14:52:21 +03:00
. close = h264_decode_end ,
2012-03-16 20:40:05 +03:00
. decode = decode_frame ,
. capabilities = /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 |
CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS |
CODEC_CAP_FRAME_THREADS ,
. flush = flush_dpb ,
. long_name = NULL_IF_CONFIG_SMALL ( " H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 " ) ,
2011-03-22 23:36:57 +02:00
. init_thread_copy = ONLY_IF_THREADS_ENABLED ( decode_init_thread_copy ) ,
. update_thread_context = ONLY_IF_THREADS_ENABLED ( decode_update_thread_context ) ,
2012-03-16 20:40:05 +03:00
. profiles = NULL_IF_CONFIG_SMALL ( profiles ) ,
2012-03-17 06:43:12 +03:00
. priv_class = & h264_class ,
2003-04-04 17:42:28 +03:00
} ;
2009-01-14 01:44:16 +02:00
# if CONFIG_H264_VDPAU_DECODER
2011-01-25 23:40:11 +02:00
AVCodec ff_h264_vdpau_decoder = {
2011-07-17 13:54:31 +03:00
. name = " h264_vdpau " ,
. type = AVMEDIA_TYPE_VIDEO ,
. id = CODEC_ID_H264 ,
. priv_data_size = sizeof ( H264Context ) ,
. init = ff_h264_decode_init ,
2012-03-29 14:52:21 +03:00
. close = h264_decode_end ,
2011-07-17 13:54:31 +03:00
. decode = decode_frame ,
. capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU ,
2012-03-16 20:40:05 +03:00
. flush = flush_dpb ,
. long_name = NULL_IF_CONFIG_SMALL ( " H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration) " ) ,
. pix_fmts = ( const enum PixelFormat [ ] ) { PIX_FMT_VDPAU_H264 ,
PIX_FMT_NONE } ,
. profiles = NULL_IF_CONFIG_SMALL ( profiles ) ,
2011-11-02 20:39:42 +03:00
. priv_class = & h264_vdpau_class ,
2009-01-05 01:55:27 +02:00
} ;
# endif