blob: 1fcaf0200b80f5901b7960b4eb7a77e37d7be605 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 2008 PacketVideo
*
* 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.
* -------------------------------------------------------------------
*/
#include "pv_video_config_parser.h"
#include "m4v_config_parser.h"
#include "oscl_mem.h"
#include "oscl_dll.h"
#define GetUnalignedWord( pb, w ) \
(w) = ((uint16) *(pb + 1) << 8) + *pb;
#define GetUnalignedDword( pb, dw ) \
(dw) = ((uint32) *(pb + 3) << 24) + \
((uint32) *(pb + 2) << 16) + \
((uint16) *(pb + 1) << 8) + *pb;
#define GetUnalignedWordEx( pb, w ) GetUnalignedWord( pb, w ); (pb) += sizeof(uint16);
#define GetUnalignedDwordEx( pb, dw ) GetUnalignedDword( pb, dw ); (pb) += sizeof(uint32);
#define GetUnalignedQwordEx( pb, qw ) GetUnalignedQword( pb, qw ); (pb) += sizeof(uint64);
#define LoadBYTE( b, p ) b = *(uint8 *)p; p += sizeof( uint8 )
#define LoadWORD( w, p ) GetUnalignedWordEx( p, w )
#define LoadDWORD( dw, p ) GetUnalignedDwordEx( p, dw )
#define LoadQWORD( qw, p ) GetUnalignedQwordEx( p, qw )
#ifndef MAKEFOURCC_WMC
#define MAKEFOURCC_WMC(ch0, ch1, ch2, ch3) \
((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \
((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 ))
#define mmioFOURCC_WMC(ch0, ch1, ch2, ch3) MAKEFOURCC_WMC(ch0, ch1, ch2, ch3)
#endif
#define FOURCC_WMV3 mmioFOURCC_WMC('W','M','V','3')
#define FOURCC_WMVA mmioFOURCC_WMC('W','M','V','A')
#define FOURCC_WVC1 mmioFOURCC_WMC('W','V','C','1')
OSCL_DLL_ENTRY_POINT_DEFAULT()
int32 GetNAL_Config(uint8** bitstream, int32* size);
OSCL_EXPORT_REF int16 pv_video_config_parser(pvVideoConfigParserInputs *aInputs, pvVideoConfigParserOutputs *aOutputs)
{
switch (aInputs->iMimeType)
{
case PVMF_M4V: //m4v
{
mp4StreamType psBits;
psBits.data = aInputs->inPtr;
psBits.numBytes = aInputs->inBytes;
psBits.bytePos = 0;
psBits.bitBuf = 0;
psBits.dataBitPos = 0;
psBits.bitPos = 32;
int32 width, height, display_width, display_height = 0;
int16 retval = 0;
retval = iDecodeVOLHeader(&psBits, &width, &height, &display_width, &display_height);
if (retval != 0)
{
return retval;
}
aOutputs->width = (uint32)display_width;
aOutputs->height = (uint32)display_height;
}
break;
case PVMF_H263: //h263
{
// Nothing to do for h263
aOutputs->width = 0;
aOutputs->height = 0;
}
break;
case PVMF_H264: //avc
case PVMF_H264_MP4:
{
int32 width, height, display_width, display_height = 0;
uint8 *tp = aInputs->inPtr;
if (aInputs->inBytes > 1)
{
if (tp[0] == 0 && tp[1] == 0)
{
// ByteStream Format
uint8* tmp_ptr = tp;
uint8* buffer_begin = tp;
int16 length = 0;
int initbufsize = aInputs->inBytes;
int tConfigSize = 0;
do
{
tmp_ptr += length;
length = GetNAL_Config(&tmp_ptr, &initbufsize);
buffer_begin[0] = length & 0xFF;
buffer_begin[1] = (length >> 8) & 0xFF;
oscl_memcpy(buffer_begin + 2, tmp_ptr, length);
buffer_begin += (length + 2);
tConfigSize += (length + 2);
}
while (initbufsize > 0);
}
}
// check codec info and get settings
int16 retval;
retval = iGetAVCConfigInfo(tp,
aInputs->inBytes,
(int*) & width,
(int*) & height,
(int*) & display_width,
(int*) & display_height);
if (retval != 0)
{
return retval;
}
aOutputs->width = (uint32)display_width;
aOutputs->height = (uint32)display_height;
}
break;
case PVMF_WMV: //wmv
{
uint32 dwdat;
uint16 wdat;
uint8 bdat;
uint8 *pData = aInputs->inPtr;
LoadDWORD(dwdat, pData); // Window width
LoadDWORD(dwdat, pData); // Window height
LoadBYTE(bdat, pData);
LoadWORD(wdat, pData); // Size of image info.
// BITMAPINFOHEADER
LoadDWORD(dwdat, pData); // Size of BMAPINFOHDR
LoadDWORD(dwdat, pData);
aOutputs->width = dwdat;
LoadDWORD(dwdat, pData);
aOutputs->height = dwdat;
/* WMV1 and WMV2 are not supported. Rejected here. */
pData += 4;
LoadDWORD(dwdat, pData);
uint32 NewCompression = dwdat;
if (NewCompression != FOURCC_WMV3 &&
NewCompression != FOURCC_WVC1 &&
NewCompression != FOURCC_WMVA)
{
return -1;
}
}
break;
default:
return -1;
break;
}
return 0;
}
/* This function finds a nal from the SC's, moves the bitstream pointer to the beginning of the NAL unit, returns the
size of the NAL, and at the same time, updates the remaining size in the bitstream buffer that is passed in */
int32 GetNAL_Config(uint8** bitstream, int32* size)
{
int i = 0;
int j;
uint8* nal_unit = *bitstream;
int count = 0;
/* find SC at the beginning of the NAL */
while (nal_unit[i++] == 0 && i < *size)
{
}
if (nal_unit[i-1] == 1)
{
*bitstream = nal_unit + i;
}
else
{
j = *size;
*size = 0;
return j; // no SC at the beginning, not supposed to happen
}
j = i;
/* found the SC at the beginning of the NAL, now find the SC at the beginning of the next NAL */
while (i < *size)
{
if (count == 2 && nal_unit[i] == 0x01)
{
i -= 2;
break;
}
if (nal_unit[i])
count = 0;
else
count++;
i++;
}
*size -= i;
return (i -j);
}