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 #include "avmetadatahelper_impl.h"
17
18 #include "common/media_source.h"
19 #include "media_errors.h"
20 #include "media_log.h"
21 #include "media_description.h"
22 #include "meta_utils.h"
23 #include "uri_helper.h"
24 #include "osal/task/pipeline_threadpool.h"
25
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_METADATA, "AVMetadataHelperImpl" };
28 }
29
30 namespace OHOS {
31 namespace Media {
OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode)32 void AVMetadataHelperImpl::OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode)
33 {
34 MEDIA_LOGE("OnError errorType:%{public}d, errorCode:%{public}d", static_cast<int32_t>(errorType), errorCode);
35 stopProcessing_ = true;
36 }
37
AVMetadataHelperImpl()38 AVMetadataHelperImpl::AVMetadataHelperImpl()
39 {
40 MEDIA_LOGD("Constructor, instance: 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
41 groupId_ = std::string("AVMeta_") + std::to_string(OHOS::Media::Pipeline::Pipeline::GetNextPipelineId());
42 }
43
~AVMetadataHelperImpl()44 AVMetadataHelperImpl::~AVMetadataHelperImpl()
45 {
46 MEDIA_LOGD("Destructor, instance: 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
47 Destroy();
48 }
49
SetSource(const std::string &uri, int32_t )50 int32_t AVMetadataHelperImpl::SetSource(const std::string &uri, int32_t /* usage */)
51 {
52 UriHelper uriHelper(uri);
53 if (uriHelper.UriType() != UriHelper::URI_TYPE_FILE && uriHelper.UriType() != UriHelper::URI_TYPE_FD) {
54 MEDIA_LOGE("Unsupported uri type : %{private}s", uri.c_str());
55 return MSERR_UNSUPPORT;
56 }
57
58 MEDIA_LOGD("0x%{public}06" PRIXPTR " SetSource uri: %{private}s, type:%{public}d", FAKE_POINTER(this), uri.c_str(),
59 uriHelper.UriType());
60
61 auto ret = SetSourceInternel(uri);
62 CHECK_AND_RETURN_RET_LOG(ret == Status::OK, MSERR_INVALID_VAL,
63 "0x%{public}06" PRIXPTR " Failed to call SetSourceInternel", FAKE_POINTER(this));
64 CHECK_AND_RETURN_RET_LOG(MetaUtils::CheckFileType(mediaDemuxer_->GetGlobalMetaInfo()),
65 MSERR_UNSUPPORT, "0x%{public}06" PRIXPTR "SetSource unsupport", FAKE_POINTER(this));
66 return MSERR_OK;
67 }
68
SetSource(const std::shared_ptr<IMediaDataSource> &dataSrc)69 int32_t AVMetadataHelperImpl::SetSource(const std::shared_ptr<IMediaDataSource> &dataSrc)
70 {
71 MEDIA_LOGI("0x%{public}06" PRIXPTR "SetSource dataSrc", FAKE_POINTER(this));
72 Status ret = SetSourceInternel(dataSrc);
73 CHECK_AND_RETURN_RET_LOG(ret == Status::OK, MSERR_INVALID_VAL, "Failed to call SetSourceInternel");
74
75 CHECK_AND_RETURN_RET_LOG(MetaUtils::CheckFileType(mediaDemuxer_->GetGlobalMetaInfo()),
76 MSERR_UNSUPPORT, "0x%{public}06" PRIXPTR "SetSource unsupport", FAKE_POINTER(this));
77 MEDIA_LOGI("0x%{public}06" PRIXPTR "set source success", FAKE_POINTER(this));
78 return MSERR_OK;
79 }
80
SetSourceInternel(const std::string &uri)81 Status AVMetadataHelperImpl::SetSourceInternel(const std::string &uri)
82 {
83 Reset();
84 mediaDemuxer_ = std::make_shared<MediaDemuxer>();
85 mediaDemuxer_->SetEnableOnlineFdCache(false);
86 mediaDemuxer_->SetInterruptState(isInterruptNeeded_.load());
87 mediaDemuxer_->SetPlayerId(groupId_);
88 CHECK_AND_RETURN_RET_LOG(
89 mediaDemuxer_ != nullptr, Status::ERROR_INVALID_DATA, "SetSourceInternel demuxer is nullptr");
90 Status ret = mediaDemuxer_->SetDataSource(std::make_shared<MediaSource>(uri));
91 CHECK_AND_RETURN_RET_LOG(ret == Status::OK, ret,
92 "0x%{public}06" PRIXPTR " SetSourceInternel demuxer failed to call SetDataSource", FAKE_POINTER(this));
93 return Status::OK;
94 }
95
SetSourceInternel(const std::shared_ptr<IMediaDataSource> &dataSrc)96 Status AVMetadataHelperImpl::SetSourceInternel(const std::shared_ptr<IMediaDataSource> &dataSrc)
97 {
98 Reset();
99 mediaDemuxer_ = std::make_shared<MediaDemuxer>();
100 mediaDemuxer_->SetEnableOnlineFdCache(false);
101 mediaDemuxer_->SetPlayerId(groupId_);
102 CHECK_AND_RETURN_RET_LOG(
103 mediaDemuxer_ != nullptr, Status::ERROR_INVALID_DATA, "SetSourceInternel demuxer is nullptr");
104 Status ret = mediaDemuxer_->SetDataSource(std::make_shared<MediaSource>(dataSrc));
105 CHECK_AND_RETURN_RET_LOG(ret == Status::OK, ret, "Failed to call SetDataSource");
106 return Status::OK;
107 }
108
ResolveMetadata(int32_t key)109 std::string AVMetadataHelperImpl::ResolveMetadata(int32_t key)
110 {
111 MEDIA_LOGI("enter ResolveMetadata with key: %{public}d", key);
112 auto res = InitMetadataCollector();
113 CHECK_AND_RETURN_RET(res == Status::OK, "");
114 return metadataCollector_->ExtractMetadata(key);
115 }
116
ResolveMetadata()117 std::unordered_map<int32_t, std::string> AVMetadataHelperImpl::ResolveMetadata()
118 {
119 MEDIA_LOGD("enter ResolveMetadata");
120 auto res = InitMetadataCollector();
121 CHECK_AND_RETURN_RET(res == Status::OK, {});
122 return metadataCollector_->ExtractMetadata();
123 }
124
FetchArtPicture()125 std::shared_ptr<AVSharedMemory> AVMetadataHelperImpl::FetchArtPicture()
126 {
127 MEDIA_LOGI("0x%{public}06" PRIXPTR " enter FetchArtPicture", FAKE_POINTER(this));
128 auto res = InitMetadataCollector();
129 CHECK_AND_RETURN_RET(res == Status::OK, nullptr);
130 return metadataCollector_->GetArtPicture();
131 }
132
GetAVMetadata()133 std::shared_ptr<Meta> AVMetadataHelperImpl::GetAVMetadata()
134 {
135 MEDIA_LOGE("enter GetAVMetadata");
136 auto res = InitMetadataCollector();
137 CHECK_AND_RETURN_RET(res == Status::OK, nullptr);
138 return metadataCollector_->GetAVMetadata();
139 }
140
FetchFrameAtTime( int64_t timeUs, int32_t option, const OutputConfiguration ¶m)141 std::shared_ptr<AVSharedMemory> AVMetadataHelperImpl::FetchFrameAtTime(
142 int64_t timeUs, int32_t option, const OutputConfiguration ¶m)
143 {
144 MEDIA_LOGD("enter FetchFrameAtTime");
145 auto res = InitThumbnailGenerator();
146 CHECK_AND_RETURN_RET(res == Status::OK, nullptr);
147 return thumbnailGenerator_->FetchFrameAtTime(timeUs, option, param);
148 }
149
FetchFrameYuv( int64_t timeUs, int32_t option, const OutputConfiguration ¶m)150 std::shared_ptr<AVBuffer> AVMetadataHelperImpl::FetchFrameYuv(
151 int64_t timeUs, int32_t option, const OutputConfiguration ¶m)
152 {
153 MEDIA_LOGD("enter FetchFrameAtTime");
154 auto res = InitThumbnailGenerator();
155 CHECK_AND_RETURN_RET(res == Status::OK, nullptr);
156 return thumbnailGenerator_->FetchFrameYuv(timeUs, option, param);
157 }
158
GetTimeByFrameIndex(uint32_t index, uint64_t &time)159 int32_t AVMetadataHelperImpl::GetTimeByFrameIndex(uint32_t index, uint64_t &time)
160 {
161 auto res = InitMetadataCollector();
162 CHECK_AND_RETURN_RET_LOG(res == Status::OK, MSERR_INVALID_STATE, "Create collector failed");
163 return metadataCollector_->GetTimeByFrameIndex(index, time);
164 }
165
GetFrameIndexByTime(uint64_t time, uint32_t &index)166 int32_t AVMetadataHelperImpl::GetFrameIndexByTime(uint64_t time, uint32_t &index)
167 {
168 auto res = InitMetadataCollector();
169 CHECK_AND_RETURN_RET_LOG(res == Status::OK, MSERR_INVALID_STATE, "Create collector failed");
170 return metadataCollector_->GetFrameIndexByTime(time, index);
171 }
172
Reset()173 void AVMetadataHelperImpl::Reset()
174 {
175 if (metadataCollector_ != nullptr) {
176 metadataCollector_->Reset();
177 }
178
179 if (thumbnailGenerator_ != nullptr) {
180 thumbnailGenerator_->Reset();
181 }
182
183 if (mediaDemuxer_ != nullptr) {
184 mediaDemuxer_->Reset();
185 }
186 }
187
Destroy()188 void AVMetadataHelperImpl::Destroy()
189 {
190 if (metadataCollector_ != nullptr) {
191 metadataCollector_->Destroy();
192 }
193
194 if (thumbnailGenerator_ != nullptr) {
195 thumbnailGenerator_->Destroy();
196 }
197
198 metadataCollector_ = nullptr;
199 thumbnailGenerator_ = nullptr;
200 PipeLineThreadPool::GetInstance().DestroyThread(groupId_);
201 MEDIA_LOGD("0x%{public}06" PRIXPTR " Finish Destroy.", FAKE_POINTER(this));
202 }
203
InitMetadataCollector()204 Status AVMetadataHelperImpl::InitMetadataCollector()
205 {
206 if (metadataCollector_ == nullptr) {
207 metadataCollector_ = std::make_shared<AVMetaDataCollector>(mediaDemuxer_);
208 }
209 CHECK_AND_RETURN_RET_LOG(
210 metadataCollector_ != nullptr, Status::ERROR_INVALID_STATE, "Init metadata collector failed.");
211 return Status::OK;
212 }
213
InitThumbnailGenerator()214 Status AVMetadataHelperImpl::InitThumbnailGenerator()
215 {
216 if (thumbnailGenerator_ == nullptr) {
217 thumbnailGenerator_ = std::make_shared<AVThumbnailGenerator>(mediaDemuxer_);
218 }
219 CHECK_AND_RETURN_RET_LOG(
220 thumbnailGenerator_ != nullptr, Status::ERROR_INVALID_STATE, "Init thumbnail generator failed.");
221 return Status::OK;
222 }
223
SetInterruptState(bool isInterruptNeeded)224 void AVMetadataHelperImpl::SetInterruptState(bool isInterruptNeeded)
225 {
226 MEDIA_LOGI("Metadata set interrupt state %{public}d", isInterruptNeeded);
227 isInterruptNeeded_ = isInterruptNeeded;
228 CHECK_AND_RETURN(mediaDemuxer_ != nullptr);
229 mediaDemuxer_->SetInterruptState(isInterruptNeeded);
230 }
231 } // namespace Media
232 } // namespace OHOS