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 <cinttypes>
21 :
22 : #include "IGstWrapper.h"
23 : #include "RialtoServerLogging.h"
24 : #include "WebAudioPlayerContext.h"
25 : #include "tasks/webAudio/WriteBuffer.h"
26 :
27 : namespace firebolt::rialto::server::tasks::webaudio
28 : {
29 9 : WriteBuffer::WriteBuffer(WebAudioPlayerContext &context,
30 : std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper, uint8_t *mainPtr,
31 9 : uint32_t mainLength, uint8_t *wrapPtr, uint32_t wrapLength)
32 18 : : m_context{context}, m_gstWrapper{gstWrapper}, m_mainPtr{mainPtr}, m_mainLength{mainLength}, m_wrapPtr{wrapPtr},
33 9 : m_wrapLength{wrapLength}
34 : {
35 9 : RIALTO_SERVER_LOG_DEBUG("Constructing WriteBuffer");
36 : }
37 :
38 10 : WriteBuffer::~WriteBuffer()
39 : {
40 9 : RIALTO_SERVER_LOG_DEBUG("WriteBuffer finished");
41 10 : }
42 :
43 8 : void WriteBuffer::execute() const
44 : {
45 8 : RIALTO_SERVER_LOG_DEBUG("Executing WriteBuffer");
46 :
47 8 : uint64_t freeBytes = kMaxWebAudioBytes - m_gstWrapper->gstAppSrcGetCurrentLevelBytes(GST_APP_SRC(m_context.source));
48 8 : uint64_t maxBytesToWrite = std::min(freeBytes, m_mainLength + m_wrapLength);
49 8 : uint64_t bytesToWrite = maxBytesToWrite - (maxBytesToWrite % m_context.bytesPerSample);
50 8 : uint64_t bytesWritten = 0;
51 :
52 8 : if (bytesToWrite > 0)
53 : {
54 7 : GstBuffer *gstBuffer = m_gstWrapper->gstBufferNewAllocate(nullptr, bytesToWrite, nullptr);
55 7 : if (gstBuffer)
56 : {
57 6 : if (bytesToWrite == m_mainLength + m_wrapLength)
58 : {
59 3 : bytesWritten += m_gstWrapper->gstBufferFill(gstBuffer, 0, m_mainPtr, m_mainLength);
60 3 : if (m_wrapLength > 0)
61 : {
62 3 : bytesWritten += m_gstWrapper->gstBufferFill(gstBuffer, bytesWritten, m_wrapPtr, m_wrapLength);
63 : }
64 : }
65 3 : else if (bytesToWrite > m_mainLength)
66 : {
67 2 : bytesWritten += m_gstWrapper->gstBufferFill(gstBuffer, 0, m_mainPtr, m_mainLength);
68 2 : bytesWritten +=
69 2 : m_gstWrapper->gstBufferFill(gstBuffer, bytesWritten, m_wrapPtr, bytesToWrite - bytesWritten);
70 : }
71 : else
72 : {
73 1 : bytesWritten += m_gstWrapper->gstBufferFill(gstBuffer, 0, m_mainPtr, bytesToWrite);
74 : }
75 :
76 6 : if (bytesWritten != bytesToWrite)
77 : {
78 1 : RIALTO_SERVER_LOG_WARN("Did not write the correct number of bytes! expected %" PRIu64
79 : ", actual %" PRIu64,
80 : bytesToWrite, bytesWritten);
81 : }
82 :
83 6 : if (GST_FLOW_OK != m_gstWrapper->gstAppSrcPushBuffer(GST_APP_SRC(m_context.source), gstBuffer))
84 : {
85 1 : RIALTO_SERVER_LOG_ERROR("Failed to push the buffers to the appsrc");
86 1 : m_gstWrapper->gstBufferUnref(gstBuffer);
87 1 : bytesWritten = 0;
88 : }
89 :
90 6 : RIALTO_SERVER_LOG_INFO("%" PRIu64 "bytes written to gstreamer", bytesWritten);
91 : }
92 : else
93 : {
94 1 : RIALTO_SERVER_LOG_ERROR("Failed to create the gst buffer");
95 : }
96 : }
97 : else
98 : {
99 1 : RIALTO_SERVER_LOG_INFO("No space in gstreamer buffer to write samples");
100 : }
101 :
102 : {
103 8 : std::unique_lock<std::mutex> lock(m_context.writeBufferMutex);
104 8 : m_context.lastBytesWritten = bytesWritten;
105 : }
106 8 : m_context.writeBufferCond.notify_one();
107 : }
108 : } // namespace firebolt::rialto::server::tasks::webaudio
|