| /* |
| * Copyright (c) 2014 Intel Corporation. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef PROTECTED_DATA_BUFFER_H |
| #define PROTECTED_DATA_BUFFER_H |
| |
| #include <stdint.h> |
| #include <stdbool.h> |
| #include <stddef.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| // NOTE: this size takes into account the space used by DRM |
| // schemes with full sample encryption (e.g., WV Classic) or |
| // subsample encryption (e.g., WV Modular, which uses 2KB for |
| // frame info data). |
| #define NALU_BUFFER_SIZE (4 * 1024) |
| |
| // Either start code + type (00 00 00 01 <type byte>) or 4 byte length + type. |
| #define NALU_HEADER_SIZE 5 |
| |
| // This should be able to fit compressed 1080p video I-frame, use half |
| // of NV12 1080p frame, which on average uses 12 bits per pixel. |
| #define MAX_COMPRESSED_FRAME_SIZE (1920 * 1080 * 3 / 4) |
| |
| #define MAX_PROT_BUFFER_DATA_SIZE (MAX_COMPRESSED_FRAME_SIZE + NALU_BUFFER_SIZE) |
| |
| #define MAX_PES_BUFFER_SIZE (64*1024) |
| |
| // TODO: it's not clear, how to calculate this value, since PES packet may contain |
| // less than 64KB worth of data. |
| #define MAX_PES_PACKETS_PER_FRAME 64 |
| |
| // Video decoder defines maximum number of NALUs per frame as 16. |
| // (At least, as of June of 2014.) Use the same value here. |
| #define MAX_NALUS_IN_FRAME 16 |
| |
| // Integer, which "PDBF", but no 0 terminator |
| #define PROTECTED_DATA_BUFFER_MAGIC (0UL | ('F' << 24) | ('B' << 16) | ('D' << 8) | 'P') |
| |
| #define DRM_SCHEME_NONE 0 |
| #define DRM_SCHEME_WV_CLASSIC 1 |
| #define DRM_SCHEME_WV_MODULAR 2 |
| #define DRM_SCHEME_MCAST_SINK 3 |
| #define DRM_SCHEME_PLAYREADY_ASF 4 |
| |
| // Flag to indicate if Last Subsample flag is received for MDRM |
| #define PDB_FLAG_COMPLETE_FRAME 0x1000 |
| |
| #pragma pack(push, 4) |
| |
| typedef struct ProtectedPESBuffer_tag { |
| |
| // AES CTR stream counter, needed for HDCP decryption. |
| // If ProtectedDataBuffer::clear is 1, streamCounter is ignored. |
| uint32_t streamCounter ; |
| |
| // AES CTR input counter, needed for HDCP decryption |
| // If ProtectedDataBuffer::clear is 1, inputCounter is ignored. |
| uint64_t inputCounter ; |
| |
| // Offset within ProtectedDataBuffer::data buffer, to the start |
| // of this PES packet's data. |
| // |
| // IMPORTANT: for protected content (ProtectedDataBuffer::clear is 0), |
| // this offset must be divisible by 16 (AES block size). This is to allow |
| // for in-place transcryption from AES CTR to IED (AES ECB). OMX will |
| // check that the offset is divisible by 16, and will abort |
| // playback, if the offset is NOT divisible by 16. For this reason, |
| // the offset is used and not a byte pointer. |
| uint32_t pesDataOffset ; |
| |
| // Size of the PES data, pointed to by pesData |
| uint32_t pesSize ; |
| } |
| ProtectedPESBuffer ; |
| |
| typedef struct ProtectedDataBuffer_tag { |
| |
| // Must be set to PROTECTED_DATA_BUFFER_MAGIC. Must be the first |
| // member of ProtectedDataBuffer structure. |
| uint32_t magic; |
| |
| // See DRM_SCHEME_* defines above |
| uint32_t drmScheme; |
| |
| // 1 if clear, 0 if encrypted |
| uint32_t clear; |
| |
| // Session ID, used by some DRM schemes (e.g. PlayReady) |
| uint32_t session_id ; |
| |
| // Flags, used by some DRM schemes |
| // MDRM uses it to indicate Complete Frame received |
| // Miracast Sink uses it to indicate if Transcription is required |
| uint32_t flags ; |
| |
| // Information about the PES data buffers. Used for DRM_SCHEME_MCAST_SINK. |
| // Reserve space for one more PES data buffer for sentinel value, for |
| // ease of implementation. |
| // |
| ProtectedPESBuffer pesBuffers[MAX_PES_PACKETS_PER_FRAME + 1] ; |
| |
| // Number of filled-out entries in pesBuffers array. |
| // Used for DRM_SCHEME_MCAST_SINK. If data buffer is not partitioned |
| // into PES packet buffers, set numPesBuffers must be 0. |
| // |
| uint32_t numPesBuffers ; |
| |
| // Size of the data buffer. |
| uint32_t size ; |
| |
| // For clear content, this is the space for clear data. |
| // For encrypted content, this space is occupied by IED encrypted |
| // data or HDCP encrypted data (payloads only, no PES headers), |
| // depending on the DRM scheme. |
| // |
| // A space is made at the end of encrypted data for |
| // decrypted SPS/PPS headers. |
| // |
| // NOTE: data must be last, to allow for flexibility not |
| // to copy the whole ProtectedDataBuffer, if not whole data |
| // buffer is filled. |
| // |
| uint8_t data[MAX_PROT_BUFFER_DATA_SIZE]; |
| } |
| ProtectedDataBuffer; |
| |
| #pragma pack(pop) |
| |
| #define PDBUFFER_DATA_OFFSET offsetof(ProtectedDataBuffer, data) |
| |
| static inline void Init_ProtectedDataBuffer(ProtectedDataBuffer* buf) |
| { |
| // This is internal helper function. If you pass invalid (e.g. NULL) |
| // pointer to it, you deserve to crash. |
| |
| // Perform initialization of certain members, ignore the data |
| // areas, which will be overwritten in the course of the |
| // normal usage. |
| |
| buf->magic = PROTECTED_DATA_BUFFER_MAGIC ; |
| buf->drmScheme = DRM_SCHEME_NONE ; |
| buf->clear = 0 ; |
| buf->size = 0 ; |
| buf->numPesBuffers = 0 ; |
| buf->session_id = 0 ; |
| buf->flags = 0 ; |
| } |
| // End of Init_ProtectedDataBuffer() |
| |
| #ifdef __cplusplus |
| } |
| #endif // __cplusplus |
| |
| #endif // PROTECTED_DATA_BUFFER_H |