• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Using AVCodec to Play DRM Content (C/C++)
2
3## When to Use
4
5You can call the native APIs of DRM Kit to play DRM-protected programs.
6
7Currently, the following decryption capabilities are supported:
8
9| Audio Container Format| Audio Decryption Type|
10|----------|:-------|
11| mp4      | AAC    |
12
13| Video Container Format| Video Decryption Type|
14|----------|:------------|
15| ts       | AVC(H.264)  |
16| mp4      | AVC(H.264)  |
17<!--RP1--><!--RP1End-->
18
19**Usage Scenario**
20
21Before creating DRM, obtain the DRM information. For details, see step 4 in [Media Data Demultiplexing](../avcodec/audio-video-demuxer.md#how-to-develop).
22
23## How to Develop
24
25Read [DRM](../../reference/apis-drm-kit/capi-drm.md) for the API reference.
26
27Refer to the following sample code to complete the entire DRM process, including obtaining the name and ID list of the DRM solutions supported by the device, creating MediaKeySystem and MediaKeySession instances, generating a media key request, processing a media key response, checking whether secure video decoding is required, and destroying resources.
28
29During application development, you must call the APIs in the defined sequence. Otherwise, an exception or undefined behavior may occur.
30
31### Linking the Dynamic Libraries in the CMake Script
32
33``` cmake
34target_link_libraries(sample PUBLIC libnative_drm.so)
35```
36
37> **NOTE**
38>
39> The word **sample** in the preceding code snippet is only an example. Use the actual project directory name.
40>
41
42## How to Develop
43
441. Import the DRM Kit module.
45
46    ```c++
47    #include "multimedia/drm_framework/native_drm_common.h"
48    #include "multimedia/drm_framework/native_drm_err.h"
49    #include "multimedia/drm_framework/native_mediakeysession.h"
50    #include "multimedia/drm_framework/native_mediakeysystem.h"
51    ```
52
532. Obtain the name and ID list of the DRM solutions supported by the device.
54
55    ```c++
56    uint32_t count = 3; // count indicates the number of DRM plugins supported by the device. Pass in the actual number.
57    DRM_MediaKeySystemDescription descriptions[3];
58    memset(descriptions, 0, sizeof(descriptions));
59    Drm_ErrCode ret = OH_MediaKeySystem_GetMediaKeySystems(descriptions, &count);
60    if (ret != DRM_ERR_OK) {
61        printf("OH_MediaKeySystem_GetMediaKeySystems failed.");
62    }
63    ```
64
65    After obtaining the name and ID list of DRM solutions supported by the device, match against the DRM information and create the corresponding DRM solution. You can obtain the DRM information by referring to step 4 in the [Media Data Demultiplexing](../avcodec/audio-video-demuxer.md#how-to-develop).
66
67    Alternatively, directly parse the media protocol or media data to obtain the unique identifier of the DRM solution and the PSSH data, so as to generate the DRM information.
68
693. Create a MediaKeySystem instance.
70
71    ```c++
72    MediaKeySystem *mediaKeySystem = nullptr;
73    ret = OH_MediaKeySystem_Create("com.clearplay.drm", &mediaKeySystem);
74    if (ret != DRM_ERR_OK || mediaKeySystem == nullptr) {
75        printf("OH_MediaKeySystem_Create failed.");
76    }
77    ```
78
794. Create a MediaKeySession instance.
80
81    ```c++
82    MediaKeySession *mediaKeySession = nullptr;
83    DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_SW_CRYPTO; // Set the content protection level supported by the device.
84    ret = OH_MediaKeySystem_CreateMediaKeySession(mediaKeySystem, &contentProtectionLevel, &mediaKeySession);
85    if (ret != DRM_ERR_OK || mediaKeySession == nullptr) {
86        printf("OH_MediaKeySystem_CreateMediaKeySession failed.");
87    }
88    ```
89
905. Check whether secure decoding is required.
91
92    ```c++
93    bool requireSecureDecoder;
94    ret = OH_MediaKeySession_RequireSecureDecoderModule(mediaKeySession, "video/avc", &requireSecureDecoder);
95    if (ret != DRM_ERR_OK) {
96        printf("OH_MediaKeySession_RequireSecureDecoderModule failed.");
97    }
98    ```
99
1006. Generate a media key request and process its response.
101
102    ```c++
103    #define MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE 24576 // 24576: (2 * 12 * 1024)
104    DRM_MediaKeyRequest mediaKeyRequest;
105    DRM_MediaKeyRequestInfo info;
106    // initData corresponds to PSSH data in the stream. Pass in the actual data.
107    unsigned char initData[512] = {0x00};
108    memset(&info, 0, sizeof(DRM_MediaKeyRequestInfo));
109    info.initDataLen = sizeof(initData);
110    info.type = MEDIA_KEY_TYPE_ONLINE; // MEDIA_KEY_TYPE_ONLINE: online media key request; MEDIA_KEY_TYPE_OFFLINE: offline media key request.
111    memcpy(info.mimeType, (char *)"video/mp4", sizeof("video/mp4"));
112    memcpy(info.initData, initData, sizeof(initData));
113    memcpy(info.optionName[0], (char *)"optionalDataName", sizeof("optionalDataName"));
114    memcpy(info.optionData[0], (char *)"optionalDataValue", sizeof("optionalDataValue"));
115    info.optionsCount = 1;
116    ret = OH_MediaKeySession_GenerateMediaKeyRequest(mediaKeySession, &info, &mediaKeyRequest);
117    if (ret != DRM_ERR_OK) {
118        printf("OH_MediaKeySession_GenerateMediaKeyRequest failed.");
119    }
120    /*
121      The application requests the DRM service through the network, obtains a media key response, and sends the response to OH_MediaKeySession_ProcessMediaKeyResponse.
122      If the response is an offline media key response, the offline media key ID is returned. Set mediaKeyId based on the actual data and length.
123    */
124    unsigned char mediaKeyId[128] = {0x00};
125    int32_t mediaKeyIdLen = 128;
126    // MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE specifies the maximum length of a media key response. Pass in the actual length.
127    unsigned char mediaKeyResponse[MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE] = {0x00};
128    int32_t mediaKeyResponseLen = MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE;
129    ret = OH_MediaKeySession_ProcessMediaKeyResponse(mediaKeySession, mediaKeyResponse,
130        mediaKeyResponseLen, mediaKeyId, &mediaKeyIdLen);
131    if (ret != DRM_ERR_OK) {
132        printf("OH_MediaKeySession_ProcessMediaKeyResponse failed.");
133    }
134    ```
135
136    If required, set the audio decryption configuration by following step 4 in [Audio Decoding](../avcodec/audio-decoding.md#how-to-develop), and set the video decryption configuration by following step 4 in [Surface Output in Video Decoding](../avcodec/video-decoding.md#surface-output) or step 4 in [Buffer Output in Video Decoding](../avcodec/video-decoding.md#buffer-output).
137
1387. Destroy the MediaKeySession instance.
139
140    ```c++
141    ret = OH_MediaKeySession_Destroy(mediaKeySession);
142    if (ret != DRM_ERR_OK) {
143        printf("OH_MediaKeySession_Destroy failed.");
144    }
145    ```
146
1478. Destroy the MediaKeySystem instance.
148
149    ```c++
150    ret = OH_MediaKeySystem_Destroy(mediaKeySystem);
151    if (ret != DRM_ERR_OK) {
152        printf("OH_MediaKeySystem_Destroy failed.");
153    }
154    ```
155