1 /*
2 * Copyright (c) 2023-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 "reader.h"
17
18 #include "dp_log.h"
19 #include "track_factory.h"
20
21 namespace OHOS {
22 namespace CameraStandard {
23 namespace DeferredProcessing {
24 namespace {
25 constexpr int32_t DEFAULT_INT_VAL = 0;
26 constexpr double DEFAULT_DOUBLE_VAL = 0.0;
27 constexpr int32_t FPS_30 = 30;
28 constexpr int32_t FPS_60 = 60;
29 constexpr double FACTOR = 1.1;
30 }
31
~Reader()32 Reader::~Reader()
33 {
34 source_ = nullptr;
35 sourceFormat_ = nullptr;
36 userFormat_ = nullptr;
37 inputDemuxer_ = nullptr;
38 tracks_.clear();
39 }
40
Create(int32_t inputFd)41 MediaManagerError Reader::Create(int32_t inputFd)
42 {
43 DP_DEBUG_LOG("entered.");
44 DP_CHECK_ERROR_RETURN_RET_LOG(inputFd == INVALID_FD, ERROR_FAIL, "inputFd is invalid: %{public}d.", inputFd);
45
46 auto off = lseek(inputFd, DEFAULT_OFFSET, SEEK_END);
47 DP_CHECK_ERROR_RETURN_RET_LOG(off == static_cast<off_t>(ERROR_FAIL), ERROR_FAIL, "reader lseek failed.");
48 source_ = MediaAVCodec::AVSourceFactory::CreateWithFD(inputFd, DEFAULT_OFFSET, off);
49 DP_CHECK_ERROR_RETURN_RET_LOG(source_ == nullptr, ERROR_FAIL, "create avsource failed.");
50
51 auto ret = GetSourceFormat();
52 DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "get avsource format failed.");
53
54 ret = InitTracksAndDemuxer();
55 DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "init tracks and demuxer failed.");
56 return OK;
57 }
58
GetSourceFormat()59 MediaManagerError Reader::GetSourceFormat()
60 {
61 DP_DEBUG_LOG("entered.");
62 DP_CHECK_ERROR_RETURN_RET_LOG(source_ == nullptr, ERROR_FAIL, "avsource is nullptr.");
63
64 Format sourceFormat;
65 auto ret = source_->GetSourceFormat(sourceFormat);
66 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "get avsource format failed.");
67 sourceFormat_ = std::make_shared<Format>(sourceFormat);
68
69 Format userMeta;
70 ret = source_->GetUserMeta(userMeta);
71 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "get avsource user meta failed.");
72 userFormat_ = std::make_shared<Format>(userMeta);
73 return OK;
74 }
75
InitTracksAndDemuxer()76 MediaManagerError Reader::InitTracksAndDemuxer()
77 {
78 DP_DEBUG_LOG("entered.");
79 DP_CHECK_ERROR_RETURN_RET_LOG(!sourceFormat_->GetIntValue(Tag::MEDIA_TRACK_COUNT, trackCount_), ERROR_FAIL,
80 "get track count failed.");
81
82 for (int32_t index = 0; index < trackCount_; ++index) {
83 auto track = TrackFactory::GetInstance().CreateTrack(source_, index);
84 DP_CHECK_ERROR_RETURN_RET_LOG(track == nullptr, ERROR_FAIL, "track: %{public}d is nullptr", index);
85 DP_DEBUG_LOG("track type: %{public}d", track->GetType());
86 tracks_.emplace(std::pair(track->GetType(), track));
87 }
88 DP_DEBUG_LOG("trackCount num: %{public}d, trackMap size: %{public}d",
89 trackCount_, static_cast<int32_t>(tracks_.size()));
90 inputDemuxer_ = std::make_shared<Demuxer>();
91 auto ret = inputDemuxer_->Create(source_, tracks_);
92 DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "audio demuxer init failed.");
93 return OK;
94 }
95
Read(TrackType trackType,std::shared_ptr<AVBuffer> & sample)96 MediaManagerError Reader::Read(TrackType trackType, std::shared_ptr<AVBuffer>& sample)
97 {
98 DP_CHECK_ERROR_RETURN_RET_LOG(inputDemuxer_ == nullptr, ERROR_FAIL, "demuxer is nullptr.");
99 auto ret = inputDemuxer_->ReadStream(trackType, sample);
100 DP_CHECK_ERROR_RETURN_RET_LOG(ret == ERROR_FAIL, ERROR_FAIL,
101 "read sample failed, track type: %{public}d", trackType);
102 DP_CHECK_RETURN_RET_LOG(ret == EOS, EOS, "reading finished.");
103 return ret;
104 }
105
GetMediaInfo(std::shared_ptr<MediaInfo> & mediaInfo)106 MediaManagerError Reader::GetMediaInfo(std::shared_ptr<MediaInfo>& mediaInfo)
107 {
108 GetSourceMediaInfo(mediaInfo);
109 mediaInfo->streamCount = trackCount_;
110
111 auto it = tracks_.find(TrackType::AV_KEY_VIDEO_TYPE);
112 DP_CHECK_ERROR_RETURN_RET_LOG(it == tracks_.end(), ERROR_FAIL, "no video track.");
113
114 auto videoFormat = it->second->GetFormat();
115 GetTrackMediaInfo(videoFormat, mediaInfo);
116 return OK;
117 }
118
Reset(int64_t resetPts)119 MediaManagerError Reader::Reset(int64_t resetPts)
120 {
121 DP_DEBUG_LOG("entered.");
122 DP_CHECK_ERROR_RETURN_RET_LOG(resetPts < 0, ERROR_FAIL, "invalid reset pts.");
123 DP_CHECK_ERROR_RETURN_RET_LOG(inputDemuxer_ == nullptr, ERROR_FAIL, "demuxer is null.");
124
125 auto ret = inputDemuxer_->SeekToTime(resetPts);
126 DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "reset pts failed.");
127 return OK;
128 }
129
GetSourceMediaInfo(std::shared_ptr<MediaInfo> & mediaInfo) const130 void Reader::GetSourceMediaInfo(std::shared_ptr<MediaInfo>& mediaInfo) const
131 {
132 DP_DEBUG_LOG("entered.");
133 auto ret = sourceFormat_->GetStringValue(Tag::MEDIA_CREATION_TIME, mediaInfo->creationTime);
134 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::MEDIA_CREATION_TIME);
135 ret = sourceFormat_->GetLongValue(Tag::MEDIA_DURATION, mediaInfo->codecInfo.duration);
136 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::MEDIA_DURATION);
137 ret = sourceFormat_->GetStringValue(RECORD_SYSTEM_TIMESTAMP, mediaInfo->recorderTime);
138 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", RECORD_SYSTEM_TIMESTAMP.c_str());
139 ret = sourceFormat_->GetFloatValue(Tag::MEDIA_LATITUDE, mediaInfo->latitude);
140 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::MEDIA_LATITUDE);
141 ret = sourceFormat_->GetFloatValue(Tag::MEDIA_LONGITUDE, mediaInfo->longitude);
142 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::MEDIA_LONGITUDE);
143 }
144
GetTrackMediaInfo(const TrackFormat & trackFormat,std::shared_ptr<MediaInfo> & mediaInfo) const145 MediaManagerError Reader::GetTrackMediaInfo(const TrackFormat& trackFormat,
146 std::shared_ptr<MediaInfo>& mediaInfo) const
147 {
148 DP_DEBUG_LOG("entered.");
149 auto& format = trackFormat.format;
150 auto ret = format->GetStringValue(Tag::MIME_TYPE, mediaInfo->codecInfo.mimeType);
151 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::MIME_TYPE);
152
153 int32_t intVal {DEFAULT_INT_VAL};
154 ret = format->GetIntValue(Tag::VIDEO_COLOR_RANGE, intVal);
155 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_COLOR_RANGE);
156 if (intVal != DEFAULT_INT_VAL) {
157 mediaInfo->codecInfo.colorRange = static_cast<ColorRange>(intVal);
158 }
159 ret = format->GetIntValue(Tag::VIDEO_PIXEL_FORMAT, intVal);
160 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_PIXEL_FORMAT);
161 if (intVal != DEFAULT_INT_VAL) {
162 mediaInfo->codecInfo.pixelFormat = static_cast<PixelFormat>(intVal);
163 }
164 ret = format->GetIntValue(Tag::VIDEO_COLOR_PRIMARIES, intVal);
165 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_COLOR_PRIMARIES);
166 if (intVal != DEFAULT_INT_VAL) {
167 mediaInfo->codecInfo.colorPrimary = static_cast<ColorPrimaries>(intVal);
168 }
169 ret = format->GetIntValue(Tag::VIDEO_COLOR_TRC, intVal);
170 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_COLOR_TRC);
171 if (intVal != DEFAULT_INT_VAL) {
172 mediaInfo->codecInfo.colorTransferCharacter = static_cast<ColorTransferCharacteristic>(intVal);
173 }
174 ret = format->GetIntValue(Tag::VIDEO_IS_HDR_VIVID, mediaInfo->codecInfo.isHdrvivid);
175 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_IS_HDR_VIVID);
176 ret = format->GetIntValue(Tag::MEDIA_PROFILE, mediaInfo->codecInfo.profile);
177 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::MEDIA_PROFILE);
178 ret = format->GetIntValue(Tag::MEDIA_LEVEL, mediaInfo->codecInfo.level);
179 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::MEDIA_LEVEL);
180 ret = format->GetIntValue(Tag::VIDEO_WIDTH, mediaInfo->codecInfo.width);
181 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_WIDTH);
182 ret = format->GetIntValue(Tag::VIDEO_HEIGHT, mediaInfo->codecInfo.height);
183 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_HEIGHT);
184 ret = format->GetIntValue(Tag::VIDEO_ROTATION, mediaInfo->codecInfo.rotation);
185 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_ROTATION);
186 ret = format->GetIntValue(Tag::VIDEO_ENCODE_BITRATE_MODE, mediaInfo->codecInfo.bitMode);
187 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_ENCODE_BITRATE_MODE);
188 ret = format->GetLongValue(Tag::MEDIA_BITRATE, mediaInfo->codecInfo.bitRate);
189 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::MEDIA_BITRATE);
190
191 double doubleVal {DEFAULT_DOUBLE_VAL};
192 ret = format->GetDoubleValue(Tag::VIDEO_FRAME_RATE, doubleVal);
193 DP_CHECK_ERROR_PRINT_LOG(!ret, "cannot get %{public}s", Tag::VIDEO_FRAME_RATE);
194 if (doubleVal !=DEFAULT_DOUBLE_VAL) {
195 mediaInfo->codecInfo.fps = FixFPS(doubleVal);
196 }
197
198 DP_DEBUG_LOG("colorRange: %{public}d, pixelFormat: %{public}d, colorPrimary: %{public}d, "
199 "transfer: %{public}d, profile: %{public}d, level: %{public}d, bitRate: %{public}lld, "
200 "fps: %{public}d, rotation: %{public}d, frame count: %{public}d, mime: %{public}s, isHdrvivid: %{public}d",
201 mediaInfo->codecInfo.colorRange, mediaInfo->codecInfo.pixelFormat, mediaInfo->codecInfo.colorPrimary,
202 mediaInfo->codecInfo.colorTransferCharacter, mediaInfo->codecInfo.profile, mediaInfo->codecInfo.level,
203 static_cast<long long>(mediaInfo->codecInfo.bitRate), mediaInfo->codecInfo.fps, mediaInfo->codecInfo.rotation,
204 mediaInfo->codecInfo.numFrames, mediaInfo->codecInfo.mimeType.c_str(), mediaInfo->codecInfo.isHdrvivid);
205 return OK;
206 }
207
FixFPS(const double fps)208 inline int32_t Reader::FixFPS(const double fps)
209 {
210 return fps < static_cast<double>(FPS_30) * FACTOR ? FPS_30 : FPS_60;
211 }
212 } // namespace DeferredProcessing
213 } // namespace CameraStandard
214 } // namespace OHOS
215