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 "demuxer.h"
17 
18 #include "dp_log.h"
19 
20 namespace OHOS {
21 namespace CameraStandard {
22 namespace DeferredProcessing {
23 namespace {
24     constexpr int32_t INVALID_TRACK_ID = -1;
25 }
26 
~Demuxer()27 Demuxer::~Demuxer()
28 {
29     DP_DEBUG_LOG("entered.");
30     demuxer_ = nullptr;
31 }
32 
Create(const std::shared_ptr<AVSource> & source,const std::map<TrackType,const std::shared_ptr<Track>> & tracks)33 MediaManagerError Demuxer::Create(const std::shared_ptr<AVSource>& source,
34     const std::map<TrackType, const std::shared_ptr<Track>>& tracks)
35 {
36     DP_CHECK_ERROR_RETURN_RET_LOG(source == nullptr, ERROR_FAIL, "source is nullptr.");
37 
38     demuxer_ = AVDemuxerFactory::CreateWithSource(source);
39     DP_CHECK_ERROR_RETURN_RET_LOG(demuxer_ == nullptr, ERROR_FAIL, "create demuxer failed.");
40 
41     auto ret = OK;
42     DP_INFO_LOG("tracks size: %{public}d", static_cast<int32_t>(tracks.size()));
43     auto iter = tracks.cbegin();
44     for (; iter != tracks.cend(); ++iter) {
45         auto trackFormat = iter->second->GetFormat();
46         if (iter->first == TrackType::AV_KEY_AUDIO_TYPE) {
47             audioTrackId_ = trackFormat.trackId;
48         }
49         if (iter->first == TrackType::AV_KEY_VIDEO_TYPE) {
50             videoTrackId_ = trackFormat.trackId;
51         }
52         DP_DEBUG_LOG("track id: %{public}d, track type: %{public}d", trackFormat.trackId, iter->first);
53         ret = SeletctTrackByID(trackFormat.trackId);
54         DP_CHECK_ERROR_BREAK_LOG(ret != OK, "select track by id failed, track type: %{public}d", iter->first);
55     }
56     return ret;
57 }
58 
ReadStream(TrackType trackType,std::shared_ptr<AVBuffer> & sample)59 MediaManagerError Demuxer::ReadStream(TrackType trackType, std::shared_ptr<AVBuffer>& sample)
60 {
61     DP_DEBUG_LOG("entered.");
62     int32_t trackId = INVALID_TRACK_ID;
63     if (trackType == TrackType::AV_KEY_VIDEO_TYPE) {
64         trackId = videoTrackId_;
65     }
66     if (trackType == TrackType::AV_KEY_AUDIO_TYPE) {
67         trackId = audioTrackId_;
68     }
69 
70     DP_CHECK_ERROR_RETURN_RET_LOG(trackId == INVALID_TRACK_ID, ERROR_FAIL, "invalid track id.");
71     auto ret = demuxer_->ReadSampleBuffer(trackId, sample);
72     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "read sample failed.");
73     DP_CHECK_RETURN_RET_LOG(sample->flag_ == AVCODEC_BUFFER_FLAG_EOS, EOS, "track(%{public}d) is end.", trackId);
74     return OK;
75 }
76 
SeekToTime(int64_t lastPts)77 MediaManagerError Demuxer::SeekToTime(int64_t lastPts)
78 {
79     DP_DEBUG_LOG("entered.");
80     DP_CHECK_ERROR_RETURN_RET_LOG(lastPts < 0, ERROR_FAIL, "don't need to seek, demuxer from start.");
81     auto ret = demuxer_->SeekToTime(lastPts / 1000, SeekMode::SEEK_PREVIOUS_SYNC);
82     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "failed to seek.");
83     return OK;
84 }
85 
SeletctTrackByID(int32_t trackId)86 MediaManagerError Demuxer::SeletctTrackByID(int32_t trackId)
87 {
88     DP_DEBUG_LOG("entered.");
89     auto ret = demuxer_->SelectTrackByID(trackId);
90     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "select track by id failed.");
91     return OK;
92 }
93 } // namespace DeferredProcessing
94 } // namespace CameraStandard
95 } // namespace OHOS
96