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
25extern "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
67typedef 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}
91ProtectedPESBuffer ;
92
93typedef 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}
142ProtectedDataBuffer;
143
144#pragma pack(pop)
145
146#define PDBUFFER_DATA_OFFSET     offsetof(ProtectedDataBuffer, data)
147
148static 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