[vlc-devel] [PATCH] avcodec: added skip-frames option for encoder

Paweł Wegner pawel.wegner95 at gmail.com
Tue Jul 24 21:59:03 CEST 2018


Encoder will encode only one frame per timestamp. Since timestamps may be
inaccurate, skipping frames may render encoder's output nondeterministic.
Added an option which instructs to encode all frames which come out of avcodec.
---
 modules/codec/avcodec/avcodec.c |  3 +++
 modules/codec/avcodec/avcodec.h |  6 ++++++
 modules/codec/avcodec/encoder.c | 32 ++++++++++++++++++--------------
 3 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/modules/codec/avcodec/avcodec.c b/modules/codec/avcodec/avcodec.c
index 0e08c11fc6..d5df52871a 100644
--- a/modules/codec/avcodec/avcodec.c
+++ b/modules/codec/avcodec/avcodec.c
@@ -235,6 +235,9 @@ vlc_module_begin ()
                 ENC_PROFILE_TEXT, ENC_PROFILE_LONGTEXT, true )
 
     add_string( ENC_CFG_PREFIX "options", NULL, AV_OPTIONS_TEXT, AV_OPTIONS_LONGTEXT, true )
+
+    add_bool( ENC_CFG_PREFIX "skip-frames", true,
+              ENC_SKIP_FRAMES_TEXT, ENC_SKIP_FRAMES_LONGTEXT, true )
 #endif /* ENABLE_SOUT */
 
 #ifdef MERGE_FFMPEG
diff --git a/modules/codec/avcodec/avcodec.h b/modules/codec/avcodec/avcodec.h
index 52e522dc32..2900b86b3a 100644
--- a/modules/codec/avcodec/avcodec.h
+++ b/modules/codec/avcodec/avcodec.h
@@ -233,6 +233,12 @@ int ffmpeg_OpenCodec( decoder_t *p_dec, AVCodecContext *, const AVCodec * );
    "main, low, ssr (not supported),ltp, hev1, hev2 (default: low). " \
    "hev1 and hev2 are currently supported only with libfdk-aac enabled libavcodec" )
 
+#define ENC_SKIP_FRAMES_TEXT N_( "Skip frames" )
+#define ENC_SKIP_FRAMES_LONGTEXT N_( "Encoder will encode only one frame \
+    per timestamp. Since timestamps may be inaccurate, skipping frames may \
+    render encoder's output nondeterministic. Disable in order to encode all frames \
+    which come out of avcodec." )
+
 #ifndef AV_VERSION_INT
 #   define AV_VERSION_INT(a, b, c) ((a)<<16 | (b)<<8 | (c))
 #endif
diff --git a/modules/codec/avcodec/encoder.c b/modules/codec/avcodec/encoder.c
index a00439e939..7c1082c099 100644
--- a/modules/codec/avcodec/encoder.c
+++ b/modules/codec/avcodec/encoder.c
@@ -144,6 +144,7 @@ typedef struct
     int        i_quality; /* for VBR */
     float      f_lumi_masking, f_dark_masking, f_p_masking, f_border_masking;
     int        i_aac_profile; /* AAC profile to use.*/
+    bool       b_skip_frames;
 
     AVFrame    *frame;
 } encoder_sys_t;
@@ -193,7 +194,7 @@ static const char *const ppsz_enc_options[] = {
     "interlace", "interlace-me", "i-quant-factor", "noise-reduction", "mpeg4-matrix",
     "trellis", "qscale", "strict", "lumi-masking", "dark-masking",
     "p-masking", "border-masking",
-    "aac-profile", "options",
+    "aac-profile", "options", "skip-frames",
     NULL
 };
 
@@ -419,6 +420,7 @@ int InitVideoEnc( vlc_object_t *p_this )
     p_sys->f_rc_buffer_aggressivity = var_GetFloat( p_enc, ENC_CFG_PREFIX "rc-buffer-aggressivity" );
     p_sys->f_i_quant_factor = var_GetFloat( p_enc, ENC_CFG_PREFIX "i-quant-factor" );
     p_sys->b_mpeg4_matrix = var_GetBool( p_enc, ENC_CFG_PREFIX "mpeg4-matrix" );
+    p_sys->b_skip_frames = var_GetBool( p_enc,  ENC_CFG_PREFIX "skip-frames" );
 
     f_val = var_GetFloat( p_enc, ENC_CFG_PREFIX "qscale" );
 
@@ -1213,21 +1215,23 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
 
         if ( ( frame->pts != AV_NOPTS_VALUE ) && ( frame->pts != VLC_TICK_INVALID ) )
         {
-            if ( p_sys->i_last_pts == frame->pts )
+            if ( p_sys->b_skip_frames )
             {
-                msg_Warn( p_enc, "almost fed libavcodec with two frames with "
-                          "the same PTS (%"PRId64 ")", frame->pts );
-                return NULL;
-            }
-            else if ( p_sys->i_last_pts > frame->pts )
-            {
-                msg_Warn( p_enc, "almost fed libavcodec with a frame in the "
-                         "past (current: %"PRId64 ", last: %"PRId64")",
-                         frame->pts, p_sys->i_last_pts );
-                return NULL;
+                if ( p_sys->i_last_pts == frame->pts )
+                {
+                    msg_Warn( p_enc, "almost fed libavcodec with two frames with "
+                            "the same PTS (%"PRId64 ")", frame->pts );
+                    return NULL;
+                }
+                else if ( p_sys->i_last_pts > frame->pts )
+                {
+                    msg_Warn( p_enc, "almost fed libavcodec with a frame in the "
+                            "past (current: %"PRId64 ", last: %"PRId64")",
+                            frame->pts, p_sys->i_last_pts );
+                    return NULL;
+                }
             }
-            else
-                p_sys->i_last_pts = frame->pts;
+            p_sys->i_last_pts = frame->pts;
         }
 
         frame->quality = p_sys->i_quality;
-- 
2.17.1



More information about the vlc-devel mailing list