1 /*
2 * Copyright (c) 2014 Intel Corporation. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef PROTECTED_DATA_BUFFER_H
18 #define PROTECTED_DATA_BUFFER_H
19
20 #include <stdint.h>
21 #include <stdbool.h>
22 #include <stddef.h>
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 // NOTE: this size takes into account the space used by DRM
29 // schemes with full sample encryption (e.g., WV Classic) or
30 // subsample encryption (e.g., WV Modular, which uses 2KB for
31 // frame info data).
32 #define NALU_BUFFER_SIZE (4 * 1024)
33
34 // Either start code + type (00 00 00 01 <type byte>) or 4 byte length + type.
35 #define NALU_HEADER_SIZE 5
36
37 // This should be able to fit compressed 1080p video I-frame, use half
38 // of NV12 1080p frame, which on average uses 12 bits per pixel.
39 #define MAX_COMPRESSED_FRAME_SIZE (1920 * 1080 * 3 / 4)
40
41 #define MAX_PROT_BUFFER_DATA_SIZE (MAX_COMPRESSED_FRAME_SIZE + NALU_BUFFER_SIZE)
42
43 #define MAX_PES_BUFFER_SIZE (64*1024)
44
45 // TODO: it's not clear, how to calculate this value, since PES packet may contain
46 // less than 64KB worth of data.
47 #define MAX_PES_PACKETS_PER_FRAME 64
48
49 // Video decoder defines maximum number of NALUs per frame as 16.
50 // (At least, as of June of 2014.) Use the same value here.
51 #define MAX_NALUS_IN_FRAME 16
52
53 // Integer, which "PDBF", but no 0 terminator
54 #define PROTECTED_DATA_BUFFER_MAGIC (0UL | ('F' << 24) | ('B' << 16) | ('D' << 8) | 'P')
55
56 #define DRM_SCHEME_NONE 0
57 #define DRM_SCHEME_WV_CLASSIC 1
58 #define DRM_SCHEME_WV_MODULAR 2
59 #define DRM_SCHEME_MCAST_SINK 3
60 #define DRM_SCHEME_PLAYREADY_ASF 4
61
62 // Flag to indicate if Last Subsample flag is received for MDRM
63 #define PDB_FLAG_COMPLETE_FRAME 0x1000
64
65 #pragma pack(push, 4)
66
67 typedef struct ProtectedPESBuffer_tag {
68
69 // AES CTR stream counter, needed for HDCP decryption.
70 // If ProtectedDataBuffer::clear is 1, streamCounter is ignored.
71 uint32_t streamCounter ;
72
73 // AES CTR input counter, needed for HDCP decryption
74 // If ProtectedDataBuffer::clear is 1, inputCounter is ignored.
75 uint64_t inputCounter ;
76
77 // Offset within ProtectedDataBuffer::data buffer, to the start
78 // of this PES packet's data.
79 //
80 // IMPORTANT: for protected content (ProtectedDataBuffer::clear is 0),
81 // this offset must be divisible by 16 (AES block size). This is to allow
82 // for in-place transcryption from AES CTR to IED (AES ECB). OMX will
83 // check that the offset is divisible by 16, and will abort
84 // playback, if the offset is NOT divisible by 16. For this reason,
85 // the offset is used and not a byte pointer.
86 uint32_t pesDataOffset ;
87
88 // Size of the PES data, pointed to by pesData
89 uint32_t pesSize ;
90 }
91 ProtectedPESBuffer ;
92
93 typedef struct ProtectedDataBuffer_tag {
94
95 // Must be set to PROTECTED_DATA_BUFFER_MAGIC. Must be the first
96 // member of ProtectedDataBuffer structure.
97 uint32_t magic;
98
99 // See DRM_SCHEME_* defines above
100 uint32_t drmScheme;
101
102 // 1 if clear, 0 if encrypted
103 uint32_t clear;
104
105 // Session ID, used by some DRM schemes (e.g. PlayReady)
106 uint32_t session_id ;
107
108 // Flags, used by some DRM schemes
109 // MDRM uses it to indicate Complete Frame received
110 // Miracast Sink uses it to indicate if Transcription is required
111 uint32_t flags ;
112
113 // Information about the PES data buffers. Used for DRM_SCHEME_MCAST_SINK.
114 // Reserve space for one more PES data buffer for sentinel value, for
115 // ease of implementation.
116 //
117 ProtectedPESBuffer pesBuffers[MAX_PES_PACKETS_PER_FRAME + 1] ;
118
119 // Number of filled-out entries in pesBuffers array.
120 // Used for DRM_SCHEME_MCAST_SINK. If data buffer is not partitioned
121 // into PES packet buffers, set numPesBuffers must be 0.
122 //
123 uint32_t numPesBuffers ;
124
125 // Size of the data buffer.
126 uint32_t size ;
127
128 // For clear content, this is the space for clear data.
129 // For encrypted content, this space is occupied by IED encrypted
130 // data or HDCP encrypted data (payloads only, no PES headers),
131 // depending on the DRM scheme.
132 //
133 // A space is made at the end of encrypted data for
134 // decrypted SPS/PPS headers.
135 //
136 // NOTE: data must be last, to allow for flexibility not
137 // to copy the whole ProtectedDataBuffer, if not whole data
138 // buffer is filled.
139 //
140 uint8_t data[MAX_PROT_BUFFER_DATA_SIZE];
141 }
142 ProtectedDataBuffer;
143
144 #pragma pack(pop)
145
146 #define PDBUFFER_DATA_OFFSET offsetof(ProtectedDataBuffer, data)
147
Init_ProtectedDataBuffer(ProtectedDataBuffer * buf)148 static inline void Init_ProtectedDataBuffer(ProtectedDataBuffer* buf)
149 {
150 // This is internal helper function. If you pass invalid (e.g. NULL)
151 // pointer to it, you deserve to crash.
152
153 // Perform initialization of certain members, ignore the data
154 // areas, which will be overwritten in the course of the
155 // normal usage.
156
157 buf->magic = PROTECTED_DATA_BUFFER_MAGIC ;
158 buf->drmScheme = DRM_SCHEME_NONE ;
159 buf->clear = 0 ;
160 buf->size = 0 ;
161 buf->numPesBuffers = 0 ;
162 buf->session_id = 0 ;
163 buf->flags = 0 ;
164 }
165 // End of Init_ProtectedDataBuffer()
166
167 #ifdef __cplusplus
168 }
169 #endif // __cplusplus
170
171 #endif // PROTECTED_DATA_BUFFER_H
172