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         : dataSource_(dataSource)
36     {
37     }
38     virtual ~NativeAVDataSource() = default;
39 
ReadAt(const std::shared_ptr<AVSharedMemory> & mem,uint32_t length,int64_t pos=-1)40     int32_t ReadAt(const std::shared_ptr<AVSharedMemory> &mem, uint32_t length, int64_t pos = -1)
41     {
42         std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer(
43             mem->GetBase(), mem->GetSize(), mem->GetSize()
44         );
45         OH_AVBuffer avBuffer(buffer);
46         return dataSource_->readAt(&avBuffer, length, pos);
47     }
48 
GetSize(int64_t & size)49     int32_t GetSize(int64_t &size)
50     {
51         size = dataSource_->size;
52         return 0;
53     }
54 
ReadAt(int64_t pos,uint32_t length,const std::shared_ptr<AVSharedMemory> & mem)55     int32_t ReadAt(int64_t pos, uint32_t length, const std::shared_ptr<AVSharedMemory> &mem)
56     {
57         return ReadAt(mem, length, pos);
58     }
59 
ReadAt(uint32_t length,const std::shared_ptr<AVSharedMemory> & mem)60     int32_t ReadAt(uint32_t length, const std::shared_ptr<AVSharedMemory> &mem)
61     {
62         return ReadAt(mem, length);
63     }
64 
65 private:
66     OH_AVDataSource* dataSource_;
67 };
68 
OH_AVSource_CreateWithURI(char * uri)69 struct OH_AVSource *OH_AVSource_CreateWithURI(char *uri)
70 {
71     CHECK_AND_RETURN_RET_LOG(uri != nullptr, nullptr, "Uri is nullptr");
72 
73     std::shared_ptr<AVSource> source = AVSourceFactory::CreateWithURI(uri);
74     CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "New avsource failed");
75 
76     struct AVSourceObject *object = new(std::nothrow) AVSourceObject(source);
77     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "New sourceObject failed");
78 
79     return object;
80 }
81 
OH_AVSource_CreateWithFD(int32_t fd,int64_t offset,int64_t size)82 struct OH_AVSource *OH_AVSource_CreateWithFD(int32_t fd, int64_t offset, int64_t size)
83 {
84     CHECK_AND_RETURN_RET_LOG(fd >= 0, nullptr, "Fd is negative");
85     CHECK_AND_RETURN_RET_LOG(offset >= 0, nullptr, "Offset is negative");
86     CHECK_AND_RETURN_RET_LOG(size > 0, nullptr, "Size must be greater than zero");
87 
88     std::shared_ptr<AVSource> source = AVSourceFactory::CreateWithFD(fd, offset, size);
89     CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "New avsource failed");
90     struct AVSourceObject *object = new(std::nothrow) AVSourceObject(source);
91     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "New sourceObject failed");
92     return object;
93 }
94 
OH_AVSource_CreateWithDataSource(OH_AVDataSource * dataSource)95 struct OH_AVSource *OH_AVSource_CreateWithDataSource(OH_AVDataSource *dataSource)
96 {
97     CHECK_AND_RETURN_RET_LOG(dataSource != nullptr, nullptr, "Input dataSource is nullptr");
98     CHECK_AND_RETURN_RET_LOG(dataSource->size != 0, nullptr, "Datasource size must be greater than zero");
99     std::shared_ptr<NativeAVDataSource> nativeAVDataSource = std::make_shared<NativeAVDataSource>(dataSource);
100     CHECK_AND_RETURN_RET_LOG(nativeAVDataSource != nullptr, nullptr, "New nativeAVDataSource failed");
101 
102     std::shared_ptr<AVSource> source = AVSourceFactory::CreateWithDataSource(nativeAVDataSource);
103     CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "New avsource failed");
104 
105     struct AVSourceObject *object = new(std::nothrow) AVSourceObject(source);
106     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "New sourceObject failed");
107 
108     return object;
109 }
110 
OH_AVSource_Destroy(OH_AVSource * source)111 OH_AVErrCode OH_AVSource_Destroy(OH_AVSource *source)
112 {
113     CHECK_AND_RETURN_RET_LOG(source != nullptr, AV_ERR_INVALID_VAL, "Input source is nullptr");
114     CHECK_AND_RETURN_RET_LOG(source->magic_ == AVMagic::AVCODEC_MAGIC_AVSOURCE, AV_ERR_INVALID_VAL, "Magic error");
115 
116     delete source;
117     return AV_ERR_OK;
118 }
119 
OH_AVSource_GetSourceFormat(OH_AVSource * source)120 OH_AVFormat *OH_AVSource_GetSourceFormat(OH_AVSource *source)
121 {
122     CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "Input source is nullptr");
123     CHECK_AND_RETURN_RET_LOG(source->magic_ == AVMagic::AVCODEC_MAGIC_AVSOURCE, nullptr, "Magic error");
124 
125     struct AVSourceObject *sourceObj = reinterpret_cast<AVSourceObject *>(source);
126     CHECK_AND_RETURN_RET_LOG(sourceObj != nullptr, nullptr, "Get sourceObject failed");
127     CHECK_AND_RETURN_RET_LOG(sourceObj->source_ != nullptr, nullptr, "Get sourceObject failed");
128 
129     Format format;
130     int32_t ret = sourceObj->source_->GetSourceFormat(format);
131     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Source GetSourceFormat failed");
132 
133     OH_AVFormat *avFormat = OH_AVFormat_Create();
134     CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Format is nullptr");
135     avFormat->format_ = format;
136 
137     return avFormat;
138 }
139 
OH_AVSource_GetTrackFormat(OH_AVSource * source,uint32_t trackIndex)140 OH_AVFormat *OH_AVSource_GetTrackFormat(OH_AVSource *source, uint32_t trackIndex)
141 {
142     CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "Input source is nullptr");
143     CHECK_AND_RETURN_RET_LOG(source->magic_ == AVMagic::AVCODEC_MAGIC_AVSOURCE, nullptr, "Magic error");
144 
145     struct AVSourceObject *sourceObj = reinterpret_cast<AVSourceObject *>(source);
146     CHECK_AND_RETURN_RET_LOG(sourceObj != nullptr, nullptr, "Get sourceObject failed");
147     CHECK_AND_RETURN_RET_LOG(sourceObj->source_ != nullptr, nullptr, "Get sourceObject failed");
148 
149     Format format;
150     int32_t ret = sourceObj->source_->GetTrackFormat(format, trackIndex);
151     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Source GetTrackFormat failed");
152 
153     OH_AVFormat *avFormat = OH_AVFormat_Create();
154     CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Format is nullptr");
155     avFormat->format_ = format;
156 
157     return avFormat;
158 }