• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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