• 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 "media_log.h"
17 #include <native_avcapability.h>
18 #include <native_avcodec_videoencoder.h>
19 #include <native_averrors.h>
20 #include <native_avformat.h>
21 #include "codec/video/encoder/video_muxer.h"
22 
23 namespace OHOS {
24 namespace Media {
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_VIDEOEDITOR, "VideoEditorMuxer"};
27 }
28 
VideoMuxer(uint64_t id)29 VideoMuxer::VideoMuxer(uint64_t id)
30 {
31     logTag_ = "video-muxer-" + std::to_string(id);
32 }
33 
~VideoMuxer()34 VideoMuxer::~VideoMuxer()
35 {
36     MEDIA_LOGD("[%{public}s] video muxer destruct begin.", logTag_.c_str());
37     if (muxer_) {
38         OH_AVMuxer_Destroy(muxer_);
39         muxer_ = nullptr;
40     }
41     MEDIA_LOGD("[%{public}s] video muxer destruct finish.", logTag_.c_str());
42 }
43 
Start()44 VEFError VideoMuxer::Start()
45 {
46     MEDIA_LOGI("[%{public}s] start muxer.", logTag_.c_str());
47     OH_AVErrCode error = OH_AVMuxer_Start(muxer_);
48     if (error != AV_ERR_OK) {
49         MEDIA_LOGE("[%{public}s] start muxer failed, OH_AVMuxer_Start return: %{public}d.", logTag_.c_str(), error);
50         return VEFError::ERR_INTERNAL_ERROR;
51     }
52     MEDIA_LOGI("[%{public}s] start muxer success.", logTag_.c_str());
53     return VEFError::ERR_OK;
54 }
55 
Stop()56 VEFError VideoMuxer::Stop()
57 {
58     MEDIA_LOGI("[%{public}s] stop muxer.", logTag_.c_str());
59     OH_AVErrCode error = OH_AVMuxer_Stop(muxer_);
60     if (error != AV_ERR_OK) {
61         MEDIA_LOGE("[%{public}s] stop muxer failed, OH_AVMuxer_Stop return: %{public}d.", logTag_.c_str(), error);
62         return VEFError::ERR_INTERNAL_ERROR;
63     }
64     MEDIA_LOGI("[%{public}s] stop muxer success.", logTag_.c_str());
65     return VEFError::ERR_OK;
66 }
67 
Init(const VideoMuxerParam & muxerParam)68 VEFError VideoMuxer::Init(const VideoMuxerParam& muxerParam)
69 {
70     MEDIA_LOGD("[%{public}s] init video muxer, format = %{public}d, rotation = %{public}d.", logTag_.c_str(),
71         muxerParam.avOutputFormat, muxerParam.rotation);
72     muxer_ = OH_AVMuxer_Create(muxerParam.targetFileFd, muxerParam.avOutputFormat);
73     if (muxer_ == nullptr) {
74         MEDIA_LOGE("[%{public}s] create muxer by OH_AVMuxer_Create failed, fd = %{public}d, format = %{public}d.",
75             logTag_.c_str(), muxerParam.targetFileFd, muxerParam.avOutputFormat);
76         return VEFError::ERR_INTERNAL_ERROR;
77     }
78 
79     OH_AVErrCode error = OH_AVMuxer_SetRotation(muxer_, muxerParam.rotation);
80     if (error != AV_ERR_OK) {
81         MEDIA_LOGE("[%{public}s] set rotation to %{public}d failed, err = %{public}d.",
82             logTag_.c_str(), muxerParam.rotation, error);
83         return VEFError::ERR_INTERNAL_ERROR;
84     }
85 
86     MEDIA_LOGI("[%{public}s] init video muxer success.", logTag_.c_str());
87     return VEFError::ERR_OK;
88 }
89 
AddVideoTrack(OH_AVFormat * format)90 VEFError VideoMuxer::AddVideoTrack(OH_AVFormat* format)
91 {
92     MEDIA_LOGI("[%{public}s] add video track.", logTag_.c_str());
93     if (format == nullptr) {
94         MEDIA_LOGE("[%{public}s] add video track failed, parameter format is nullptr.", logTag_.c_str());
95         return VEFError::ERR_INTERNAL_ERROR;
96     }
97     OH_AVErrCode error = OH_AVMuxer_AddTrack(muxer_, &videoTrackId_, format);
98     if (error != AV_ERR_OK) {
99         MEDIA_LOGE("[%{public}s] add video track failed, OH_AVMuxer_AddTrack return: %{public}d.", logTag_.c_str(),
100             error);
101         return VEFError::ERR_INTERNAL_ERROR;
102     }
103     return VEFError::ERR_OK;
104 }
105 
AddAudioTrack(OH_AVFormat * format)106 VEFError VideoMuxer::AddAudioTrack(OH_AVFormat* format)
107 {
108     MEDIA_LOGI("[%{public}s] add audio track.", logTag_.c_str());
109     if (format == nullptr) {
110         MEDIA_LOGE("[%{public}s] add audio track failed, parameter format is nullptr.", logTag_.c_str());
111         return VEFError::ERR_INTERNAL_ERROR;
112     }
113     OH_AVErrCode error = OH_AVMuxer_AddTrack(muxer_, &audioTrackId_, format);
114     if (error != AV_ERR_OK) {
115         MEDIA_LOGE("[%{public}s] add audio track failed, OH_AVMuxer_AddTrack return: %{public}d.", logTag_.c_str(),
116             error);
117         return VEFError::ERR_INTERNAL_ERROR;
118     }
119     return VEFError::ERR_OK;
120 }
121 
WriteVideoData(OH_AVMemory * data,OH_AVCodecBufferAttr * attr)122 VEFError VideoMuxer::WriteVideoData(OH_AVMemory* data, OH_AVCodecBufferAttr* attr)
123 {
124     MEDIA_LOGD("[%{public}s] OH_AVMuxer_WriteSample video flags=%{public}u, pts=%{public}" PRIu64 ","
125         "size:%{public}d.", logTag_.c_str(), attr->flags, attr->pts, attr->size);
126     std::lock_guard<ffrt::mutex> lk(writeFrameMutex_);
127     auto ret = OH_AVMuxer_WriteSample(muxer_, videoTrackId_, data, *attr);
128     if (attr->flags == AVCODEC_BUFFER_FLAGS_EOS) {
129         MEDIA_LOGI("[%{public}s] write video finish(EOS).", logTag_.c_str());
130         return VEFError::ERR_OK;
131     }
132     if (ret != AV_ERR_OK) {
133         MEDIA_LOGE("[%{public}s] OH_AVMuxer_WriteSample video failed, pts=%{public}" PRIu64 ".",
134             logTag_.c_str(), attr->pts);
135         return VEFError::ERR_INTERNAL_ERROR;
136     }
137     return VEFError::ERR_OK;
138 }
139 
WriteAudioData(OH_AVMemory * data,OH_AVCodecBufferAttr * attr)140 VEFError VideoMuxer::WriteAudioData(OH_AVMemory* data, OH_AVCodecBufferAttr* attr)
141 {
142     if (data == nullptr || attr == nullptr) {
143         MEDIA_LOGE("[%{public}s] invalid parameter, data or attr is nullptr.", logTag_.c_str());
144         return VEFError::ERR_INTERNAL_ERROR;
145     }
146     MEDIA_LOGD("[%{public}s] OH_AVMuxer_WriteSample audio flags=%{public}u, pts=%{public}" PRIu64
147         ", size:%{public}d.", logTag_.c_str(), attr->flags, attr->pts, attr->size);
148     std::lock_guard<ffrt::mutex> lk(writeFrameMutex_);
149     auto ret = OH_AVMuxer_WriteSample(muxer_, audioTrackId_, data, *attr);
150     if (ret != AV_ERR_OK) {
151         MEDIA_LOGE("[%{public}s] OH_AVMuxer_WriteSample audio failed, pts=%{public}" PRIu64 ".",
152             logTag_.c_str(), attr->pts);
153         return VEFError::ERR_INTERNAL_ERROR;
154     }
155     return VEFError::ERR_OK;
156 }
157 } // namespace Media
158 } // namespace OHOS
159