• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# HDMI
2
3
4## Overview
5
6### HDMI
7
8High-definition multimedia interface (HDMI) is an interface for transmitting audio and video data from a source device, such as a DVD player or set-top box (STB), to a sink device, such as a TV or display.
9HDMI usually has a source and a sink.
10The HDMI APIs provide a set of common functions for HDMI transmission, including:
11
12- Opening and closing an HDMI controller
13- Starting and stopping HDMI transmission
14- Setting audio, video, and High Dynamic Range (HDR) attributes, color depth, and AV mute
15- Reading the raw Extended Display Identification Data (EDID) from a sink
16- Registering and unregistering a callback for HDMI hot plug detect (HPD)
17
18### Basic Concepts
19
20HDMI is an audio and video transmission protocol released by Hitachi, Panasonic, Philips, Silicon Image, Sony, Thomson, and Toshiba. The transmission process complies with the Transition-minimized Differential Signaling (TMDS).
21
22- TMDS is used to transmit audio, video, and various auxiliary data.
23- Display data channel (DDC) allows the TX and RX ends to obtain the transmitting and receiving capabilities. However, HDMI only needs to unidirectionally obtain the capabilities of the RX end (display).
24- Consumer Electronics Control (CEC) enables interaction between the HDMI TX and RX devices.
25- Fixed rate link (FRL) allows the maximum TMDS bandwidth to be increased from 18 Gbit/s to 48 Gbit/s.
26- High-bandwidth Digital Content Protection (HDCP) prevents copying of digital audio and video content being transmitted across devices.
27- EDID, usually stored in the display firmware, provides the vendor information, EDID version, maximum image size, color settings, vendor pre-settings, frequency range limit, display name, and serial number.
28
29### Working Principles
30
31The HDMI source provides +5 V and GND for DDC and CEC communication. Through the DDC, the source obtains the sink parameters, such as the RX capabilities. The CEC provides an optional channel to synchronize control signals between the source and sink for better user experience. There are four TMDS channels between the HDMI source and sink. The TMDS clock channel provides clock signals for TMDS, and the other three channels transmit audio, video, and auxiliary data. HDP is the hot plug detect port. When the sink is connected, the source responds by using an interrupt service routine (ISR).
32
33The figure below shows the HDMI physical connection.
34
35**Figure 1** HDMI physical connection
36
37![](figures/HDMI_physical_connection.png "HDMI_physical_connection")
38
39### Constraints
40
41Currently, the HDMI module supports only the kernels (LiteOS) of mini and small systems.
42
43## Development Guidelines
44
45### When to Use
46
47HDMI features high transmission rate, wide transmission bandwidth, high compatibility, and can transmit uncompressed audio and video signals. Compared with the traditional full analog interface, HDMI simplifies connection between devices and provides HDMI-specific intelligent features, which are ideal for high-quality audio and video transmission of small-sized devices.
48
49### Available APIs
50
51**Table 1** HDMI driver APIs
52
53
54| API                       | Description                      |
55| ----------------------------- | -------------------------- |
56| HdmiOpen                      | Opens an HDMI controller.            |
57| HdmiClose                     | Closes an HDMI controller.            |
58| HdmiStart                     | Starts HDMI transmission.              |
59| HdmiStop                      | Stops HDMI transmission.              |
60| HdmiAvmuteSet                 | Sets the AV mute feature.          |
61| HdmiDeepColorSet              | Sets the color depth.              |
62| HdmiDeepColorGet              | Obtains the color depth.              |
63| HdmiSetVideoAttribute         | Sets video attributes.              |
64| HdmiSetAudioAttribute         | Sets audio attributes.              |
65| HdmiSetHdrAttribute           | Sets HDR attributes.               |
66| HdmiReadSinkEdid              | Reads the raw EDID from a sink.    |
67| HdmiRegisterHpdCallbackFunc   | Registers a callback for HDMI HPD.|
68| HdmiUnregisterHpdCallbackFunc | Unregisters a callback for HDMI HPD.|
69
70### How to Develop
71
72The figure below illustrates the general HDMI development process.
73
74**Figure 2** Using HDMI driver APIs
75
76![](figures/using-HDMI-process.png "using-HDMI-process")
77
78#### Opening an HDMI Controller
79
80Before HDMI communication, call **HdmiOpen()** to open an HDMI controller.
81
82```c
83DevHandle HdmiOpen(int16_t number);
84```
85
86**Table 2** Description of HdmiOpen
87
88| Parameter      | Description            |
89| ---------- | -------------------- |
90| number     | HDMI controller ID.        |
91| **Return Value**| **Description**      |
92| NULL       | The operation failed.  |
93| Controller handle| Handle of the opened HDMI controller.|
94
95For example, open controller 0 of the two HDMI controllers (numbered 0 and 1) in the system:
96
97```c
98DevHandle hdmiHandle = NULL; /* HDMI controller handle /
99
100/* Open HDMI controller 0. */
101hdmiHandle = HdmiOpen(0);
102if (hdmiHandle == NULL) {
103    HDF_LOGE("HdmiOpen: failed\n");
104    return;
105}
106```
107
108#### Registering a Callback for HPD
109
110```c
111int32_t HdmiRegisterHpdCallbackFunc(DevHandle handle, struct HdmiHpdCallbackInfo *callback);
112```
113
114**Table 3** Description of HdmiRegisterHpdCallbackFunc
115
116| Parameter      | Description          |
117| ---------- | ------------------ |
118| handle     | HDMI controller handle.    |
119| callback   | Pointer to the callback to be invoked to return the HPD result.|
120| **Return Value**| **Description**    |
121| 0          | The operation is successful.          |
122| Negative value      | The operation failed.          |
123
124The following is an example of registering a callback for HPD:
125
126```c
127/* Definition of the callback for HPD */
128static void HdmiHpdHandle(void *data, bool hpd)
129{
130    if (data == NULL) {
131        HDF_LOGE("priv data is NULL");
132        return;
133    }
134    if (hpd == true) {
135        HDF_LOGD("HdmiHpdHandle: hot plug");
136        /* Add related processing if required. */
137    } else {
138        HDF_LOGD("HdmiHpdHandle: hot unplug");
139        /* Add related processing if required. */
140    }
141}
142
143/* Example of registering a callback for HPD */
144···
145struct HdmiHpdCallbackInfo info = {0};
146info.data = handle;
147info.callbackFunc = HdmiHpdHandle;
148ret = HdmiRegisterHpdCallbackFunc(hdmiHandle, info);
149if (ret != 0) {
150    HDF_LOGE("HdmiRegisterHpdCallbackFunc: Register failed.");
151}
152···
153```
154
155#### Reading the Raw EDID
156
157```c
158int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len);
159```
160
161**Table 4** Description of HdmiReadSinkEdid
162
163| Parameter      | Description              |
164| ---------- | ---------------------- |
165| handle     | HDMI controller handle.        |
166| buffer     | Pointer to the data buffer.            |
167| len        | Data length.              |
168| **Return Value**| **Description**        |
169| Positive integer    | Raw EDID read.|
170| Negative number or 0   | Failed to read the EDID.              |
171
172The following is an example of reading the raw EDID from a sink:
173
174```c
175int32_t len;
176uint8_t edid[HDMI_EDID_MAX_LEN] = {0};
177
178len = HdmiReadSinkEdid(hdmiHandle, edid, HDMI_EDID_MAX_LEN);
179if (len <= 0) {
180    HDF_LOGE("%s: HdmiReadSinkEdid failed len = %d.", __func__, len);
181}
182```
183
184#### Setting Audio Attributes
185
186```c
187int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr);
188```
189
190**Table 5** Description of HdmiSetAudioAttribute
191
192
193| Parameter  | Description      |
194| ------ | -------------- |
195| handle | HDMI controller handle.|
196| attr   | Pointer to the audio attributes.      |
197| **Return Value**| **Description**    |
198| 0      | The operation is successful.      |
199| Negative value  | The operation failed.      |
200
201The following is an example of setting audio attributes:
202
203```c
204struct HdmiAudioAttr audioAttr = {0};
205int32_t ret;
206
207audioAttr.codingType = HDMI_AUDIO_CODING_TYPE_MP3;
208audioAttr.ifType = HDMI_AUDIO_IF_TYPE_I2S;
209audioAttr.bitDepth = HDMI_ADIO_BIT_DEPTH_16;
210audioAttr.sampleRate = HDMI_SAMPLE_RATE_8K;
211audioAttr.channels = HDMI_AUDIO_FORMAT_CHANNEL_3;
212ret = HdmiSetAudioAttribute(handle, &audioAttr);
213if (ret != 0) {
214    HDF_LOGE("HdmiSetAudioAttribute failed.");
215}
216```
217
218#### Setting Video Attributes
219
220```c
221int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr);
222```
223
224**Table 6** Description of HdmiSetVideoAttribute
225
226
227| Parameter      | Description      |
228| ---------- | -------------- |
229| handle     | HDMI controller handle.|
230| attr       | Pointer to the video attributes.      |
231| **Return Value**| **Description**|
232| 0          | The operation is successful.      |
233| Negative value      | The operation failed.      |
234
235The following is an example of setting video attributes:
236
237```c
238struct HdmiVideoAttr videoAttr = {0};
239int32_t ret;
240
241videoAttr.colorSpace = HDMI_COLOR_SPACE_YCBCR444;
242videoAttr.colorimetry = HDMI_COLORIMETRY_EXTENDED;
243videoAttr.extColorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM;
244videoAttr.quantization = HDMI_QUANTIZATION_RANGE_FULL;
245ret = HdmiSetVideoAttribute(handle, &videoAttr);
246if (ret != 0) {
247    HDF_LOGE("HdmiSetVideoAttribute failed.");
248}
249```
250
251#### Setting HDR Attributes
252
253```c
254int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr);
255```
256
257**Table 7** Description of HdmiSetHdrAttribute
258
259
260| Parameter      | Description      |
261| ---------- | -------------- |
262| handle     | HDMI controller handle.|
263| attr       | Pointer to the HDR attributes       |
264| **Return Value**| **Description**|
265| 0          | The operation is successful.      |
266| Negative value      | The operation failed.      |
267
268The following is an example of setting HDR attributes:
269
270```c
271struct HdmiHdrAttr hdrAttr = {0};
272int32_t ret;
273
274hdrAttr.mode = HDMI_HDR_MODE_CEA_861_3;
275hdrAttr.userMode = HDMI_HDR_USERMODE_DOLBY;
276hdrAttr.eotfType = HDMI_EOTF_SMPTE_ST_2048;
277hdrAttr.metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1;
278hdrAttr.colorimetry = HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709;
279ret = HdmiSetHdrAttribute(handle, &hdrAttr);
280if (ret != 0) {
281    HDF_LOGE("HdmiSetHdrAttribute failed.");
282}
283```
284
285#### Setting HDMI AV Mute
286
287```c
288int32_t HdmiAvmuteSet(DevHandle handle, bool enable);
289```
290
291**Table 8** Description of HdmiAvmuteSet
292
293
294| Parameter      | Description         |
295| ---------- | ----------------- |
296| handle     | HDMI controller handle.   |
297| enable     | Whether to enable the AV mute feature.|
298| **Return Value**| **Description**   |
299| 0          | The operation is successful.         |
300| Negative value      | The operation failed.         |
301
302The following is an example of setting AV mute:
303
304```c
305int32_t ret;
306
307ret = HdmiAvmuteSet(hdmiHandle, true);
308if (ret != 0) {
309    HDF_LOGE("HdmiAvmuteSet failed.");
310}
311```
312
313#### Setting the Color Depth
314
315```c
316int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color);
317```
318
319**Table 9** Description of HdmiDeepColorSet
320
321
322| Parameter      | Description      |
323| ---------- | -------------- |
324| handle     | HDMI controller handle.|
325| color      | Color depth to set.      |
326| **Return Value**| **Description**|
327| 0          | The operation is successful.      |
328| Negative value      | The operation failed.      |
329
330The following is an example of setting the color depth:
331
332```c
333int32_t ret;
334
335ret = HdmiDeepColorSet(handle, HDMI_DEEP_COLOR_48BITS);
336if (ret != 0) {
337    HDF_LOGE("HdmiDeepColorSet failed.");
338}
339```
340
341#### Obtaining the Color Depth
342
343```c
344int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color);
345```
346
347**Table 10** Description of HdmiDeepColorGet
348
349
350| Parameter      | Description      |
351| ---------- | -------------- |
352| handle     | HDMI controller handle.|
353| color      | Pointer to the color depth.      |
354| **Return Value**| **Description**|
355| 0          | The operation is successful.      |
356| Negative value      | The operation failed.      |
357
358The following is an example of obtaining the color depth:
359
360```c
361enum HdmiDeepColor color;
362int32_t ret;
363
364ret = HdmiDeepColorGet(handle, &color);
365if (ret != 0) {
366    HDF_LOGE("HdmiDeepColorGet failed.");
367}
368```
369
370#### Starting HDMI Transmission
371
372```c
373int32_t HdmiStart(DevHandle handle);
374```
375
376**Table 11** Description of HdmiStart
377
378
379| Parameter      | Description      |
380| ---------- | -------------- |
381| handle     | HDMI controller handle.|
382| **Return Value**| **Description**|
383| 0          | The operation is successful.      |
384| Negative value      | The operation failed.      |
385
386The following is an example of starting HDMI transmission:
387
388```c
389int32_t ret;
390
391ret = HdmiStart(hdmiHandle);
392if (ret != 0) {
393    HDF_LOGE("Failed to start transmission.");
394}
395```
396
397#### Stopping HDMI Transmission<a name="section11"></a>
398
399```c
400int32_t HdmiStop(DevHandle handle);
401```
402
403**Table 12** Description of HdmiStop
404
405
406| Parameter      | Description      |
407| ---------- | -------------- |
408| handle     | HDMI controller handle.|
409| **Return Value**| **Description**|
410| 0          | The operation is successful.      |
411| Negative value      | The operation failed.      |
412
413The following is an example of stopping HDMI transmission:
414
415```c
416int32_t ret;
417
418ret = HdmiStop(hdmiHandle);
419if (ret != 0) {
420    HDF_LOGE("Failed to stop transmission.");
421}
422```
423
424#### Unregistering the Callback for HPD
425
426```c
427int32_t HdmiUnregisterHpdCallbackFunc(DevHandle handle);
428```
429
430**Table 13** Description of HdmiUnregisterHpdCallbackFunc
431
432
433| Parameter      | Description      |
434| ---------- | -------------- |
435| handle     | HDMI controller handle.|
436| **Return Value**| **Description**|
437| 0          | The operation is successful.      |
438| Negative value      | The operation failed.      |
439
440The following is an example of unregistering the callback for HPD:
441
442```c
443int32_t ret;
444
445ret = HdmiUnregisterHpdCallbackFunc(hdmiHandle);
446if (ret != 0) {
447    HDF_LOGE("unregister failed.");
448}
449```
450
451#### Closing an HDMI Controller
452
453```c
454void HdmiClose(DevHandle handle);
455```
456
457**Table 14** Description of HdmiClose
458
459
460| Parameter      | Description      |
461| ---------- | -------------- |
462| handle     | HDMI controller handle.|
463
464The following is an example of closing an HDMI controller:
465
466```c
467HdmiClose(hdmiHandle);
468```
469
470### Example
471
472This following example shows how to use HDMI APIs to manage an HDMI device on a Hi3516D V300 development board.
473
474A virtual driver is used in this example. The hardware information is as follows:
475
476-   SoC: Hi3516D V300
477
478-   HDMI controller: HDMI controller 0
479
480
481The sample code is as follows:
482
483```c
484#include "hdmi_if.h"          /* Header file for HDMI standard APIs */
485#include "hdf_log.h"         /* Header file for log APIs */
486#include "osal_time.h"       /* Header file for delay and sleep APIs */
487
488/* Callback for hog plug detect */
489static void HdmiHpdHandle(void *data, bool hpd)
490{
491    if (data == NULL) {
492    HDF_LOGE("priv data is NULL");
493    return;
494    }
495
496    if (hpd == true) {
497        HDF_LOGD("HdmiHpdHandle: hot plug");
498        /* Add related processing if required. */
499    } else {
500        HDF_LOGD("HdmiHpdHandle: hot unplug");
501        /* Add related processing if required. */
502    }
503}
504
505/* Set HDMI attributes. */
506static int32_t TestHdmiSetAttr(DevHandle handle)
507{
508    enum HdmiDeepColor color;
509    struct HdmiVideoAttr videoAttr = {0};
510    struct HdmiAudioAttr audioAttr = {0};
511    struct HdmiHdrAttr hdrAttr = {0};
512    int32_t ret;
513
514    ret = HdmiDeepColorSet(handle, HDMI_DEEP_COLOR_48BITS);
515
516    if (ret != 0) {
517        HDF_LOGE("HdmiDeepColorSet failed.");
518        return ret;
519    }
520    ret = HdmiDeepColorGet(handle, &color);
521    if (ret != 0) {
522        HDF_LOGE("HdmiDeepColorGet failed.");
523        return ret;
524    }
525    HDF_LOGE("HdmiDeepColorGet successful, color = %d.", color);
526    videoAttr.colorSpace = HDMI_COLOR_SPACE_YCBCR444;
527    videoAttr.colorimetry = HDMI_COLORIMETRY_EXTENDED;
528    videoAttr.extColorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM;
529    videoAttr.quantization = HDMI_QUANTIZATION_RANGE_FULL;
530    ret = HdmiSetVideoAttribute(handle, &videoAttr);
531    if (ret != 0) {
532        HDF_LOGE("HdmiSetVideoAttribute failed.");
533        return ret;
534    }
535    audioAttr.codingType = HDMI_AUDIO_CODING_TYPE_MP3;
536    audioAttr.ifType = HDMI_AUDIO_IF_TYPE_I2S;
537    audioAttr.bitDepth = HDMI_ADIO_BIT_DEPTH_16;
538    audioAttr.sampleRate = HDMI_SAMPLE_RATE_8K;
539    audioAttr.channels = HDMI_AUDIO_FORMAT_CHANNEL_3;
540    ret = HdmiSetAudioAttribute(handle, &audioAttr);
541    if (ret != 0) {
542        HDF_LOGE("HdmiSetAudioAttribute failed.");
543        return ret;
544    }
545    hdrAttr.mode = HDMI_HDR_MODE_CEA_861_3;
546    hdrAttr.userMode = HDMI_HDR_USERMODE_DOLBY;
547    hdrAttr.eotfType = HDMI_EOTF_SMPTE_ST_2048;
548    hdrAttr.metadataType = HDMI_DRM_STATIC_METADATA_TYPE_1;
549    hdrAttr.colorimetry = HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709;
550    ret = HdmiSetHdrAttribute(handle, &hdrAttr);
551    if (ret != 0) {
552        HDF_LOGE("HdmiSetHdrAttribute failed.");
553        return ret;
554    }
555
556    return 0;
557}
558
559/* Main entry of HDMI routines */
560static int32_t TestCaseHdmi(void)
561{
562    DevHandle handle = NULL;
563    int32_t ret;
564
565    struct HdmiHpdCallbackInfo info = {0};
566    uint8_t data[128] = {0};
567
568    HDF_LOGD("HdmiAdapterInit: successful.");
569    handle = HdmiOpen(0);
570    if (handle == NULL) {
571        HDF_LOGE("HdmiOpen failed.");
572        return ret;
573    }
574    info.data = handle;
575    info.callbackFunc = HdmiHpdHandle;
576    ret = HdmiRegisterHpdCallbackFunc(handle, &info);
577    if (ret != 0) {
578        HDF_LOGE("HdmiRegisterHpdCallbackFunc failed.");
579        return ret;
580    }
581
582    ret = HdmiReadSinkEdid(handle, data, 128);
583    if (ret <= 0) {
584        HDF_LOGE("HdmiReadSinkEdid failed.");
585        return ret;
586    }
587    HDF_LOGE("HdmiReadSinkEdid successful, data[6] = %d, data[8] = %d.", data[6], data[8]);
588
589    ret = TestHdmiSetAttr(handle);
590    if (ret != 0) {
591        HDF_LOGE("TestHdmiSetAttr failed.");
592        return ret;
593    }
594
595    ret = HdmiStart(handle);
596    if (ret != 0) {
597        HDF_LOGE("HdmiStart failed.");
598        return ret;
599    }
600
601    OsalMSleep(1000);
602
603    ret = HdmiStop(handle);
604    if (ret != 0) {
605        HDF_LOGE("HdmiStop failed.");
606        return ret;
607    }
608
609    ret = HdmiUnregisterHpdCallbackFunc(handle);
610    if (ret != 0) {
611        HDF_LOGE("HdmiUnregisterHpdCallbackFunc failed.");
612        return ret;
613    }
614    HdmiClose(handle);
615    return 0;
616}
617
618```
619