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 "tasks/generic/AttachSource.h"
21 : #include "GstMimeMapping.h"
22 : #include "IGlibWrapper.h"
23 : #include "IGstWrapper.h"
24 : #include "IMediaPipeline.h"
25 : #include "RialtoServerLogging.h"
26 : #include "TypeConverters.h"
27 : #include "Utils.h"
28 : #include <unordered_map>
29 :
30 : namespace firebolt::rialto::server::tasks::generic
31 : {
32 21 : AttachSource::AttachSource(GenericPlayerContext &context,
33 : const std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> &gstWrapper,
34 : const std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> &glibWrapper,
35 : const std::shared_ptr<IGstTextTrackSinkFactory> &gstTextTrackSinkFactory,
36 21 : IGstGenericPlayerPrivate &player, const std::unique_ptr<IMediaPipeline::MediaSource> &source)
37 21 : : m_context{context}, m_gstWrapper{gstWrapper}, m_glibWrapper{glibWrapper},
38 42 : m_gstTextTrackSinkFactory{gstTextTrackSinkFactory}, m_player{player}, m_attachedSource{source->copy()}
39 : {
40 21 : RIALTO_SERVER_LOG_DEBUG("Constructing AttachSource");
41 : }
42 :
43 22 : AttachSource::~AttachSource()
44 : {
45 21 : RIALTO_SERVER_LOG_DEBUG("AttachSource finished");
46 22 : }
47 :
48 20 : void AttachSource::execute() const
49 : {
50 20 : RIALTO_SERVER_LOG_DEBUG("Executing AttachSource %u", static_cast<uint32_t>(m_attachedSource->getType()));
51 :
52 20 : if (m_attachedSource->getType() == MediaSourceType::UNKNOWN)
53 : {
54 1 : RIALTO_SERVER_LOG_ERROR("Unknown media source type");
55 1 : return;
56 : }
57 :
58 19 : if (m_context.streamInfo.find(m_attachedSource->getType()) == m_context.streamInfo.end())
59 : {
60 16 : addSource();
61 : }
62 3 : else if (m_attachedSource->getType() == MediaSourceType::AUDIO && m_context.audioSourceRemoved)
63 : {
64 2 : reattachAudioSource();
65 : }
66 : else
67 : {
68 1 : RIALTO_SERVER_LOG_ERROR("cannot update caps");
69 : }
70 : }
71 :
72 16 : void AttachSource::addSource() const
73 : {
74 16 : GstCaps *caps = createCapsFromMediaSource(m_gstWrapper, m_glibWrapper, m_attachedSource);
75 16 : if (!caps)
76 : {
77 3 : RIALTO_SERVER_LOG_ERROR("Failed to create caps from media source");
78 3 : return;
79 : }
80 :
81 13 : GstElement *appSrc = nullptr;
82 13 : if (m_attachedSource->getType() == MediaSourceType::AUDIO)
83 : {
84 5 : RIALTO_SERVER_LOG_MIL("Adding Audio appsrc");
85 5 : appSrc = m_gstWrapper->gstElementFactoryMake("appsrc", "audsrc");
86 : }
87 8 : else if (m_attachedSource->getType() == MediaSourceType::VIDEO)
88 : {
89 7 : RIALTO_SERVER_LOG_MIL("Adding Video appsrc");
90 7 : appSrc = m_gstWrapper->gstElementFactoryMake("appsrc", "vidsrc");
91 : }
92 1 : else if (m_attachedSource->getType() == MediaSourceType::SUBTITLE)
93 : {
94 1 : RIALTO_SERVER_LOG_MIL("Adding Subtitle appsrc");
95 1 : appSrc = m_gstWrapper->gstElementFactoryMake("appsrc", "subsrc");
96 :
97 1 : if (m_glibWrapper->gObjectClassFindProperty(G_OBJECT_GET_CLASS(m_context.pipeline), "text-sink"))
98 : {
99 1 : GstElement *elem = m_gstTextTrackSinkFactory->createGstTextTrackSink();
100 1 : m_context.subtitleSink = elem;
101 :
102 1 : m_glibWrapper->gObjectSet(m_context.pipeline, "text-sink", elem, nullptr);
103 : }
104 : }
105 :
106 13 : m_gstWrapper->gstAppSrcSetCaps(GST_APP_SRC(appSrc), caps);
107 13 : m_context.streamInfo.emplace(m_attachedSource->getType(), StreamInfo{appSrc, m_attachedSource->getHasDrm()});
108 :
109 13 : if (caps)
110 13 : m_gstWrapper->gstCapsUnref(caps);
111 : }
112 :
113 2 : void AttachSource::reattachAudioSource() const
114 : {
115 2 : if (!m_player.reattachSource(m_attachedSource))
116 : {
117 1 : RIALTO_SERVER_LOG_ERROR("Reattaching source failed!");
118 1 : return;
119 : }
120 :
121 : // Restart audio sink
122 1 : m_player.setPlaybinFlags(true);
123 :
124 1 : m_context.streamInfo[m_attachedSource->getType()].isDataNeeded = true;
125 1 : m_context.audioSourceRemoved = false;
126 1 : m_player.notifyNeedMediaData(MediaSourceType::AUDIO);
127 : }
128 : } // namespace firebolt::rialto::server::tasks::generic
|