# HDMI ## Overview - The High-Definition Multimedia Interface (HDMI) is an audio/video transmission protocol released by Hitachi, Panasonic, Philips, Silicon Image, Sony, Thomson, Toshiba. - The HDMI works in master/slave mode and usually has a source and a sink. - The HDMI APIs provide a set of common functions for HDMI transmission, including: - Opening and closing an HDMI controller. - Starting and stopping HDMI transmission. - Setting audio, video, and High Dynamic Range (HDR) attributes, color depth, and AV mute. - Reading the raw Extended Display Identification Data (EDID) from a sink. - Registering and unregistering a callback for HDMI hot plug detect. - [Figure 1](#fig1) shows the HDMI physical connection. **Figure 1** HDMI physical connection ![](figures/HDMI_physical_connection.png "HDMI_physical_connection") ## Available APIs **Table 1** HDMI driver APIs

Category

API

Description

Managing HDMI controllers

HdmiOpen

Opens an HDMI controller.

HdmiClose

Closes an HDMI controller.

Starting or stopping HDMI transmission

HdmiStart

Starts HDMI transmission.

HdmiStop

Stops HDMI transmission.

Setting an HDMI controller

HdmiAvmuteSet

Sets the AV mute feature.

HdmiDeepColorSet

Sets the color depth.

HdmiDeepColorGet

Obtains the color depth.

HdmiSetVideoAttribute

Sets video attributes.

HdmiSetAudioAttribute

Sets audio attributes.

HdmiSetHdrAttribute

Sets HDR attributes.

Reading EDID

HdmiReadSinkEdid

Reads the raw EDID from a sink.

Registering or unregistering a callback for HDMI hot plug detect

HdmiRegisterHpdCallbackFunc

Registers a callback for HDMI hot plug detect.

HdmiUnregisterHpdCallbackFunc

Unregisters the callback for HDMI hot plug detect.

## Usage Guidelines ### How to Use [Figure 2](#fig2) shows how HDMI works. **Figure 2** How HDMI works ![](figures/HDMI_usage_flowchart.png "HDMI_usage_flowchart") ### Opening an HDMI Controller Before HDMI communication, call **HdmiOpen** to enable an HDMI controller. ```c DevHandle HdmiOpen(int16_t number); ``` **Table 2** Description of HdmiOpen

Parameter

Description

number

HDMI controller ID.

Return Value

Description

NULL

Failed to open the HDMI controller.

Controller handle

Handle of the HDMI controller opened.

For example, the system has two HDMI controllers, numbered 0 and 1. Open controller 0. ```c DevHandle hdmiHandle = NULL; /* HDMI controller handle / /* Open HDMI controller 0. */ hdmiHandle = HdmiOpen(0); if (hdmiHandle == NULL) { HDF_LOGE("HdmiOpen: failed\n"); return; } ``` ### Registering a Callback for Hot Plug Detect ```c int32_t HdmiRegisterHpdCallbackFunc(DevHandle handle, struct HdmiHpdCallbackInfo *callback); ``` **Table 3** Description of HdmiRegisterHpdCallbackFunc

Parameter

Description

handle

HDMI controller handle.

callback

Callback invoked to return the hot plug detect result.

Return Value

Description

0

The callback is registered successfully.

Negative number

Failed to register the callback.

The following is an example of registering a callback for hot plug detect: ```c /* Definition of the callback for hot plug detect */ static void HdmiHpdHandle(void *data, bool hpd) { if (data == NULL) { HDF_LOGE("priv data is NULL"); return; } if (hpd == true) { HDF_LOGD("HdmiHpdHandle: hot plug"); /* Add related processing if required. */ } else { HDF_LOGD("HdmiHpdHandle: hot unplog"); /* Add related processing if required. */ } } /* Example of registering a callback for hot plug detect */ struct HdmiHpdCallbackInfo info = {0}; info.data = handle; info.callbackFunc = HdmiHpdHandle; ret = HdmiRegisterHpdCallbackFunc(hdmiHandle, info); if (ret != 0) { HDF_LOGE("HdmiRegisterHpdCallbackFunc: Register failed."); } ``` ### Reading the EDID ```c int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len); ``` **Table 4** Description of HdmiReadSinkEdid

Parameter

Description

handle

HDMI controller handle.

buffer

Data buffer.

len

Data length.

Return Value

Description

Positive integer

Raw EDID read.

Negative number or **0**

Failed to read the EDID.

The following is an example of reading the raw EDID data from a sink: ```c int32_t len; uint8_t edid[HDMI_EDID_MAX_LEN] = {0}; len = HdmiReadSinkEdid(hdmiHandle, edid, HDMI_EDID_MAX_LEN); if (len <= 0) { HDF_LOGE("%s: HdmiReadSinkEdid failed len = %d.", __func__, len); } ``` ### Setting Video, Audio, and HDR Attributes #### Setting Audio Attributes ```c int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr); ``` **Table 5** Description of HdmiSetAudioAttribute

Parameter

Description

handle

HDMI controller handle.

attr

Audio attributes.

Return Value

Description

0

The operation is successful.

Negative number

The operation failed.

The following is an example of setting audio attributes: ```c struct HdmiAudioAttr audioAttr = {0}; int32_t ret; audioAttr.codingType = HDMI_AUDIO_CODING_TYPE_MP3; audioAttr.ifType = HDMI_AUDIO_IF_TYPE_I2S; audioAttr.bitDepth = HDMI_ADIO_BIT_DEPTH_16; audioAttr.sampleRate = HDMI_SAMPLE_RATE_8K; audioAttr.channels = HDMI_AUDIO_FORMAT_CHANNEL_3; ret = HdmiSetAudioAttribute(handle, &audioAttr); if (ret != 0) { HDF_LOGE("HdmiSetAudioAttribute failed."); } ``` #### Setting Video Attributes ```c int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr); ``` **Table 6** Description of HdmiSetVideoAttribute

Parameter

Description

handle

HDMI controller handle.

attr

Video attributes.

Return Value

Description

0

The operation is successful.

Negative number

The operation failed.

The following is an example of setting video attributes: ```c struct HdmiVideoAttr videoAttr = {0}; int32_t ret; videoAttr.colorSpace = HDMI_COLOR_SPACE_YCBCR444; videoAttr.colorimetry = HDMI_COLORIMETRY_EXTENDED; videoAttr.extColorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM; videoAttr.quantization = HDMI_QUANTIZATION_RANGE_FULL; ret = HdmiSetVideoAttribute(handle, &videoAttr); if (ret != 0) { HDF_LOGE("HdmiSetVideoAttribute failed."); } ``` #### Setting HDR Attributes ```c int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr); ``` **Table 7** Description of HdmiSetHdrAttribute

Parameter

Description

handle

HDMI controller handle.

attr

HDR attributes.

Return Value

Description

0

The operation is successful.

Negative number

The operation failed.

The following is an example of setting HDR attributes: ```c struct HdmiHdrAttr hdrAttr = {0}; int32_t ret; hdrAttr.mode = HDMI_HDR_MODE_CEA_861_3; hdrAttr.userMode = HDMI_HDR_USERMODE_DOLBY; hdrAttr.eotfType = HDMI_EOTF_SMPTE_ST_2048; hdrAttr.metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1; hdrAttr.colorimetry = HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709; ret = HdmiSetHdrAttribute(handle, &hdrAttr); if (ret != 0) { HDF_LOGE("HdmiSetHdrAttribute failed."); } ``` ### Setting Other Attributes #### Setting HDMI AV Mute ```c int32_t HdmiAvmuteSet(DevHandle handle, bool enable); ``` **Table 8** Description of HdmiAvmuteSet

Parameter

Description

handle

HDMI controller handle.

enable

Whether the AV mute feature is enabled.

Return Value

Description

0

The operation is successful.

Negative number

The operation failed.

The following is an example of setting AV mute: ```c int32_t ret; ret = HdmiAvmuteSet(hdmiHandle, true); if (ret != 0) { HDF_LOGE("HdmiAvmuteSet failed."); } ``` #### Setting the Color Depth ```c int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color); ``` **Table 9** Description of HdmiDeepColorSet

Parameter

Description

handle

HDMI controller handle.

color

Color depth to set.

Return Value

Description

0

The operation is successful.

Negative number

The operation failed.

The following is an example of setting the color depth: ```c int32_t ret; ret = HdmiDeepColorSet(handle, HDMI_DEEP_COLOR_48BITS); if (ret != 0) { HDF_LOGE("HdmiDeepColorSet failed."); } ``` #### Obtaining the Color Depth ```c int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color); ``` **Table 10** Description of HdmiDeepColorGet

Parameter

Description

handle

HDMI controller handle.

color

Color depth.

Return Value

Description

0

The operation is successful.

Negative number

The operation failed.

The following is an example of obtaining the color depth: ```c enum HdmiDeepColor color; int32_t ret; ret = HdmiDeepColorGet(handle, &color); if (ret != 0) { HDF_LOGE("HdmiDeepColorGet failed."); } ``` ### Starting HDMI Transmission ```c int32_t HdmiStart(DevHandle handle); ``` **Table 11** Description of HdmiStart

Parameter

Description

handle

HDMI controller handle.

Return Value

Description

0

The operation is successful.

Negative number

The operation failed.

The following is an example of starting HDMI transmission: ```c int32_t ret; ret = HdmiStart(hdmiHandle); if (ret != 0) { HDF_LOGE("Failed to start transmission."); } ``` ### Stopping HDMI Transmission ```c int32_t HdmiStop(DevHandle handle); ``` **Table 12** Description of HdmiStop

Parameter

Description

handle

HDMI controller handle.

Return Value

Description

0

The operation is successful.

Negative number

The operation failed.

The following is an example of stopping HDMI transmission: ```c int32_t ret; ret = HdmiStop(hdmiHandle); if (ret != 0) { HDF_LOGE("Failed to stop transmission."); } ``` ### Unregistering the Callback for Hot Plug Detect ```c int32_t HdmiUnregisterHpdCallbackFunc(DevHandle handle); ``` **Table 13** Description of HdmiUnregisterHpdCallbackFunc

Parameter

Description

handle

HDMI controller handle.

Return Value

Description

0

The operation is successful.

Negative number

The operation failed.

The following is an example of unregistering the callback for hot plug detect: ```c int32_t ret; ret = HdmiUnregisterHpdCallbackFunc(hdmiHandle); if (ret != 0) { HDF_LOGE("unregister failed."); } ``` ### Closing an HDMI Controller ```c void HdmiClose(DevHandle handle); ``` **Table 14** Description of HdmiClose

Parameter

Description

handle

HDMI controller handle.

The following is an example of closing an HDMI controller: ```c HdmiClose(hdmiHandle); ``` ## Example This following example shows how to use HDMI APIs to manage an HDMI device on a Hi3516D V300 development board. A virtual driver is used in this example. The hardware information is as follows: - SoC: Hi3516D V300 - HDMI controller: HDMI controller 0 The sample code is as follows: ```c #include "hdmi_if.h" /* Header file for HDMI standard APIs */ #include "hdf_log.h" /* Header file for log APIs */ ##include "osal_time.h" /* Header file for delay and sleep APIs */ /* Callback for hog plug detect */ static void HdmiHpdHandle(void *data, bool hpd) { if (data == NULL) { HDF_LOGE("priv data is NULL"); return; } if (hpd == true) { HDF_LOGD("HdmiHpdHandle: hot plug"); /* Add related processing if required. */ } else { HDF_LOGD("HdmiHpdHandle: hot unplog"); /* Add related processing if required. */ } } /* Set HDMI attributes. */ static int32_t TestHdmiSetAttr(DevHandle handle) { enum HdmiDeepColor color; struct HdmiVideoAttr videoAttr = {0}; struct HdmiAudioAttr audioAttr = {0}; struct HdmiHdrAttr hdrAttr = {0}; int32_t ret; ret = HdmiDeepColorSet(handle, HDMI_DEEP_COLOR_48BITS); if (ret != 0) { HDF_LOGE("HdmiDeepColorSet failed."); return ret; } ret = HdmiDeepColorGet(handle, &color); if (ret != 0) { HDF_LOGE("HdmiDeepColorGet failed."); return ret; } HDF_LOGE("HdmiDeepColorGet successful, color = %d.", color); videoAttr.colorSpace = HDMI_COLOR_SPACE_YCBCR444; videoAttr.colorimetry = HDMI_COLORIMETRY_EXTENDED; videoAttr.extColorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM; videoAttr.quantization = HDMI_QUANTIZATION_RANGE_FULL; ret = HdmiSetVideoAttribute(handle, &videoAttr); if (ret != 0) { HDF_LOGE("HdmiSetVideoAttribute failed."); return ret; } audioAttr.codingType = HDMI_AUDIO_CODING_TYPE_MP3; audioAttr.ifType = HDMI_AUDIO_IF_TYPE_I2S; audioAttr.bitDepth = HDMI_ADIO_BIT_DEPTH_16; audioAttr.sampleRate = HDMI_SAMPLE_RATE_8K; audioAttr.channels = HDMI_AUDIO_FORMAT_CHANNEL_3; ret = HdmiSetAudioAttribute(handle, &audioAttr); if (ret != 0) { HDF_LOGE("HdmiSetAudioAttribute failed."); return ret; } hdrAttr.mode = HDMI_HDR_MODE_CEA_861_3; hdrAttr.userMode = HDMI_HDR_USERMODE_DOLBY; hdrAttr.eotfType = HDMI_EOTF_SMPTE_ST_2048; hdrAttr.metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1; hdrAttr.colorimetry = HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709; ret = HdmiSetHdrAttribute(handle, &hdrAttr); if (ret != 0) { HDF_LOGE("HdmiSetHdrAttribute failed."); return ret; } return 0; } /* Main entry of HDMI routines */ static int32_t TestCaseHdmi(void) { DevHandle handle = NULL; int32_t ret; struct HdmiHpdCallbackInfo info = {0}; uint8_t data[128] = {0}; HDF_LOGD("HdmiAdapterInit: successful."); handle = HdmiOpen(0); if (handle == NULL) { HDF_LOGE("HdmiOpen failed."); return ret; } info.data = handle; info.callbackFunc = HdmiHpdHandle; ret = HdmiRegisterHpdCallbackFunc(handle, &info); if (ret != 0) { HDF_LOGE("HdmiRegisterHpdCallbackFunc failed."); return ret; } ret = HdmiReadSinkEdid(handle, data, 128); if (ret <= 0) { HDF_LOGE("HdmiReadSinkEdid failed."); return ret; } HDF_LOGE("HdmiReadSinkEdid successful, data[6] = %d, data[8] = %d.", data[6], data[8]); ret = TestHdmiSetAttr(handle); if (ret != 0) { HDF_LOGE("TestHdmiSetAttr failed."); return ret; } ret = HdmiStart(handle); if (ret != 0) { HDF_LOGE("HdmiStart failed."); return ret; } OsalMSleep(1000); ret = HdmiStop(handle); if (ret != 0) { HDF_LOGE("HdmiStop failed."); return ret; } ret = HdmiUnregisterHpdCallbackFunc(handle); if (ret != 0) { HDF_LOGE("HdmiUnregisterHpdCallbackFunc failed."); return ret; } HdmiClose(handle); return 0; } ```