为了解码Surface模式的正常创建,在XComponent尚未创建或OpenGL后处理(NativeImage)尚未初始化的情况下,可以创建一个空的surface,以确保视频解码器能够正常创建和运行。
以下步骤描述了在surface的消费端没有创建之前,如何并行创建视频解码器和NativeWindow,让视频解码器正常创建执行。
添加动态链接库
target_link_libraries(sample PUBLIC libnative_image.so) target_link_libraries(sample PUBLIC libnative_window.so) target_link_libraries(sample PUBLIC libnative_buffer.so) target_link_libraries(sample PUBLIC libnative_media_vdec.so)
上述'sample'字样仅为示例,此处由开发者根据实际工程目录自定义。
头文件
#include <iostream> #include <string> #include <native_image/native_image.h> #include <native_window/external_window.h> #include <native_buffer/native_buffer.h> #include <multimedia/player_framework/native_avcodec_videodecoder.h>
创建OH_NativeImage实例。
// 创建NativeImage实例,作为surface的消费者。 OH_NativeImage* image = OH_ConsumerSurface_Create();
获取对应的数据生产者端NativeWindow。
// 获取生产者NativeWindow。 OHNativeWindow* nativeImageWindow = OH_NativeImage_AcquireNativeWindow(image);
设置NativeWindow的宽高。
int code = SET_BUFFER_GEOMETRY;
int32_t width = 800;
int32_t height = 600;
int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeImageWindow, code, width, height);
if (ret != AV_ERR_OK) {
// 异常处理。
} 注册NativeImage的回调函数。
注册OH_NativeImage的监听者OH_OnFrameAvailableListener,包括:
// onFrameAvailable实现。
static void onFrameAvailable()
{
OHNativeWindowBuffer *buffer = nullptr;
int fenceFd;
// 通过消费端的OH_NativeImage获取一个OHNativeWindowBuffer。
OH_NativeImage_AcquireNativeWindowBuffer(image, &buffer, &fenceFd);
// 通过OH_NativeImage实例将OHNativeWindowBuffer归还到buffer队列中。
OH_NativeImage_ReleaseNativeWindowBuffer(image, buffer, fenceFd);
}
static void context()
{
// 开发者自定义的上下文信息。
}
// 设置回调监听者。
OH_OnFrameAvailableListener listener = {&onFrameAvailable, &context};
// 设置帧可用回调。
ret = OH_NativeImage_SetOnFrameAvailableListener(image, listener);
if (ret != AV_ERR_OK) {
// 异常处理。
}
在此示例中,回调函数的实现仅仅是将buffer取出来并释放,开发者可以根据业务需求自行拓展。
配置解码器。
具体开发指导请参考视频解码Surface模式“步骤-5:调用OH_VideoDecoder_Configure()配置解码器”。
设置surface。
在应用业务真正的surface消费端创建成功之前,可以先使用上面临时创建的消费端连接解码器。
示例中的变量说明如下:
ret = OH_VideoDecoder_SetSurface(videoDec, nativeImageWindow);
if (ret != AV_ERR_OK) {
// 异常处理。
} 启动解码器。
具体开发指导请参考视频解码Surface模式“步骤-8:调用OH_VideoDecoder_Start()启动解码器”。
设置surface。
在应用业务真正的surface消费端创建成功后,可以调用OH_VideoDecoder_SetSurface接口,将解码输出重定向到新的surface上。
本例中的nativeWindow,有两种方式获取:
ret = OH_VideoDecoder_SetSurface(videoDec, nativeWindow);
if (ret != AV_ERR_OK) {
// 异常处理。
} 取消NativeImage的回调监听并销毁OH_NativeImage实例。
在调用OH_VideoDecoder_Destroy接口后,调用OH_NativeImage_UnsetOnFrameAvailableListener接口取消帧可用回调监听,再调用OH_NativeImage_Destroy接口销毁OH_NativeImage实例。
// 取消帧可用回调监听。
ret = OH_NativeImage_UnsetOnFrameAvailableListener(image);
if (ret != AV_ERR_OK) {
// 异常处理。
}
// 销毁OH_NativeImage实例。
OH_NativeImage_Destroy(&image);