• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 <sys/stat.h>
17 #include "media_log.h"
18 #include <native_avcapability.h>
19 #include <native_avcodec_videoencoder.h>
20 #include <native_averrors.h>
21 #include <native_avformat.h>
22 #include "codec/video/decoder/video_demuxer.h"
23 
24 namespace OHOS {
25 namespace Media {
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_VIDEOEDITOR, "VideoEditorDemuxer"};
28 }
29 
VideoDeMuxer(uint64_t id,int fd)30 VideoDeMuxer::VideoDeMuxer(uint64_t id, int fd) : fd_(fd)
31 {
32     logTag_ = "video-demuxer-" + std::to_string(id);
33 }
34 
~VideoDeMuxer()35 VideoDeMuxer::~VideoDeMuxer()
36 {
37     MEDIA_LOGI("[%{public}s] video deMuxer destruct begin.", logTag_.c_str());
38     if (sourceFormat_) {
39         OH_AVFormat_Destroy(sourceFormat_);
40         sourceFormat_ = nullptr;
41     }
42     if (videoFormat_) {
43         OH_AVFormat_Destroy(videoFormat_);
44         videoFormat_ = nullptr;
45     }
46     if (audioFormat_) {
47         OH_AVFormat_Destroy(audioFormat_);
48         audioFormat_ = nullptr;
49     }
50     if (deMuxer_) {
51         OH_AVDemuxer_Destroy(deMuxer_);
52         deMuxer_ = nullptr;
53     }
54     if (source_) {
55         OH_AVSource_Destroy(source_);
56         source_ = nullptr;
57     }
58     MEDIA_LOGI("[%{public}s] video deMuxer destruct finish.", logTag_.c_str());
59 }
60 
Init()61 VEFError VideoDeMuxer::Init()
62 {
63     MEDIA_LOGI("[%{public}s] init, source file fd: %{public}d.", logTag_.c_str(), fd_);
64     struct stat st;
65     if (fstat(fd_, &st) != 0) {
66         MEDIA_LOGE("[%{public}s] init failed, fstat file failed with error: %{public}d.", logTag_.c_str(), errno);
67         return VEFError::ERR_INTERNAL_ERROR;
68     }
69     MEDIA_LOGI("[%{public}s] init, source file size: %{public}" PRIu64 ".", logTag_.c_str(), st.st_size);
70     source_ = OH_AVSource_CreateWithFD(fd_, 0, st.st_size);
71     if (source_ == nullptr) {
72         MEDIA_LOGE("[%{public}s] init failed, OH_AVSource_CreateWithFD failed.", logTag_.c_str());
73         return VEFError::ERR_INTERNAL_ERROR;
74     }
75     deMuxer_ = OH_AVDemuxer_CreateWithSource(source_);
76     if (deMuxer_ == nullptr) {
77         MEDIA_LOGE("[%{public}s] init failed, OH_AVDemuxer_CreateWithSource failed.", logTag_.c_str());
78         return VEFError::ERR_INTERNAL_ERROR;
79     }
80     sourceFormat_ = OH_AVSource_GetSourceFormat(source_);
81     if (sourceFormat_ == nullptr) {
82         MEDIA_LOGE("[%{public}s] init failed, OH_AVSource_GetSourceFormat failed.", logTag_.c_str());
83         return VEFError::ERR_INTERNAL_ERROR;
84     }
85 
86     VEFError error = ParseTrackInfo();
87     if (error != VEFError::ERR_OK) {
88         MEDIA_LOGE("[%{public}s] init failed, parse track info with error: %{public}d.", logTag_.c_str(), error);
89         return VEFError::ERR_INTERNAL_ERROR;
90     }
91 
92     MEDIA_LOGI("[%{public}s] init success.", logTag_.c_str());
93     return VEFError::ERR_OK;
94 }
95 
ParseTrackInfo()96 VEFError VideoDeMuxer::ParseTrackInfo()
97 {
98     int32_t trackCount = 0;
99     if (!OH_AVFormat_GetIntValue(sourceFormat_, OH_MD_KEY_TRACK_COUNT, &trackCount)) {
100         MEDIA_LOGE("[%{public}s] get [%{public}s] from source format failed.", logTag_.c_str(), OH_MD_KEY_TRACK_COUNT);
101         return VEFError::ERR_INTERNAL_ERROR;
102     }
103     MEDIA_LOGI("[%{public}s] get track count = %{public}d.", logTag_.c_str(), trackCount);
104 
105     for (int32_t trackIndex = 0; trackIndex < trackCount; trackIndex++) {
106         OH_AVFormat* trackFormat = OH_AVSource_GetTrackFormat(source_, trackIndex);
107         if (trackFormat == nullptr) {
108             MEDIA_LOGE("[%{public}s] get track format of track[%{public}d] failed.", logTag_.c_str(), trackIndex);
109             continue;
110         }
111         int32_t trackType;
112         if (!OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &trackType)) {
113             MEDIA_LOGE("[%{public}s] get track type of track[%{public}d] failed.", logTag_.c_str(), trackIndex);
114             continue;
115         }
116         if (trackType == OH_MediaType::MEDIA_TYPE_VID) {
117             videoFormat_ = trackFormat;
118             videoTrackId_ = trackIndex;
119             MEDIA_LOGI("[%{public}s] get video track success, track id = %{public}d.", logTag_.c_str(), trackIndex);
120         } else if (trackType == OH_MediaType::MEDIA_TYPE_AUD) {
121             audioFormat_ = trackFormat;
122             audioTrackId_ = trackIndex;
123             MEDIA_LOGI("[%{public}s] get audio track success, track id = %{public}d.", logTag_.c_str(), trackIndex);
124         }
125     }
126 
127     if (videoTrackId_ == -1 || videoFormat_ == nullptr) {
128         MEDIA_LOGE("[%{public}s] get video track failed.", logTag_.c_str());
129         return VEFError::ERR_INTERNAL_ERROR;
130     }
131 
132     if (audioTrackId_ == -1 || audioFormat_ == nullptr) {
133         audioTrackId_ = -1;
134         audioFormat_ = nullptr;
135         MEDIA_LOGW("[%{public}s] no invalid audio track.", logTag_.c_str());
136     } else {
137         auto ret = OH_AVDemuxer_SelectTrackByID(deMuxer_, audioTrackId_);
138         if (ret != AV_ERR_OK) {
139             MEDIA_LOGE("[%{public}s] select audio track failed with error: %{public}d.", logTag_.c_str(), ret);
140             return VEFError::ERR_INTERNAL_ERROR;
141         }
142     }
143 
144     auto ret = OH_AVDemuxer_SelectTrackByID(deMuxer_, videoTrackId_);
145     if (ret != AV_ERR_OK) {
146         MEDIA_LOGE("[%{public}s] select video track failed with error: %{public}d.", logTag_.c_str(), ret);
147         return VEFError::ERR_INTERNAL_ERROR;
148     }
149     return VEFError::ERR_OK;
150 }
151 
GetVideoFormat() const152 OH_AVFormat* VideoDeMuxer::GetVideoFormat() const
153 {
154     return videoFormat_;
155 }
156 
GetAudioFormat() const157 OH_AVFormat* VideoDeMuxer::GetAudioFormat() const
158 {
159     return audioFormat_;
160 }
161 
GetSourceFormat() const162 OH_AVFormat* VideoDeMuxer::GetSourceFormat() const
163 {
164     return sourceFormat_;
165 }
166 
ReadVideoData(OH_AVMemory * data,OH_AVCodecBufferAttr * attr)167 VEFError VideoDeMuxer::ReadVideoData(OH_AVMemory* data, OH_AVCodecBufferAttr* attr)
168 {
169     auto ret = OH_AVDemuxer_ReadSample(deMuxer_, videoTrackId_, data, attr);
170     if (ret != AV_ERR_OK) {
171         MEDIA_LOGE("[%{public}s] read video packet failed, OH_AVDemuxer_ReadSample return: %{public}d.",
172             logTag_.c_str(), ret);
173         return VEFError::ERR_INTERNAL_ERROR;
174     }
175     return VEFError::ERR_OK;
176 }
177 
ReadAudioData(OH_AVMemory * data,OH_AVCodecBufferAttr * attr)178 VEFError VideoDeMuxer::ReadAudioData(OH_AVMemory* data, OH_AVCodecBufferAttr* attr)
179 {
180     auto ret = OH_AVDemuxer_ReadSample(deMuxer_, audioTrackId_, data, attr);
181     if (ret != AV_ERR_OK) {
182         MEDIA_LOGE("[%{public}s] read audio packet failed, OH_AVDemuxer_ReadSample return: %{public}d.",
183             logTag_.c_str(), ret);
184         return VEFError::ERR_INTERNAL_ERROR;
185     }
186     return VEFError::ERR_OK;
187 }
188 } // namespace Media
189 } // namespace OHOS
190