[vlc-devel] [PATCH] avcodec: don't guess size when encoding video
Rémi Denis-Courmont
remi at remlab.net
Fri Jul 4 16:00:10 CEST 2014
Le 2014-07-04 16:54, Tristan Matthews a écrit :
> Fixes #11605
> ---
> modules/codec/avcodec/encoder.c | 31 +++++++++++--------------------
> 1 file changed, 11 insertions(+), 20 deletions(-)
>
> diff --git a/modules/codec/avcodec/encoder.c
> b/modules/codec/avcodec/encoder.c
> index a6fcf66..3646b6e 100644
> --- a/modules/codec/avcodec/encoder.c
> +++ b/modules/codec/avcodec/encoder.c
> @@ -1013,19 +1013,6 @@ static block_t *EncodeVideo( encoder_t *p_enc,
> picture_t *p_pict )
> {
> encoder_sys_t *p_sys = p_enc->p_sys;
> int i_plane;
> - /* Initialize the video output buffer the first time.
> - * This is done here instead of OpenEncoder() because we need
> the actual
> - * bits_per_pixel value, without having to assume anything.
> - */
> - const int bitsPerPixel = p_enc->fmt_out.video.i_bits_per_pixel ?
> - p_enc->fmt_out.video.i_bits_per_pixel :
> - p_sys->p_context->bits_per_coded_sample ?
> - p_sys->p_context->bits_per_coded_sample :
> - 24;
> - const int blocksize = __MAX( FF_MIN_BUFFER_SIZE, ( bitsPerPixel
> * p_sys->p_context->height * p_sys->p_context->width ) / 8 + 200 );
> - block_t *p_block = block_Alloc( blocksize );
> - if( unlikely(p_block == NULL) )
> - return NULL;
>
> AVFrame *frame = NULL;
> if( likely(p_pict) ) {
> @@ -1090,7 +1077,6 @@ static block_t *EncodeVideo( encoder_t *p_enc,
> picture_t *p_pict )
> {
> msg_Warn( p_enc, "almost fed libavcodec with two
> frames with "
> "the same PTS (%"PRId64 ")", frame->pts );
> - block_Release( p_block );
> return NULL;
> }
> else if ( p_sys->i_last_pts > frame->pts )
> @@ -1098,7 +1084,6 @@ static block_t *EncodeVideo( encoder_t *p_enc,
> picture_t *p_pict )
> msg_Warn( p_enc, "almost fed libavcodec with a frame
> in the "
> "past (current: %"PRId64 ", last:
> %"PRId64")",
> frame->pts, p_sys->i_last_pts );
> - block_Release( p_block );
> return NULL;
> }
> else
> @@ -1108,21 +1093,27 @@ static block_t *EncodeVideo( encoder_t
> *p_enc, picture_t *p_pict )
> frame->quality = p_sys->i_quality;
> }
>
> - AVPacket av_pkt;
> + AVPacket av_pkt = {0};
Why is this needed now?
> int is_data;
>
> av_init_packet( &av_pkt );
> - av_pkt.data = p_block->p_buffer;
> - av_pkt.size = p_block->i_buffer;
>
> if( avcodec_encode_video2( p_sys->p_context, &av_pkt, frame,
> &is_data ) < 0
> || is_data == 0 )
> {
> - block_Release( p_block );
> return NULL;
> }
>
> - p_block->i_buffer = av_pkt.size;
> + block_t *p_block = block_Alloc( av_pkt.size );
> + if( unlikely(p_block == NULL) )
> + {
> + av_free_packet( &av_pkt );
> + return NULL;
> + }
> +
> + memcpy( p_block->p_buffer, av_pkt.data, av_pkt.size );
> + av_free_packet( &av_pkt );
"memcpy() is evil." IMHO, the AVPacket should be wrapped into a block_t
rather than copied.
> +
> p_block->i_length = av_pkt.duration /
> p_sys->p_context->time_base.den;
> p_block->i_pts = av_pkt.pts;
> p_block->i_dts = av_pkt.dts;
--
Rémi Denis-Courmont
More information about the vlc-devel
mailing list