LCOV - code coverage report
Current view: top level - media/server/gstplayer/source - GstSrc.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 43.9 % 262 115
Test Date: 2025-02-18 13:13:53 Functions: 40.0 % 25 10

            Line data    Source code
       1              : /*
       2              :  * If not stated otherwise in this file or this component's LICENSE file the
       3              :  * following copyright and licenses apply:
       4              :  *
       5              :  * Copyright 2022 Sky UK
       6              :  *
       7              :  * Licensed under the Apache License, Version 2.0 (the "License");
       8              :  * you may not use this file except in compliance with the License.
       9              :  * You may obtain a copy of the License at
      10              :  *
      11              :  * http://www.apache.org/licenses/LICENSE-2.0
      12              :  *
      13              :  * Unless required by applicable law or agreed to in writing, software
      14              :  * distributed under the License is distributed on an "AS IS" BASIS,
      15              :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      16              :  * See the License for the specific language governing permissions and
      17              :  * limitations under the License.
      18              :  */
      19              : 
      20              : #include <stdexcept>
      21              : 
      22              : #include "GstSrc.h"
      23              : #include "GstTextTrackSinkFactory.h"
      24              : #include "RialtoServerLogging.h"
      25              : #include <MediaCommon.h>
      26              : 
      27              : static void gstRialtoSrcUriHandlerInit(gpointer gIface, gpointer ifaceData);
      28              : 
      29              : static GstStaticPadTemplate rialto_src_template =
      30              :     GST_STATIC_PAD_TEMPLATE("src_%u", GST_PAD_SRC, GST_PAD_SOMETIMES, GST_STATIC_CAPS_ANY);
      31              : 
      32              : GST_DEBUG_CATEGORY(rialto_gst_player_debug);
      33              : #define GST_CAT_DEFAULT rialto_gst_player_debug
      34              : #define gst_rialto_src_parent_class parent_class
      35              : #define RIALTO_SRC_CATEGORY_INIT                                                                                       \
      36              :     GST_DEBUG_CATEGORY_INIT(rialto_gst_player_debug, "rialtosrc", 0, "Rialto source element");
      37           14 : G_DEFINE_TYPE_WITH_CODE(GstRialtoSrc, gst_rialto_src, GST_TYPE_BIN,
      38              :                         G_ADD_PRIVATE(GstRialtoSrc)
      39              :                             G_IMPLEMENT_INTERFACE(GST_TYPE_URI_HANDLER, gstRialtoSrcUriHandlerInit)
      40              :                                 RIALTO_SRC_CATEGORY_INIT)
      41              : 
      42            0 : static void gstRialtoSrcDispose(GObject *object)
      43              : {
      44            0 :     GST_CALL_PARENT(G_OBJECT_CLASS, dispose, (object));
      45              : }
      46              : 
      47            0 : static void gstRialtoSrcFinalize(GObject *object)
      48              : {
      49            0 :     GstRialtoSrc *src = GST_RIALTO_SRC(object);
      50            0 :     GstRialtoSrcPrivate *priv = src->priv;
      51            0 :     g_free(priv->uri);
      52            0 :     priv->~GstRialtoSrcPrivate();
      53            0 :     GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object));
      54              : }
      55              : 
      56            0 : static void gstRialtoSrcSetProperty(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
      57              : {
      58            0 :     GST_CALL_PARENT(G_OBJECT_CLASS, set_property, (object, prop_id, value, pspec));
      59              : }
      60              : 
      61            0 : static void gstRialtoSrcGetProperty(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
      62              : {
      63            0 :     GST_CALL_PARENT(G_OBJECT_CLASS, get_property, (object, prop_id, value, pspec));
      64              : }
      65              : 
      66            0 : static GstURIType gstRialtoSrcUriGetType(GType)
      67              : {
      68            0 :     return GST_URI_SRC;
      69              : }
      70              : 
      71            0 : const gchar *const *gstRialtoSrcGetProtocols(GType)
      72              : {
      73              :     static const char *protocols[] = {"rialto", 0};
      74            0 :     return protocols;
      75              : }
      76              : 
      77            0 : static gchar *gstRialtoSrcGetUri(GstURIHandler *handler)
      78              : {
      79            0 :     GstRialtoSrc *src = GST_RIALTO_SRC(handler);
      80              :     gchar *ret;
      81            0 :     GST_OBJECT_LOCK(src);
      82            0 :     ret = g_strdup(src->priv->uri);
      83            0 :     GST_OBJECT_UNLOCK(src);
      84            0 :     return ret;
      85              : }
      86              : 
      87            0 : static gboolean gstRialtoSrcSetUri(GstURIHandler *handler, const gchar *uri, GError **error)
      88              : {
      89            0 :     GstRialtoSrc *src = GST_RIALTO_SRC(handler);
      90            0 :     GstRialtoSrcPrivate *priv = src->priv;
      91            0 :     if (GST_STATE(src) >= GST_STATE_PAUSED)
      92              :     {
      93            0 :         GST_ERROR_OBJECT(src, "URI can only be set in states < PAUSED");
      94            0 :         return FALSE;
      95              :     }
      96            0 :     GST_OBJECT_LOCK(src);
      97            0 :     g_free(priv->uri);
      98            0 :     priv->uri = 0;
      99            0 :     if (!uri)
     100              :     {
     101            0 :         GST_OBJECT_UNLOCK(src);
     102            0 :         return TRUE;
     103              :     }
     104            0 :     priv->uri = g_strdup(uri);
     105            0 :     GST_OBJECT_UNLOCK(src);
     106            0 :     return TRUE;
     107              : }
     108              : 
     109            0 : static void gstRialtoSrcUriHandlerInit(gpointer gIface, gpointer)
     110              : {
     111            0 :     GstURIHandlerInterface *iface = reinterpret_cast<GstURIHandlerInterface *>(gIface);
     112            0 :     iface->get_type = gstRialtoSrcUriGetType;
     113            0 :     iface->get_protocols = gstRialtoSrcGetProtocols;
     114            0 :     iface->get_uri = gstRialtoSrcGetUri;
     115            0 :     iface->set_uri = gstRialtoSrcSetUri;
     116              : }
     117              : 
     118            0 : static gboolean gstRialtoSrcQueryWithParent(GstPad *pad, GstObject *parent, GstQuery *query)
     119              : {
     120            0 :     gboolean result = FALSE;
     121            0 :     switch (GST_QUERY_TYPE(query))
     122              :     {
     123              :     default:
     124              :     {
     125            0 :         GstPad *target = gst_ghost_pad_get_target(GST_GHOST_PAD_CAST(pad));
     126              :         // Forward the query to the proxy target pad.
     127            0 :         if (target)
     128            0 :             result = gst_pad_query(target, query);
     129            0 :         gst_object_unref(target);
     130            0 :         break;
     131              :     }
     132              :     }
     133            0 :     return result;
     134              : }
     135              : 
     136            0 : void gstRialtoSrcHandleMessage(GstBin *bin, GstMessage *message)
     137              : {
     138            0 :     GstRialtoSrc *src = GST_RIALTO_SRC(GST_ELEMENT(bin));
     139            0 :     switch (GST_MESSAGE_TYPE(message))
     140              :     {
     141            0 :     case GST_MESSAGE_EOS:
     142              :     {
     143            0 :         gboolean emit_eos = TRUE;
     144            0 :         GstPad *pad = gst_element_get_static_pad(GST_ELEMENT(GST_MESSAGE_SRC(message)), "src");
     145            0 :         GST_DEBUG_OBJECT(src, "EOS received from %s", GST_MESSAGE_SRC_NAME(message));
     146            0 :         g_object_set_data(G_OBJECT(pad), "is-eos", GINT_TO_POINTER(1));
     147            0 :         gst_object_unref(pad);
     148            0 :         for (guint i = 0; i < src->priv->appsrc_count; i++)
     149              :         {
     150            0 :             gchar *name = g_strdup_printf("src_%u", i);
     151            0 :             GstPad *src_pad = gst_element_get_static_pad(GST_ELEMENT(src), name);
     152            0 :             GstPad *target = gst_ghost_pad_get_target(GST_GHOST_PAD_CAST(src_pad));
     153            0 :             gint is_eos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(target), "is-eos"));
     154            0 :             gst_object_unref(target);
     155            0 :             gst_object_unref(src_pad);
     156            0 :             g_free(name);
     157            0 :             if (!is_eos)
     158              :             {
     159            0 :                 emit_eos = FALSE;
     160            0 :                 break;
     161              :             }
     162              :         }
     163            0 :         gst_message_unref(message);
     164            0 :         if (emit_eos)
     165              :         {
     166            0 :             GST_DEBUG_OBJECT(src, "All appsrc elements are EOS, emitting event now.");
     167            0 :             gst_element_send_event(GST_ELEMENT(bin), gst_event_new_eos());
     168              :         }
     169            0 :         break;
     170              :     }
     171            0 :     default:
     172            0 :         GST_BIN_CLASS(parent_class)->handle_message(bin, message);
     173            0 :         break;
     174              :     }
     175              : }
     176              : 
     177            0 : static void gstRialtoSrcDoAsyncStart(GstRialtoSrc *rialtoSrc)
     178              : {
     179            0 :     GstRialtoSrcPrivate *privateData = rialtoSrc->priv;
     180            0 :     if (privateData->async_done)
     181              :     {
     182            0 :         GST_DEBUG_OBJECT(rialtoSrc, "Rialto src already done");
     183            0 :         return;
     184              :     }
     185              : 
     186            0 :     GstMessage *message = gst_message_new_async_start(GST_OBJECT(rialtoSrc));
     187            0 :     GstBin *bin = GST_BIN(rialtoSrc);
     188              : 
     189            0 :     privateData->async_start = TRUE;
     190            0 :     GST_BIN_CLASS(parent_class)->handle_message(bin, message);
     191              : }
     192              : 
     193            1 : static void gstRialtoSrcDoAsyncDone(GstRialtoSrc *rialtoSrc)
     194              : {
     195            1 :     GstRialtoSrcPrivate *privateData = rialtoSrc->priv;
     196            1 :     if (!privateData->async_start)
     197              :     {
     198            1 :         GST_DEBUG_OBJECT(rialtoSrc, "Rialto src not started");
     199            1 :         return;
     200              :     }
     201              : 
     202            0 :     GstMessage *message = gst_message_new_async_done(GST_OBJECT(rialtoSrc), GST_CLOCK_TIME_NONE);
     203            0 :     GstBin *bin = GST_BIN(rialtoSrc);
     204              : 
     205            0 :     GST_BIN_CLASS(parent_class)->handle_message(bin, message);
     206              : 
     207            0 :     privateData->async_done = TRUE;
     208            0 :     privateData->async_start = FALSE;
     209              : }
     210              : 
     211            0 : static GstStateChangeReturn gstRialtoSrcChangeState(GstElement *element, GstStateChange transition)
     212              : {
     213            0 :     GstRialtoSrc *rialtoSrc = GST_RIALTO_SRC(element);
     214            0 :     GstRialtoSrcPrivate *privateData = rialtoSrc->priv;
     215            0 :     GstStateChangeReturn status = GST_STATE_CHANGE_SUCCESS;
     216              : 
     217            0 :     if (transition == GST_STATE_CHANGE_READY_TO_PAUSED)
     218              :     {
     219            0 :         gstRialtoSrcDoAsyncStart(rialtoSrc);
     220              :     }
     221              : 
     222            0 :     status = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
     223            0 :     if (G_UNLIKELY(status == GST_STATE_CHANGE_FAILURE))
     224              :     {
     225            0 :         gstRialtoSrcDoAsyncDone(rialtoSrc);
     226            0 :         return status;
     227              :     }
     228              : 
     229            0 :     switch (transition)
     230              :     {
     231            0 :     case GST_STATE_CHANGE_READY_TO_PAUSED:
     232              :     {
     233            0 :         if (!privateData->async_done)
     234            0 :             status = GST_STATE_CHANGE_ASYNC;
     235            0 :         break;
     236              :     }
     237            0 :     case GST_STATE_CHANGE_PAUSED_TO_READY:
     238              :     {
     239            0 :         gstRialtoSrcDoAsyncDone(rialtoSrc);
     240            0 :         break;
     241              :     }
     242            0 :     default:
     243            0 :         break;
     244              :     }
     245              : 
     246            0 :     return status;
     247              : }
     248              : 
     249            0 : static void gst_rialto_src_init(GstRialtoSrc *src) // NOLINT(build/function_format)
     250              : {
     251            0 :     GstRialtoSrcPrivate *priv = reinterpret_cast<GstRialtoSrcPrivate *>(gst_rialto_src_get_instance_private(src));
     252            0 :     src->priv = priv;
     253            0 :     src->priv->appsrc_count = 0;
     254            0 :     src->priv->async_start = FALSE;
     255            0 :     src->priv->async_done = FALSE;
     256            0 :     g_object_set(GST_BIN(src), "message-forward", TRUE, nullptr);
     257              : }
     258              : 
     259            0 : static void gst_rialto_src_class_init(GstRialtoSrcClass *klass) // NOLINT(build/function_format)
     260              : {
     261            0 :     GObjectClass *oklass = G_OBJECT_CLASS(klass);
     262            0 :     GstElementClass *eklass = GST_ELEMENT_CLASS(klass);
     263            0 :     GstBinClass *bklass = GST_BIN_CLASS(klass);
     264            0 :     oklass->dispose = gstRialtoSrcDispose;
     265            0 :     oklass->finalize = gstRialtoSrcFinalize;
     266            0 :     oklass->set_property = gstRialtoSrcSetProperty;
     267            0 :     oklass->get_property = gstRialtoSrcGetProperty;
     268            0 :     GstPadTemplate *templ = gst_static_pad_template_get(&rialto_src_template);
     269            0 :     gst_element_class_add_pad_template(eklass, templ);
     270            0 :     gst_element_class_set_metadata(eklass, "Rialto source element", "Source",
     271              :                                    "Handles data incoming from the Rialto player", "POC <poc@sky.uk>");
     272            0 :     g_object_class_install_property(oklass, PROP_LOCATION,
     273              :                                     g_param_spec_string("location", "location", "Location to read from", 0,
     274              :                                                         (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
     275            0 :     bklass->handle_message = GST_DEBUG_FUNCPTR(gstRialtoSrcHandleMessage);
     276            0 :     eklass->change_state = GST_DEBUG_FUNCPTR(gstRialtoSrcChangeState);
     277              : }
     278              : 
     279              : namespace firebolt::rialto::server
     280              : {
     281              : std::weak_ptr<IGstSrcFactory> GstSrcFactory::m_factory;
     282              : std::weak_ptr<IGstSrc> GstSrcFactory::m_gstSrc;
     283              : std::mutex GstSrcFactory::m_creationMutex;
     284              : 
     285            3 : std::shared_ptr<IGstSrcFactory> IGstSrcFactory::getFactory()
     286              : {
     287            3 :     std::shared_ptr<IGstSrcFactory> factory = GstSrcFactory::m_factory.lock();
     288              : 
     289            3 :     if (!factory)
     290              :     {
     291              :         try
     292              :         {
     293            3 :             factory = std::make_shared<GstSrcFactory>();
     294              :         }
     295            0 :         catch (const std::exception &e)
     296              :         {
     297            0 :             RIALTO_SERVER_LOG_ERROR("Failed to create the gstreamer src factory, reason: %s", e.what());
     298              :         }
     299              : 
     300            3 :         GstSrcFactory::m_factory = factory;
     301              :     }
     302              : 
     303            3 :     return factory;
     304              : }
     305              : 
     306            3 : std::shared_ptr<IGstSrc> GstSrcFactory::getGstSrc()
     307              : {
     308            3 :     std::lock_guard<std::mutex> lock{m_creationMutex};
     309              : 
     310            3 :     std::shared_ptr<IGstSrc> gstSrc = GstSrcFactory::m_gstSrc.lock();
     311              : 
     312            3 :     if (!gstSrc)
     313              :     {
     314              :         try
     315              :         {
     316            6 :             gstSrc = std::make_shared<GstSrc>(firebolt::rialto::wrappers::IGstWrapperFactory::getFactory(),
     317            6 :                                               firebolt::rialto::wrappers::IGlibWrapperFactory::getFactory(),
     318            9 :                                               IGstDecryptorElementFactory::createFactory());
     319              :         }
     320            0 :         catch (const std::exception &e)
     321              :         {
     322            0 :             RIALTO_SERVER_LOG_ERROR("Failed to create the gstreamer src, reason: %s", e.what());
     323              :         }
     324              : 
     325            3 :         GstSrcFactory::m_gstSrc = gstSrc;
     326              :     }
     327              : 
     328            6 :     return gstSrc;
     329            3 : }
     330              : 
     331           17 : GstSrc::GstSrc(const std::shared_ptr<firebolt::rialto::wrappers::IGstWrapperFactory> &gstWrapperFactory,
     332              :                const std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapperFactory> &glibWrapperFactory,
     333           17 :                const std::shared_ptr<IGstDecryptorElementFactory> &decryptorFactory)
     334           17 :     : m_decryptorFactory(decryptorFactory)
     335              : {
     336           17 :     if ((!gstWrapperFactory) || (!(m_gstWrapper = gstWrapperFactory->getGstWrapper())))
     337              :     {
     338            0 :         throw std::runtime_error("Cannot create GstWrapper");
     339              :     }
     340           17 :     if ((!glibWrapperFactory) || (!(m_glibWrapper = glibWrapperFactory->getGlibWrapper())))
     341              :     {
     342            0 :         throw std::runtime_error("Cannot create GlibWrapper");
     343              :     }
     344           17 :     if (!m_decryptorFactory)
     345              :     {
     346            0 :         throw std::runtime_error("No decryptor factory provided");
     347              :     }
     348           17 : }
     349              : 
     350            4 : void GstSrc::initSrc()
     351              : {
     352            4 :     GstElementFactory *src_factory = m_gstWrapper->gstElementFactoryFind("rialtosrc");
     353            4 :     if (!src_factory)
     354              :     {
     355            3 :         m_gstWrapper->gstElementRegister(0, "rialtosrc", GST_RANK_PRIMARY + 100, GST_RIALTO_TYPE_SRC);
     356              :     }
     357              :     else
     358              :     {
     359            1 :         m_gstWrapper->gstObjectUnref(src_factory);
     360            1 :         src_factory = nullptr;
     361              :     }
     362            4 : }
     363              : 
     364            6 : void GstSrc::setDefaultStreamFormatIfNeeded(GstElement *appSrc)
     365              : {
     366            6 :     GstCaps *currentCaps = m_gstWrapper->gstAppSrcGetCaps(GST_APP_SRC(appSrc));
     367            6 :     if (currentCaps)
     368              :     {
     369            6 :         GstStructure *structure = m_gstWrapper->gstCapsGetStructure(currentCaps, 0);
     370            7 :         if (structure && (m_gstWrapper->gstStructureHasName(structure, "video/x-h264") ||
     371            1 :                           m_gstWrapper->gstStructureHasName(structure, "video/x-h265")))
     372              :         {
     373            5 :             bool hasStreamFormat = m_gstWrapper->gstStructureHasField(structure, "stream-format");
     374            5 :             bool hasCodecData = m_gstWrapper->gstStructureHasField(structure, "codec_data");
     375              : 
     376            5 :             if (!hasStreamFormat && !hasCodecData)
     377              :             {
     378            3 :                 GstCaps *newCaps = m_gstWrapper->gstCapsCopy(currentCaps);
     379            3 :                 if (newCaps)
     380              :                 {
     381            3 :                     m_gstWrapper->gstCapsSetSimple(newCaps, "stream-format", G_TYPE_STRING, "byte-stream", nullptr);
     382            3 :                     m_gstWrapper->gstAppSrcSetCaps(GST_APP_SRC(appSrc), newCaps);
     383            3 :                     GST_INFO("Added stream-format=byte-stream to caps %" GST_PTR_FORMAT, newCaps);
     384            3 :                     m_gstWrapper->gstCapsUnref(newCaps);
     385              :                 }
     386              :             }
     387              :         }
     388              :     }
     389            6 :     m_gstWrapper->gstCapsUnref(currentCaps);
     390              : }
     391              : 
     392            9 : void GstSrc::setupAndAddAppArc(IDecryptionService *decryptionService, GstElement *source, StreamInfo &streamInfo,
     393              :                                GstAppSrcCallbacks *callbacks, gpointer userData, firebolt::rialto::MediaSourceType type)
     394              : {
     395              :     // Configure and add appsrc
     396            9 :     m_glibWrapper->gObjectSet(streamInfo.appSrc, "block", FALSE, "format", GST_FORMAT_TIME, "stream-type",
     397              :                               GST_APP_STREAM_TYPE_STREAM, "min-percent", 20, "handle-segment-change", TRUE, nullptr);
     398            9 :     m_gstWrapper->gstAppSrcSetCallbacks(GST_APP_SRC(streamInfo.appSrc), callbacks, userData, nullptr);
     399              : 
     400              :     const std::unordered_map<firebolt::rialto::MediaSourceType, uint32_t> queueSize =
     401              :         {{firebolt::rialto::MediaSourceType::VIDEO, 8 * 1024 * 1024},
     402              :          {firebolt::rialto::MediaSourceType::AUDIO, 512 * 1024},
     403            9 :          {firebolt::rialto::MediaSourceType::SUBTITLE, 256 * 1024}};
     404              : 
     405            9 :     auto sizeIt = queueSize.find(type);
     406            9 :     if (sizeIt != queueSize.end())
     407              :     {
     408            9 :         m_gstWrapper->gstAppSrcSetMaxBytes(GST_APP_SRC(streamInfo.appSrc), sizeIt->second);
     409              :     }
     410              :     else
     411              :     {
     412            0 :         GST_WARNING_OBJECT(source, "Could not find max-bytes value for appsrc");
     413              :     }
     414              : 
     415            9 :     m_gstWrapper->gstAppSrcSetStreamType(GST_APP_SRC(streamInfo.appSrc), GST_APP_STREAM_TYPE_SEEKABLE);
     416              : 
     417            9 :     GstRialtoSrc *src = GST_RIALTO_SRC(source);
     418            9 :     guint id = src->priv->appsrc_count;
     419            9 :     src->priv->appsrc_count++;
     420            9 :     gchar *name = m_glibWrapper->gStrdupPrintf("src_%u", id);
     421            9 :     m_gstWrapper->gstBinAdd(GST_BIN(source), streamInfo.appSrc);
     422              : 
     423            9 :     GstElement *src_elem = streamInfo.appSrc;
     424              : 
     425              :     // Configure and add decryptor
     426            9 :     if (streamInfo.hasDrm)
     427              :     {
     428              :         gchar *decryptorName =
     429           16 :             m_glibWrapper->gStrdupPrintf("rialtodecryptor%s_%u",
     430            8 :                                          (type == firebolt::rialto::MediaSourceType::VIDEO) ? "video" : "audio", id);
     431              :         GstElement *decryptor =
     432            8 :             m_decryptorFactory->createDecryptorElement(decryptorName, decryptionService, m_gstWrapper);
     433            8 :         m_glibWrapper->gFree(decryptorName);
     434            8 :         if (decryptor)
     435              :         {
     436            7 :             GST_DEBUG_OBJECT(src, "Injecting decryptor element %" GST_PTR_FORMAT, decryptor);
     437              : 
     438            7 :             m_gstWrapper->gstBinAdd(GST_BIN(source), decryptor);
     439            7 :             m_gstWrapper->gstElementSyncStateWithParent(decryptor);
     440            7 :             m_gstWrapper->gstElementLink(src_elem, decryptor);
     441            7 :             src_elem = decryptor;
     442              :         }
     443              :         else
     444              :         {
     445            1 :             GST_WARNING_OBJECT(src, "Could not create decryptor element");
     446              :         }
     447              : 
     448            8 :         if (type == firebolt::rialto::MediaSourceType::VIDEO)
     449              :         {
     450              :             // Configure and add payloader
     451            7 :             GstElement *payloader = createPayloader();
     452            7 :             if (payloader)
     453              :             {
     454              :                 /*
     455              :                 h264secparse and h265secparse have problems with parsing blank caps (with no stream-format nor
     456              :                 codec_data defined). This is a workaround to set the stream-format to byte-stream if needed.
     457              :                 */
     458            6 :                 setDefaultStreamFormatIfNeeded(streamInfo.appSrc);
     459              : 
     460            6 :                 if (GST_IS_BASE_TRANSFORM(payloader))
     461              :                 {
     462            0 :                     m_gstWrapper->gstBaseTransformSetInPlace(GST_BASE_TRANSFORM(payloader), TRUE);
     463              :                 }
     464            6 :                 m_gstWrapper->gstBinAdd(GST_BIN(source), payloader);
     465            6 :                 m_gstWrapper->gstElementSyncStateWithParent(payloader);
     466            6 :                 m_gstWrapper->gstElementLink(src_elem, payloader);
     467            6 :                 src_elem = payloader;
     468              :             }
     469              :             else
     470              :             {
     471            1 :                 GST_WARNING_OBJECT(src, "Could not create payloader element");
     472              :             }
     473              :         }
     474              : 
     475              :         // Configure and add buffer queue
     476            8 :         GstElement *queue = m_gstWrapper->gstElementFactoryMake("queue", nullptr);
     477            8 :         if (queue)
     478              :         {
     479            7 :             m_glibWrapper->gObjectSet(G_OBJECT(queue), "max-size-buffers", 10, "max-size-bytes", 0, "max-size-time",
     480              :                                       (gint64)0, "silent", TRUE, nullptr);
     481            7 :             m_gstWrapper->gstBinAdd(GST_BIN(source), queue);
     482            7 :             m_gstWrapper->gstElementSyncStateWithParent(queue);
     483            7 :             m_gstWrapper->gstElementLink(src_elem, queue);
     484            7 :             src_elem = queue;
     485              :         }
     486              :         else
     487              :         {
     488            1 :             GST_WARNING_OBJECT(src, "Could not create buffer queue element");
     489              :         }
     490              :     }
     491              : 
     492              :     // Setup pad
     493            9 :     GstPad *target = m_gstWrapper->gstElementGetStaticPad(src_elem, "src");
     494            9 :     GstPad *pad = m_gstWrapper->gstGhostPadNew(name, target);
     495            9 :     m_gstWrapper->gstPadSetQueryFunction(pad, gstRialtoSrcQueryWithParent);
     496            9 :     m_gstWrapper->gstPadSetActive(pad, TRUE);
     497              : 
     498            9 :     m_gstWrapper->gstElementAddPad(source, pad);
     499            9 :     GST_OBJECT_FLAG_SET(pad, GST_PAD_FLAG_NEED_PARENT);
     500              : 
     501            9 :     m_gstWrapper->gstElementSyncStateWithParent(streamInfo.appSrc);
     502              : 
     503            9 :     m_glibWrapper->gFree(name);
     504            9 :     m_gstWrapper->gstObjectUnref(target);
     505              : }
     506              : 
     507            1 : void GstSrc::allAppSrcsAdded(GstElement *element)
     508              : {
     509            1 :     GstRialtoSrc *src = GST_RIALTO_SRC(element);
     510            1 :     m_gstWrapper->gstElementNoMorePads(element);
     511            1 :     gstRialtoSrcDoAsyncDone(src);
     512              : }
     513              : 
     514            7 : GstElement *GstSrc::createPayloader()
     515              : {
     516              :     static GstElementFactory *factory = nullptr;
     517              :     static gsize init = 0;
     518            7 :     if (m_glibWrapper->gOnceInitEnter(&init))
     519              :     {
     520            7 :         factory = m_gstWrapper->gstElementFactoryFind("svppay");
     521            7 :         m_glibWrapper->gOnceInitLeave(&init, 1);
     522              :     }
     523            7 :     if (!factory)
     524              :     {
     525            0 :         GST_WARNING("svppay not found");
     526            0 :         return nullptr;
     527              :     }
     528            7 :     return m_gstWrapper->gstElementFactoryCreate(factory, nullptr);
     529              : }
     530              : 
     531              : }; // namespace firebolt::rialto::server
        

Generated by: LCOV version 2.0-1