@ -42,7 +42,7 @@ static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
pic - > bPicEntry = index | ( flag < < 7 ) ;
}
static void fill_picture_parameters ( struct dxva_c ontext * ctx , const H264Context * h ,
static void fill_picture_parameters ( const AVCodecContext * avctx , AVDXVAC ontext * ctx , const H264Context * h ,
DXVA_PicParams_H264 * pp )
{
const H264Picture * current_picture = h - > cur_pic_ptr ;
@ -51,7 +51,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
memset ( pp , 0 , sizeof ( * pp ) ) ;
/* Configure current picture */
fill_picture_entry ( & pp - > CurrPic ,
ff_dxva2_get_surface_index ( ctx , current_picture - > f ) ,
ff_dxva2_get_surface_index ( avctx , ctx , current_picture - > f ) ,
h - > picture_structure = = PICT_BOTTOM_FIELD ) ;
/* Configure the set of references */
pp - > UsedForReferenceFlags = 0 ;
@ -67,7 +67,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
}
if ( r ) {
fill_picture_entry ( & pp - > RefFrameList [ i ] ,
ff_dxva2_get_surface_index ( ctx , r - > f ) ,
ff_dxva2_get_surface_index ( avctx , ctx , r - > f ) ,
r - > long_ref ! = 0 ) ;
if ( ( r - > reference & PICT_TOP_FIELD ) & & r - > field_poc [ 0 ] ! = INT_MAX )
@ -114,13 +114,13 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
pp - > bit_depth_luma_minus8 = h - > sps . bit_depth_luma - 8 ;
pp - > bit_depth_chroma_minus8 = h - > sps . bit_depth_chroma - 8 ;
if ( ctx - > workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG )
if ( DXVA_CONTEXT_WORKAROUND ( avctx , ctx ) & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG )
pp - > Reserved16Bits = 0 ;
else if ( ctx - > workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO )
else if ( DXVA_CONTEXT_WORKAROUND ( avctx , ctx ) & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO )
pp - > Reserved16Bits = 0x34c ;
else
pp - > Reserved16Bits = 3 ; /* FIXME is there a way to detect the right mode ? */
pp - > StatusReportFeedbackNumber = 1 + ctx - > report_id + + ;
pp - > StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID ( avctx , ctx ) + + ;
pp - > CurrFieldOrderCnt [ 0 ] = 0 ;
if ( ( h - > picture_structure & PICT_TOP_FIELD ) & &
current_picture - > field_poc [ 0 ] ! = INT_MAX )
@ -156,11 +156,11 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
//pp->SliceGroupMap[810]; /* XXX not implemented by Libav */
}
static void fill_scaling_lists ( struct dxva_c ontext * ctx , const H264Context * h , DXVA_Qmatrix_H264 * qm )
static void fill_scaling_lists ( const AVCodecContext * avctx , AVDXVAC ontext * ctx , const H264Context * h , DXVA_Qmatrix_H264 * qm )
{
unsigned i , j ;
memset ( qm , 0 , sizeof ( * qm ) ) ;
if ( ctx - > workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG ) {
if ( DXVA_CONTEXT_WORKAROUND ( avctx , ctx ) & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG ) {
for ( i = 0 ; i < 6 ; i + + )
for ( j = 0 ; j < 16 ; j + + )
qm - > bScalingLists4x4 [ i ] [ j ] = h - > pps . scaling_matrix4 [ i ] [ j ] ;
@ -181,11 +181,11 @@ static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, D
}
}
static int is_slice_short ( struct dxva_c ontext * ctx )
static int is_slice_short ( const AVCodecContext * avctx , AVDXVAC ontext * ctx )
{
assert ( ctx - > cfg - > ConfigBitstreamRaw = = 1 | |
ctx - > cfg - > ConfigBitstreamRaw = = 2 ) ;
return ctx - > cfg - > ConfigBitstreamRaw = = 2 ;
assert ( DXVA_CONTEXT_CFG_BITSTREAM ( avctx , ctx ) = = 1 | |
DXVA_CONTEXT_CFG_BITSTREAM ( avctx , ctx ) = = 2 ) ;
return DXVA_CONTEXT_CFG_BITSTREAM ( avctx , ctx ) = = 2 ;
}
static void fill_slice_short ( DXVA_Slice_H264_Short * slice ,
@ -212,7 +212,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
{
const H264Context * h = avctx - > priv_data ;
H264SliceContext * sl = & h - > slice_ctx [ 0 ] ;
struct dxva_c ontext * ctx = avctx - > hwaccel_context ;
AVDXVAC ontext * ctx = avctx - > hwaccel_context ;
unsigned list ;
memset ( slice , 0 , sizeof ( * slice ) ) ;
@ -243,10 +243,10 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
const H264Picture * r = sl - > ref_list [ list ] [ i ] . parent ;
unsigned plane ;
unsigned index ;
if ( ctx - > workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO )
index = ff_dxva2_get_surface_index ( ctx , r - > f ) ;
if ( DXVA_CONTEXT_WORKAROUND ( avctx , ctx ) & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO )
index = ff_dxva2_get_surface_index ( avctx , ctx , r - > f ) ;
else
index = get_refpic_index ( pp , ff_dxva2_get_surface_index ( ctx , r - > f ) ) ;
index = get_refpic_index ( pp , ff_dxva2_get_surface_index ( avctx , ctx , r - > f ) ) ;
fill_picture_entry ( & slice - > RefPicList [ list ] [ i ] , index ,
r - > reference = = PICT_BOTTOM_FIELD ) ;
for ( plane = 0 ; plane < 3 ; plane + + ) {
@ -289,12 +289,12 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
}
static int commit_bitstream_and_slice_buffer ( AVCodecContext * avctx ,
DXVA2_DecodeBufferDesc * bs ,
DXVA2_DecodeBufferDesc * sc )
DECODER_BUFFER_DESC * bs ,
DECODER_BUFFER_DESC * sc )
{
const H264Context * h = avctx - > priv_data ;
const unsigned mb_count = h - > mb_width * h - > mb_height ;
struct dxva_c ontext * ctx = avctx - > hwaccel_context ;
AVDXVAC ontext * ctx = avctx - > hwaccel_context ;
const H264Picture * current_picture = h - > cur_pic_ptr ;
struct dxva2_picture_context * ctx_pic = current_picture - > hwaccel_picture_private ;
DXVA_Slice_H264_Short * slice = NULL ;
@ -305,12 +305,28 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
unsigned slice_size ;
unsigned padding ;
unsigned i ;
unsigned type ;
/* Create an annex B bitstream buffer with only slice NAL and finalize slice */
if ( FAILED ( IDirectXVideoDecoder_GetBuffer ( ctx - > decoder ,
DXVA2_BitStreamDateBufferType ,
& dxva_data_ptr , & dxva_size ) ) )
return - 1 ;
# if CONFIG_D3D11VA
if ( avctx - > pix_fmt = = AV_PIX_FMT_D3D11VA_VLD ) {
type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM ;
if ( FAILED ( ID3D11VideoContext_GetDecoderBuffer ( D3D11VA_CONTEXT ( ctx ) - > video_context ,
D3D11VA_CONTEXT ( ctx ) - > decoder ,
type ,
& dxva_size , & dxva_data_ptr ) ) )
return - 1 ;
}
# endif
# if CONFIG_DXVA2
if ( avctx - > pix_fmt = = AV_PIX_FMT_DXVA2_VLD ) {
type = DXVA2_BitStreamDateBufferType ;
if ( FAILED ( IDirectXVideoDecoder_GetBuffer ( DXVA2_CONTEXT ( ctx ) - > decoder ,
type ,
& dxva_data_ptr , & dxva_size ) ) )
return - 1 ;
}
# endif
dxva_data = dxva_data_ptr ;
current = dxva_data ;
@ -326,7 +342,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
assert ( offsetof ( DXVA_Slice_H264_Short , SliceBytesInBuffer ) = =
offsetof ( DXVA_Slice_H264_Long , SliceBytesInBuffer ) ) ;
if ( is_slice_short ( ctx ) )
if ( is_slice_short ( avctx , ctx ) )
slice = & ctx_pic - > slice_short [ i ] ;
else
slice = ( DXVA_Slice_H264_Short * ) & ctx_pic - > slice_long [ i ] ;
@ -341,7 +357,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
slice - > BSNALunitDataLocation = current - dxva_data ;
slice - > SliceBytesInBuffer = start_code_size + size ;
if ( ! is_slice_short ( ctx ) ) {
if ( ! is_slice_short ( avctx , ctx ) ) {
DXVA_Slice_H264_Long * slice_long = ( DXVA_Slice_H264_Long * ) slice ;
if ( i < ctx_pic - > slice_count - 1 )
slice_long - > NumMbsForSlice =
@ -363,18 +379,43 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
slice - > SliceBytesInBuffer + = padding ;
}
if ( FAILED ( IDirectXVideoDecoder_ReleaseBuffer ( ctx - > decoder ,
DXVA2_BitStreamDateBufferType ) ) )
return - 1 ;
# if CONFIG_D3D11VA
if ( avctx - > pix_fmt = = AV_PIX_FMT_D3D11VA_VLD )
if ( FAILED ( ID3D11VideoContext_ReleaseDecoderBuffer ( D3D11VA_CONTEXT ( ctx ) - > video_context , D3D11VA_CONTEXT ( ctx ) - > decoder , type ) ) )
return - 1 ;
# endif
# if CONFIG_DXVA2
if ( avctx - > pix_fmt = = AV_PIX_FMT_DXVA2_VLD )
if ( FAILED ( IDirectXVideoDecoder_ReleaseBuffer ( DXVA2_CONTEXT ( ctx ) - > decoder , type ) ) )
return - 1 ;
# endif
if ( i < ctx_pic - > slice_count )
return - 1 ;
memset ( bs , 0 , sizeof ( * bs ) ) ;
bs - > CompressedBufferType = DXVA2_BitStreamDateBufferType ;
bs - > DataSize = current - dxva_data ;
bs - > NumMBsInBuffer = mb_count ;
# if CONFIG_D3D11VA
if ( avctx - > pix_fmt = = AV_PIX_FMT_D3D11VA_VLD ) {
D3D11_VIDEO_DECODER_BUFFER_DESC * dsc11 = bs ;
memset ( dsc11 , 0 , sizeof ( * dsc11 ) ) ;
dsc11 - > BufferType = type ;
dsc11 - > DataSize = current - dxva_data ;
dsc11 - > NumMBsInBuffer = mb_count ;
if ( is_slice_short ( ctx ) ) {
type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL ;
}
# endif
# if CONFIG_DXVA2
if ( avctx - > pix_fmt = = AV_PIX_FMT_DXVA2_VLD ) {
DXVA2_DecodeBufferDesc * dsc2 = bs ;
memset ( dsc2 , 0 , sizeof ( * dsc2 ) ) ;
dsc2 - > CompressedBufferType = type ;
dsc2 - > DataSize = current - dxva_data ;
dsc2 - > NumMBsInBuffer = mb_count ;
type = DXVA2_SliceControlBufferType ;
}
# endif
if ( is_slice_short ( avctx , ctx ) ) {
slice_data = ctx_pic - > slice_short ;
slice_size = ctx_pic - > slice_count * sizeof ( * ctx_pic - > slice_short ) ;
} else {
@ -383,7 +424,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
}
assert ( ( bs - > DataSize & 127 ) = = 0 ) ;
return ff_dxva2_commit_buffer ( avctx , ctx , sc ,
DXVA2_SliceCon trolBufferT ype,
type ,
slice_data , slice_size , mb_count ) ;
}
@ -393,18 +434,20 @@ static int dxva2_h264_start_frame(AVCodecContext *avctx,
av_unused uint32_t size )
{
const H264Context * h = avctx - > priv_data ;
struct dxva_c ontext * ctx = avctx - > hwaccel_context ;
AVDXVAC ontext * ctx = avctx - > hwaccel_context ;
struct dxva2_picture_context * ctx_pic = h - > cur_pic_ptr - > hwaccel_picture_private ;
if ( ! ctx - > decoder | | ! ctx - > cfg | | ctx - > surface_count < = 0 )
if ( DXVA_CONTEXT_DECODER ( avctx , ctx ) = = NULL | |
DXVA_CONTEXT_CFG ( avctx , ctx ) = = NULL | |
DXVA_CONTEXT_COUNT ( avctx , ctx ) < = 0 )
return - 1 ;
assert ( ctx_pic ) ;
/* Fill up DXVA_PicParams_H264 */
fill_picture_parameters ( ctx , h , & ctx_pic - > pp ) ;
fill_picture_parameters ( avctx , ctx , h , & ctx_pic - > pp ) ;
/* Fill up DXVA_Qmatrix_H264 */
fill_scaling_lists ( ctx , h , & ctx_pic - > qm ) ;
fill_scaling_lists ( avctx , ctx , h , & ctx_pic - > qm ) ;
ctx_pic - > slice_count = 0 ;
ctx_pic - > bitstream_size = 0 ;
@ -418,7 +461,7 @@ static int dxva2_h264_decode_slice(AVCodecContext *avctx,
{
const H264Context * h = avctx - > priv_data ;
const H264SliceContext * sl = & h - > slice_ctx [ 0 ] ;
struct dxva_c ontext * ctx = avctx - > hwaccel_context ;
AVDXVAC ontext * ctx = avctx - > hwaccel_context ;
const H264Picture * current_picture = h - > cur_pic_ptr ;
struct dxva2_picture_context * ctx_pic = current_picture - > hwaccel_picture_private ;
unsigned position ;
@ -431,7 +474,7 @@ static int dxva2_h264_decode_slice(AVCodecContext *avctx,
ctx_pic - > bitstream_size + = size ;
position = buffer - ctx_pic - > bitstream ;
if ( is_slice_short ( ctx ) )
if ( is_slice_short ( avctx , ctx ) )
fill_slice_short ( & ctx_pic - > slice_short [ ctx_pic - > slice_count ] ,
position , size ) ;
else
@ -463,6 +506,7 @@ static int dxva2_h264_end_frame(AVCodecContext *avctx)
return ret ;
}
# if CONFIG_H264_DXVA2_HWACCEL
AVHWAccel ff_h264_dxva2_hwaccel = {
. name = " h264_dxva2 " ,
. type = AVMEDIA_TYPE_VIDEO ,
@ -473,3 +517,17 @@ AVHWAccel ff_h264_dxva2_hwaccel = {
. end_frame = dxva2_h264_end_frame ,
. frame_priv_data_size = sizeof ( struct dxva2_picture_context ) ,
} ;
# endif
# if CONFIG_H264_D3D11VA_HWACCEL
AVHWAccel ff_h264_d3d11va_hwaccel = {
. name = " h264_d3d11va " ,
. type = AVMEDIA_TYPE_VIDEO ,
. id = AV_CODEC_ID_H264 ,
. pix_fmt = AV_PIX_FMT_D3D11VA_VLD ,
. start_frame = dxva2_h264_start_frame ,
. decode_slice = dxva2_h264_decode_slice ,
. end_frame = dxva2_h264_end_frame ,
. frame_priv_data_size = sizeof ( struct dxva2_picture_context ) ,
} ;
# endif