171 lines
5.5 KiB
C
171 lines
5.5 KiB
C
/*
|
|
* 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
|