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 #include "native_avsource.h"
16 #include <unistd.h>
17 #include "avcodec_errors.h"
18 #include "avcodec_log.h"
19 #include "avsource.h"
20 #include "common/native_mfmagic.h"
21 #include "native_avformat.h"
22 #include "native_avmagic.h"
23 #include "native_object.h"
24 #include "avbuffer.h"
25
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_DEMUXER, "NativeAVSource"};
28 }
29
30 using namespace OHOS::MediaAVCodec;
31
32 class NativeAVDataSource : public OHOS::Media::IMediaDataSource {
33 public:
NativeAVDataSource(OH_AVDataSource * dataSource)34 explicit NativeAVDataSource(OH_AVDataSource *dataSource)
35 : isExt_(false), dataSource_(dataSource), dataSourceExt_(nullptr), userData_(nullptr)
36 {
37 }
38
NativeAVDataSource(OH_AVDataSourceExt * dataSourceExt,void * userData)39 NativeAVDataSource(OH_AVDataSourceExt* dataSourceExt, void* userData)
40 : isExt_(true), dataSource_(nullptr), dataSourceExt_(dataSourceExt), userData_(userData)
41 {
42 }
43
44 virtual ~NativeAVDataSource() = default;
45
ReadAt(const std::shared_ptr<AVSharedMemory> & mem,uint32_t length,int64_t pos=-1)46 int32_t ReadAt(const std::shared_ptr<AVSharedMemory> &mem, uint32_t length, int64_t pos = -1)
47 {
48 std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer(
49 mem->GetBase(), mem->GetSize(), mem->GetSize()
50 );
51 OH_AVBuffer avBuffer(buffer);
52
53 if (isExt_) {
54 return dataSourceExt_->readAt(&avBuffer, length, pos, userData_);
55 } else {
56 return dataSource_->readAt(&avBuffer, length, pos);
57 }
58 }
59
GetSize(int64_t & size)60 int32_t GetSize(int64_t &size)
61 {
62 if (isExt_) {
63 size = dataSourceExt_->size;
64 } else {
65 size = dataSource_->size;
66 }
67 return 0;
68 }
69
ReadAt(int64_t pos,uint32_t length,const std::shared_ptr<AVSharedMemory> & mem)70 int32_t ReadAt(int64_t pos, uint32_t length, const std::shared_ptr<AVSharedMemory> &mem)
71 {
72 return ReadAt(mem, length, pos);
73 }
74
ReadAt(uint32_t length,const std::shared_ptr<AVSharedMemory> & mem)75 int32_t ReadAt(uint32_t length, const std::shared_ptr<AVSharedMemory> &mem)
76 {
77 return ReadAt(mem, length);
78 }
79
80 private:
81 bool isExt_ = false;
82 OH_AVDataSource* dataSource_;
83 OH_AVDataSourceExt* dataSourceExt_ = nullptr;
84 void* userData_ = nullptr;
85 };
86
OH_AVSource_CreateWithURI(char * uri)87 struct OH_AVSource *OH_AVSource_CreateWithURI(char *uri)
88 {
89 CHECK_AND_RETURN_RET_LOG(uri != nullptr, nullptr, "Uri is nullptr");
90
91 std::shared_ptr<AVSource> source = AVSourceFactory::CreateWithURI(uri);
92 CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "New avsource failed");
93
94 struct AVSourceObject *object = new(std::nothrow) AVSourceObject(source);
95 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "New sourceObject failed");
96
97 return object;
98 }
99
OH_AVSource_CreateWithFD(int32_t fd,int64_t offset,int64_t size)100 struct OH_AVSource *OH_AVSource_CreateWithFD(int32_t fd, int64_t offset, int64_t size)
101 {
102 CHECK_AND_RETURN_RET_LOG(fd >= 0, nullptr, "Fd is negative");
103 CHECK_AND_RETURN_RET_LOG(offset >= 0, nullptr, "Offset is negative");
104 CHECK_AND_RETURN_RET_LOG(size > 0, nullptr, "Size must be greater than zero");
105
106 std::shared_ptr<AVSource> source = AVSourceFactory::CreateWithFD(fd, offset, size);
107 CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "New avsource failed");
108 struct AVSourceObject *object = new(std::nothrow) AVSourceObject(source);
109 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "New sourceObject failed");
110 return object;
111 }
112
OH_AVSource_CreateWithDataSource(OH_AVDataSource * dataSource)113 struct OH_AVSource *OH_AVSource_CreateWithDataSource(OH_AVDataSource *dataSource)
114 {
115 CHECK_AND_RETURN_RET_LOG(dataSource != nullptr, nullptr, "Input dataSource is nullptr");
116 CHECK_AND_RETURN_RET_LOG(dataSource->size != 0, nullptr, "Datasource size must be greater than zero");
117 CHECK_AND_RETURN_RET_LOG(dataSource->readAt != nullptr, nullptr, "Datasource readAt is nullptr");
118 std::shared_ptr<NativeAVDataSource> nativeAVDataSource = std::make_shared<NativeAVDataSource>(dataSource);
119 CHECK_AND_RETURN_RET_LOG(nativeAVDataSource != nullptr, nullptr, "New nativeAVDataSource failed");
120
121 std::shared_ptr<AVSource> source = AVSourceFactory::CreateWithDataSource(nativeAVDataSource);
122 CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "New avsource failed");
123
124 struct AVSourceObject *object = new(std::nothrow) AVSourceObject(source);
125 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "New sourceObject failed");
126
127 return object;
128 }
129
OH_AVSource_Destroy(OH_AVSource * source)130 OH_AVErrCode OH_AVSource_Destroy(OH_AVSource *source)
131 {
132 CHECK_AND_RETURN_RET_LOG(source != nullptr, AV_ERR_INVALID_VAL, "Input source is nullptr");
133 CHECK_AND_RETURN_RET_LOG(source->magic_ == AVMagic::AVCODEC_MAGIC_AVSOURCE, AV_ERR_INVALID_VAL, "Magic error");
134
135 delete source;
136 return AV_ERR_OK;
137 }
138
OH_AVSource_GetSourceFormat(OH_AVSource * source)139 OH_AVFormat *OH_AVSource_GetSourceFormat(OH_AVSource *source)
140 {
141 CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "Input source is nullptr");
142 CHECK_AND_RETURN_RET_LOG(source->magic_ == AVMagic::AVCODEC_MAGIC_AVSOURCE, nullptr, "Magic error");
143
144 struct AVSourceObject *sourceObj = reinterpret_cast<AVSourceObject *>(source);
145 CHECK_AND_RETURN_RET_LOG(sourceObj != nullptr, nullptr, "Get sourceObject failed");
146 CHECK_AND_RETURN_RET_LOG(sourceObj->source_ != nullptr, nullptr, "Get sourceObject failed");
147
148 Format format;
149 int32_t ret = sourceObj->source_->GetSourceFormat(format);
150 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Source GetSourceFormat failed");
151
152 OH_AVFormat *avFormat = OH_AVFormat_Create();
153 CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Format is nullptr");
154 avFormat->format_ = format;
155
156 return avFormat;
157 }
158
OH_AVSource_GetTrackFormat(OH_AVSource * source,uint32_t trackIndex)159 OH_AVFormat *OH_AVSource_GetTrackFormat(OH_AVSource *source, uint32_t trackIndex)
160 {
161 CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "Input source is nullptr");
162 CHECK_AND_RETURN_RET_LOG(source->magic_ == AVMagic::AVCODEC_MAGIC_AVSOURCE, nullptr, "Magic error");
163
164 struct AVSourceObject *sourceObj = reinterpret_cast<AVSourceObject *>(source);
165 CHECK_AND_RETURN_RET_LOG(sourceObj != nullptr, nullptr, "Get sourceObject failed");
166 CHECK_AND_RETURN_RET_LOG(sourceObj->source_ != nullptr, nullptr, "Get sourceObject failed");
167
168 Format format;
169 int32_t ret = sourceObj->source_->GetTrackFormat(format, trackIndex);
170 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Source GetTrackFormat failed");
171
172 OH_AVFormat *avFormat = OH_AVFormat_Create();
173 CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Format is nullptr");
174 avFormat->format_ = format;
175
176 return avFormat;
177 }
178
OH_AVSource_GetCustomMetadataFormat(OH_AVSource * source)179 OH_AVFormat *OH_AVSource_GetCustomMetadataFormat(OH_AVSource *source)
180 {
181 CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "Input source is nullptr");
182 CHECK_AND_RETURN_RET_LOG(source->magic_ == AVMagic::AVCODEC_MAGIC_AVSOURCE, nullptr, "Magic error");
183
184 struct AVSourceObject *sourceObj = reinterpret_cast<AVSourceObject *>(source);
185 CHECK_AND_RETURN_RET_LOG(sourceObj != nullptr, nullptr, "Get sourceObject failed");
186 CHECK_AND_RETURN_RET_LOG(sourceObj->source_ != nullptr, nullptr, "Get sourceObject failed");
187
188 Format format;
189 int32_t ret = sourceObj->source_->GetUserMeta(format);
190 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Source GetMetaData failed");
191
192 OH_AVFormat *avFormat = OH_AVFormat_Create();
193 CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Format is nullptr");
194 avFormat->format_ = format;
195
196 return avFormat;
197 }
198
OH_AVSource_CreateWithDataSourceExt(OH_AVDataSourceExt * dataSource,void * userData)199 struct OH_AVSource *OH_AVSource_CreateWithDataSourceExt(OH_AVDataSourceExt *dataSource, void *userData)
200 {
201 CHECK_AND_RETURN_RET_LOG(dataSource != nullptr, nullptr, "Input dataSourceExt is nullptr");
202 CHECK_AND_RETURN_RET_LOG(dataSource->size > 0, nullptr, "DatasourceExt size must be greater than zero");
203 CHECK_AND_RETURN_RET_LOG(dataSource->readAt != nullptr, nullptr, "DatasourceExt readAt is nullptr");
204
205 std::shared_ptr<NativeAVDataSource> nativeAVDataSource = std::make_shared<NativeAVDataSource>(dataSource, userData);
206 CHECK_AND_RETURN_RET_LOG(nativeAVDataSource != nullptr, nullptr, "New nativeAVDataSourceExt failed");
207
208 std::shared_ptr<AVSource> source = AVSourceFactory::CreateWithDataSource(nativeAVDataSource);
209 CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "New avsource failed");
210
211 struct AVSourceObject *object = new(std::nothrow) AVSourceObject(source);
212 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "New sourceObject failed");
213
214 return object;
215 }
216