<html dir="ltr"><head></head><body style="text-align:left; direction:ltr;"><div>On Fri, 2018-12-07 at 18:12 +0530, Shaleen Jain wrote:</div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><pre>---</pre><pre> modules/stream_out/Makefile.am         |   2 +</pre><pre> modules/stream_out/chromecast/cast.cpp | 278 +-----------------------</pre><pre> modules/stream_out/renderer_common.cpp | 281 +++++++++++++++++++++++++</pre><pre> modules/stream_out/renderer_common.hpp |  85 ++++++++</pre><pre> 4 files changed, 375 insertions(+), 271 deletions(-)</pre><pre> create mode 100644 modules/stream_out/renderer_common.cpp</pre><pre> create mode 100644 modules/stream_out/renderer_common.hpp</pre><pre><br></pre><pre>diff --git a/modules/stream_out/Makefile.am b/modules/stream_out/Makefile.am</pre><pre>index 6bfc38fff2..dfb262c467 100644</pre><pre>--- a/modules/stream_out/Makefile.am</pre><pre>+++ b/modules/stream_out/Makefile.am</pre><pre>@@ -107,6 +107,8 @@ libdemux_chromecast_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -Istream_out/chromecast</pre><pre> </pre><pre> libstream_out_chromecast_plugin_la_SOURCES = stream_out/chromecast/cast.cpp stream_out/chromecast/chromecast.h \</pre><pre>                                              stream_out/chromecast/cast_channel.proto \</pre><pre>+                                             stream_out/renderer_common.hpp \</pre><pre>+                                             stream_out/renderer_common.cpp \</pre><pre>                                              stream_out/chromecast/chromecast_common.h stream_out/chromecast/chromecast_ctrl.cpp \</pre><pre>                                              misc/webservices/json.h misc/webservices/json.c stream_out/chromecast/chromecast_communication.cpp</pre><pre> nodist_libstream_out_chromecast_plugin_la_SOURCES = stream_out/chromecast/cast_channel.pb.cc</pre><pre>diff --git a/modules/stream_out/chromecast/cast.cpp b/modules/stream_out/chromecast/cast.cpp</pre><pre>index 7026eb1a95..329afe5d54 100644</pre><pre>--- a/modules/stream_out/chromecast/cast.cpp</pre><pre>+++ b/modules/stream_out/chromecast/cast.cpp</pre><pre>@@ -30,6 +30,7 @@</pre><pre> # include "config.h"</pre><pre> #endif</pre><pre> </pre><pre>+#include "../renderer_common.hpp"</pre><pre> #include "chromecast.h"</pre><pre> #include <vlc_dialog.h></pre><pre> </pre><pre>@@ -157,10 +158,7 @@ struct sout_stream_sys_t</pre><pre>     unsigned int                       spu_streams_count;</pre><pre> </pre><pre> private:</pre><pre>-    std::string GetVencOption( sout_stream_t *, vlc_fourcc_t *,</pre><pre>-                               const video_format_t *, int );</pre><pre>     std::string GetAcodecOption( sout_stream_t *, vlc_fourcc_t *, const audio_format_t *, int );</pre><pre>-    std::string GetVcodecOption( sout_stream_t *, vlc_fourcc_t *, const video_format_t *, int );</pre><pre>     bool UpdateOutput( sout_stream_t * );</pre><pre> };</pre><pre> </pre><pre>@@ -199,39 +197,6 @@ static const char *const ppsz_sout_options[] = {</pre><pre> #define HTTP_PORT_TEXT N_("HTTP port")</pre><pre> #define HTTP_PORT_LONGTEXT N_("This sets the HTTP port of the local server " \</pre><pre>                               "used to stream the media to the Chromecast.")</pre><pre>-#define PERF_TEXT N_( "Performance warning" )</pre><pre>-#define PERF_LONGTEXT N_( "Display a performance warning when transcoding" )</pre><pre>-#define AUDIO_PASSTHROUGH_TEXT N_( "Enable Audio passthrough" )</pre><pre>-#define AUDIO_PASSTHROUGH_LONGTEXT N_( "Disable if your receiver does not support Dolby®." )</pre><pre>-</pre><pre>-enum {</pre><pre>-    CONVERSION_QUALITY_HIGH = 0,</pre><pre>-    CONVERSION_QUALITY_MEDIUM = 1,</pre><pre>-    CONVERSION_QUALITY_LOW = 2,</pre><pre>-    CONVERSION_QUALITY_LOWCPU = 3,</pre><pre>-};</pre><pre>-</pre><pre>-#if defined (__ANDROID__) || defined (__arm__) || (defined (TARGET_OS_IPHONE) && TARGET_OS_IPHONE)</pre><pre>-# define CONVERSION_QUALITY_DEFAULT CONVERSION_QUALITY_LOW</pre><pre>-#else</pre><pre>-# define CONVERSION_QUALITY_DEFAULT CONVERSION_QUALITY_MEDIUM</pre><pre>-#endif</pre><pre>-</pre><pre>-static const int conversion_quality_list[] = {</pre><pre>-    CONVERSION_QUALITY_HIGH,</pre><pre>-    CONVERSION_QUALITY_MEDIUM,</pre><pre>-    CONVERSION_QUALITY_LOW,</pre><pre>-    CONVERSION_QUALITY_LOWCPU,</pre><pre>-};</pre><pre>-static const char *const conversion_quality_list_text[] = {</pre><pre>-    N_( "High (high quality and high bandwidth)" ),</pre><pre>-    N_( "Medium (medium quality and medium bandwidth)" ),</pre><pre>-    N_( "Low (low quality and low bandwidth)" ),</pre><pre>-    N_( "Low CPU (low quality but high bandwidth)" ),</pre><pre>-};</pre><pre>-</pre><pre>-#define CONVERSION_QUALITY_TEXT N_( "Conversion quality" )</pre><pre>-#define CONVERSION_QUALITY_LONGTEXT N_( "Change this option to increase conversion speed or quality." )</pre><pre> </pre><pre> #define IP_ADDR_TEXT N_("IP Address")</pre><pre> #define IP_ADDR_LONGTEXT N_("IP Address of the Chromecast.")</pre><pre>@@ -263,12 +228,7 @@ vlc_module_begin ()</pre><pre>     add_integer(SOUT_CFG_PREFIX "http-port", HTTP_PORT, HTTP_PORT_TEXT, HTTP_PORT_LONGTEXT, false)</pre><pre>     add_obsolete_string(SOUT_CFG_PREFIX "mux")</pre><pre>     add_obsolete_string(SOUT_CFG_PREFIX "mime")</pre><pre>-    add_integer(SOUT_CFG_PREFIX "show-perf-warning", 1, PERF_TEXT, PERF_LONGTEXT, true )</pre><pre>-        change_private()</pre><pre>-    add_bool(SOUT_CFG_PREFIX "audio-passthrough", false, AUDIO_PASSTHROUGH_TEXT, AUDIO_PASSTHROUGH_LONGTEXT, false )</pre><pre>-    add_integer(SOUT_CFG_PREFIX "conversion-quality", CONVERSION_QUALITY_DEFAULT,</pre><pre>-                CONVERSION_QUALITY_TEXT, CONVERSION_QUALITY_LONGTEXT, false );</pre><pre>-        change_integer_list(conversion_quality_list, conversion_quality_list_text)</pre><pre>+    add_renderer_opts(SOUT_CFG_PREFIX)</pre><pre> </pre><pre>     add_submodule()</pre><pre>         /* sout proxy that start the cc input when all streams are loaded */</pre><pre>@@ -927,231 +887,6 @@ bool sout_stream_sys_t::transcodingCanFallback() const</pre><pre>     return transcoding_state != (TRANSCODING_VIDEO|TRANSCODING_AUDIO);</pre><pre> }</pre><pre> </pre><pre>-static std::string GetVencVPXOption( sout_stream_t * /* p_stream */,</pre><pre>-                                      const video_format_t * /* p_vid */,</pre><pre>-                                      int /* i_quality */ )</pre><pre>-{</pre><pre>-    return "venc=vpx{quality-mode=1}";</pre><pre>-}</pre><pre>-</pre><pre>-static std::string GetVencQSVH264Option( sout_stream_t * /* p_stream */,</pre><pre>-                                         const video_format_t * /* p_vid */,</pre><pre>-                                         int i_quality )</pre><pre>-{</pre><pre>-    std::stringstream ssout;</pre><pre>-    static const char video_target_usage_quality[]  = "quality";</pre><pre>-    static const char video_target_usage_balanced[] = "balanced";</pre><pre>-    static const char video_target_usage_speed[]    = "speed";</pre><pre>-    static const char video_bitrate_high[] = "vb=8000000";</pre><pre>-    static const char video_bitrate_low[]  = "vb=3000000";</pre><pre>-    const char *psz_video_target_usage;</pre><pre>-    const char *psz_video_bitrate;</pre><pre>-</pre><pre>-    switch ( i_quality )</pre><pre>-    {</pre><pre>-        case CONVERSION_QUALITY_HIGH:</pre><pre>-            psz_video_target_usage = video_target_usage_quality;</pre><pre>-            psz_video_bitrate = video_bitrate_high;</pre><pre>-            break;</pre><pre>-        case CONVERSION_QUALITY_MEDIUM:</pre><pre>-            psz_video_target_usage = video_target_usage_balanced;</pre><pre>-            psz_video_bitrate = video_bitrate_high;</pre><pre>-            break;</pre><pre>-        case CONVERSION_QUALITY_LOW:</pre><pre>-            psz_video_target_usage = video_target_usage_balanced;</pre><pre>-            psz_video_bitrate = video_bitrate_low;</pre><pre>-            break;</pre><pre>-        default:</pre><pre>-        case CONVERSION_QUALITY_LOWCPU:</pre><pre>-            psz_video_target_usage = video_target_usage_speed;</pre><pre>-            psz_video_bitrate = video_bitrate_low;</pre><pre>-            break;</pre><pre>-    }</pre><pre>-</pre><pre>-    ssout << "venc=qsv{target-usage=" << psz_video_target_usage <<</pre><pre>-             "}," << psz_video_bitrate;</pre><pre>-    return ssout.str();</pre><pre>-}</pre><pre>-</pre><pre>-static std::string GetVencX264Option( sout_stream_t * /* p_stream */,</pre><pre>-                                      const video_format_t *p_vid,</pre><pre>-                                      int i_quality )</pre><pre>-{</pre><pre>-    std::stringstream ssout;</pre><pre>-    static const char video_x264_preset_veryfast[] = "veryfast";</pre><pre>-    static const char video_x264_preset_ultrafast[] = "ultrafast";</pre><pre>-    const char *psz_video_x264_preset;</pre><pre>-    unsigned i_video_x264_crf_hd, i_video_x264_crf_720p;</pre><pre>-</pre><pre>-    switch ( i_quality )</pre><pre>-    {</pre><pre>-        case CONVERSION_QUALITY_HIGH:</pre><pre>-            i_video_x264_crf_hd = i_video_x264_crf_720p = 21;</pre><pre>-            psz_video_x264_preset = video_x264_preset_veryfast;</pre><pre>-            break;</pre><pre>-        case CONVERSION_QUALITY_MEDIUM:</pre><pre>-            i_video_x264_crf_hd = 23;</pre><pre>-            i_video_x264_crf_720p = 21;</pre><pre>-            psz_video_x264_preset = video_x264_preset_veryfast;</pre><pre>-            break;</pre><pre>-        case CONVERSION_QUALITY_LOW:</pre><pre>-            i_video_x264_crf_hd = i_video_x264_crf_720p = 23;</pre><pre>-            psz_video_x264_preset = video_x264_preset_veryfast;</pre><pre>-            break;</pre><pre>-        default:</pre><pre>-        case CONVERSION_QUALITY_LOWCPU:</pre><pre>-            i_video_x264_crf_hd = i_video_x264_crf_720p = 23;</pre><pre>-            psz_video_x264_preset = video_x264_preset_ultrafast;</pre><pre>-            break;</pre><pre>-    }</pre><pre>-</pre><pre>-    const bool b_hdres = p_vid->i_height == 0 || p_vid->i_height >= 800;</pre><pre>-    unsigned i_video_x264_crf = b_hdres ? i_video_x264_crf_hd : i_video_x264_crf_720p;</pre><pre>-</pre><pre>-    ssout << "venc=x264{preset=" << psz_video_x264_preset</pre><pre>-          << ",crf=" << i_video_x264_crf << "}";</pre><pre>-    return ssout.str();</pre><pre>-}</pre><pre>-</pre><pre>-#ifdef __APPLE__</pre><pre>-static std::string GetVencAvcodecVTOption( sout_stream_t * /* p_stream */,</pre><pre>-                                           const video_format_t * p_vid,</pre><pre>-                                           int i_quality )</pre><pre>-{</pre><pre>-    std::stringstream ssout;</pre><pre>-    ssout << "venc=avcodec{codec=h264_videotoolbox,options{realtime=1}}";</pre><pre>-    switch( i_quality )</pre><pre>-    {</pre><pre>-        /* Here, performances issues won't come from videotoolbox but from</pre><pre>-         * some old chromecast devices */</pre><pre>-</pre><pre>-        case CONVERSION_QUALITY_HIGH:</pre><pre>-            break;</pre><pre>-        case CONVERSION_QUALITY_MEDIUM:</pre><pre>-            ssout << ",vb=8000000";</pre><pre>-            break;</pre><pre>-        case CONVERSION_QUALITY_LOW:</pre><pre>-        case CONVERSION_QUALITY_LOWCPU:</pre><pre>-            ssout << ",vb=3000000";</pre><pre>-            break;</pre><pre>-    }</pre><pre>-</pre><pre>-    return ssout.str();</pre><pre>-}</pre><pre>-#endif</pre><pre>-</pre><pre>-static struct</pre><pre>-{</pre><pre>-    vlc_fourcc_t fcc;</pre><pre>-    std::string (*get_opt)( sout_stream_t *, const video_format_t *, int);</pre><pre>-} venc_opt_list[] = {</pre><pre>-#ifdef __APPLE__</pre><pre>-    { .fcc = VLC_CODEC_H264, .get_opt = GetVencAvcodecVTOption },</pre><pre>-#endif</pre><pre>-    { .fcc = VLC_CODEC_H264, .get_opt = GetVencQSVH264Option },</pre><pre>-    { .fcc = VLC_CODEC_H264, .get_opt = GetVencX264Option },</pre><pre>-    { .fcc = VLC_CODEC_VP8,  .get_opt = GetVencVPXOption },</pre><pre>-    { .fcc = VLC_CODEC_H264, .get_opt = NULL },</pre><pre>-};</pre><pre>-</pre><pre>-std::string</pre><pre>-sout_stream_sys_t::GetVencOption( sout_stream_t *p_stream, vlc_fourcc_t *p_codec_video,</pre><pre>-                                  const video_format_t *p_vid, int i_quality )</pre><pre>-{</pre><pre>-    for( size_t i = (venc_opt_idx == -1 ? 0 : venc_opt_idx);</pre><pre>-         i < ARRAY_SIZE(venc_opt_list); ++i )</pre><pre>-    {</pre><pre>-        std::stringstream ssout, ssvenc;</pre><pre>-        char fourcc[5];</pre><pre>-        ssvenc << "vcodec=";</pre><pre>-        vlc_fourcc_to_char( venc_opt_list[i].fcc, fourcc );</pre><pre>-        fourcc[4] = '\0';</pre><pre>-        ssvenc << fourcc << ',';</pre><pre>-</pre><pre>-        if( venc_opt_list[i].get_opt != NULL )</pre><pre>-            ssvenc << venc_opt_list[i].get_opt( p_stream, p_vid, i_quality ) << ',';</pre><pre>-</pre><pre>-        if( venc_opt_list[i].get_opt == NULL</pre><pre>-         || ( venc_opt_idx != -1 && (unsigned) venc_opt_idx == i) )</pre><pre>-        {</pre><pre>-            venc_opt_idx = i;</pre><pre>-            *p_codec_video = venc_opt_list[i].fcc;</pre><pre>-            return ssvenc.str();</pre><pre>-        }</pre><pre>-</pre><pre>-        /* Test if a module can encode with the specified options / fmt_video. */</pre><pre>-        ssout << "transcode{" << ssvenc.str() << "}:dummy";</pre><pre>-</pre><pre>-        sout_stream_t *p_sout_test =</pre><pre>-            sout_StreamChainNew( p_stream->p_sout, ssout.str().c_str(), NULL, NULL );</pre><pre>-</pre><pre>-        if( p_sout_test != NULL )</pre><pre>-        {</pre><pre>-            p_sout_test->obj.flags |= OBJECT_FLAGS_QUIET|OBJECT_FLAGS_NOINTERACT;</pre><pre>-</pre><pre>-            es_format_t fmt;</pre><pre>-            es_format_InitFromVideo( &fmt, p_vid );</pre><pre>-            fmt.i_codec = fmt.video.i_chroma = VLC_CODEC_I420;</pre><pre>-</pre><pre>-            /* Test the maximum size/fps we will encode */</pre><pre>-            fmt.video.i_visible_width = fmt.video.i_width = 1920;</pre><pre>-            fmt.video.i_visible_height = fmt.video.i_height = 1080;</pre><pre>-            fmt.video.i_frame_rate = 30;</pre><pre>-            fmt.video.i_frame_rate_base = 1;</pre><pre>-</pre><pre>-            void *id = sout_StreamIdAdd( p_sout_test, &fmt );</pre><pre>-</pre><pre>-            es_format_Clean( &fmt );</pre><pre>-            const bool success = id != NULL;</pre><pre>-</pre><pre>-            if( id )</pre><pre>-                sout_StreamIdDel( p_sout_test, id );</pre><pre>-            sout_StreamChainDelete( p_sout_test, NULL );</pre><pre>-</pre><pre>-            if( success )</pre><pre>-            {</pre><pre>-                venc_opt_idx = i;</pre><pre>-                *p_codec_video = venc_opt_list[i].fcc;</pre><pre>-                return ssvenc.str();</pre><pre>-            }</pre><pre>-        }</pre><pre>-    }</pre><pre>-    vlc_assert_unreachable();</pre><pre>-}</pre><pre>-</pre><pre>-std::string</pre><pre>-sout_stream_sys_t::GetVcodecOption( sout_stream_t *p_stream, vlc_fourcc_t *p_codec_video,</pre><pre>-                                    const video_format_t *p_vid, int i_quality )</pre><pre>-{</pre><pre>-    std::stringstream ssout;</pre><pre>-    static const char video_maxres_hd[] = "maxwidth=1920,maxheight=1080";</pre><pre>-    static const char video_maxres_720p[] = "maxwidth=1280,maxheight=720";</pre><pre>-</pre><pre>-    ssout << GetVencOption( p_stream, p_codec_video, p_vid, i_quality );</pre><pre>-</pre><pre>-    switch ( i_quality )</pre><pre>-    {</pre><pre>-        case CONVERSION_QUALITY_HIGH:</pre><pre>-        case CONVERSION_QUALITY_MEDIUM:</pre><pre>-            ssout << ( ( p_vid->i_width > 1920 ) ? "width=1920," : "" ) << video_maxres_hd << ',';</pre><pre>-            break;</pre><pre>-        default:</pre><pre>-            ssout << ( ( p_vid->i_width > 1280 ) ? "width=1280," : "" ) << video_maxres_720p << ',';</pre><pre>-    }</pre><pre>-</pre><pre>-    if( p_vid->i_frame_rate == 0 || p_vid->i_frame_rate_base == 0</pre><pre>-     || ( p_vid->i_frame_rate / p_vid->i_frame_rate_base ) > 30 )</pre><pre>-    {</pre><pre>-        /* Even force 24fps if the frame rate is unknown */</pre><pre>-        msg_Warn( p_stream, "lowering frame rate to 24fps" );</pre><pre>-        ssout << "fps=24,";</pre><pre>-    }</pre><pre>-</pre><pre>-    msg_Dbg( p_stream, "Converting video to %.4s", (const char*)p_codec_video );</pre><pre>-</pre><pre>-    return ssout.str();</pre><pre>-}</pre><pre>-</pre><pre> std::string</pre><pre> sout_stream_sys_t::GetAcodecOption( sout_stream_t *p_stream, vlc_fourcc_t *p_codec_audio,</pre><pre>                                     const audio_format_t *p_aud, int i_quality )</pre><pre>@@ -1291,7 +1026,7 @@ bool sout_stream_sys_t::UpdateOutput( sout_stream_t *p_stream )</pre><pre>     if ( !canRemux )</pre><pre>     {</pre><pre>         if ( !perf_warning_shown && i_codec_video == 0 && p_original_video</pre><pre>-          && var_InheritInteger( p_stream, SOUT_CFG_PREFIX "show-perf-warning" ) )</pre><pre>+          && var_InheritInteger( p_stream, RENDERER_CFG_PREFIX "show-perf-warning" ) )</pre><pre>         {</pre><pre>             int res = vlc_dialog_wait_question( p_stream,</pre><pre>                           VLC_DIALOG_QUESTION_WARNING,</pre><pre>@@ -1304,7 +1039,7 @@ bool sout_stream_sys_t::UpdateOutput( sout_stream_t *p_stream )</pre><pre>                  return false;</pre><pre>             perf_warning_shown = true;</pre><pre>             if ( res == 2 )</pre><pre>-                config_PutInt(SOUT_CFG_PREFIX "show-perf-warning", 0 );</pre><pre>+                config_PutInt(RENDERER_CFG_PREFIX "show-perf-warning", 0 );</pre><pre>         }</pre><pre> </pre><pre>         const int i_quality = var_InheritInteger( p_stream, SOUT_CFG_PREFIX "conversion-quality" );</pre><pre>@@ -1319,8 +1054,9 @@ bool sout_stream_sys_t::UpdateOutput( sout_stream_t *p_stream )</pre><pre>         }</pre><pre>         if ( i_codec_video == 0 && p_original_video )</pre><pre>         {</pre><pre>-            ssout << GetVcodecOption( p_stream, &i_codec_video,</pre><pre>-                                      &p_original_video->video, i_quality );</pre><pre>+            ssout << vlc_sout_renderer_GetVcodecOption( p_stream,</pre><pre>+                                        { VLC_CODEC_H264, VLC_CODEC_VP9 },</pre></blockquote><div><br></div><div>this will be { VLC_CODEC_H264, VLC_CODEC_VP8 },</div><div><br></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><pre>+                                        &p_original_video->video, i_quality );</pre><pre>             new_transcoding_state |= TRANSCODING_VIDEO;</pre><pre>         }</pre><pre>         if ( p_original_spu )</pre><pre>diff --git a/modules/stream_out/renderer_common.cpp b/modules/stream_out/renderer_common.cpp</pre><pre>new file mode 100644</pre><pre>index 0000000000..2f5d5d06e2</pre><pre>--- /dev/null</pre><pre>+++ b/modules/stream_out/renderer_common.cpp</pre><pre>@@ -0,0 +1,281 @@</pre><pre>+/*****************************************************************************</pre><pre>+ * renderer_common.cpp : renderer helper functions</pre><pre>+ *****************************************************************************</pre><pre>+ * Copyright © 2014-2018 VideoLAN</pre><pre>+ *</pre><pre>+ * Authors: Adrien Maglo <</pre><a href="mailto:magsoft@videolan.org"><pre>magsoft@videolan.org</pre></a><pre>></pre><pre>+ *          Jean-Baptiste Kempf <</pre><a href="mailto:jb@videolan.org"><pre>jb@videolan.org</pre></a><pre>></pre><pre>+ *          Steve Lhomme <</pre><a href="mailto:robux4@videolabs.io"><pre>robux4@videolabs.io</pre></a><pre>></pre><pre>+ *          Shaleen Jain <</pre><a href="mailto:shaleen@jain.sh"><pre>shaleen@jain.sh</pre></a><pre>></pre><pre>+ *</pre><pre>+ * This program is free software; you can redistribute it and/or modify it</pre><pre>+ * under the terms of the GNU Lesser General Public License as published by</pre><pre>+ * the Free Software Foundation; either version 2.1 of the License, or</pre><pre>+ * (at your option) any later version.</pre><pre>+ *</pre><pre>+ * This program is distributed in the hope that it will be useful,</pre><pre>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</pre><pre>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</pre><pre>+ * GNU Lesser General Public License for more details.</pre><pre>+ *</pre><pre>+ * You should have received a copy of the GNU Lesser General Public License</pre><pre>+ * along with this program; if not, write to the Free Software Foundation,</pre><pre>+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.</pre><pre>+ *****************************************************************************/</pre><pre>+</pre><pre>+#ifdef HAVE_CONFIG_H</pre><pre>+# include "config.h"</pre><pre>+#endif</pre><pre>+</pre><pre>+#include <assert.h></pre><pre>+#include <map></pre><pre>+#include <sstream></pre><pre>+</pre><pre>+#include "renderer_common.hpp"</pre><pre>+</pre><pre>+std::string</pre><pre>+GetVencOption( sout_stream_t *p_stream, vlc_fourcc_t *p_codec_video,</pre><pre>+        const video_format_t *p_vid, int i_quality );</pre><pre>+</pre><pre>+std::string GetVencVPXOption( sout_stream_t * /* p_stream */,</pre><pre>+                                      const video_format_t * /* p_vid */,</pre><pre>+                                      int /* i_quality */ );</pre><pre>+</pre><pre>+std::string GetVencQSVH264Option( sout_stream_t * /* p_stream */,</pre><pre>+                                         const video_format_t * /* p_vid */,</pre><pre>+                                         int i_quality );</pre><pre>+</pre><pre>+std::string GetVencX264Option( sout_stream_t * /* p_stream */,</pre><pre>+                                      const video_format_t *p_vid,</pre><pre>+                                      int i_quality );</pre><pre>+#ifdef __APPLE__</pre><pre>+std::string GetVencAvcodecVTOption( sout_stream_t * /* p_stream */,</pre><pre>+                                           const video_format_t * p_vid,</pre><pre>+                                           int i_quality );</pre><pre>+#endif</pre><pre>+</pre><pre>+struct venc_options</pre><pre>+{</pre><pre>+    std::string (*get_opt)( sout_stream_t *, const video_format_t *, int);</pre><pre>+};</pre><pre>+</pre><pre>+std::map<vlc_fourcc_t, std::vector<venc_options>> opts = {</pre><pre>+    {</pre><pre>+        VLC_CODEC_H264,</pre><pre>+        {</pre><pre>+        #ifdef __APPLE__</pre><pre>+            { GetVencAvcodecVTOption },</pre><pre>+        #endif</pre><pre>+            { GetVencQSVH264Option },</pre><pre>+            { GetVencX264Option },</pre><pre>+            { NULL },</pre><pre>+        }</pre><pre>+    },</pre><pre>+    {</pre><pre>+        VLC_CODEC_VP8,</pre><pre>+        {</pre><pre>+            { GetVencVPXOption }</pre><pre>+        }</pre><pre>+    },</pre><pre>+};</pre><pre>+</pre><pre>+std::string</pre><pre>+GetVencOption( sout_stream_t *p_stream, std::vector<vlc_fourcc_t> codecs,</pre><pre>+        const video_format_t *p_vid, int i_quality )</pre><pre>+{</pre><pre>+    for (vlc_fourcc_t codec : codecs) {</pre><pre>+        for (venc_options venc_opt : opts.find(codec)->second)</pre><pre>+        {</pre><pre>+            std::stringstream ssout, ssvenc;</pre><pre>+            char fourcc[5];</pre><pre>+            ssvenc << "vcodec=";</pre><pre>+            vlc_fourcc_to_char( codec, fourcc );</pre><pre>+            fourcc[4] = '\0';</pre><pre>+            ssvenc << fourcc << ',';</pre><pre>+</pre><pre>+            if( venc_opt.get_opt != NULL )</pre><pre>+                ssvenc << venc_opt.get_opt( p_stream, p_vid, i_quality ) << ',';</pre><pre>+</pre><pre>+            /* Test if a module can encode with the specified options / fmt_video. */</pre><pre>+            ssout << "transcode{" << ssvenc.str() << "}:dummy";</pre><pre>+</pre><pre>+            sout_stream_t *p_sout_test =</pre><pre>+                sout_StreamChainNew( p_stream->p_sout, ssout.str().c_str(), NULL, NULL );</pre><pre>+</pre><pre>+            if( p_sout_test != NULL )</pre><pre>+            {</pre><pre>+                p_sout_test->obj.flags |= OBJECT_FLAGS_QUIET|OBJECT_FLAGS_NOINTERACT;</pre><pre>+</pre><pre>+                es_format_t fmt;</pre><pre>+                es_format_InitFromVideo( &fmt, p_vid );</pre><pre>+                fmt.i_codec = fmt.video.i_chroma = VLC_CODEC_I420;</pre><pre>+</pre><pre>+                /* Test the maximum size/fps we will encode */</pre><pre>+                fmt.video.i_visible_width = fmt.video.i_width = 1920;</pre><pre>+                fmt.video.i_visible_height = fmt.video.i_height = 1080;</pre><pre>+                fmt.video.i_frame_rate = 30;</pre><pre>+                fmt.video.i_frame_rate_base = 1;</pre><pre>+</pre><pre>+                void *id = sout_StreamIdAdd( p_sout_test, &fmt );</pre><pre>+</pre><pre>+                es_format_Clean( &fmt );</pre><pre>+                const bool success = id != NULL;</pre><pre>+</pre><pre>+                if( id )</pre><pre>+                    sout_StreamIdDel( p_sout_test, id );</pre><pre>+                sout_StreamChainDelete( p_sout_test, NULL );</pre><pre>+</pre><pre>+                if( success )</pre><pre>+                {</pre><pre>+                    msg_Dbg( p_stream, "Converting video to %.4s", (const char*)&codec );</pre><pre>+                    return ssvenc.str();</pre><pre>+                }</pre><pre>+            }</pre><pre>+        }</pre><pre>+    }</pre><pre>+    vlc_assert_unreachable();</pre><pre>+}</pre><pre>+</pre><pre>+std::string</pre><pre>+vlc_sout_renderer_GetVcodecOption(sout_stream_t *p_stream,</pre><pre>+        std::vector<vlc_fourcc_t> codecs, const video_format_t *p_vid, int i_quality)</pre><pre>+{</pre><pre>+    std::stringstream ssout;</pre><pre>+    static const char video_maxres_hd[] = "maxwidth=1920,maxheight=1080";</pre><pre>+    static const char video_maxres_720p[] = "maxwidth=1280,maxheight=720";</pre><pre>+</pre><pre>+    ssout << GetVencOption( p_stream, codecs, p_vid, i_quality );</pre><pre>+</pre><pre>+    switch ( i_quality )</pre><pre>+    {</pre><pre>+        case CONVERSION_QUALITY_HIGH:</pre><pre>+        case CONVERSION_QUALITY_MEDIUM:</pre><pre>+            ssout << ( ( p_vid->i_width > 1920 ) ? "width=1920," : "" ) << video_maxres_hd << ',';</pre><pre>+            break;</pre><pre>+        default:</pre><pre>+            ssout << ( ( p_vid->i_width > 1280 ) ? "width=1280," : "" ) << video_maxres_720p << ',';</pre><pre>+    }</pre><pre>+</pre><pre>+    if( p_vid->i_frame_rate == 0 || p_vid->i_frame_rate_base == 0</pre><pre>+     || ( p_vid->i_frame_rate / p_vid->i_frame_rate_base ) > 30 )</pre><pre>+    {</pre><pre>+        /* Even force 24fps if the frame rate is unknown */</pre><pre>+        msg_Warn( p_stream, "lowering frame rate to 24fps" );</pre><pre>+        ssout << "fps=24,";</pre><pre>+    }</pre><pre>+</pre><pre>+    return ssout.str();</pre><pre>+}</pre><pre>+</pre><pre>+std::string GetVencVPXOption( sout_stream_t * /* p_stream */,</pre><pre>+                                      const video_format_t * /* p_vid */,</pre><pre>+                                      int /* i_quality */ )</pre><pre>+{</pre><pre>+    return "venc=vpx{quality-mode=1}";</pre><pre>+}</pre><pre>+</pre><pre>+std::string GetVencQSVH264Option( sout_stream_t * /* p_stream */,</pre><pre>+                                         const video_format_t * /* p_vid */,</pre><pre>+                                         int i_quality )</pre><pre>+{</pre><pre>+    std::stringstream ssout;</pre><pre>+    static const char video_target_usage_quality[]  = "quality";</pre><pre>+    static const char video_target_usage_balanced[] = "balanced";</pre><pre>+    static const char video_target_usage_speed[]    = "speed";</pre><pre>+    static const char video_bitrate_high[] = "vb=8000000";</pre><pre>+    static const char video_bitrate_low[]  = "vb=3000000";</pre><pre>+    const char *psz_video_target_usage;</pre><pre>+    const char *psz_video_bitrate;</pre><pre>+</pre><pre>+    switch ( i_quality )</pre><pre>+    {</pre><pre>+        case CONVERSION_QUALITY_HIGH:</pre><pre>+            psz_video_target_usage = video_target_usage_quality;</pre><pre>+            psz_video_bitrate = video_bitrate_high;</pre><pre>+            break;</pre><pre>+        case CONVERSION_QUALITY_MEDIUM:</pre><pre>+            psz_video_target_usage = video_target_usage_balanced;</pre><pre>+            psz_video_bitrate = video_bitrate_high;</pre><pre>+            break;</pre><pre>+        case CONVERSION_QUALITY_LOW:</pre><pre>+            psz_video_target_usage = video_target_usage_balanced;</pre><pre>+            psz_video_bitrate = video_bitrate_low;</pre><pre>+            break;</pre><pre>+        default:</pre><pre>+        case CONVERSION_QUALITY_LOWCPU:</pre><pre>+            psz_video_target_usage = video_target_usage_speed;</pre><pre>+            psz_video_bitrate = video_bitrate_low;</pre><pre>+            break;</pre><pre>+    }</pre><pre>+</pre><pre>+    ssout << "venc=qsv{target-usage=" << psz_video_target_usage <<</pre><pre>+             "}," << psz_video_bitrate;</pre><pre>+    return ssout.str();</pre><pre>+}</pre><pre>+</pre><pre>+std::string GetVencX264Option( sout_stream_t * /* p_stream */,</pre><pre>+                                      const video_format_t *p_vid,</pre><pre>+                                      int i_quality )</pre><pre>+{</pre><pre>+    std::stringstream ssout;</pre><pre>+    static const char video_x264_preset_veryfast[] = "veryfast";</pre><pre>+    static const char video_x264_preset_ultrafast[] = "ultrafast";</pre><pre>+    const char *psz_video_x264_preset;</pre><pre>+    unsigned i_video_x264_crf_hd, i_video_x264_crf_720p;</pre><pre>+</pre><pre>+    switch ( i_quality )</pre><pre>+    {</pre><pre>+        case CONVERSION_QUALITY_HIGH:</pre><pre>+            i_video_x264_crf_hd = i_video_x264_crf_720p = 21;</pre><pre>+            psz_video_x264_preset = video_x264_preset_veryfast;</pre><pre>+            break;</pre><pre>+        case CONVERSION_QUALITY_MEDIUM:</pre><pre>+            i_video_x264_crf_hd = 23;</pre><pre>+            i_video_x264_crf_720p = 21;</pre><pre>+            psz_video_x264_preset = video_x264_preset_veryfast;</pre><pre>+            break;</pre><pre>+        case CONVERSION_QUALITY_LOW:</pre><pre>+            i_video_x264_crf_hd = i_video_x264_crf_720p = 23;</pre><pre>+            psz_video_x264_preset = video_x264_preset_veryfast;</pre><pre>+            break;</pre><pre>+        default:</pre><pre>+        case CONVERSION_QUALITY_LOWCPU:</pre><pre>+            i_video_x264_crf_hd = i_video_x264_crf_720p = 23;</pre><pre>+            psz_video_x264_preset = video_x264_preset_ultrafast;</pre><pre>+            break;</pre><pre>+    }</pre><pre>+</pre><pre>+    const bool b_hdres = p_vid->i_height == 0 || p_vid->i_height >= 800;</pre><pre>+    unsigned i_video_x264_crf = b_hdres ? i_video_x264_crf_hd : i_video_x264_crf_720p;</pre><pre>+</pre><pre>+    ssout << "venc=x264{preset=" << psz_video_x264_preset</pre><pre>+          << ",crf=" << i_video_x264_crf << "}";</pre><pre>+    return ssout.str();</pre><pre>+}</pre><pre>+</pre><pre>+#ifdef __APPLE__</pre><pre>+std::string GetVencAvcodecVTOption( sout_stream_t * /* p_stream */,</pre><pre>+                                           const video_format_t * p_vid,</pre><pre>+                                           int i_quality )</pre><pre>+{</pre><pre>+    std::stringstream ssout;</pre><pre>+    ssout << "venc=avcodec{codec=h264_videotoolbox,options{realtime=1}}";</pre><pre>+    switch( i_quality )</pre><pre>+    {</pre><pre>+        /* Here, performances issues won't come from videotoolbox but from</pre><pre>+         * some old chromecast devices */</pre><pre>+</pre><pre>+        case CONVERSION_QUALITY_HIGH:</pre><pre>+            break;</pre><pre>+        case CONVERSION_QUALITY_MEDIUM:</pre><pre>+            ssout << ",vb=8000000";</pre><pre>+            break;</pre><pre>+        case CONVERSION_QUALITY_LOW:</pre><pre>+        case CONVERSION_QUALITY_LOWCPU:</pre><pre>+            ssout << ",vb=3000000";</pre><pre>+            break;</pre><pre>+    }</pre><pre>+</pre><pre>+    return ssout.str();</pre><pre>+}</pre><pre>+#endif</pre><pre>diff --git a/modules/stream_out/renderer_common.hpp b/modules/stream_out/renderer_common.hpp</pre><pre>new file mode 100644</pre><pre>index 0000000000..7a440a6674</pre><pre>--- /dev/null</pre><pre>+++ b/modules/stream_out/renderer_common.hpp</pre><pre>@@ -0,0 +1,85 @@</pre><pre>+/*****************************************************************************</pre><pre>+ * renderer_common.hpp : renderer helper functions</pre><pre>+ *****************************************************************************</pre><pre>+ * Copyright © 2014-2018 VideoLAN</pre><pre>+ *</pre><pre>+ * Authors: Adrien Maglo <</pre><a href="mailto:magsoft@videolan.org"><pre>magsoft@videolan.org</pre></a><pre>></pre><pre>+ *          Jean-Baptiste Kempf <</pre><a href="mailto:jb@videolan.org"><pre>jb@videolan.org</pre></a><pre>></pre><pre>+ *          Steve Lhomme <</pre><a href="mailto:robux4@videolabs.io"><pre>robux4@videolabs.io</pre></a><pre>></pre><pre>+ *          Shaleen Jain <</pre><a href="mailto:shaleen@jain.sh"><pre>shaleen@jain.sh</pre></a><pre>></pre><pre>+ *</pre><pre>+ * This program is free software; you can redistribute it and/or modify it</pre><pre>+ * under the terms of the GNU Lesser General Public License as published by</pre><pre>+ * the Free Software Foundation; either version 2.1 of the License, or</pre><pre>+ * (at your option) any later version.</pre><pre>+ *</pre><pre>+ * This program is distributed in the hope that it will be useful,</pre><pre>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</pre><pre>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</pre><pre>+ * GNU Lesser General Public License for more details.</pre><pre>+ *</pre><pre>+ * You should have received a copy of the GNU Lesser General Public License</pre><pre>+ * along with this program; if not, write to the Free Software Foundation,</pre><pre>+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.</pre><pre>+ *****************************************************************************/</pre><pre>+</pre><pre>+#ifndef RENDERER_COMMON_H</pre><pre>+#define RENDERER_COMMON_H</pre><pre>+</pre><pre>+#include <string></pre><pre>+#include <vector></pre><pre>+</pre><pre>+#include <vlc_common.h></pre><pre>+#include <vlc_sout.h></pre><pre>+</pre><pre>+#define PERF_TEXT N_( "Performance warning" )</pre><pre>+#define PERF_LONGTEXT N_( "Display a performance warning when transcoding" )</pre><pre>+#define AUDIO_PASSTHROUGH_TEXT N_( "Enable Audio passthrough" )</pre><pre>+#define AUDIO_PASSTHROUGH_LONGTEXT N_( "Disable if your receiver does not support Dolby®." )</pre><pre>+#define CONVERSION_QUALITY_TEXT N_( "Conversion quality" )</pre><pre>+#define CONVERSION_QUALITY_LONGTEXT N_( "Change this option to increase conversion speed or quality." )</pre><pre>+</pre><pre>+#if defined (__ANDROID__) || defined (__arm__) || (defined (TARGET_OS_IPHONE) && TARGET_OS_IPHONE)</pre><pre>+# define CONVERSION_QUALITY_DEFAULT CONVERSION_QUALITY_LOW</pre><pre>+#else</pre><pre>+# define CONVERSION_QUALITY_DEFAULT CONVERSION_QUALITY_MEDIUM</pre><pre>+#endif</pre><pre>+</pre><pre>+#define RENDERER_CFG_PREFIX "sout-renderer-"</pre><pre>+</pre><pre>+#define add_renderer_opts(prefix) \</pre><pre>+    add_integer(RENDERER_CFG_PREFIX "show-perf-warning", 1, \</pre><pre>+            PERF_TEXT, PERF_LONGTEXT, true ) \</pre><pre>+        change_private() \</pre><pre>+    add_bool(prefix "audio-passthrough", false, \</pre><pre>+            AUDIO_PASSTHROUGH_TEXT, AUDIO_PASSTHROUGH_LONGTEXT, false ) \</pre><pre>+    add_integer(prefix "conversion-quality", CONVERSION_QUALITY_DEFAULT, \</pre><pre>+                CONVERSION_QUALITY_TEXT, CONVERSION_QUALITY_LONGTEXT, false ); \</pre><pre>+        change_integer_list(conversion_quality_list, conversion_quality_list_text)</pre><pre>+</pre><pre>+static const char *const conversion_quality_list_text[] = {</pre><pre>+    N_( "High (high quality and high bandwidth)" ),</pre><pre>+    N_( "Medium (medium quality and medium bandwidth)" ),</pre><pre>+    N_( "Low (low quality and low bandwidth)" ),</pre><pre>+    N_( "Low CPU (low quality but high bandwidth)" ),</pre><pre>+};</pre><pre>+</pre><pre>+enum {</pre><pre>+    CONVERSION_QUALITY_HIGH = 0,</pre><pre>+    CONVERSION_QUALITY_MEDIUM = 1,</pre><pre>+    CONVERSION_QUALITY_LOW = 2,</pre><pre>+    CONVERSION_QUALITY_LOWCPU = 3,</pre><pre>+};</pre><pre>+</pre><pre>+static const int conversion_quality_list[] = {</pre><pre>+    CONVERSION_QUALITY_HIGH,</pre><pre>+    CONVERSION_QUALITY_MEDIUM,</pre><pre>+    CONVERSION_QUALITY_LOW,</pre><pre>+    CONVERSION_QUALITY_LOWCPU,</pre><pre>+};</pre><pre>+</pre><pre>+std::string</pre><pre>+vlc_sout_renderer_GetVcodecOption(sout_stream_t *p_stream,</pre><pre>+        std::vector<vlc_fourcc_t> codecs, const video_format_t *p_vid, int i_quality);</pre><pre>+</pre><pre>+#endif /* RENDERER_COMMON_H */</pre></blockquote><div><span><pre>-- <br></pre><div style="width: 71ch;">Regards,</div><div style="width: 71ch;">Shaleen Jain</div></span></div></body></html>