• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2024 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_utils.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     inputDemuxer_ = nullptr;
37     tracks_.clear();
38 }
39 
Create(int32_t inputFd)40 MediaManagerError Reader::Create(int32_t inputFd)
41 {
42     DP_DEBUG_LOG("entered.");
43     DP_CHECK_ERROR_RETURN_RET_LOG(inputFd == INVALID_FD, ERROR_FAIL, "inputFd is invalid: %{public}d.", inputFd);
44 
45     auto off = lseek(inputFd, DEFAULT_OFFSET, SEEK_END);
46     DP_CHECK_ERROR_RETURN_RET_LOG(off == static_cast<off_t>(ERROR_FAIL), ERROR_FAIL, "Reader lseek failed.");
47     source_ = MediaAVCodec::AVSourceFactory::CreateWithFD(inputFd, DEFAULT_OFFSET, off);
48     DP_CHECK_ERROR_RETURN_RET_LOG(source_ == nullptr, ERROR_FAIL, "Create avsource failed.");
49 
50     auto ret = GetSourceFormat();
51     DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Get avsource format failed.");
52 
53     ret = GetUserMeta();
54     DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Get user format failed.");
55 
56     ret = InitTracksAndDemuxer();
57     DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Init tracks and demuxer failed.");
58     return OK;
59 }
60 
GetSourceFormat()61 MediaManagerError Reader::GetSourceFormat()
62 {
63     DP_DEBUG_LOG("entered.");
64     DP_CHECK_ERROR_RETURN_RET_LOG(source_ == nullptr, ERROR_FAIL, "AVSource is nullptr.");
65 
66     Format sourceFormat;
67     auto ret = source_->GetSourceFormat(sourceFormat);
68     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "Get avsource format failed.");
69     sourceFormat_ = std::make_shared<Format>(sourceFormat);
70     return OK;
71 }
72 
GetUserMeta()73 MediaManagerError Reader::GetUserMeta()
74 {
75     DP_DEBUG_LOG("entered.");
76     DP_CHECK_ERROR_RETURN_RET_LOG(source_ == nullptr, ERROR_FAIL, "AVSource is nullptr.");
77 
78     Format userFormat;
79     auto ret = source_->GetUserMeta(userFormat);
80     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "Get user format failed.");
81     userFormat_ = std::make_shared<Format>(userFormat);
82     return OK;
83 }
84 
InitTracksAndDemuxer()85 MediaManagerError Reader::InitTracksAndDemuxer()
86 {
87     DP_DEBUG_LOG("entered.");
88     DP_CHECK_ERROR_RETURN_RET_LOG(!sourceFormat_->GetIntValue(Tag::MEDIA_TRACK_COUNT, trackCount_), ERROR_FAIL,
89         "Get track count failed.");
90 
91     for (int32_t index = 0; index < trackCount_; ++index) {
92         auto track = TrackFactory::GetInstance().CreateTrack(source_, index);
93         DP_LOOP_CONTINUE_LOG(track == nullptr, "Track index: %{public}d is nullptr.", index);
94         tracks_.emplace(std::pair(track->GetType(), track));
95     }
96     DP_DEBUG_LOG("TrackCount num: %{public}d, trackMap size: %{public}d",
97         trackCount_, static_cast<int32_t>(tracks_.size()));
98     inputDemuxer_ = std::make_shared<Demuxer>();
99     auto ret = inputDemuxer_->Create(source_, tracks_);
100     DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Audio demuxer init failed.");
101     return OK;
102 }
103 
Read(Media::Plugins::MediaType trackType,std::shared_ptr<AVBuffer> & sample)104 MediaManagerError Reader::Read(Media::Plugins::MediaType trackType, std::shared_ptr<AVBuffer>& sample)
105 {
106     DP_CHECK_ERROR_RETURN_RET_LOG(inputDemuxer_ == nullptr, ERROR_FAIL, "Demuxer is nullptr.");
107     auto ret = inputDemuxer_->ReadStream(trackType, sample);
108     DP_CHECK_ERROR_RETURN_RET_LOG(ret == ERROR_FAIL, ERROR_FAIL,
109         "Read sample failed, track type: %{public}d", trackType);
110     DP_CHECK_RETURN_RET_LOG(ret == EOS, EOS, "Reading finished.");
111     return ret;
112 }
113 
GetMediaInfo(std::shared_ptr<MediaInfo> & mediaInfo)114 MediaManagerError Reader::GetMediaInfo(std::shared_ptr<MediaInfo>& mediaInfo)
115 {
116     GetSourceMediaInfo(mediaInfo);
117     mediaInfo->streamCount = trackCount_;
118 
119     auto it = tracks_.find(Media::Plugins::MediaType::VIDEO);
120     DP_CHECK_ERROR_RETURN_RET_LOG(it == tracks_.end(), ERROR_FAIL, "Not find video track.");
121 
122     auto videoFormat = it->second->GetFormat();
123     GetTrackMediaInfo(videoFormat, mediaInfo);
124     return OK;
125 }
126 
Reset(int64_t resetPts)127 MediaManagerError Reader::Reset(int64_t resetPts)
128 {
129     DP_DEBUG_LOG("entered.");
130     DP_CHECK_ERROR_RETURN_RET_LOG(resetPts < 0, ERROR_FAIL, "Invalid reset pts.");
131     DP_CHECK_ERROR_RETURN_RET_LOG(inputDemuxer_ == nullptr, ERROR_FAIL, "Demuxer is null.");
132 
133     auto ret = inputDemuxer_->SeekToTime(resetPts);
134     DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Reset pts failed.");
135     return OK;
136 }
137 
GetSourceMediaInfo(std::shared_ptr<MediaInfo> & mediaInfo) const138 void Reader::GetSourceMediaInfo(std::shared_ptr<MediaInfo>& mediaInfo) const
139 {
140     CheckAndGetValue(sourceFormat_, Tag::MEDIA_CREATION_TIME, mediaInfo->creationTime);
141     CheckAndGetValue(sourceFormat_, Tag::MEDIA_DURATION, mediaInfo->codecInfo.duration);
142     CheckAndGetValue(sourceFormat_, Tag::MEDIA_LATITUDE, mediaInfo->latitude);
143     CheckAndGetValue(sourceFormat_, Tag::MEDIA_LONGITUDE, mediaInfo->longitude);
144     CheckAndGetValue(userFormat_, LIVE_PHOTO_COVERTIME, mediaInfo->livePhotoCovertime);
145     std::string encParam;
146     CheckAndGetValue(userFormat_, STAGE_ENC_PARAM_KEY, encParam);
147     auto result = ParseKeyValue(encParam);
148     for (const auto& [tag, value] : result) {
149         if (tag == Tag::VIDEO_ENCODE_BITRATE_MODE) {
150             mediaInfo->codecInfo.bitMode = MapVideoBitrateMode(value);
151         } else if (tag == Tag::MEDIA_BITRATE) {
152             int64_t bitRate;
153             DP_CHECK_EXECUTE(StrToI64(value, bitRate), mediaInfo->codecInfo.bitRate = bitRate);
154         }
155     }
156     DP_INFO_LOG("MediaInfo creationTime: %{public}s, duration: %{public}" PRId64 ", livePhotoCovertime: %{public}f, "
157         "bitMode: %{public}d, bitRate: %{public}" PRId64,
158         mediaInfo->creationTime.c_str(), mediaInfo->codecInfo.duration, mediaInfo->livePhotoCovertime,
159         mediaInfo->codecInfo.bitMode, mediaInfo->codecInfo.bitRate);
160 }
161 
GetTrackMediaInfo(const TrackFormat & trackFormat,std::shared_ptr<MediaInfo> & mediaInfo) const162 MediaManagerError Reader::GetTrackMediaInfo(const TrackFormat& trackFormat,
163     std::shared_ptr<MediaInfo>& mediaInfo) const
164 {
165     auto& format = trackFormat.format;
166     CheckAndGetValue(format, Tag::MIME_TYPE, mediaInfo->codecInfo.mimeType);
167     CheckAndGetValue(format, Tag::MEDIA_PROFILE, mediaInfo->codecInfo.profile);
168     CheckAndGetValue(format, Tag::MEDIA_LEVEL, mediaInfo->codecInfo.level);
169     CheckAndGetValue(format, Tag::VIDEO_WIDTH, mediaInfo->codecInfo.width);
170     CheckAndGetValue(format, Tag::VIDEO_HEIGHT, mediaInfo->codecInfo.height);
171     CheckAndGetValue(format, Tag::VIDEO_ROTATION, mediaInfo->codecInfo.rotation);
172     DP_CHECK_EXECUTE(mediaInfo->codecInfo.bitRate == 0,
173         CheckAndGetValue(format, Tag::MEDIA_BITRATE, mediaInfo->codecInfo.bitRate));
174 
175     int32_t intVal {DEFAULT_INT_VAL};
176     if (CheckAndGetValue(format, Tag::VIDEO_COLOR_RANGE, intVal)) {
177         mediaInfo->codecInfo.colorRange = static_cast<ColorRange>(intVal);
178     }
179     if (CheckAndGetValue(format, Tag::VIDEO_PIXEL_FORMAT, intVal)) {
180         mediaInfo->codecInfo.pixelFormat = static_cast<Media::Plugins::VideoPixelFormat>(intVal);
181     }
182     if (CheckAndGetValue(format, Tag::VIDEO_COLOR_PRIMARIES, intVal)) {
183         mediaInfo->codecInfo.colorPrimary = static_cast<Media::Plugins::ColorPrimary>(intVal);
184     }
185     if (CheckAndGetValue(format, Tag::VIDEO_COLOR_TRC, intVal)) {
186         mediaInfo->codecInfo.colorTransferCharacter = static_cast<Media::Plugins::TransferCharacteristic>(intVal);
187     }
188     if (CheckAndGetValue(format, Tag::VIDEO_IS_HDR_VIVID, intVal)) {
189         mediaInfo->codecInfo.isHdrvivid = static_cast<bool>(intVal);
190     }
191 
192     double doubleVal {DEFAULT_DOUBLE_VAL};
193     if (CheckAndGetValue(format, Tag::VIDEO_FRAME_RATE, doubleVal)) {
194         mediaInfo->codecInfo.fps = FixFPS(doubleVal);
195     }
196 
197     DP_INFO_LOG("TrackMediaInfo colorRange: %{public}d, pixelFormat: %{public}d, colorPrimary: %{public}d, "
198         "transfer: %{public}d, profile: %{public}d, level: %{public}d, bitRate: %{public}" PRId64 ", "
199         "fps: %{public}d, rotation: %{public}d, mime: %{public}s, isHdrvivid: %{public}d",
200         mediaInfo->codecInfo.colorRange, mediaInfo->codecInfo.pixelFormat, mediaInfo->codecInfo.colorPrimary,
201         mediaInfo->codecInfo.colorTransferCharacter, mediaInfo->codecInfo.profile, mediaInfo->codecInfo.level,
202         mediaInfo->codecInfo.bitRate, mediaInfo->codecInfo.fps, mediaInfo->codecInfo.rotation,
203         mediaInfo->codecInfo.mimeType.c_str(), mediaInfo->codecInfo.isHdrvivid);
204     return OK;
205 }
206 
FixFPS(const double fps)207 inline int32_t Reader::FixFPS(const double fps)
208 {
209     return fps < static_cast<double>(FPS_30) * FACTOR ? FPS_30 : FPS_60;
210 }
211 
MapVideoBitrateMode(const std::string & modeName) const212 Media::Plugins::VideoEncodeBitrateMode Reader::MapVideoBitrateMode(const std::string& modeName) const
213 {
214     static const std::unordered_map<std::string, Media::Plugins::VideoEncodeBitrateMode> modeMap = {
215         {"CBR", Media::Plugins::VideoEncodeBitrateMode::CBR},
216         {"VBR", Media::Plugins::VideoEncodeBitrateMode::VBR},
217         {"CQ", Media::Plugins::VideoEncodeBitrateMode::CQ},
218         {"CRF", Media::Plugins::VideoEncodeBitrateMode::CRF},
219         {"SQR", Media::Plugins::VideoEncodeBitrateMode::SQR},
220         {"CBR_VIDEOCALL", Media::Plugins::VideoEncodeBitrateMode::CBR_VIDEOCALL}
221     };
222     auto it = modeMap.find(modeName);
223     DP_CHECK_RETURN_RET(it == modeMap.end(), Media::Plugins::VideoEncodeBitrateMode::CBR);
224     return it->second;
225 }
226 } // namespace DeferredProcessing
227 } // namespace CameraStandard
228 } // namespace OHOS
229