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 2023 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/webAudio/HandleBusMessage.h"
21 : #include "IGstWebAudioPlayerClient.h"
22 : #include "IGstWrapper.h"
23 : #include "RialtoServerLogging.h"
24 : #include "WebAudioPlayerContext.h"
25 :
26 : namespace firebolt::rialto::server::tasks::webaudio
27 : {
28 13 : HandleBusMessage::HandleBusMessage(WebAudioPlayerContext &context, IGstWebAudioPlayerPrivate &player,
29 : IGstWebAudioPlayerClient *client,
30 : std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
31 : std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper,
32 13 : GstMessage *message)
33 13 : : m_context{context}, m_player{player}, m_gstPlayerClient{client}, m_gstWrapper{gstWrapper},
34 13 : m_glibWrapper{glibWrapper}, m_message{message}
35 : {
36 13 : RIALTO_SERVER_LOG_DEBUG("Constructing HandleBusMessage");
37 : }
38 :
39 14 : HandleBusMessage::~HandleBusMessage()
40 : {
41 13 : RIALTO_SERVER_LOG_DEBUG("HandleBusMessage finished");
42 14 : }
43 :
44 12 : void HandleBusMessage::execute() const
45 : {
46 12 : RIALTO_SERVER_LOG_DEBUG("Executing HandleBusMessage");
47 12 : switch (GST_MESSAGE_TYPE(m_message))
48 : {
49 6 : case GST_MESSAGE_STATE_CHANGED:
50 : {
51 6 : if (m_context.pipeline && GST_MESSAGE_SRC(m_message) == GST_OBJECT(m_context.pipeline))
52 : {
53 : GstState oldState, newState, pending;
54 4 : m_gstWrapper->gstMessageParseStateChanged(m_message, &oldState, &newState, &pending);
55 4 : RIALTO_SERVER_LOG_INFO("State changed (old: %s, new: %s, pending: %s)",
56 : m_gstWrapper->gstElementStateGetName(oldState),
57 : m_gstWrapper->gstElementStateGetName(newState),
58 : m_gstWrapper->gstElementStateGetName(pending));
59 :
60 8 : std::string filename = std::string(m_gstWrapper->gstElementStateGetName(oldState)) + "-" +
61 12 : std::string(m_gstWrapper->gstElementStateGetName(newState));
62 4 : m_gstWrapper->gstDebugBinToDotFileWithTs(GST_BIN(m_context.pipeline), GST_DEBUG_GRAPH_SHOW_ALL,
63 : filename.c_str());
64 4 : if (!m_gstPlayerClient)
65 : {
66 1 : break;
67 : }
68 3 : switch (newState)
69 : {
70 2 : case GST_STATE_PAUSED:
71 : {
72 2 : if (pending != GST_STATE_PAUSED)
73 : {
74 : // newState==GST_STATE_PAUSED, pending==GST_STATE_PAUSED state transition is received as a result of
75 : // waiting for preroll after seek.
76 : // Subsequent newState==GST_STATE_PAUSED, pending!=GST_STATE_PAUSED transition will
77 : // indicate that the pipeline is prerolled and it reached GST_STATE_PAUSED state after seek.
78 1 : m_gstPlayerClient->notifyState(WebAudioPlayerState::PAUSED);
79 : }
80 2 : break;
81 : }
82 1 : case GST_STATE_PLAYING:
83 : {
84 1 : m_gstPlayerClient->notifyState(WebAudioPlayerState::PLAYING);
85 1 : break;
86 : }
87 0 : case GST_STATE_READY:
88 : {
89 0 : m_gstPlayerClient->notifyState(WebAudioPlayerState::IDLE);
90 0 : break;
91 : }
92 0 : case GST_STATE_NULL:
93 : case GST_STATE_VOID_PENDING:
94 : default:
95 0 : break;
96 : }
97 4 : }
98 5 : break;
99 : }
100 4 : case GST_MESSAGE_EOS:
101 : {
102 4 : if (m_context.pipeline && GST_MESSAGE_SRC(m_message) == GST_OBJECT(m_context.pipeline))
103 : {
104 2 : RIALTO_SERVER_LOG_MIL("End of stream reached.");
105 2 : if (m_gstPlayerClient)
106 : {
107 2 : m_gstPlayerClient->notifyState(WebAudioPlayerState::END_OF_STREAM);
108 : }
109 :
110 : // Flush the pipeline so that it can be reused
111 3 : if ((!m_gstWrapper->gstElementSendEvent(m_context.pipeline, m_gstWrapper->gstEventNewFlushStart())) ||
112 1 : (!m_gstWrapper->gstElementSendEvent(m_context.pipeline, m_gstWrapper->gstEventNewFlushStop(TRUE))))
113 : {
114 1 : RIALTO_SERVER_LOG_ERROR("Failed to flush the pipeline");
115 : }
116 : }
117 4 : break;
118 : }
119 1 : case GST_MESSAGE_ERROR:
120 : {
121 1 : GError *err = nullptr;
122 1 : gchar *debug = nullptr;
123 1 : m_gstWrapper->gstMessageParseError(m_message, &err, &debug);
124 :
125 1 : RIALTO_SERVER_LOG_ERROR("Error from %s - %d: %s (%s)", GST_OBJECT_NAME(GST_MESSAGE_SRC(m_message)), err->code,
126 : err->message, debug);
127 1 : m_gstPlayerClient->notifyState(WebAudioPlayerState::FAILURE);
128 :
129 1 : m_glibWrapper->gFree(debug);
130 1 : m_glibWrapper->gErrorFree(err);
131 1 : break;
132 : }
133 1 : default:
134 1 : break;
135 : }
136 :
137 12 : m_gstWrapper->gstMessageUnref(m_message);
138 : }
139 : } // namespace firebolt::rialto::server::tasks::webaudio
|