Developing Video Codec Drivers with OpenHarmony's HDF Framework
The OpenHarmony Codec HDI (Hardware Device Interface) driver framework implements video hardware encoding and decoding based on OpenMax standards. It provides foundational codec APIs to upper-layer media services to access capabilities such as component creation, parameter configuration, data buffering, and component lifecycle management. This enables processing of video data formats like YUV/RGB into encoded streams such as H.264/H.265, and vice versa.
Codec HDI Architecture
Built on the HDF (Hardware Driver Foundation) framework, the Codec HDI driver consists of:
- Codec HDI Callback Remote Service: An anonymous callback service for handling asynchronous events.
- Codec HDI Interface: Standard OpenMax-based APIs for hardware codec operasions.
- Codec HDI Adapter: Implementation layer that bridges HDI interfaces with OpenMax IL.
- OpenMax IL Interface: Direct interface to the OpenMax IL layer.
- Vendor Implementation: Manufacturer-specific OpenMax adaptation layer.
- Codec Hardware: Physical decoding/encoding devices.
Core Concepts
Before development, understand these key terms:
- Sampling Rate: Number of samples per second taken from a continuous signal, measured in Hertz (Hz).
- OpenMax IL: Standard for hardware/software codecs, enabling uniform interaction between applications and multimedia components.
- Frame Rate: Number of images transmitted per second, affecting visual smoothness.
- Bitrate: Amount of video data transmitted per unit time (kbps), influencing clarity and artifacts.
- Component: OpenMax IL component abstraction for video stream processing modules.
Constraints
Codec HDI is designed for standard systems only; other platforms are not supported. Interface constraints follow OpenMax IL specifications.
Development Guide
Use Case
Codec modules perform hardware video encoding/decoding, converting raw YUV/RGB data to compressed formats like H.264, and decoding compressed streams back to raw formats.
Interface Specifications
-
icodec_component_manager.h
Interface Description CreateComponent(sptr& component, uint32_t& componentId, const std::string& compName, int64_t appData, const sptr& callbacks)Instantiates a codec component. DestroyComponent(uint32_t componentId)Destroys a codec component instance. -
icodec_component.h
Interface Description SendCommand(CodecCommandType cmd, uint32_t param, const std::vector<int8_t>& cmdData)Sends commands to a component. GetParameter(uint32_t index, const std::vector<int8_t>& inParamStruct, std::vector<int8_t>& outParamStruct)Retrieves component parameters. SetParameter(uint32_t index, const std::vector<int8_t>& paramStruct)Configures component parameters. GetState(CodecStateType& state)Queries component state. UseBuffer(uint32_t portIndex, const OmxCodecBuffer& inBuffer, OmxCodecBuffer& outBuffer)Assigns buffers to componant ports. FreeBuffer(uint32_t portIndex, const OmxCodecBuffer& buffer)Releases allocated buffers. EmptyThisBuffer(const OmxCodecBuffer& buffer)Submits input buffers for encoding/decoding. FillThisBuffer(const OmxCodecBuffer& buffer)Fills output buffers with processed data. -
icodec_callback.h
Interface Descripsion EventHandler(CodecEventType event, const EventInfo& info)Reports component events. EmptyBufferDone(int64_t appData, const OmxCodecBuffer& buffer)Notifies completion of input buffer processing. FillBufferDone(int64_t appData, const OmxCodecBuffer& buffer)Notifies completion of output buffer filling.
Refer to the Codec driver repository for additional interfaces.
Development Steps
Codec HDI driver development involves:
Driver Registration and Initialization
Define the HdfDriverEntry structure for Codec HDI, implementing Bind, Init, and Release function pointers.
static struct HdfDriverEntry g_codecManagerDriverEntry = {
.moduleVersion = 1,
.moduleName = "codec_component_manager_service",
.Bind = CodecManagerDriverBind,
.Init = CodecManagerDriverInit,
.Release = CodecManagerDriverRelease,
};
- CodecManagerDriverBind: Binds HDF device to host and registers the codec service.
static int CodecManagerDriverBind(struct HdfDeviceObject *devObj)
{
CODEC_LOG_INFO("Binding Codec Manager Driver");
auto *hostInstance = new (std::nothrow) CodecManagerHost;
if (hostInstance == nullptr) {
CODEC_LOG_ERROR("Failed to allocate host instance");
return HDF_FAILURE;
}
hostInstance->ioService.Dispatch = CodecManagerDispatch;
hostInstance->ioService.Open = NULL;
hostInstance->ioService.Release = NULL;
auto serviceImpl = ICodecComponentManager::Get(true);
if (serviceImpl == nullptr) {
CODEC_LOG_ERROR("Service implementation unavailable");
delete hostInstance;
return HDF_FAILURE;
}
hostInstance->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl, ICodecComponentManager::GetDescriptor());
if (hostInstance->stub == nullptr) {
CODEC_LOG_ERROR("Stub object creation failed");
delete hostInstance;
return HDF_FAILURE;
}
devObj->service = &hostInstance->ioService;
return HDF_SUCCESS;
}
- CodecManagerDriverInit: Loads configuration properties from HCS (HDF Configuration Source).
static int CodecManagerDriverInit(struct HdfDeviceObject *devObj)
{
CODEC_LOG_INFO("Initializing Codec Manager Driver");
// Load HCS configuration
return HDF_SUCCESS;
}