@ -232,12 +232,35 @@ static void free_frame_buffer(MpegEncContext *s, Picture *pic)
av_freep ( & pic - > f . hwaccel_picture_private ) ;
}
int ff_mpv_frame_size_alloc ( MpegEncContext * s , int linesize )
{
int alloc_size = FFALIGN ( FFABS ( linesize ) + 64 , 32 ) ;
// edge emu needs blocksize + filter length - 1
// (= 17x17 for halfpel / 21x21 for h264)
// linesize * interlaced * MBsize
FF_ALLOCZ_OR_GOTO ( s - > avctx , s - > edge_emu_buffer , alloc_size * 4 * 21 ,
fail ) ;
FF_ALLOCZ_OR_GOTO ( s - > avctx , s - > me . scratchpad , alloc_size * 2 * 16 * 2 ,
fail )
s - > me . temp = s - > me . scratchpad ;
s - > rd_scratchpad = s - > me . scratchpad ;
s - > b_scratchpad = s - > me . scratchpad ;
s - > obmc_scratchpad = s - > me . scratchpad + 16 ;
return 0 ;
fail :
av_freep ( & s - > edge_emu_buffer ) ;
return AVERROR ( ENOMEM ) ;
}
/**
* Allocate a frame buffer
*/
static int alloc_frame_buffer ( MpegEncContext * s , Picture * pic )
{
int r ;
int r , ret ;
if ( s - > avctx - > hwaccel ) {
assert ( ! pic - > f . hwaccel_picture_private ) ;
@ -279,6 +302,14 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
return - 1 ;
}
if ( ! s - > edge_emu_buffer & &
( ret = ff_mpv_frame_size_alloc ( s , pic - > f . linesize [ 0 ] ) ) < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR ,
" get_buffer() failed to allocate context scratch buffers. \n " ) ;
free_frame_buffer ( s , pic ) ;
return ret ;
}
return 0 ;
}
@ -416,19 +447,13 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base)
int yc_size = y_size + 2 * c_size ;
int i ;
// edge emu needs blocksize + filter length - 1
// (= 17x17 for halfpel / 21x21 for h264)
FF_ALLOCZ_OR_GOTO ( s - > avctx , s - > edge_emu_buffer ,
( s - > width + 95 ) * 2 * 21 * 4 , fail ) ; // (width + edge + align)*interlaced*MBsize*tolerance
s - > edge_emu_buffer =
s - > me . scratchpad =
s - > me . temp =
s - > rd_scratchpad =
s - > b_scratchpad =
s - > obmc_scratchpad = NULL ;
// FIXME should be linesize instead of s->width * 2
// but that is not known before get_buffer()
FF_ALLOCZ_OR_GOTO ( s - > avctx , s - > me . scratchpad ,
( s - > width + 95 ) * 4 * 16 * 2 * sizeof ( uint8_t ) , fail )
s - > me . temp = s - > me . scratchpad ;
s - > rd_scratchpad = s - > me . scratchpad ;
s - > b_scratchpad = s - > me . scratchpad ;
s - > obmc_scratchpad = s - > me . scratchpad + 16 ;
if ( s - > encoding ) {
FF_ALLOCZ_OR_GOTO ( s - > avctx , s - > me . map ,
ME_MAP_SIZE * sizeof ( uint32_t ) , fail )
@ -507,10 +532,10 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
# undef COPY
}
void ff_update_duplicate_context ( MpegEncContext * dst , MpegEncContext * src )
int ff_update_duplicate_context ( MpegEncContext * dst , MpegEncContext * src )
{
MpegEncContext bak ;
int i ;
int i , ret ;
// FIXME copy only needed parts
// START_TIMER
backup_duplicate_context ( & bak , dst ) ;
@ -519,8 +544,15 @@ void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src)
for ( i = 0 ; i < 12 ; i + + ) {
dst - > pblocks [ i ] = & dst - > block [ i ] ;
}
if ( ! dst - > edge_emu_buffer & &
( ret = ff_mpv_frame_size_alloc ( dst , dst - > linesize ) ) < 0 ) {
av_log ( dst - > avctx , AV_LOG_ERROR , " failed to allocate context "
" scratch buffers. \n " ) ;
return ret ;
}
// STOP_TIMER("update_duplicate_context")
// about 10k cycles / 0.01 sec for 1000frames on 1ghz with 2 threads
return 0 ;
}
int ff_mpeg_update_thread_context ( AVCodecContext * dst ,
@ -612,6 +644,19 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
FF_INPUT_BUFFER_PADDING_SIZE ) ;
}
// linesize dependend scratch buffer allocation
if ( ! s - > edge_emu_buffer )
if ( s1 - > linesize ) {
if ( ff_mpv_frame_size_alloc ( s , s1 - > linesize ) < 0 ) {
av_log ( s - > avctx , AV_LOG_ERROR , " Failed to allocate context "
" scratch buffers. \n " ) ;
return AVERROR ( ENOMEM ) ;
}
} else {
av_log ( s - > avctx , AV_LOG_ERROR , " Context scratch buffers could not "
" be allocated due to unknown size. \n " ) ;
}
// MPEG2/interlacing info
memcpy ( & s - > progressive_sequence , & s1 - > progressive_sequence ,
( char * ) & s1 - > rtp_mode - ( char * ) & s1 - > progressive_sequence ) ;