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

Generated by: LCOV version 2.0-1