]> git.sesse.net Git - vlc/blobdiff - modules/codec/avcodec/encoder.c
Use var_Inherit* instead of var_CreateGet*.
[vlc] / modules / codec / avcodec / encoder.c
index df7daf3625c8cc2eb9d3a568c6fad91d07a49bd8..0981c1b2458ffe227d5ffb987893971f34541b3f 100644 (file)
@@ -436,13 +436,7 @@ int OpenEncoder( vlc_object_t *p_this )
                    p_enc->fmt_in.video.i_sar_num,
                    p_enc->fmt_in.video.i_sar_den, 1 << 30 );
 
-        p_sys->i_buffer_out = p_context->height * p_context->width
-            * 3     /* Assume 24bpp maximum */
-            + 200;  /* some room for potential headers (such as BMP) */
-
-        if( p_sys->i_buffer_out < FF_MIN_BUFFER_SIZE )
-            p_sys->i_buffer_out = FF_MIN_BUFFER_SIZE;
-        p_sys->p_buffer_out = malloc( p_sys->i_buffer_out );
+        p_sys->p_buffer_out = NULL;
 
         p_enc->fmt_in.i_codec = VLC_CODEC_I420;
         p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec;
@@ -500,7 +494,8 @@ int OpenEncoder( vlc_object_t *p_this )
         if ( p_sys->i_qmin > 0 && p_sys->i_qmin == p_sys->i_qmax )
             p_context->flags |= CODEC_FLAG_QSCALE;
         /* These codecs cause libavcodec to exit if thread_count is > 1.
-           See libavcodec/mpegvideo_enc.c:MPV_encode_init
+           See libavcodec/mpegvideo_enc.c:MPV_encode_init and
+           libavcodec/svq3.c , WMV2 calls MPV_encode_init also.
          */
         if ( i_codec_id == CODEC_ID_FLV1 ||
              i_codec_id == CODEC_ID_H261 ||
@@ -512,6 +507,7 @@ int OpenEncoder( vlc_object_t *p_this )
              i_codec_id == CODEC_ID_MSMPEG4V2 ||
              i_codec_id == CODEC_ID_MSMPEG4V3 ||
              i_codec_id == CODEC_ID_WMV1 ||
+             i_codec_id == CODEC_ID_WMV2 ||
              i_codec_id == CODEC_ID_RV10 ||
              i_codec_id == CODEC_ID_RV20 ||
              i_codec_id == CODEC_ID_SVQ3 )
@@ -598,10 +594,38 @@ int OpenEncoder( vlc_object_t *p_this )
        libvpx-720p preset from libvpx ffmpeg-patch */
     if( i_codec_id == CODEC_ID_VP8 )
     {
+        /* Lets give bitrate tolerance */
         p_context->bit_rate_tolerance = __MAX(2 * p_enc->fmt_out.i_bitrate, p_sys->i_vtolerance );
-        /* I used Harrison-stetson method here to get there values */
-        p_context->rc_max_rate = 3 * p_enc->fmt_out.i_bitrate;
-        p_context->rc_min_rate = p_enc->fmt_out.i_bitrate / 200;
+        /* default to 120 frames between keyframe */
+        if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "keyint" ) )
+           p_context->gop_size = 120;
+        /* Don't set rc-values atm, they were from time before
+           libvpx was officially in ffmpeg */
+        //p_context->rc_max_rate = 24 * 1000 * 1000; //24M
+        //p_context->rc_min_rate = 40 * 1000; // 40k
+        /* seems that ffmpeg presets have 720p as divider for buffers */
+        if( p_enc->fmt_out.video.i_height >= 720 )
+        {
+           /* Check that we don't overrun users qmin/qmax values */
+           if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" ) )
+           {
+              p_context->mb_qmin = p_context->qmin = 10;
+              p_context->mb_lmin = p_context->lmin = 10 * FF_QP2LAMBDA;
+           }
+
+           if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmax" ) )
+           {
+              p_context->mb_qmax = p_context->qmax = 42;
+              p_context->mb_lmax = p_context->lmax = 42 * FF_QP2LAMBDA;
+           }
+
+        } else {
+           if( !var_GetInteger( p_enc, ENC_CFG_PREFIX "qmin" ) )
+           {
+              p_context->mb_qmin = p_context->qmin = 1;
+              p_context->mb_lmin = p_context->lmin = FF_QP2LAMBDA;
+           }
+        }
 
 
 #if 0 /* enable when/if vp8 encoder is accepted in libavcodec */
@@ -733,6 +757,10 @@ int OpenEncoder( vlc_object_t *p_this )
         if( p_enc->fmt_out.i_extra )
         {
             p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
+            if ( p_enc->fmt_out.p_extra == NULL )
+            {
+                goto error;
+            }
             memcpy( p_enc->fmt_out.p_extra, p_context->extradata,
                     p_enc->fmt_out.i_extra );
         }
@@ -751,6 +779,10 @@ int OpenEncoder( vlc_object_t *p_this )
                                     p_context->frame_size :
                                     RAW_AUDIO_FRAME_SIZE;
         p_sys->p_buffer = malloc( p_sys->i_frame_size * p_sys->i_sample_bytes );
+        if ( p_sys->p_buffer == NULL )
+        {
+            goto error;
+        }
         p_enc->fmt_out.audio.i_blockalign = p_context->block_align;
         p_enc->fmt_out.audio.i_bitspersample = aout_BitsPerSample( vlc_fourcc_GetCodec( AUDIO_ES, p_enc->fmt_out.i_codec ) );
 
@@ -759,11 +791,21 @@ int OpenEncoder( vlc_object_t *p_this )
         else
             p_sys->i_buffer_out = p_sys->i_frame_size * p_sys->i_sample_bytes;
         p_sys->p_buffer_out = malloc( p_sys->i_buffer_out );
+        if ( p_sys->p_buffer_out == NULL )
+        {
+            goto error;
+        }
     }
 
     msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
 
     return VLC_SUCCESS;
+error:
+    free( p_enc->fmt_out.p_extra );
+    free( p_sys->p_buffer );
+    free( p_sys->p_buffer_out );
+    free( p_sys );
+    return VLC_ENOMEM;
 }
 
 /****************************************************************************
@@ -775,6 +817,24 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
     AVFrame frame;
     int i_out, 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.
+     */
+    if ( p_sys->p_buffer_out == NULL )
+    {
+        int bytesPerPixel = p_enc->fmt_out.video.i_bits_per_pixel ?
+                            p_enc->fmt_out.video.i_bits_per_pixel / 8 : 3;
+
+        p_sys->i_buffer_out = p_sys->p_context->height * p_sys->p_context->width
+            * bytesPerPixel + 200;  /* some room for potential headers (such as BMP) */
+
+        if( p_sys->i_buffer_out < FF_MIN_BUFFER_SIZE )
+            p_sys->i_buffer_out = FF_MIN_BUFFER_SIZE;
+        p_sys->p_buffer_out = malloc( p_sys->i_buffer_out );
+        if ( p_sys->p_buffer_out == NULL )
+            return NULL;
+    }
 
     memset( &frame, 0, sizeof( AVFrame ) );
     if( likely(p_pict) ) {