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