182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON/* 282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Copyright (c) 2009-2011 Intel Corporation. All rights reserved. 382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* 482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Licensed under the Apache License, Version 2.0 (the "License"); 582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* you may not use this file except in compliance with the License. 682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* You may obtain a copy of the License at 782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* 882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* http://www.apache.org/licenses/LICENSE-2.0 982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* 1082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Unless required by applicable law or agreed to in writing, software 1182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* distributed under the License is distributed on an "AS IS" BASIS, 1282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* See the License for the specific language governing permissions and 1482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* limitations under the License. 1582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*/ 1682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 1782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoDecoderAVCSecure.h" 1882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoDecoderTrace.h" 1982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <string.h> 2082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 2182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 2282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define STARTCODE_00 0x00 2382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define STARTCODE_01 0x01 2482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define STARTCODE_PREFIX_LEN 3 2582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define NALU_TYPE_MASK 0x1F 2682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 2782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 2882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// mask for little endian, to mast the second and fourth bytes in the byte stream 2982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define STARTCODE_MASK0 0xFF000000 //0x00FF0000 3082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define STARTCODE_MASK1 0x0000FF00 //0x000000FF 3182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 3282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 3382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONtypedef enum { 3482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_unspecified0 = 0, 3582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_SLICE, 3682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_DPA, 3782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_DPB, 3882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_DPC, 3982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_IDR, 4082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_SEI, 4182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_SPS, 4282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_PPS, 4382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Acc_unit_delimiter, 4482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_EOSeq, 4582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_EOstream, 4682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_filler_data, 4782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_SPS_extension, 4882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Reserved14, 4982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Reserved15, 5082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Reserved16, 5182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Reserved17, 5282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Reserved18, 5382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_ACP, 5482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Reserved20, 5582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Reserved21, 5682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Reserved22, 5782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_Reserved23, 5882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NAL_UNIT_TYPE_unspecified24, 5982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} NAL_UNIT_TYPE; 6082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 6182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef min 6282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define min(X, Y) ((X) <(Y) ? (X) : (Y)) 6382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif 6482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 6582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 6682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONstatic const uint8_t startcodePrefix[STARTCODE_PREFIX_LEN] = {0x00, 0x00, 0x01}; 6782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 6882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 6982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderAVCSecure::VideoDecoderAVCSecure(const char *mimeType) 7082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON : VideoDecoderAVC(mimeType), 7182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mNaluHeaderBuffer(NULL), 7282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mInputBuffer(NULL) { 7382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 7482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memset(&mMetadata, 0, sizeof(NaluMetadata)); 7582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memset(&mByteStream, 0, sizeof(NaluByteStream)); 7682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} 7782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 7882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderAVCSecure::~VideoDecoderAVCSecure() { 7982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} 8082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 8182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVCSecure::start(VideoConfigBuffer *buffer) { 8282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON Decode_Status status = VideoDecoderAVC::start(buffer); 8382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (status != DECODE_SUCCESS) { 8482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return status; 8582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 8682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 8782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mMetadata.naluInfo = new NaluInfo [MAX_NALU_NUMBER]; 8882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mByteStream.byteStream = new uint8_t [MAX_NALU_HEADER_BUFFER]; 8982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mNaluHeaderBuffer = new uint8_t [MAX_NALU_HEADER_BUFFER]; 9082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 9182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (mMetadata.naluInfo == NULL || 9282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mByteStream.byteStream == NULL || 9382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mNaluHeaderBuffer == NULL) { 9482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON ETRACE("Failed to allocate memory."); 9582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // TODO: release all allocated memory 9682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_MEMORY_FAIL; 9782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 9882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return status; 9982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} 10082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 10182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderAVCSecure::stop(void) { 10282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VideoDecoderAVC::stop(); 10382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 10482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (mMetadata.naluInfo) { 10582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON delete [] mMetadata.naluInfo; 10682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mMetadata.naluInfo = NULL; 10782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 10882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 10982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (mByteStream.byteStream) { 11082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON delete [] mByteStream.byteStream; 11182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mByteStream.byteStream = NULL; 11282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 11382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 11482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (mNaluHeaderBuffer) { 11582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON delete [] mNaluHeaderBuffer; 11682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mNaluHeaderBuffer = NULL; 11782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 11882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} 11982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 12082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVCSecure::decode(VideoDecodeBuffer *buffer) { 12182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON Decode_Status status; 12282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON int32_t sizeAccumulated = 0; 12382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON int32_t sizeLeft = 0; 12482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint8_t *pByteStream = NULL; 12582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NaluInfo *pNaluInfo = mMetadata.naluInfo; 12682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 12782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (buffer->flag & IS_SECURE_DATA) { 12882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON pByteStream = buffer->data; 12982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeLeft = buffer->size; 13082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mInputBuffer = NULL; 13182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } else { 13282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON status = parseAnnexBStream(buffer->data, buffer->size, &mByteStream); 13382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_STATUS("parseAnnexBStream"); 13482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON pByteStream = mByteStream.byteStream; 13582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeLeft = mByteStream.streamPos; 13682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mInputBuffer = buffer->data; 13782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 13882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (sizeLeft < 4) { 13982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON ETRACE("Not enough data to read number of NALU."); 14082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_INVALID_DATA; 14182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 14282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 14382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // read number of NALU 14482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(&(mMetadata.naluNumber), pByteStream, sizeof(int32_t)); 14582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON pByteStream += 4; 14682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeLeft -= 4; 14782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 14882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (mMetadata.naluNumber == 0) { 14982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON WTRACE("Number of NALU is ZERO!"); 15082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_SUCCESS; 15182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 15282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 15382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON for (int32_t i = 0; i < mMetadata.naluNumber; i++) { 15482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (sizeLeft < 12) { 15582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON ETRACE("Not enough data to parse NALU offset, size, header length for NALU %d, left = %d", i, sizeLeft); 15682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_INVALID_DATA; 15782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 15882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeLeft -= 12; 15982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // read NALU offset 16082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(&(pNaluInfo->naluOffset), pByteStream, sizeof(int32_t)); 16182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON pByteStream += 4; 16282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 16382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // read NALU size 16482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(&(pNaluInfo->naluLen), pByteStream, sizeof(int32_t)); 16582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON pByteStream += 4; 16682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 16782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // read NALU header length 16882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(&(pNaluInfo->naluHeaderLen), pByteStream, sizeof(int32_t)); 16982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON pByteStream += 4; 17082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 17182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (sizeLeft < pNaluInfo->naluHeaderLen) { 17282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON ETRACE("Not enough data to copy NALU header for %d, left = %d, header len = %d", i, sizeLeft, pNaluInfo->naluHeaderLen); 17382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_INVALID_DATA; 17482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 17582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 17682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeLeft -= pNaluInfo->naluHeaderLen; 17782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 17882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (pNaluInfo->naluHeaderLen) { 17982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // copy start code prefix to buffer 18082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(mNaluHeaderBuffer + sizeAccumulated, 18182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON startcodePrefix, 18282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON STARTCODE_PREFIX_LEN); 18382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeAccumulated += STARTCODE_PREFIX_LEN; 18482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 18582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // copy NALU header 18682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(mNaluHeaderBuffer + sizeAccumulated, pByteStream, pNaluInfo->naluHeaderLen); 18782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON pByteStream += pNaluInfo->naluHeaderLen; 18882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 18982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeAccumulated += pNaluInfo->naluHeaderLen; 19082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } else { 19182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON WTRACE("header len is zero for NALU %d", i); 19282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 19382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 19482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // for next NALU 19582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON pNaluInfo++; 19682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 19782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 19882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON buffer->data = mNaluHeaderBuffer; 19982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON buffer->size = sizeAccumulated; 20082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 20182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return VideoDecoderAVC::decode(buffer); 20282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} 20382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 20482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 20582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVCSecure::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) { 20682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 20782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON Decode_Status status; 20882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VAStatus vaStatus; 20982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint32_t bufferIDCount = 0; 21082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // maximum 4 buffers to render a slice: picture parameter, IQMatrix, slice parameter, slice data 21182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VABufferID bufferIDs[4]; 21282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 21382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]); 21482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]); 21582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VAPictureParameterBufferH264 *picParam = picData->pic_parms; 21682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms); 21782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 21882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) { 21982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // either condition indicates start of a new frame 22082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (sliceParam->first_mb_in_slice != 0) { 22182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON WTRACE("The first slice is lost."); 22282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // TODO: handle the first slice lost 22382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 22482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (mDecodingFrame) { 22582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // interlace content, complete decoding the first field 22682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vaStatus = vaEndPicture(mVADisplay, mVAContext); 22782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_VA_STATUS("vaEndPicture"); 22882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 22982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // for interlace content, top field may be valid only after the second field is parsed 23082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mAcquiredBuffer->pictureOrder= picParam->CurrPic.TopFieldOrderCnt; 23182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 23282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 23382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // Check there is no reference frame loss before decoding a frame 23482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 23582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // Update the reference frames and surface IDs for DPB and current frame 23682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON status = updateDPB(picParam); 23782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_STATUS("updateDPB"); 23882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 23982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON //We have to provide a hacked DPB rather than complete DPB for libva as workaround 24082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON status = updateReferenceFrames(picData); 24182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_STATUS("updateReferenceFrames"); 24282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 24382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface); 24482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_VA_STATUS("vaBeginPicture"); 24582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 24682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // start decoding a frame 24782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mDecodingFrame = true; 24882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 24982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vaStatus = vaCreateBuffer( 25082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVADisplay, 25182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVAContext, 25282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VAPictureParameterBufferType, 25382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeof(VAPictureParameterBufferH264), 25482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 1, 25582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON picParam, 25682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON &bufferIDs[bufferIDCount]); 25782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_VA_STATUS("vaCreatePictureParameterBuffer"); 25882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON bufferIDCount++; 25982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 26082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vaStatus = vaCreateBuffer( 26182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVADisplay, 26282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVAContext, 26382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VAIQMatrixBufferType, 26482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeof(VAIQMatrixBufferH264), 26582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 1, 26682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON data->IQ_matrix_buf, 26782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON &bufferIDs[bufferIDCount]); 26882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_VA_STATUS("vaCreateIQMatrixBuffer"); 26982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON bufferIDCount++; 27082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 27182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 27282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON status = setReference(sliceParam); 27382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_STATUS("setReference"); 27482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 27582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // find which naluinfo is correlated to current slice 27682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON int naluIndex = 0; 27782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint32_t accumulatedHeaderLen = 0; 27882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint32_t headerLen = 0; 27982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON for (; naluIndex < mMetadata.naluNumber; naluIndex++) { 28082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON headerLen = mMetadata.naluInfo[naluIndex].naluHeaderLen; 28182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (headerLen == 0) { 28282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON WTRACE("lenght of current NAL unit is 0."); 28382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON continue; 28482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 28582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON accumulatedHeaderLen += STARTCODE_PREFIX_LEN; 28682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (accumulatedHeaderLen + headerLen > sliceData->slice_offset) { 28782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON break; 28882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 28982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON accumulatedHeaderLen += headerLen; 29082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 29182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 29282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (sliceData->slice_offset != accumulatedHeaderLen) { 29382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON WTRACE("unexpected slice offset %d, accumulatedHeaderLen = %d", sliceData->slice_offset, accumulatedHeaderLen); 29482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 29582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 29682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sliceParam->slice_data_size = mMetadata.naluInfo[naluIndex].naluLen; 29782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sliceData->slice_size = sliceParam->slice_data_size; 29882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 29982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // no need to update: 30082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // sliceParam->slice_data_offset - 0 always 30182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // sliceParam->slice_data_bit_offset - relative to sliceData->slice_offset 30282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 30382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vaStatus = vaCreateBuffer( 30482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVADisplay, 30582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVAContext, 30682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VASliceParameterBufferType, 30782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sizeof(VASliceParameterBufferH264), 30882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 1, 30982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sliceParam, 31082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON &bufferIDs[bufferIDCount]); 31182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_VA_STATUS("vaCreateSliceParameterBuffer"); 31282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON bufferIDCount++; 31382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 31482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // sliceData->slice_offset - accumulatedHeaderLen is the absolute offset to start codes of current NAL unit 31582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // offset points to first byte of NAL unit 31682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint32_t sliceOffset = mMetadata.naluInfo[naluIndex].naluOffset; 31782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (mInputBuffer != NULL) { 31882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vaStatus = vaCreateBuffer( 31982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVADisplay, 32082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVAContext, 32182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VASliceDataBufferType, 32282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sliceData->slice_size, //size 32382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 1, //num_elements 32482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mInputBuffer + sliceOffset, 32582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON &bufferIDs[bufferIDCount]); 32682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } else { 32782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vaStatus = vaCreateBuffer( 32882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVADisplay, 32982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVAContext, 33082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON VAProtectedSliceDataBufferType, 33182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON sliceData->slice_size, //size 33282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 1, //num_elements 33382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON (uint8_t*)sliceOffset, // IMR offset 33482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON &bufferIDs[bufferIDCount]); 33582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 33682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_VA_STATUS("vaCreateSliceDataBuffer"); 33782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON bufferIDCount++; 33882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 33982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON vaStatus = vaRenderPicture( 34082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVADisplay, 34182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mVAContext, 34282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON bufferIDs, 34382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON bufferIDCount); 34482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON CHECK_VA_STATUS("vaRenderPicture"); 34582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 34682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_SUCCESS; 34782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} 34882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 34982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 35082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// Parse byte string pattern "0x000001" (3 bytes) in the current buffer. 35182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// Returns offset of position following the pattern in the buffer if pattern is found or -1 if not found. 35282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint32_t VideoDecoderAVCSecure::findNalUnitOffset(uint8_t *stream, int32_t offset, int32_t length) { 35382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint8_t *ptr; 35482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint32_t left = 0, data = 0, phase = 0; 35582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint8_t mask1 = 0, mask2 = 0; 35682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 35782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON /* Meaning of phase: 35882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 0: initial status, "0x000001" bytes are not found so far; 35982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 1: one "0x00" byte is found; 36082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 2: two or more consecutive "0x00" bytes" are found; 36182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 3: "0x000001" patten is found ; 36282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 4: if there is one more byte after "0x000001"; 36382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON */ 36482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 36582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON left = length; 36682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON ptr = (uint8_t *) (stream + offset); 36782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON phase = 0; 36882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 36982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // parse until there is more data and start code not found 37082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON while ((left > 0) && (phase < 3)) { 37182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // Check if the address is 32-bit aligned & phase=0, if thats the case we can check 4 bytes instead of one byte at a time. 37282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (((((uint32_t)ptr) & 0x3) == 0) && (phase == 0)) { 37382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON while (left > 3) { 37482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON data = *((uint32_t *)ptr); 37582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mask1 = (STARTCODE_00 != (data & STARTCODE_MASK0)); 37682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON mask2 = (STARTCODE_00 != (data & STARTCODE_MASK1)); 37782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // If second byte and fourth byte are not zero's then we cannot have a start code here, 37882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // as we need two consecutive zero bytes for a start code pattern. 37982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (mask1 && mask2) { 38082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // skip 4 bytes and start over 38182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON ptr += 4; 38282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON left -=4; 38382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON continue; 38482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } else { 38582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON break; 38682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 38782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 38882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 38982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 39082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // At this point either data is not on a 32-bit boundary or phase > 0 so we look at one byte at a time 39182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (left > 0) { 39282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (*ptr == STARTCODE_00) { 39382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON phase++; 39482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (phase > 2) { 39582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // more than 2 consecutive '0x00' bytes is found 39682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON phase = 2; 39782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 39882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } else if ((*ptr == STARTCODE_01) && (phase == 2)) { 39982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // start code is found 40082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON phase = 3; 40182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } else { 40282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // reset lookup 40382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON phase = 0; 40482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 40582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON ptr++; 40682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON left--; 40782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 40882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 40982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 41082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if ((left > 0) && (phase == 3)) { 41182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON phase = 4; 41282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // return offset of position following the pattern in the buffer which matches "0x000001" byte string 41382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return (int32_t)(ptr - stream); 41482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 41582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return -1; 41682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} 41782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 41882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 41982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVCSecure::copyNaluHeader(uint8_t *stream, NaluByteStream *naluStream) { 42082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint8_t naluType; 42182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON int32_t naluHeaderLen; 42282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 42382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluType = *(uint8_t *)(stream + naluStream->naluOffset); 42482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluType &= NALU_TYPE_MASK; 42582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // first update nalu header length based on nalu type 42682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (naluType >= NAL_UNIT_TYPE_SLICE && naluType <= NAL_UNIT_TYPE_IDR) { 42782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // coded slice, return only up to MAX_SLICE_HEADER_SIZE bytes 42882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluHeaderLen = min(naluStream->naluLen, MAX_SLICE_HEADER_SIZE); 42982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } else if (naluType >= NAL_UNIT_TYPE_SEI && naluType <= NAL_UNIT_TYPE_PPS) { 43082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON //sps, pps, sei, etc, return the entire NAL unit in clear 43182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluHeaderLen = naluStream->naluLen; 43282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } else { 43382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_FRAME_DROPPED; 43482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 43582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 43682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(naluStream->byteStream + naluStream->streamPos, &(naluStream->naluOffset), sizeof(int32_t)); 43782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->streamPos += 4; 43882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 43982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(naluStream->byteStream + naluStream->streamPos, &(naluStream->naluLen), sizeof(int32_t)); 44082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->streamPos += 4; 44182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 44282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(naluStream->byteStream + naluStream->streamPos, &naluHeaderLen, sizeof(int32_t)); 44382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->streamPos += 4; 44482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 44582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (naluHeaderLen) { 44682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(naluStream->byteStream + naluStream->streamPos, (uint8_t*)(stream + naluStream->naluOffset), naluHeaderLen); 44782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->streamPos += naluHeaderLen; 44882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 44982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_SUCCESS; 45082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} 45182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 45282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 45382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// parse start-code prefixed stream, also knowns as Annex B byte stream, commonly used in AVI, ES, MPEG2 TS container 45482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVCSecure::parseAnnexBStream(uint8_t *stream, int32_t length, NaluByteStream *naluStream) { 45582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON int32_t naluOffset, offset, left; 45682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON NaluInfo *info; 45782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON uint32_t ret = DECODE_SUCCESS; 45882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 45982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluOffset = 0; 46082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON offset = 0; 46182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON left = length; 46282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 46382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // leave 4 bytes to copy nalu count 46482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->streamPos = 4; 46582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->naluCount = 0; 46682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memset(naluStream->byteStream, 0, MAX_NALU_HEADER_BUFFER); 46782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 46882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON for (; ;) { 46982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluOffset = findNalUnitOffset(stream, offset, left); 47082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (naluOffset == -1) { 47182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON break; 47282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 47382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 47482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (naluStream->naluCount == 0) { 47582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->naluOffset = naluOffset; 47682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } else { 47782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->naluLen = naluOffset - naluStream->naluOffset - STARTCODE_PREFIX_LEN; 47882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON ret = copyNaluHeader(stream, naluStream); 47982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (ret != DECODE_SUCCESS && ret != DECODE_FRAME_DROPPED) { 48082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON LOGW("copyNaluHeader returned %d", ret); 48182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return ret; 48282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 48382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // starting position for next NALU 48482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->naluOffset = naluOffset; 48582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 48682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 48782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (ret == DECODE_SUCCESS) { 48882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->naluCount++; 48982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 49082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 49182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // update next lookup position and length 49282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON offset = naluOffset + 1; // skip one byte of NAL unit type 49382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON left = length - offset; 49482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 49582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 49682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON if (naluStream->naluCount > 0) { 49782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON naluStream->naluLen = length - naluStream->naluOffset; 49882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON memcpy(naluStream->byteStream, &(naluStream->naluCount), sizeof(int32_t)); 49982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON // ignore return value, either DECODE_SUCCESS or DECODE_FRAME_DROPPED 50082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON copyNaluHeader(stream, naluStream); 50182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_SUCCESS; 50282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON } 50382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 50482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON LOGW("number of valid NALU is 0!"); 50582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON return DECODE_SUCCESS; 50682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON} 50782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON 508