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 "MediaFrameWriterV1.h"
21 : #include "RialtoCommonLogging.h"
22 :
23 : namespace firebolt::rialto::common
24 : {
25 13 : MediaFrameWriterV1::MediaFrameWriterV1(uint8_t *shmBuffer, const std::shared_ptr<MediaPlayerShmInfo> &shmInfo)
26 13 : : m_shmBuffer(shmBuffer), m_kMaxMediaBytes(shmInfo->maxMediaBytes), m_kMaxMetadataBytes(shmInfo->maxMetadataBytes),
27 26 : m_mediaBytesWritten(0U), m_mediaDataOffset(shmInfo->mediaDataOffset), m_metadataOffset(shmInfo->metadataOffset)
28 : {
29 13 : RIALTO_COMMON_LOG_INFO("We are using a writer for Metadata V1");
30 :
31 : // Zero metadata memory
32 13 : m_bytewriter.fillBytes(m_shmBuffer, m_metadataOffset, 0, m_kMaxMetadataBytes);
33 :
34 : // Set metadata version
35 13 : m_metadataOffset = m_bytewriter.writeUint32(m_shmBuffer, m_metadataOffset, m_kMetadataVersion);
36 :
37 : // Track the amount of metadata bytes written
38 13 : m_metadataBytesWritten = sizeof(m_kMetadataVersion);
39 : }
40 :
41 14 : AddSegmentStatus MediaFrameWriterV1::writeFrame(const std::unique_ptr<IMediaPipeline::MediaSegment> &data)
42 : {
43 14 : if (!writeMetaDataGeneric(data))
44 : {
45 1 : RIALTO_COMMON_LOG_ERROR("Failed to write metadata");
46 1 : return AddSegmentStatus::NO_SPACE;
47 : }
48 13 : if (!writeData(data))
49 : {
50 1 : RIALTO_COMMON_LOG_ERROR("Failed to write segment data");
51 1 : return AddSegmentStatus::NO_SPACE;
52 : }
53 12 : if (!writeMetaDataTypeSpecific(data))
54 : {
55 2 : return AddSegmentStatus::ERROR;
56 : }
57 :
58 : // Track the amount of metadata bytes written
59 10 : m_numFrames++;
60 10 : m_metadataBytesWritten += METADATA_V1_SIZE_PER_FRAME_BYTES;
61 :
62 10 : return AddSegmentStatus::OK;
63 : }
64 :
65 14 : bool MediaFrameWriterV1::writeMetaDataGeneric(const std::unique_ptr<IMediaPipeline::MediaSegment> &data)
66 : {
67 : // Check that there is enough metadata space for the next frame
68 14 : if (m_metadataBytesWritten + METADATA_V1_SIZE_PER_FRAME_BYTES > m_kMaxMetadataBytes)
69 : {
70 1 : RIALTO_COMMON_LOG_ERROR("Not enough space to write metadata, max size %u, current size %u, frame metadata size "
71 : "%u",
72 : m_kMaxMetadataBytes, m_metadataBytesWritten, METADATA_V1_SIZE_PER_FRAME_BYTES);
73 1 : return false;
74 : }
75 : else
76 : {
77 13 : m_metadataOffset = m_bytewriter.writeUint32(m_shmBuffer, m_metadataOffset, m_mediaDataOffset);
78 13 : m_metadataOffset = m_bytewriter.writeUint32(m_shmBuffer, m_metadataOffset, data->getDataLength());
79 13 : m_metadataOffset = m_bytewriter.writeInt64(m_shmBuffer, m_metadataOffset, data->getTimeStamp());
80 13 : m_metadataOffset = m_bytewriter.writeInt64(m_shmBuffer, m_metadataOffset, data->getDuration());
81 13 : m_metadataOffset = m_bytewriter.writeUint32(m_shmBuffer, m_metadataOffset, static_cast<uint32_t>(data->getId()));
82 13 : m_metadataOffset =
83 13 : m_bytewriter.writeUint32(m_shmBuffer, m_metadataOffset, static_cast<uint32_t>(data->getExtraData().size()));
84 :
85 13 : if (0 != data->getExtraData().size())
86 : {
87 18 : m_metadataOffset = m_bytewriter.writeBytes(m_shmBuffer, m_metadataOffset,
88 9 : const_cast<uint8_t *>(&(data->getExtraData()[0])),
89 9 : data->getExtraData().size());
90 : }
91 13 : m_metadataOffset =
92 13 : m_bytewriter.fillBytes(m_shmBuffer, m_metadataOffset, 0, MAX_EXTRA_DATA_SIZE - data->getExtraData().size());
93 :
94 : // Not encrypted so skip the encrypted section of the metadata
95 13 : m_metadataOffset += m_kEncryptionMetadataSizeBytes;
96 : }
97 :
98 13 : return true;
99 : }
100 :
101 12 : bool MediaFrameWriterV1::writeMetaDataTypeSpecific(const std::unique_ptr<IMediaPipeline::MediaSegment> &data)
102 : {
103 12 : if (MediaSourceType::AUDIO == data->getType())
104 : {
105 6 : IMediaPipeline::MediaSegmentAudio *audioSegment = dynamic_cast<IMediaPipeline::MediaSegmentAudio *>(data.get());
106 6 : if (audioSegment)
107 : {
108 5 : m_metadataOffset = m_bytewriter.writeUint32(m_shmBuffer, m_metadataOffset,
109 5 : static_cast<uint32_t>(audioSegment->getSampleRate()));
110 5 : m_metadataOffset = m_bytewriter.writeUint32(m_shmBuffer, m_metadataOffset,
111 5 : static_cast<uint32_t>(audioSegment->getNumberOfChannels()));
112 : }
113 : else
114 : {
115 1 : RIALTO_COMMON_LOG_ERROR("Failed to get the audio segment");
116 1 : return false;
117 : }
118 : }
119 6 : else if (MediaSourceType::VIDEO == data->getType())
120 : {
121 6 : IMediaPipeline::MediaSegmentVideo *videoSegment = dynamic_cast<IMediaPipeline::MediaSegmentVideo *>(data.get());
122 6 : if (videoSegment)
123 : {
124 5 : m_metadataOffset = m_bytewriter.writeUint32(m_shmBuffer, m_metadataOffset, videoSegment->getWidth());
125 5 : m_metadataOffset = m_bytewriter.writeUint32(m_shmBuffer, m_metadataOffset, videoSegment->getHeight());
126 : }
127 : else
128 : {
129 1 : RIALTO_COMMON_LOG_ERROR("Failed to get the video segment");
130 1 : return false;
131 : }
132 : }
133 : else
134 : {
135 0 : RIALTO_COMMON_LOG_ERROR("Failed to write type specific metadata - media source type not known");
136 0 : return false;
137 : }
138 10 : return true;
139 : }
140 :
141 13 : bool MediaFrameWriterV1::writeData(const std::unique_ptr<IMediaPipeline::MediaSegment> &data)
142 : {
143 13 : if (m_mediaBytesWritten + data->getDataLength() > m_kMaxMediaBytes)
144 : {
145 1 : RIALTO_COMMON_LOG_ERROR("Not enough space to write media data, max size %u, current size %u, size to write %u",
146 : m_kMaxMediaBytes, m_mediaBytesWritten, data->getDataLength());
147 1 : return false;
148 : }
149 :
150 12 : m_mediaDataOffset = m_bytewriter.writeBytes(m_shmBuffer, m_mediaDataOffset, data->getData(), data->getDataLength());
151 :
152 : // Track the amount of media bytes written
153 12 : m_mediaBytesWritten += data->getDataLength();
154 :
155 12 : return true;
156 : }
157 : }; // namespace firebolt::rialto::common
|