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 <vector>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include "avcodec_common.h"
19 #include "i_avcodec_service.h"
20 #include "avcodec_errors.h"
21 #include "avcodec_log.h"
22 #include "avcodec_dfx.h"
23 #include "avsource_impl.h"
24
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVSourceImpl"};
27 }
28
29 namespace OHOS {
30 namespace MediaAVCodec {
CreateWithURI(const std::string & uri)31 std::shared_ptr<AVSource> AVSourceFactory::CreateWithURI(const std::string &uri)
32 {
33 AVCodecTrace trace("AVSourceFactory::CreateWithURI");
34
35 AVCODEC_LOGI("create source with uri: uri=%{private}s", uri.c_str());
36
37 std::shared_ptr<AVSourceImpl> sourceImpl = std::make_shared<AVSourceImpl>();
38 CHECK_AND_RETURN_RET_LOG(sourceImpl != nullptr, nullptr, "New AVSourceImpl failed");
39
40 int32_t ret = sourceImpl->InitWithURI(uri);
41
42 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Init AVSourceImpl failed");
43
44 return sourceImpl;
45 }
46
CreateWithFD(int32_t fd,int64_t offset,int64_t size)47 std::shared_ptr<AVSource> AVSourceFactory::CreateWithFD(int32_t fd, int64_t offset, int64_t size)
48 {
49 AVCodecTrace trace("AVSourceFactory::CreateWithFD");
50
51 AVCODEC_LOGI("create source with fd: fd=%{private}d, offset=%{public}" PRId64 ", size=%{public}" PRId64,
52 fd, offset, size);
53
54 std::shared_ptr<AVSourceImpl> sourceImpl = std::make_shared<AVSourceImpl>();
55 CHECK_AND_RETURN_RET_LOG(sourceImpl != nullptr, nullptr, "New AVSourceImpl failed");
56
57 int32_t ret = sourceImpl->InitWithFD(fd, offset, size);
58
59 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Init AVSourceImpl failed");
60
61 return sourceImpl;
62 }
63
InitWithURI(const std::string & uri)64 int32_t AVSourceImpl::InitWithURI(const std::string &uri)
65 {
66 AVCodecTrace trace("AVSource::InitWithURI");
67
68 sourceEngine_ = ISourceEngineFactory::CreateSourceEngine(uri);
69 CHECK_AND_RETURN_RET_LOG(sourceEngine_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Create source engine failed");
70
71 int32_t ret = sourceEngine_->Init();
72 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_INVALID_OPERATION, "Init source engine failed");
73
74 ret = sourceEngine_->GetTrackCount(trackCount_);
75 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_INVALID_OPERATION, "Get track count failed");
76
77 sourceUri = uri;
78 return AVCS_ERR_OK;
79 }
80
InitWithFD(int32_t fd,int64_t offset,int64_t size)81 int32_t AVSourceImpl::InitWithFD(int32_t fd, int64_t offset, int64_t size)
82 {
83 AVCodecTrace trace("AVSource::InitWithFD");
84
85 CHECK_AND_RETURN_RET_LOG(fd > STDERR_FILENO, AVCS_ERR_INVALID_VAL,
86 "Create source with uri failed because input fd is illegal, fd must be greater than 2!");
87 CHECK_AND_RETURN_RET_LOG(offset >= 0, AVCS_ERR_INVALID_VAL,
88 "Create source with fd failed because input offset is negative");
89 CHECK_AND_RETURN_RET_LOG(size > 0, AVCS_ERR_INVALID_VAL,
90 "Create source with fd failed because input size must be greater than zero");
91 int32_t flag = fcntl(fd, F_GETFL, 0);
92 CHECK_AND_RETURN_RET_LOG(flag >= 0, AVCS_ERR_INVALID_VAL, "get fd status failed");
93 CHECK_AND_RETURN_RET_LOG(
94 (static_cast<uint32_t>(flag) & static_cast<uint32_t>(O_WRONLY)) != static_cast<uint32_t>(O_WRONLY),
95 AVCS_ERR_INVALID_VAL, "Fd not be permitted to read ");
96 CHECK_AND_RETURN_RET_LOG(lseek(fd, 0, SEEK_CUR) != -1, AVCS_ERR_INVALID_VAL, "Fd is not seekable");
97
98 std::string uri = "fd://" + std::to_string(fd) + "?offset=" + \
99 std::to_string(offset) + "&size=" + std::to_string(size);
100
101 return InitWithURI(uri);
102 }
103
AVSourceImpl()104 AVSourceImpl::AVSourceImpl()
105 {
106 AVCODEC_LOGD("AVSourceImpl:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
107 }
108
~AVSourceImpl()109 AVSourceImpl::~AVSourceImpl()
110 {
111 AVCODEC_LOGI("Destroy AVSourceImpl for source %{private}s", sourceUri.c_str());
112 if (sourceEngine_ != nullptr) {
113 sourceEngine_ = nullptr;
114 }
115 AVCODEC_LOGD("AVSourceImpl:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
116 }
117
GetSourceAddr(uintptr_t & addr)118 int32_t AVSourceImpl::GetSourceAddr(uintptr_t &addr)
119 {
120 CHECK_AND_RETURN_RET_LOG(sourceEngine_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Source engine does not exist!");
121 addr = sourceEngine_->GetSourceAddr();
122 return AVCS_ERR_OK;
123 }
124
GetSourceFormat(Format & format)125 int32_t AVSourceImpl::GetSourceFormat(Format &format)
126 {
127 AVCodecTrace trace("AVSource::GetSourceFormat");
128
129 CHECK_AND_RETURN_RET_LOG(sourceEngine_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Source engine does not exist!");
130
131 return sourceEngine_->GetSourceFormat(format);
132 }
133
GetTrackFormat(Format & format,uint32_t trackIndex)134 int32_t AVSourceImpl::GetTrackFormat(Format &format, uint32_t trackIndex)
135 {
136 AVCodecTrace trace("AVSource::GetTrackFormat");
137
138 AVCODEC_LOGI("get track format: trackIndex=%{public}u", trackIndex);
139
140 CHECK_AND_RETURN_RET_LOG(sourceEngine_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Source engine does not exist!");
141
142 bool isValid = (trackIndex < trackCount_);
143 CHECK_AND_RETURN_RET_LOG(isValid, AVCS_ERR_INVALID_VAL, "track index is invalid!");
144
145 return sourceEngine_->GetTrackFormat(format, trackIndex);
146 }
147 } // namespace MediaAVCodec
148 } // namespace OHOS