1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define HST_LOG_TAG "StreamParserManager"
17 
18 #include "stream_parser_manager.h"
19 #include <dlfcn.h>
20 #include "common/log.h"
21 
22 namespace {
23 const std::string HEVC_LIB_PATH = "libav_codec_hevc_parser.z.so";
24 const std::string VVC_LIB_PATH = "libav_codec_vvc_parser.z.so";
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_DEMUXER, "StreamParserManager" };
26 }
27 
28 namespace OHOS {
29 namespace Media {
30 namespace Plugins {
31 std::mutex StreamParserManager::mtx_;
32 std::map<StreamType, void *> StreamParserManager::handlerMap_ {};
33 std::map<StreamType, CreateFunc> StreamParserManager::createFuncMap_ {};
34 std::map<StreamType, DestroyFunc> StreamParserManager::destroyFuncMap_ {};
35 
StreamParserManager()36 StreamParserManager::StreamParserManager()
37 {
38     streamType_ = StreamType::HEVC;
39 }
40 
~StreamParserManager()41 StreamParserManager::~StreamParserManager()
42 {
43     if (streamParser_) {
44         destroyFuncMap_[streamType_](streamParser_);
45         streamParser_ = nullptr;
46     }
47 }
48 
Init(StreamType streamType)49 bool StreamParserManager::Init(StreamType streamType)
50 {
51     std::lock_guard<std::mutex> lock(mtx_);
52     if (handlerMap_.count(streamType) && createFuncMap_.count(streamType) && destroyFuncMap_.count(streamType)) {
53         return true;
54     }
55 
56     std::string streamParserPath;
57     if (streamType == StreamType::HEVC) {
58         streamParserPath = HEVC_LIB_PATH;
59     } else if (streamType == StreamType::VVC) {
60         streamParserPath = VVC_LIB_PATH;
61     } else {
62         MEDIA_LOG_E("Unsupport stream parser type");
63         return false;
64     }
65     if (handlerMap_.count(streamType) == 0) {
66         handlerMap_[streamType] = LoadPluginFile(streamParserPath);
67     }
68     if (!CheckSymbol(handlerMap_[streamType], streamType)) {
69         MEDIA_LOG_E("Load stream parser failed");
70         return false;
71     }
72     return true;
73 }
74 
Create(StreamType streamType)75 std::shared_ptr<StreamParserManager> StreamParserManager::Create(StreamType streamType)
76 {
77     MEDIA_LOG_D("Parser " PUBLIC_LOG_D32, streamType);
78     std::shared_ptr<StreamParserManager> loader = std::make_shared<StreamParserManager>();
79     if (!loader->Init(streamType)) {
80         return nullptr;
81     }
82     loader->streamParser_ = loader->createFuncMap_[streamType]();
83     if (!loader->streamParser_) {
84         MEDIA_LOG_E("CreateFunc_ failed");
85         return nullptr;
86     }
87     loader->streamType_ = streamType;
88     return loader;
89 }
90 
ParseExtraData(const uint8_t * sample,int32_t size,uint8_t ** extraDataBuf,int32_t * extraDataSize)91 void StreamParserManager::ParseExtraData(const uint8_t *sample, int32_t size,
92     uint8_t **extraDataBuf, int32_t *extraDataSize)
93 {
94     FALSE_RETURN_MSG(streamParser_ != nullptr, "Stream parser is nullptr");
95     streamParser_->ParseExtraData(sample, size, extraDataBuf, extraDataSize);
96 }
97 
IsHdrVivid()98 bool StreamParserManager::IsHdrVivid()
99 {
100     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, false, "Stream parser is nullptr");
101     return streamParser_->IsHdrVivid();
102 }
103 
IsSyncFrame(const uint8_t * sample,int32_t size)104 bool StreamParserManager::IsSyncFrame(const uint8_t *sample, int32_t size)
105 {
106     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, false, "Stream parser is nullptr");
107     return streamParser_->IsSyncFrame(sample, size);
108 }
109 
GetColorRange()110 bool StreamParserManager::GetColorRange()
111 {
112     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, false, "Stream parser is nullptr");
113     return streamParser_->GetColorRange();
114 }
115 
GetColorPrimaries()116 uint8_t StreamParserManager::GetColorPrimaries()
117 {
118     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
119     return streamParser_->GetColorPrimaries();
120 }
121 
GetColorTransfer()122 uint8_t StreamParserManager::GetColorTransfer()
123 {
124     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
125     return streamParser_->GetColorTransfer();
126 }
127 
GetColorMatrixCoeff()128 uint8_t StreamParserManager::GetColorMatrixCoeff()
129 {
130     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
131     return streamParser_->GetColorMatrixCoeff();
132 }
133 
GetProfileIdc()134 uint8_t StreamParserManager::GetProfileIdc()
135 {
136     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
137     return streamParser_->GetProfileIdc();
138 }
139 
GetLevelIdc()140 uint8_t StreamParserManager::GetLevelIdc()
141 {
142     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
143     return streamParser_->GetLevelIdc();
144 }
145 
GetChromaLocation()146 uint32_t StreamParserManager::GetChromaLocation()
147 {
148     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
149     return streamParser_->GetChromaLocation();
150 }
151 
GetPicWidInLumaSamples()152 uint32_t StreamParserManager::GetPicWidInLumaSamples()
153 {
154     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
155     return streamParser_->GetPicWidInLumaSamples();
156 }
157 
GetPicHetInLumaSamples()158 uint32_t StreamParserManager::GetPicHetInLumaSamples()
159 {
160     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
161     return streamParser_->GetPicHetInLumaSamples();
162 }
163 
ConvertExtraDataToAnnexb(uint8_t * extraData,int32_t extraDataSize)164 bool StreamParserManager::ConvertExtraDataToAnnexb(uint8_t *extraData, int32_t extraDataSize)
165 {
166     FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, false, "Stream parser is nullptr");
167     return streamParser_->ConvertExtraDataToAnnexb(extraData, extraDataSize);
168 }
169 
ConvertPacketToAnnexb(uint8_t ** hvccPacket,int32_t & hvccPacketSize,uint8_t * sideData,size_t sideDataSize,bool isExtradata)170 void StreamParserManager::ConvertPacketToAnnexb(uint8_t **hvccPacket, int32_t &hvccPacketSize, uint8_t *sideData,
171     size_t sideDataSize, bool isExtradata)
172 {
173     FALSE_RETURN_MSG(streamParser_ != nullptr, "Stream parser is nullptr");
174     streamParser_->ConvertPacketToAnnexb(hvccPacket, hvccPacketSize, sideData, sideDataSize, isExtradata);
175 }
176 
ParseAnnexbExtraData(const uint8_t * sample,int32_t size)177 void StreamParserManager::ParseAnnexbExtraData(const uint8_t *sample, int32_t size)
178 {
179     FALSE_RETURN_MSG(streamParser_ != nullptr, "Stream parser is nullptr");
180     streamParser_->ParseAnnexbExtraData(sample, size);
181 }
182 
ResetXPSSendStatus()183 void StreamParserManager::ResetXPSSendStatus()
184 {
185     FALSE_RETURN_MSG(streamParser_ != nullptr, "Stream parser is nullptr");
186     streamParser_->ResetXPSSendStatus();
187 }
188 
LoadPluginFile(const std::string & path)189 void *StreamParserManager::LoadPluginFile(const std::string &path)
190 {
191     auto ptr = ::dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
192     if (ptr == nullptr) {
193         MEDIA_LOG_E("Dlopen failed due to %{public}s", ::dlerror());
194     }
195     return ptr;
196 }
197 
CheckSymbol(void * handler,StreamType streamType)198 bool StreamParserManager::CheckSymbol(void *handler, StreamType streamType)
199 {
200     if (handler) {
201         std::string createFuncName = "CreateStreamParser";
202         std::string destroyFuncName = "DestroyStreamParser";
203         CreateFunc createFunc = nullptr;
204         DestroyFunc destroyFunc = nullptr;
205         createFunc = (CreateFunc)(::dlsym(handler, createFuncName.c_str()));
206         destroyFunc = (DestroyFunc)(::dlsym(handler, destroyFuncName.c_str()));
207         if (createFunc && destroyFunc) {
208             MEDIA_LOG_D("CreateFuncName %{public}s", createFuncName.c_str());
209             MEDIA_LOG_D("DestroyFuncName %{public}s", destroyFuncName.c_str());
210             createFuncMap_[streamType] = createFunc;
211             destroyFuncMap_[streamType] = destroyFunc;
212             return true;
213         }
214     }
215     return false;
216 }
217 } // namespace Plugins
218 } // namespace Media
219 } // namespace OHOS