diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index b66e151593388f1d07634527242d4edfebb8a85f..0000000000000000000000000000000000000000
--- a/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-/node_modules
-/oh_modules
-/local.properties
-/.idea
-**/build
-/.hvigor
-.cxx
-/.clangd
-/.clang-format
-/.clang-tidy
-**/.test
-/.appanalyzer
-log.txt
-.DS_Store
\ No newline at end of file
diff --git a/README.en.md b/README.en.md
index f02e763c5853457998c25e1c246fa1bf9ad00189..6e39a28d5e18d425fa899483880140bfa65bda32 100644
--- a/README.en.md
+++ b/README.en.md
@@ -7,13 +7,11 @@ and convert it to SDR by leveraging hardware acceleration and color-space optimi
## Effect
-| Home Page | Recording Page |
-|--------------------------------------------------------|------------------------------------------------------|
-|
|
|
-
-| Transcoding Page | Save Dialog |
-|------------------------------------------------------------|---------------------------------------------------------|
-|
|
|
+| 首页 | 播放页 |
+|-----------------------------------------------------------|--------------------------------------------------------------|
+|
|
|
+| 录制页 | 转码页 |
+|
|
|
## How to Use
diff --git a/README.md b/README.md
index 78f89a635a9248b0a1f417fd4aef9a4d9d42f37a..476a19fac80c704aba7a7181ae90d12d69f5776d 100644
--- a/README.md
+++ b/README.md
@@ -6,68 +6,80 @@
## 效果图预览
-| 首页 | 录制页 |
-|-----------------------------------------------------|---------------------------------------------|
-|
|
|
-
-| 转码页 | 保存弹窗 |
-|---------------------------------------------------------|------------------------------------------------------|
-|
|
|
+| 首页 | 播放页 |
+|----------------------------------------------------------|--------------------------------------------------------------|
+|
|
|
+| 录制页 | 转码页 |
+|
|
|
## 使用说明
-1. 打开应用,点击HDR视频录制,选择Recorder或AVCodec封装方法。
+1. 打开应用,点击AVRecorder或AVCodec进行HDR视频录制。
2. 点击录制视频,完成录制后返回,点击视频播放或暂停视频。
3. 点击保存视频,确认保存。
4. 返回首页,点击HDR视频转码。
5. 点击屏幕选择视频,点击AVCodec或Video_Processing进行SDR转码并送显。
+> **注意**:
+> 1. AVRecorder录制不支持设置AVMetadata音视频元数据的HDR类型。
+> 2. 在使用转码的功能时,请选择HDR类型的视频,HDR视频在相册中有HDR标识。
+
## 工程目录
```
├──entry/src/main/cpp // Native层
-│ ├──CMakeLists.txt // 编译入口
│ ├──capbilities // 接口能力实现
-│ ├──AudioCapturer.cpp // 音频采集实现
-│ ├──AudioEncoder.cpp // 音频编码实现
-│ ├──Demuxer.cpp // 解封装实现
-│ ├──Muxer.cpp // 封装实现
-│ ├──AudioDecoder.cpp // 转码音频解码实现
-│ ├──Demuxer.cpp // 转码解封装实现
+│ │ ├──include // 编解码模块接口定义
+│ │ ├──AudioCapturer.cpp // 音频采集实现
+│ │ ├──AudioDecoder.cpp // 转码音频解码实现
+│ │ ├──AudioEncoder.cpp // 音频编码实现
+│ │ ├──Demuxer.cpp // 解封装实现
+│ │ ├──Muxer.cpp // 封装实现
│ │ ├──VideoDecoder.cpp // 转码视频解码实现
│ │ ├──VideoEncoder.cpp // 视频编码实现
-│ │ └──include // 接口能力定义
+│ │ └──VideoProcessing.cpp // 视频转换实现
│ ├──common // 公共模块
+│ │ ├──dfx // 日志实现
│ │ ├──SampleCallback.cpp // 编解码回调实现
│ │ ├──SampleCallback.h // 编解码回调定义
-│ │ ├──SampleInfo.h // 公共类
-│ │ └──dfx // 日志实现
+│ │ └──SampleInfo.h // 公共类
│ ├──render // 送显模块
+│ │ ├──include // 送显模块接口定义
│ │ ├──PluginManager.cpp // 送显模块管理实现
-│ │ ├──PluginRender.cpp // 送显模块逻辑实现
-│ │ └──include // 送显模块接口定义
+│ │ └──PluginRender.cpp // 送显模块逻辑实现
│ ├──sample
│ │ ├──player // 转码播放接口
│ │ │ ├──Player.cpp // 转码播放接口实现
│ │ │ ├──Player.h // 转码播放接口定义
│ │ │ ├──PlayerNative.cpp // 转码接口调用入口
│ │ │ └──PlayerNative.h // 调用入口定义
-│ │ └──recorder // 录制接口
-│ │ ├──Recorder.cpp // 录制功能接口实现
-│ │ ├──Recorder.h // 录制功能接口定义
-│ │ ├──RecorderNative.cpp // 录制接口调用入口
-│ │ └──RecorderNative.h // 调用入口定义
-│ └──types // Native层暴露上来的接口
-│ ├──libplayer // 转码播放模块暴露给UI层的接口
-│ └──librecorder // 录制模块暴露给UI层的接口
+│ │ ├──recorder // 录制接口
+│ │ │ ├──Recorder.cpp // 录制功能接口实现
+│ │ │ ├──Recorder.h // 录制功能接口定义
+│ │ │ ├──RecorderNative.cpp // 录制接口调用入口
+│ │ │ └──RecorderNative.h // 调用入口定义
+│ │ └──transcoder // 转码接口
+│ │ ├──AVCodecTranscoder.cpp // AVCodec转码功能接口实现
+│ │ ├──AVCodecTranscoder.h // AVCodec转码功能接口定义
+│ │ ├──AVTranscoder.cpp // AVTranscoder转码功能接口实现
+│ │ ├──AVTranscoder.h // AVTranscoder转码功能接口定义
+│ │ ├──TranscoderNative.cpp // 转码接口调用入口
+│ │ └──TranscoderNative.h // 转码调用入口定义
+│ ├──types // Native层暴露上来的接口
+│ │ ├──libplayer // 转码播放模块暴露给UI层的接口
+│ │ ├──librecorder // 录制模块暴露给UI层的接口
+│ │ └──libtranscoder // 转码模块暴露给UI层的接口
+│ └──CMakeLists.txt // 编译入口
├──ets // UI层
│ ├──common // 公共模块
+│ │ ├──utils // 公共工具类
+│ │ │ ├──DateTimeUtils.ets // 时间工具类
+│ │ │ ├──FileUtil.ets // 文件工具类
+│ │ │ ├──Logger.ets // 日志类
+│ │ │ ├──PermissionsUtils.ets // 申请权限类
+│ │ │ └──VideoOperationUtils.ets // 保存文件类
│ │ ├──CommonConstants.ets // 参数常量
-│ │ └──utils // 公共工具类
-│ │ ├──DateTimeUtils.ets // 时间工具类
-│ │ ├──FileUtil.ets // 文件工具类
-│ │ ├──PermissionsUtils.ets // 申请权限类
-│ │ └──VideoOperationUtils.ets // 保存文件类
+│ │ └──CommonEnum.ets // 枚举类
│ ├──controller // 控制模块
│ │ ├──AVCodecController.ets // AVcodec控制类
│ │ ├──AvPlayerController.ets // AVplayer播放类
@@ -79,10 +91,13 @@
│ ├──model
│ │ └──CameraDateModel.ets // 相机参数数据类
│ ├──pages
+│ │ ├──AVCodecPage.ets // 视频转码页
+│ │ ├──AVCodecPage.ets // 视频AVCodec播放页
+│ │ ├──AVPlayerPage.ets // 视频AVPlayer播放页
+│ │ ├──AVTranscoderPage.ets // 视频AVTranscoder转码页
│ │ ├──CameraPage.ets // 相机录制页
│ │ ├──Index.ets // 首页
-│ │ ├──Recording.ets // 视频录制页
-│ │ └──Transcode.ets // 视频转码页面
+│ │ └──Recording.ets // 视频录制页
│ └──view // 组件模块
│ ├──MultiStatusButton.ets // 多选框组件
│ └──SaveDialog.ets // 保存弹窗
@@ -101,7 +116,7 @@
视频转码:
-1. 用户成功选择文件后,调用playNative转码的接口。
+1. 用户成功选择文件后,调用转码的接口。
2. 开始转码前,调用init函数初始化解封装器、封装器、编码器、解码器。同时保存上下文参数。
3. 调用Start函数开始解码,开启解码线程包括输入子线程和输出子线程对视频数据进行解码。
4. 在输入子线程中,使用解封装后的bufferInfo,调用解码的PushInputData接口将帧buffer、index存入输入队列中。在输出子线程中,把上一步的帧信息储存为bufferInfo后,pop出队,调用FreeOutputData接口后,就会送显并释放buffer。
diff --git a/entry/build-profile.json5 b/entry/build-profile.json5
index 7a38cc838fbeffc2de2ee08dfed997628a3d9e74..ca8d2eb8b157342c338ef11995c83f7b9a0f4086 100644
--- a/entry/build-profile.json5
+++ b/entry/build-profile.json5
@@ -32,9 +32,6 @@
"targets": [
{
"name": "default"
- },
- {
- "name": "ohosTest",
}
]
}
\ No newline at end of file
diff --git a/entry/oh-package.json5 b/entry/oh-package.json5
index ec7d872486ca227b261d1fa73532c3fb82cf8cd0..e94da9f95e8eade042bca00c3378a42a0360f022 100644
--- a/entry/oh-package.json5
+++ b/entry/oh-package.json5
@@ -7,6 +7,7 @@
"license": "",
"dependencies": {
"librecorder.so": "file:./src/main/cpp/types/librecorder",
- "libplayer.so": "file:./src/main/cpp/types/libplayer"
+ "libplayer.so": "file:./src/main/cpp/types/libplayer",
+ "libtranscoder.so": "file:./src/main/cpp/types/libtranscoder"
}
}
\ No newline at end of file
diff --git a/entry/src/main/cpp/CMakeLists.txt b/entry/src/main/cpp/CMakeLists.txt
index e1f0111004185edb0e8694bb4327fb5603853702..ea97eb2354a9a7efcd376c7f588ba65188fdc452 100644
--- a/entry/src/main/cpp/CMakeLists.txt
+++ b/entry/src/main/cpp/CMakeLists.txt
@@ -25,6 +25,7 @@ include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/render/include
${NATIVERENDER_ROOT_PATH}/sample/player
${NATIVERENDER_ROOT_PATH}/sample/recorder
+ ${NATIVERENDER_ROOT_PATH}/sample/transcoder
)
set(BASE_LIBRARY
@@ -32,6 +33,7 @@ set(BASE_LIBRARY
libnative_media_codecbase.so libnative_media_core.so libnative_media_vdec.so libnative_window.so
libnative_media_venc.so libnative_media_acodec.so libnative_media_avdemuxer.so libnative_media_avsource.so libnative_media_avmuxer.so
libohaudio.so
+ libvideo_processing.so
)
set(VIDEO_BASE_LIBRARY
libpixelmap_ndk.z.so
@@ -56,6 +58,34 @@ set(VIDEO_BASE_LIBRARY
libnative_image.so
libohaudio.so
libpixelmap.so
+ libvideo_processing.so
+)
+
+set(TRANSCODER_BASE_LIBRARY
+ libpixelmap_ndk.z.so
+ libace_napi.z.so
+ libEGL.so
+ libGLESv3.so
+ libace_ndk.z.so
+ libuv.so
+ libhilog_ndk.z.so
+ libvideo_processing.so
+ libnative_media_codecbase.so
+ libnative_media_core.so
+ libnative_media_vdec.so
+ libnative_window.so
+ libnative_media_venc.so
+ libnative_media_acodec.so
+ libnative_media_avdemuxer.so
+ libnative_media_avsource.so
+ libnative_media_avmuxer.so
+ libnative_buffer.so
+ libnative_vsync.so
+ libnative_image.so
+ libohaudio.so
+ libpixelmap.so
+ libavtranscoder.so
+ libvideo_processing.so
)
add_library(recorder SHARED sample/recorder/RecorderNative.cpp
@@ -65,7 +95,7 @@ add_library(recorder SHARED sample/recorder/RecorderNative.cpp
capbilities/AudioCapturer.cpp
capbilities/AudioEncoder.cpp
common/SampleCallback.cpp
-)
+ capbilities/VideoProcessing.cpp)
add_library(player SHARED sample/player/PlayerNative.cpp
sample/player/Player.cpp
@@ -77,5 +107,21 @@ add_library(player SHARED sample/player/PlayerNative.cpp
common/SampleCallback.cpp
)
+add_library(transcoder SHARED sample/transcoder/TranscoderNative.cpp
+ sample/transcoder/AVTranscoder.cpp
+ sample/transcoder/AVCodecTranscoder.cpp
+ capbilities/Muxer.cpp
+ capbilities/Demuxer.cpp
+ capbilities/VideoEncoder.cpp
+ capbilities/VideoDecoder.cpp
+ capbilities/AudioEncoder.cpp
+ capbilities/AudioDecoder.cpp
+ capbilities/VideoProcessing.cpp
+ render/PluginRender.cpp
+ render/PluginManager.cpp
+ common/SampleCallback.cpp
+)
+
target_link_libraries(recorder PUBLIC ${BASE_LIBRARY})
-target_link_libraries(player PUBLIC ${VIDEO_BASE_LIBRARY})
\ No newline at end of file
+target_link_libraries(player PUBLIC ${VIDEO_BASE_LIBRARY})
+target_link_libraries(transcoder PUBLIC ${TRANSCODER_BASE_LIBRARY})
\ No newline at end of file
diff --git a/entry/src/main/cpp/capbilities/AudioCapturer.cpp b/entry/src/main/cpp/capbilities/AudioCapturer.cpp
index 0dee5a5bf35b46c334c7d33ea34278dc2e550ef8..c811fc6bdd275afc927e02e528c9c43ed0252305 100644
--- a/entry/src/main/cpp/capbilities/AudioCapturer.cpp
+++ b/entry/src/main/cpp/capbilities/AudioCapturer.cpp
@@ -16,14 +16,10 @@
#include "AudioCapturer.h"
#include "SampleCallback.h"
-AudioCapturer::~AudioCapturer()
-{
- AudioCapturerRelease();
-}
+AudioCapturer::~AudioCapturer() { AudioCapturerRelease(); }
// AudioCapturer Callback
-static int32_t AudioCapturerOnReadData(OH_AudioCapturer *capturer, void *userData, void *buffer, int32_t bufferLen)
-{
+static int32_t AudioCapturerOnReadData(OH_AudioCapturer *capturer, void *userData, void *buffer, int32_t bufferLen) {
(void)capturer;
CodecUserData *codecUserData = static_cast(userData);
if (codecUserData != nullptr) {
@@ -33,8 +29,7 @@ static int32_t AudioCapturerOnReadData(OH_AudioCapturer *capturer, void *userDat
return 0;
}
-void AudioCapturer::AudioCapturerInit(SampleInfo &sampleInfo, CodecUserData *audioEncContext)
-{
+void AudioCapturer::AudioCapturerInit(SampleInfo &sampleInfo, CodecUserData *audioEncContext) {
AudioCapturerRelease();
// Create builder
@@ -53,15 +48,13 @@ void AudioCapturer::AudioCapturerInit(SampleInfo &sampleInfo, CodecUserData *aud
OH_AudioStreamBuilder_GenerateCapturer(builder_, &audioCapturer_);
}
-void AudioCapturer::AudioCapturerStart()
-{
+void AudioCapturer::AudioCapturerStart() {
if (audioCapturer_ != nullptr) {
OH_AudioCapturer_Start(audioCapturer_);
}
}
-void AudioCapturer::AudioCapturerRelease()
-{
+void AudioCapturer::AudioCapturerRelease() {
if (audioCapturer_ != nullptr) {
OH_AudioCapturer_Stop(audioCapturer_);
OH_AudioCapturer_Release(audioCapturer_);
diff --git a/entry/src/main/cpp/capbilities/AudioEncoder.cpp b/entry/src/main/cpp/capbilities/AudioEncoder.cpp
index 4391fecfc58c6206d4d981b78c480d7dc08e8298..95a8a86e8d192ee229073c8eaed8900129ef6f9c 100644
--- a/entry/src/main/cpp/capbilities/AudioEncoder.cpp
+++ b/entry/src/main/cpp/capbilities/AudioEncoder.cpp
@@ -24,24 +24,19 @@ namespace {
constexpr int LIMIT_LOGD_FREQUENCY = 50;
}
-AudioEncoder::~AudioEncoder()
-{
- Release();
-}
+AudioEncoder::~AudioEncoder() { Release(); }
-int32_t AudioEncoder::Create(const std::string &codecMime)
-{
+int32_t AudioEncoder::Create(const std::string &codecMime) {
encoder_ = OH_AudioCodec_CreateByMime(codecMime.c_str(), true);
CHECK_AND_RETURN_RET_LOG(encoder_ != nullptr, AVCODEC_SAMPLE_ERROR, "Create failed");
return AVCODEC_SAMPLE_OK;
}
-int32_t AudioEncoder::SetCallback(CodecUserData *codecUserData)
-{
+int32_t AudioEncoder::SetCallback(CodecUserData *codecUserData) {
int32_t ret = AV_ERR_OK;
ret = OH_AudioCodec_RegisterCallback(encoder_,
- { SampleCallback::OnCodecError, SampleCallback::OnCodecFormatChange,
- SampleCallback::OnNeedInputBuffer, SampleCallback::OnNewOutputBuffer },
+ {SampleCallback::OnCodecError, SampleCallback::OnCodecFormatChange,
+ SampleCallback::OnNeedInputBuffer, SampleCallback::OnNewOutputBuffer},
codecUserData);
CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "Set callback failed, ret: %{public}d", ret);
AVCODEC_SAMPLE_LOGI("====== AudioEncoder SetCallback ======");
@@ -49,8 +44,7 @@ int32_t AudioEncoder::SetCallback(CodecUserData *codecUserData)
return AVCODEC_SAMPLE_OK;
}
-int32_t AudioEncoder::Configure(const SampleInfo &sampleInfo)
-{
+int32_t AudioEncoder::Configure(const SampleInfo &sampleInfo) {
OH_AVFormat *format = OH_AVFormat_Create();
CHECK_AND_RETURN_RET_LOG(format != nullptr, AVCODEC_SAMPLE_ERROR, "AVFormat create failed");
@@ -72,8 +66,7 @@ int32_t AudioEncoder::Configure(const SampleInfo &sampleInfo)
return AVCODEC_SAMPLE_OK;
}
-int32_t AudioEncoder::Config(const SampleInfo &sampleInfo, CodecUserData *codecUserData)
-{
+int32_t AudioEncoder::Config(const SampleInfo &sampleInfo, CodecUserData *codecUserData) {
CHECK_AND_RETURN_RET_LOG(encoder_ != nullptr, AVCODEC_SAMPLE_ERROR, "Encoder is null");
CHECK_AND_RETURN_RET_LOG(codecUserData != nullptr, AVCODEC_SAMPLE_ERROR, "Invalid param: codecUserData");
@@ -83,8 +76,8 @@ int32_t AudioEncoder::Config(const SampleInfo &sampleInfo, CodecUserData *codecU
// SetCallback for audio encoder
ret = SetCallback(codecUserData);
- CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_OK, AVCODEC_SAMPLE_ERROR,
- "Set callback failed, ret: %{public}d", ret);
+ CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_OK, AVCODEC_SAMPLE_ERROR, "Set callback failed, ret: %{public}d",
+ ret);
// Prepare audio encoder
{
@@ -95,8 +88,7 @@ int32_t AudioEncoder::Config(const SampleInfo &sampleInfo, CodecUserData *codecU
return AVCODEC_SAMPLE_OK;
}
-int32_t AudioEncoder::Start()
-{
+int32_t AudioEncoder::Start() {
CHECK_AND_RETURN_RET_LOG(encoder_ != nullptr, AVCODEC_SAMPLE_ERROR, "Encoder is null");
int ret = OH_AudioCodec_Start(encoder_);
@@ -104,8 +96,7 @@ int32_t AudioEncoder::Start()
return AVCODEC_SAMPLE_OK;
}
-int32_t AudioEncoder::PushInputData(CodecBufferInfo &info)
-{
+int32_t AudioEncoder::PushInputData(CodecBufferInfo &info) {
CHECK_AND_RETURN_RET_LOG(encoder_ != nullptr, AVCODEC_SAMPLE_ERROR, "Encoder is null");
int32_t ret = OH_AVBuffer_SetBufferAttr(reinterpret_cast(info.buffer), &info.attr);
CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "Set avbuffer attr failed");
@@ -114,8 +105,7 @@ int32_t AudioEncoder::PushInputData(CodecBufferInfo &info)
return AVCODEC_SAMPLE_OK;
}
-int32_t AudioEncoder::FreeOutputData(uint32_t bufferIndex)
-{
+int32_t AudioEncoder::FreeOutputData(uint32_t bufferIndex) {
CHECK_AND_RETURN_RET_LOG(encoder_ != nullptr, AVCODEC_SAMPLE_ERROR, "Encoder is null");
int32_t ret = AVCODEC_SAMPLE_OK;
@@ -124,23 +114,15 @@ int32_t AudioEncoder::FreeOutputData(uint32_t bufferIndex)
return AVCODEC_SAMPLE_OK;
}
-int32_t AudioEncoder::Stop()
-{
+int32_t AudioEncoder::Stop() {
CHECK_AND_RETURN_RET_LOG(encoder_ != nullptr, AVCODEC_SAMPLE_ERROR, "Encoder is null");
-
- int ret = OH_AudioCodec_Flush(encoder_);
- CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "Flush failed, ret: %{public}d", ret);
-
- ret = OH_AudioCodec_Stop(encoder_);
+ int ret = OH_AudioCodec_Stop(encoder_);
CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "Stop failed, ret: %{public}d", ret);
return AVCODEC_SAMPLE_OK;
}
-int32_t AudioEncoder::Release()
-{
+int32_t AudioEncoder::Release() {
if (encoder_ != nullptr) {
- OH_AudioCodec_Flush(encoder_);
- OH_AudioCodec_Stop(encoder_);
OH_AudioCodec_Destroy(encoder_);
encoder_ = nullptr;
}
diff --git a/entry/src/main/cpp/capbilities/Demuxer.cpp b/entry/src/main/cpp/capbilities/Demuxer.cpp
index efd38a78c64efbd1fa1f2b42f473be75191c9bbf..cd456996e64e09e9719670f8d91a3ae90e1ec830 100644
--- a/entry/src/main/cpp/capbilities/Demuxer.cpp
+++ b/entry/src/main/cpp/capbilities/Demuxer.cpp
@@ -1,17 +1,17 @@
/*
-* Copyright (c) 2025 Huawei Device Co., Ltd.
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#include "Demuxer.h"
#include "dfx/error/AVCodecSampleError.h"
@@ -23,7 +23,7 @@
Demuxer::~Demuxer() { Release(); }
-int32_t Demuxer::Create(SampleInfo &info) {
+int32_t Demuxer::Create(SampleInfo &info) {
source_ = OH_AVSource_CreateWithFD(info.inputFd, info.inputFileOffset, info.inputFileSize);
CHECK_AND_RETURN_RET_LOG(source_ != nullptr, AVCODEC_SAMPLE_ERROR, "Create AVSource failed");
demuxer_ = OH_AVDemuxer_CreateWithSource(source_);
@@ -35,16 +35,15 @@ int32_t Demuxer::Create(SampleInfo &info) {
return AVCODEC_SAMPLE_OK;
}
-int32_t Demuxer::ReadSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBufferAttr &attr) {
+int32_t Demuxer::ReadSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBufferAttr &attr) {
int32_t ret = OH_AVDemuxer_ReadSampleBuffer(demuxer_, trackId, buffer);
- CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, ""
- "ReadSampleBuffer failed");
+ CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "ReadSampleBuffer failed");
ret = OH_AVBuffer_GetBufferAttr(buffer, &attr);
CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "GetBufferAttr failed");
return AVCODEC_SAMPLE_OK;
}
-int32_t Demuxer::Release() {
+int32_t Demuxer::Release() {
if (demuxer_ != nullptr) {
OH_AVDemuxer_Destroy(demuxer_);
demuxer_ = nullptr;
@@ -56,20 +55,17 @@ int32_t Demuxer::Release() {
return AVCODEC_SAMPLE_OK;
}
-int32_t Demuxer::GetVideoTrackId() {
- return videoTrackId_;
-}
+int32_t Demuxer::GetVideoTrackId() { return videoTrackId_; }
-int32_t Demuxer::GetAudioTrackId() {
- return audioTrackId_;
-}
+int32_t Demuxer::GetAudioTrackId() { return audioTrackId_; }
-int32_t Demuxer::GetTrackInfo(std::shared_ptr sourceFormat, SampleInfo &info) {
+int32_t Demuxer::GetTrackInfo(std::shared_ptr sourceFormat, SampleInfo &info) {
int32_t trackCount = 0;
OH_AVFormat_GetIntValue(sourceFormat.get(), OH_MD_KEY_TRACK_COUNT, &trackCount);
- for(int32_t index = 0; index < trackCount; index++) {
+ for (int32_t index = 0; index < trackCount; index++) {
int trackType = -1;
- auto trackFormat = std::shared_ptr(OH_AVSource_GetTrackFormat(source_, index), OH_AVFormat_Destroy);
+ auto trackFormat =
+ std::shared_ptr(OH_AVSource_GetTrackFormat(source_, index), OH_AVFormat_Destroy);
if (trackFormat == nullptr) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "Demuxer", "Failed to get track format for index %d", index);
return AVCODEC_SAMPLE_ERROR;
@@ -82,12 +78,13 @@ int32_t Demuxer::GetTrackInfo(std::shared_ptr sourceFormat, SampleI
OH_AVFormat_GetDoubleValue(trackFormat.get(), OH_MD_KEY_FRAME_RATE, &info.frameRate);
int32_t pixelFormat = 0;
OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_PIXEL_FORMAT, &pixelFormat);
- info.pixelFormat = ConvertPixelFormat(info.pixelFormat);
+ info.pixelFormat = ConvertPixelFormat(pixelFormat);
OH_AVFormat_GetLongValue(trackFormat.get(), OH_MD_KEY_BITRATE, &info.bitrate);
OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_ROTATION, &info.rotation);
-
+ OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_VIDEO_IS_HDR_VIVID, &info.isHDRVivid);
char *videoCodecMime;
- OH_AVFormat_GetStringValue(trackFormat.get(), OH_MD_KEY_CODEC_MIME, const_cast(&videoCodecMime));
+ OH_AVFormat_GetStringValue(trackFormat.get(), OH_MD_KEY_CODEC_MIME,
+ const_cast(&videoCodecMime));
info.videoCodecMime = videoCodecMime;
AVCODEC_SAMPLE_LOGI("Video Mime: %{public}s", videoCodecMime);
OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_PROFILE, &info.hevcProfile);
@@ -99,7 +96,8 @@ int32_t Demuxer::GetTrackInfo(std::shared_ptr sourceFormat, SampleI
OH_AVFormat_GetLongValue(trackFormat.get(), OH_MD_KEY_CHANNEL_LAYOUT, &info.audioChannelLayout);
OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_AUD_SAMPLE_RATE, &info.audioSampleRate);
char *audioCodecMime;
- OH_AVFormat_GetStringValue(trackFormat.get(), OH_MD_KEY_CODEC_MIME, const_cast(&audioCodecMime));
+ OH_AVFormat_GetStringValue(trackFormat.get(), OH_MD_KEY_CODEC_MIME,
+ const_cast(&audioCodecMime));
info.audioCodecMime = audioCodecMime;
AVCODEC_SAMPLE_LOGI("Audio Mime: %{public}s", audioCodecMime);
audioTrackId_ = index;
@@ -108,19 +106,19 @@ int32_t Demuxer::GetTrackInfo(std::shared_ptr sourceFormat, SampleI
return AVCODEC_SAMPLE_OK;
}
-OH_AVPixelFormat Demuxer::ConvertPixelFormat(int32_t pixelFormat) {
+OH_AVPixelFormat Demuxer::ConvertPixelFormat(int32_t pixelFormat) {
switch (pixelFormat) {
- case 1:
- return AV_PIXEL_FORMAT_YUVI420;
- case 2:
- return AV_PIXEL_FORMAT_NV12;
- case 3:
- return AV_PIXEL_FORMAT_NV21;
- case 4:
- return AV_PIXEL_FORMAT_SURFACE_FORMAT;
- case 5:
- return AV_PIXEL_FORMAT_RGBA;
- default:
- return AV_PIXEL_FORMAT_NV12;
+ case 1:
+ return AV_PIXEL_FORMAT_YUVI420;
+ case 2:
+ return AV_PIXEL_FORMAT_NV12;
+ case 3:
+ return AV_PIXEL_FORMAT_NV21;
+ case 4:
+ return AV_PIXEL_FORMAT_SURFACE_FORMAT;
+ case 5:
+ return AV_PIXEL_FORMAT_RGBA;
+ default:
+ return AV_PIXEL_FORMAT_NV12;
}
}
\ No newline at end of file
diff --git a/entry/src/main/cpp/capbilities/Muxer.cpp b/entry/src/main/cpp/capbilities/Muxer.cpp
index bc7c7f13843a95a103048094f07883b1b825ec23..74f14660411ec064e2d2c5ee7ba99c9c5f6e40f7 100644
--- a/entry/src/main/cpp/capbilities/Muxer.cpp
+++ b/entry/src/main/cpp/capbilities/Muxer.cpp
@@ -38,13 +38,13 @@ int32_t Muxer::Create(int32_t fd) {
int32_t Muxer::Config(SampleInfo &sampleInfo) {
CHECK_AND_RETURN_RET_LOG(muxer_ != nullptr, AVCODEC_SAMPLE_ERROR, "Muxer is null");
-
+
OH_AVFormat *formatAudio = OH_AVFormat_CreateAudioFormat(sampleInfo.audioCodecMime.data(),
sampleInfo.audioSampleRate, sampleInfo.audioChannelCount);
CHECK_AND_RETURN_RET_LOG(formatAudio != nullptr, AVCODEC_SAMPLE_ERROR, "Create audio format failed");
OH_AVFormat_SetIntValue(formatAudio, OH_MD_KEY_PROFILE, AAC_PROFILE_LC);
int32_t ret = OH_AVMuxer_AddTrack(muxer_, &audioTrackId_, formatAudio);
- OH_AVFormat_Destroy(formatAudio);
+ OH_AVFormat_Destroy(formatAudio);
OH_AVFormat *formatVideo =
OH_AVFormat_CreateVideoFormat(sampleInfo.videoCodecMime.data(), sampleInfo.videoWidth, sampleInfo.videoHeight);
@@ -53,13 +53,15 @@ int32_t Muxer::Config(SampleInfo &sampleInfo) {
OH_AVFormat_SetDoubleValue(formatVideo, OH_MD_KEY_FRAME_RATE, sampleInfo.frameRate);
OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_WIDTH, sampleInfo.videoWidth);
OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_HEIGHT, sampleInfo.videoHeight);
- OH_AVFormat_SetStringValue(formatVideo, OH_MD_KEY_CODEC_MIME, sampleInfo.videoCodecMime.data());
- if (sampleInfo.isHDRVivid) {
+ if (sampleInfo.isRecordHDRVivid == 1) {
+ OH_AVFormat_SetStringValue(formatVideo, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_VIDEO_HEVC);
OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_VIDEO_IS_HDR_VIVID, 1);
OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_RANGE_FLAG, sampleInfo.rangFlag);
OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_COLOR_PRIMARIES, sampleInfo.primary);
OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_TRANSFER_CHARACTERISTICS, sampleInfo.transfer);
OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_MATRIX_COEFFICIENTS, sampleInfo.matrix);
+ } else {
+ OH_AVFormat_SetStringValue(formatVideo, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_VIDEO_AVC);
}
ret = OH_AVMuxer_AddTrack(muxer_, &videoTrackId_, formatVideo);
@@ -79,7 +81,7 @@ int32_t Muxer::Start() {
return AVCODEC_SAMPLE_OK;
}
-int32_t Muxer::WriteSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBufferAttr &attr){
+int32_t Muxer::WriteSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBufferAttr &attr) {
CHECK_AND_RETURN_RET_LOG(muxer_ != nullptr, AVCODEC_SAMPLE_ERROR, "Muxer is null");
CHECK_AND_RETURN_RET_LOG(buffer != nullptr, AVCODEC_SAMPLE_ERROR, "Get a empty buffer");
@@ -93,6 +95,7 @@ int32_t Muxer::WriteSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBuffe
int32_t Muxer::Release() {
if (muxer_ != nullptr) {
+ OH_AVMuxer_Stop(muxer_);
OH_AVMuxer_Destroy(muxer_);
muxer_ = nullptr;
}
diff --git a/entry/src/main/cpp/capbilities/VideoDecoder.cpp b/entry/src/main/cpp/capbilities/VideoDecoder.cpp
index c9f25346e7b6ed2e4eee0d0440e4203c68cae58f..a2f4b6eb83b09b0df69b1a1a9fe367ae8a0fbeb1 100644
--- a/entry/src/main/cpp/capbilities/VideoDecoder.cpp
+++ b/entry/src/main/cpp/capbilities/VideoDecoder.cpp
@@ -27,22 +27,24 @@
namespace {
constexpr int LIMIT_LOGD_FREQUENCY = 50;
constexpr int ROTATION_ANGLE = 90;
-}
+} // namespace
VideoDecoder::~VideoDecoder() { Release(); }
// [Start VideoDecoderCreate]
int32_t VideoDecoder::Create(SampleInfo &sampleInfo) {
// [StartExclude VideoDecoderCreate]
- if(sampleInfo.processType == 2){
- // [EndExclude VideoDecoderCreate]
- OH_AVCapability *capability = OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_HEVC, false, HARDWARE);
- CHECK_AND_RETURN_RET_LOG(capability != nullptr, AVCODEC_SAMPLE_ERROR, "OH_AVCodec_GetCapabilityByCategory failed");
- const char *name = OH_AVCapability_GetName(capability);
- decoder_ = OH_VideoDecoder_CreateByName(name);
- // [StartExclude VideoDecoderCreate]
+ if (sampleInfo.isHDRVivid == 1) {
+ // [EndExclude VideoDecoderCreate]
+ OH_AVCapability *capability =
+ OH_AVCodec_GetCapabilityByCategory(OH_AVCODEC_MIMETYPE_VIDEO_HEVC, false, HARDWARE);
+ CHECK_AND_RETURN_RET_LOG(capability != nullptr, AVCODEC_SAMPLE_ERROR,
+ "OH_AVCodec_GetCapabilityByCategory failed");
+ const char *name = OH_AVCapability_GetName(capability);
+ decoder_ = OH_VideoDecoder_CreateByName(name);
+ // [StartExclude VideoDecoderCreate]
} else {
- decoder_ = OH_VideoDecoder_CreateByMime(sampleInfo.videoCodecMime.c_str());
+ decoder_ = OH_VideoDecoder_CreateByMime(MIME_VIDEO_AVC.data());
}
// [EndExclude VideoDecoderCreate]
CHECK_AND_RETURN_RET_LOG(decoder_ != nullptr, AVCODEC_SAMPLE_ERROR, "Create VideoDecoder failed");
@@ -53,37 +55,27 @@ int32_t VideoDecoder::Create(SampleInfo &sampleInfo) {
int32_t VideoDecoder::Config(SampleInfo &sampleInfo, CodecUserData *codecUserData) {
int32_t ret = Configure(sampleInfo);
CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_OK, AVCODEC_SAMPLE_ERROR, "Configure failed");
- if (sampleInfo.videoIndex == 0) {
- ret = OH_VideoDecoder_SetSurface(decoder_, NativeXComponentSample::PluginManager::GetInstance()->renderWindow);
- CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK && NativeXComponentSample::PluginManager::GetInstance()->renderWindow,
- AVCODEC_SAMPLE_ERROR, "VideoDecoder SetSurface failed");
- } else if (sampleInfo.videoIndex == 1) {
- if (sampleInfo.processType == 1) {
- NativeXComponentSample::PluginManager::GetInstance()->PrepareSurface(sampleInfo);
- if (NativeXComponentSample::PluginManager::GetInstance()->pluginWindow_ != nullptr) {
- ret = OH_VideoDecoder_SetSurface(decoder_, NativeXComponentSample::PluginManager::GetInstance()->pluginWindow_);
- CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK && NativeXComponentSample::PluginManager::GetInstance()->pluginWindow_,
- AVCODEC_SAMPLE_ERROR, "VideoDecoder SetSurface failed");
- }
- } else {
- ret = OH_VideoDecoder_SetSurface(decoder_, NativeXComponentSample::PluginManager::GetInstance()->windowOut);
- CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK && NativeXComponentSample::PluginManager::GetInstance()->windowOut,
- AVCODEC_SAMPLE_ERROR, "VideoDecoder SetSurface failed");
- }
+ if (sampleInfo.processType > 1) {
+ ret = OH_VideoDecoder_SetSurface(decoder_, sampleInfo.inWindow);
+ } else {
+ ret = OH_VideoDecoder_SetSurface(decoder_, sampleInfo.window);
}
+ CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "VideoDecoder SetSurface failed");
ret = SetCallback(codecUserData);
CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_OK, AVCODEC_SAMPLE_ERROR, "VideoDecoder SetCallback failed");
{
ret = OH_VideoDecoder_Prepare(decoder_);
CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "VideoDecoder Prepare failed");
}
- if (sampleInfo.videoIndex == 1 && sampleInfo.processType == 1) {
- NativeXComponentSample::PluginManager::GetInstance()->InitProcessing(sampleInfo);
- int32_t rotation = sampleInfo.rotation == 0 ? 0 : (360 - sampleInfo.rotation) / 90;
- AVCODEC_SAMPLE_LOGI("Set Surface Rotation: %{public}d", rotation);
- OH_NativeWindow_NativeWindowHandleOpt(NativeXComponentSample::PluginManager::GetInstance()->windowOut, SET_TRANSFORM, rotation);
- OH_NativeWindow_NativeWindowHandleOpt(NativeXComponentSample::PluginManager::GetInstance()->pluginWindow_, SET_USAGE, NATIVEBUFFER_USAGE_CPU_READ);
- }
+// if (sampleInfo.videoIndex == 1 && sampleInfo.processType == 1) {
+// NativeXComponentSample::PluginManager::GetInstance()->InitProcessing(sampleInfo);
+// int32_t rotation = sampleInfo.rotation == 0 ? 0 : (360 - sampleInfo.rotation) / 90;
+// AVCODEC_SAMPLE_LOGI("Set Surface Rotation: %{public}d", rotation);
+// OH_NativeWindow_NativeWindowHandleOpt(NativeXComponentSample::PluginManager::GetInstance()->windowOut,
+// SET_TRANSFORM, rotation);
+// OH_NativeWindow_NativeWindowHandleOpt(NativeXComponentSample::PluginManager::GetInstance()->pluginWindow_,
+// SET_USAGE, NATIVEBUFFER_USAGE_CPU_READ);
+// }
return AVCODEC_SAMPLE_OK;
}
@@ -122,11 +114,12 @@ int32_t VideoDecoder::Release() {
}
// [Start VideoDecoderSetCallback]
-int32_t VideoDecoder::SetCallback(CodecUserData *codecUserData){
- int32_t ret = OH_VideoDecoder_RegisterCallback(decoder_,
- {SampleCallback::OnCodecError, SampleCallback::OnCodecFormatChange,
- SampleCallback::OnNeedInputBuffer, SampleCallback::OnNewOutputBuffer},
- codecUserData);
+int32_t VideoDecoder::SetCallback(CodecUserData *codecUserData) {
+ int32_t ret =
+ OH_VideoDecoder_RegisterCallback(decoder_,
+ {SampleCallback::OnCodecError, SampleCallback::OnCodecFormatChange,
+ SampleCallback::OnNeedInputBuffer, SampleCallback::OnNewOutputBuffer},
+ codecUserData);
CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "Create SetCallback failed");
return AVCODEC_SAMPLE_OK;
}
@@ -142,7 +135,7 @@ int32_t VideoDecoder::Configure(const SampleInfo &sampleInfo) {
OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, sampleInfo.pixelFormat);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_ROTATION, sampleInfo.rotation);
// [StartExclude VideoDecoderConfigure]
- if(sampleInfo.processType == 2){
+ if (sampleInfo.processType == 1) {
// [EndExclude VideoDecoderConfigure]
// Key configuration: HDR to SDR conversion
OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_DECODER_OUTPUT_COLOR_SPACE, OH_COLORSPACE_BT709_LIMIT);
diff --git a/entry/src/main/cpp/capbilities/VideoEncoder.cpp b/entry/src/main/cpp/capbilities/VideoEncoder.cpp
index 9c1c622e37afbc7671b3374d46ce9bba45591664..2f2043659bab0b3a023a35fe4a31e42df54bc787 100644
--- a/entry/src/main/cpp/capbilities/VideoEncoder.cpp
+++ b/entry/src/main/cpp/capbilities/VideoEncoder.cpp
@@ -14,8 +14,10 @@
*/
#include "VideoEncoder.h"
+#include "VideoProcessing.h"
#include "dfx/error/AVCodecSampleError.h"
#include "AVCodecSampleLog.h"
+#include
#undef LOG_TAG
#define LOG_TAG "VideoEncoder"
@@ -45,8 +47,8 @@ int32_t VideoEncoder::Config(SampleInfo &sampleInfo, CodecUserData *codecUserDat
// SetCallback for video encoder
ret = SetCallback(codecUserData);
- CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_OK, AVCODEC_SAMPLE_ERROR,
- "Set callback failed, ret: %{public}d", ret);
+ CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_OK, AVCODEC_SAMPLE_ERROR, "Set callback failed, ret: %{public}d",
+ ret);
// Prepare video encoder
ret = OH_VideoEncoder_Prepare(encoder_);
@@ -70,8 +72,7 @@ int32_t VideoEncoder::FreeOutputBuffer(uint32_t bufferIndex) {
CHECK_AND_RETURN_RET_LOG(encoder_ != nullptr, AVCODEC_SAMPLE_ERROR, "Encoder is null");
int32_t ret = OH_VideoEncoder_FreeOutputBuffer(encoder_, bufferIndex);
- CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "Free output data failed, ret: %{public}d",
- ret);
+ CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "Free output data failed, ret: %{public}d", ret);
return AVCODEC_SAMPLE_OK;
}
@@ -128,15 +129,17 @@ int32_t VideoEncoder::Configure(const SampleInfo &sampleInfo) {
OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, sampleInfo.pixelFormat);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, sampleInfo.bitrateMode);
OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, sampleInfo.bitrate);
- OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, sampleInfo.hevcProfile);
// [EndExclude camera_AVCodec]
// Setting HDRVivid-related parameters
- if (sampleInfo.isHDRVivid) {
+ if (sampleInfo.isRecordHDRVivid == 1) {
+ OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, sampleInfo.hevcProfile);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_I_FRAME_INTERVAL, sampleInfo.iFrameInterval);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_RANGE_FLAG, sampleInfo.rangFlag);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_COLOR_PRIMARIES, sampleInfo.primary);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_TRANSFER_CHARACTERISTICS, sampleInfo.transfer);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_MATRIX_COEFFICIENTS, sampleInfo.matrix);
+ } else {
+ OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, OH_AVCProfile::AVC_PROFILE_HIGH);
}
// [StartExclude video_encoder_faq]
// [StartExclude camera_AVCodec]
@@ -163,8 +166,12 @@ int32_t VideoEncoder::Configure(const SampleInfo &sampleInfo) {
// [End camera_AVCodec]
int32_t VideoEncoder::GetSurface(SampleInfo &sampleInfo) {
- int32_t ret = OH_VideoEncoder_GetSurface(encoder_, &sampleInfo.window);
- CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK && sampleInfo.window, AVCODEC_SAMPLE_ERROR,
- "Get surface failed, ret: %{public}d", ret);
+ int32_t ret;
+ if (sampleInfo.processType > 1) {
+ ret = OH_VideoEncoder_GetSurface(encoder_, &sampleInfo.outWindow);
+ } else {
+ ret = OH_VideoEncoder_GetSurface(encoder_, &sampleInfo.window);
+ }
+ CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERROR, "Get surface failed, ret: %{public}d", ret);
return AVCODEC_SAMPLE_OK;
-}
\ No newline at end of file
+}
diff --git a/entry/src/main/cpp/capbilities/VideoProcessing.cpp b/entry/src/main/cpp/capbilities/VideoProcessing.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e9cc05eb27595a84c0350ace43d519c40c582a69
--- /dev/null
+++ b/entry/src/main/cpp/capbilities/VideoProcessing.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/VideoProcessing.h"
+#include "AVCodecSampleLog.h"
+#include
+#include
+#include
+
+constexpr uint32_t LOG_PRINT_DOMAIN = 0xFF00;
+
+// [Start set_callback]
+void OnError(OH_VideoProcessing *videoProcessor, VideoProcessing_ErrorCode error, void *userData) {
+ (void)videoProcessor;
+ (void)error;
+ (void)userData;
+ OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_TAG, "OnError: %{public}d", error);
+}
+
+void OnState(OH_VideoProcessing *videoProcessor, VideoProcessing_State state, void *userData) {
+ (void)videoProcessor;
+ (void)state;
+ (void)userData;
+}
+
+void OnNewOutputBuffer(OH_VideoProcessing *videoProcessor, uint32_t index, void *userData) {
+
+ OH_VideoProcessing_RenderOutputBuffer(videoProcessor, index);
+ (void)userData;
+}
+// [End set_callback]
+
+void VideoProcessing::InitProcessing(SampleInfo &sampleInfo) {
+ VideoProcessing_ErrorCode ret = VIDEO_PROCESSING_ERROR_INVALID_VALUE;
+ // [Start SetSurface]
+ int32_t err = 0;
+ err = OH_NativeWindow_SetMetadataValue(sampleInfo.outWindow, OH_HDR_METADATA_TYPE, sizeof(uint8_t),
+ (uint8_t *)&sampleInfo.outputFormat.metadataType);
+ CHECK_AND_RETURN_LOG(err == 0, "SetMetadataValue BT2020_PQ_LIMIT failed");
+ err = OH_NativeWindow_NativeWindowHandleOpt(sampleInfo.outWindow, SET_FORMAT, sampleInfo.outputFormat.pixelFormat);
+ CHECK_AND_RETURN_LOG(err == 0, "NativeWindowHandleOpt BT2020_PQ_LIMIT failed");
+ err = OH_NativeWindow_SetColorSpace(sampleInfo.outWindow,
+ OH_NativeBuffer_ColorSpace(sampleInfo.outputFormat.colorSpace));
+ CHECK_AND_RETURN_LOG(err == 0, "SetColorSpace failed");
+
+ ret = OH_VideoProcessing_SetSurface(processor, sampleInfo.outWindow);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "SetSurface failed");
+ // [End SetSurface]
+ // [Start VideoProcessingRegisterCallback]
+ ret = OH_VideoProcessingCallback_Create(&callback);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessingCallback_Create failed");
+ ret = OH_VideoProcessingCallback_BindOnError(callback, OnError);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessingCallback_BindOnError failed");
+ ret = OH_VideoProcessingCallback_BindOnState(callback, OnState);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessingCallback_BindOnState failed");
+ ret = OH_VideoProcessingCallback_BindOnNewOutputBuffer(callback, OnNewOutputBuffer);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessingCallback_BindOnNewOutputBuffer failed");
+ ret = OH_VideoProcessing_RegisterCallback(processor, callback, nullptr);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessing_RegisterCallback failed");
+ // [End VideoProcessingRegisterCallback]
+ OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_TAG, "InitProcessing succeed");
+}
+
+// [Start SetProcessingSurface]
+void VideoProcessing::SetProcessingSurface(SampleInfo &sampleInfo) {
+ VideoProcessing_ErrorCode ret = OH_VideoProcessing_Create(&processor, VIDEO_PROCESSING_TYPE_COLOR_SPACE_CONVERSION);
+ ret = OH_VideoProcessing_GetSurface(processor, &sampleInfo.inWindow);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessing_GetSurface failed");
+}
+// [End SetProcessingSurface]
+
+// [Start IsColorSpaceConversionSupported]
+bool VideoProcessing::IsColorSpaceConversionSupported(SampleInfo &sampleInfo) {
+ OH_VideoProcessing_InitializeEnvironment();
+ return OH_VideoProcessing_IsColorSpaceConversionSupported(&sampleInfo.inputFormat, &sampleInfo.outputFormat);
+}
+// [End IsColorSpaceConversionSupported]
+
+// [Start StartProcessing]
+void VideoProcessing::StartProcessing() {
+ VideoProcessing_ErrorCode ret = OH_VideoProcessing_Start(processor);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessing_Start failed");
+}
+// [End StartProcessing]
+
+// [Start DestroyProcessing]
+void VideoProcessing::DestroyProcessing() {
+ CHECK_AND_RETURN_LOG(processor != nullptr, "processor is nullptr");
+ OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_TAG, "start DestroyProcessing");
+ VideoProcessing_ErrorCode ret = OH_VideoProcessing_Destroy(processor);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessing_Destroy failed");
+ processor = nullptr;
+ CHECK_AND_RETURN_LOG(callback != nullptr, "callback is nullptr");
+ ret = OH_VideoProcessingCallback_Destroy(callback);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessingCallback_Destroy failed");
+ callback = nullptr;
+ OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, LOG_TAG, "Destroy And Callback_Destroy succeed");
+ OH_VideoProcessing_DeinitializeEnvironment();
+}
+// [End DestroyProcessing]
+
+// [Start StopProcessing]
+void VideoProcessing::StopProcessing() {
+ VideoProcessing_ErrorCode ret = OH_VideoProcessing_Stop(processor);
+ CHECK_AND_RETURN_LOG(ret == VIDEO_PROCESSING_SUCCESS, "OH_VideoProcessing_Stop failed");
+ DestroyProcessing();
+}
+// [End StopProcessing]
\ No newline at end of file
diff --git a/entry/src/main/cpp/capbilities/include/AudioCapturer.h b/entry/src/main/cpp/capbilities/include/AudioCapturer.h
index 1fd8898a78f34eca77383f01b55d99978c6ea731..ec5f8f59dd6f3468117810ed27cc1023926753e4 100644
--- a/entry/src/main/cpp/capbilities/include/AudioCapturer.h
+++ b/entry/src/main/cpp/capbilities/include/AudioCapturer.h
@@ -27,7 +27,7 @@ public:
AudioCapturer() = default;
~AudioCapturer();
- void AudioCapturerInit(SampleInfo& sampleInfo, CodecUserData *audioEncContext);
+ void AudioCapturerInit(SampleInfo &sampleInfo, CodecUserData *audioEncContext);
void AudioCapturerStart();
void AudioCapturerRelease();
@@ -36,5 +36,4 @@ private:
OH_AudioStreamBuilder *builder_ = nullptr;
};
-
#endif // AVCODECVIDEO_AUDIOCAPTURER_H
diff --git a/entry/src/main/cpp/capbilities/include/AudioDecoder.h b/entry/src/main/cpp/capbilities/include/AudioDecoder.h
index 69e5486400b097a5c33ef3d6e79b83dc35268b50..39095bce52ff9b580f2a7de364d4efa9f15c9a8e 100644
--- a/entry/src/main/cpp/capbilities/include/AudioDecoder.h
+++ b/entry/src/main/cpp/capbilities/include/AudioDecoder.h
@@ -36,6 +36,6 @@ private:
int32_t Configure(const SampleInfo &sampleInfo);
bool isAVBufferMode_ = false;
- OH_AVCodec *decoder_;
+ OH_AVCodec *decoder_ = nullptr;
};
#endif // AUDIODECODER_H
\ No newline at end of file
diff --git a/entry/src/main/cpp/capbilities/include/AudioEncoder.h b/entry/src/main/cpp/capbilities/include/AudioEncoder.h
index 2d365d8bf3a5b57753a93e5c9ff5461df3d424d5..5ab4f95da89f03dd827ac2be149c8f2de92bf23e 100644
--- a/entry/src/main/cpp/capbilities/include/AudioEncoder.h
+++ b/entry/src/main/cpp/capbilities/include/AudioEncoder.h
@@ -32,13 +32,13 @@ public:
int32_t FreeOutputData(uint32_t bufferIndex);
int32_t Stop();
int32_t Release();
-
+
private:
int32_t SetCallback(CodecUserData *codecUserData);
int32_t Configure(const SampleInfo &sampleInfo);
-
+
bool isAVBufferMode_ = false;
- OH_AVCodec *encoder_;
+ OH_AVCodec *encoder_ = nullptr;
};
#endif // AVCODECVIDEO_AUDIOENCODER_H
diff --git a/entry/src/main/cpp/capbilities/include/Demuxer.h b/entry/src/main/cpp/capbilities/include/Demuxer.h
index ed94788820bd491f0cf0c2ef85f252cd4df00a77..fe5d212bfceb105558451f2da807eae43f6375b8 100644
--- a/entry/src/main/cpp/capbilities/include/Demuxer.h
+++ b/entry/src/main/cpp/capbilities/include/Demuxer.h
@@ -28,15 +28,15 @@ public:
int32_t Release();
int32_t GetVideoTrackId();
int32_t GetAudioTrackId();
-
+
private:
int32_t GetTrackInfo(std::shared_ptr sourceFormat, SampleInfo &info);
OH_AVPixelFormat ConvertPixelFormat(int32_t pixelFormat);
-
- OH_AVSource *source_;
- OH_AVDemuxer *demuxer_;
- int32_t videoTrackId_;
- int32_t audioTrackId_;
+
+ OH_AVSource *source_ = nullptr;
+ OH_AVDemuxer *demuxer_ = nullptr;
+ int32_t videoTrackId_ = -1;
+ int32_t audioTrackId_ = -1;
};
#endif // DEMUXER_H
\ No newline at end of file
diff --git a/entry/src/main/cpp/capbilities/include/VideoDecoder.h b/entry/src/main/cpp/capbilities/include/VideoDecoder.h
index 73681fa3cccfa9fe9762845ccc6d515471f849e4..d713ab2b4a85666a93c48ad12e393c799a28ffa3 100644
--- a/entry/src/main/cpp/capbilities/include/VideoDecoder.h
+++ b/entry/src/main/cpp/capbilities/include/VideoDecoder.h
@@ -40,7 +40,7 @@ private:
int32_t Configure(const SampleInfo &sampleInfo);
bool isAVBufferMode_ = false;
// [EndExclude VideoDecoderDecoder]
- OH_AVCodec *decoder_;
+ OH_AVCodec *decoder_ = nullptr;
};
// [End VideoDecoderDecoder]
#endif // VIDEODECODER_H
\ No newline at end of file
diff --git a/entry/src/main/cpp/capbilities/include/VideoProcessing.h b/entry/src/main/cpp/capbilities/include/VideoProcessing.h
new file mode 100644
index 0000000000000000000000000000000000000000..034a70fcf0c91efaa52ad7c6e45b8efb8c1f6b08
--- /dev/null
+++ b/entry/src/main/cpp/capbilities/include/VideoProcessing.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HDR2SDR_VIDEOPROCESSING_H
+#define HDR2SDR_VIDEOPROCESSING_H
+
+#include "SampleInfo.h"
+#include
+
+class VideoProcessing {
+public:
+ OH_VideoProcessing *processor = nullptr;
+ VideoProcessing_ColorSpaceInfo inputFormat;
+ VideoProcessing_ColorSpaceInfo outputFormat;
+ VideoProcessing_Callback *callback = nullptr;
+ void InitProcessing(SampleInfo &sampleInfo);
+ void DestroyProcessing();
+ void StopProcessing();
+ void SetProcessingSurface(SampleInfo &sampleInfo);
+ bool IsColorSpaceConversionSupported(SampleInfo &sampleInfo);
+ void StartProcessing();
+};
+
+#endif // HDR2SDR_VIDEOPROCESSING_H
diff --git a/entry/src/main/cpp/common/SampleInfo.h b/entry/src/main/cpp/common/SampleInfo.h
index e1fd1cda2860d49f94e7d996bdb3f8c03ffea6f9..e6ab68143c3be3c532e92dfc3fbb0f192741e7c6 100644
--- a/entry/src/main/cpp/common/SampleInfo.h
+++ b/entry/src/main/cpp/common/SampleInfo.h
@@ -17,7 +17,10 @@
#define AVCODEC_SAMPLE_INFO_H
#include
+#include