blob: 4e60a13979364c208fdc351dde7f45c4f9bfcd5a [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 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.
* -------------------------------------------------------------------
*/
/*
This PVA_FF_DecoderConfigDescriptor Class
*/
#define IMPLEMENT_DecoderConfigDescriptor
#include "decoderconfigdescriptor.h"
#include "atomutils.h"
#include "a_atomdefs.h"
typedef Oscl_Vector<PVA_FF_DecoderSpecificInfo*, OsclMemAllocator> PVA_FF_DecoderSpecificInfoVecType;
// Constructor
PVA_FF_DecoderConfigDescriptor::PVA_FF_DecoderConfigDescriptor(int32 streamType, int32 codecType)
: PVA_FF_BaseDescriptor(0x04)
{
_codecType = codecType;
iCurrFilePos = 0;
init(streamType);
recomputeSize();
}
// Destructor
PVA_FF_DecoderConfigDescriptor::~PVA_FF_DecoderConfigDescriptor()
{
if (_pdecSpecificInfoVec != NULL)
{
for (uint32 i = 0; i < _pdecSpecificInfoVec->size(); i++)
{
PV_MP4_FF_DELETE(NULL, PVA_FF_DecoderSpecificInfo, (*_pdecSpecificInfoVec)[i]);
}
PV_MP4_FF_TEMPLATED_DELETE(NULL, PVA_FF_DecoderSpecificInfoVecType, Oscl_Vector, _pdecSpecificInfoVec);
}
}
void
PVA_FF_DecoderConfigDescriptor::init(int32 mediaType)
{
_pdecSpecificInfoVec = NULL;
switch (mediaType)
{
case MEDIA_TYPE_AUDIO:
{
switch (_codecType)
{
case CODEC_TYPE_AAC_AUDIO:
_objectTypeIndication = 0x40;
break;
default:
_objectTypeIndication = 0xFF;
break;
}
_streamType = 0x05; // 0x05 for AudioStream
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_DecoderSpecificInfoVecType, (), _pdecSpecificInfoVec);
}
break;
case MEDIA_TYPE_VISUAL:
{
switch (_codecType)
{
case CODEC_TYPE_BASELINE_H263_VIDEO:
_objectTypeIndication = 0xc0; // Simple profile
break;
case CODEC_TYPE_MPEG4_VIDEO:
_objectTypeIndication = 0x20; // Simple profile
break;
case CODEC_TYPE_AVC_VIDEO:
_objectTypeIndication = 0x30;
break;
}
_streamType = 0x04; // 0x04 for VisualStream
PV_MP4_FF_NEW(fp->auditCB, PVA_FF_DecoderSpecificInfoVecType, (), _pdecSpecificInfoVec);
}
break;
default:
{
_objectTypeIndication = 0xFF; // No profile specified
_streamType = 0x20; // user private
}
break;
}
_upStream = false;
_reserved = 1;
_bufferSizeDB = 0; // Need better default value
_maxBitrate = 0; // Need better default value
_avgBitrate = 0; // Need better default value
}
void
PVA_FF_DecoderConfigDescriptor::addDecoderSpecificInfo(PVA_FF_DecoderSpecificInfo *info)
{
if (_pdecSpecificInfoVec != NULL)
_pdecSpecificInfoVec->push_back(info);
info->setParent(this);
recomputeSize();
if (_pparent != NULL)
_pparent->recomputeSize();
}
PVA_FF_DecoderSpecificInfo *
PVA_FF_DecoderConfigDescriptor::getDecoderSpecificInfo() const
{
if ((_pdecSpecificInfoVec != NULL) && (_pdecSpecificInfoVec->size() > 0))
{
return (*_pdecSpecificInfoVec)[(int32)0];
}
return NULL;
}
void
PVA_FF_DecoderConfigDescriptor::nextSampleSize(uint32 size)
{
if (size > _bufferSizeDB)
{
_bufferSizeDB = size;
}
}
// Rendering the Descriptor in proper format (bitlengths, etc.) to an ostream
bool
PVA_FF_DecoderConfigDescriptor::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp)
{
int32 rendered = 0; // Keep track of number of bytes rendered
// Render attributes of the PVA_FF_BaseDescriptor class
int32 numBytes = renderBaseDescriptorMembers(fp);
if (numBytes == 0)
{
return false;
}
rendered += numBytes;
if (!PVA_FF_AtomUtils::render8(fp, _objectTypeIndication))
{
return false;
}
rendered += 1;
// Pack and render stream type, upstream, and reserved
uint8 data = _reserved; // Initial data byte including reserved bit set
data |= ((_streamType & 0x3f) << 2); // 0b00XXXXXX << 2
if (_upStream)
{
data |= 0x02;
}
if (!PVA_FF_AtomUtils::render8(fp, data))
{
return false;
}
rendered += 1;
iCurrFilePos = PVA_FF_AtomUtils::getCurrentFilePosition(fp);
if (!PVA_FF_AtomUtils::render24(fp, _bufferSizeDB))
{
return false;
}
rendered += 3;
if (!PVA_FF_AtomUtils::render32(fp, _maxBitrate))
{
return false;
}
rendered += 4;
if (!PVA_FF_AtomUtils::render32(fp, _avgBitrate))
{
return false;
}
rendered += 4;
if (_pdecSpecificInfoVec != NULL)
{
for (uint32 i = 0; i < _pdecSpecificInfoVec->size(); i++)
{
if (!(*_pdecSpecificInfoVec)[i]->renderToFileStream(fp))
{
return false;
}
rendered += (*_pdecSpecificInfoVec)[i]->getSizeOfDescriptorObject();
}
}
return true;
}
void
PVA_FF_DecoderConfigDescriptor::recomputeSize()
{
int32 contents = 0;
contents += 1; // (8 bits for OTI)
contents += 1; // (8 bits for Stream type, upStream flag and reserved)
contents += 3; // (24 bits for buffer size DB)
contents += 4; // (32 bits for max bitrate)
contents += 4; // (32 bits for avg bitrate)
if (_pdecSpecificInfoVec != NULL)
{
for (uint32 i = 0; i < _pdecSpecificInfoVec->size(); i++)
{
contents += (*_pdecSpecificInfoVec)[i]->getSizeOfDescriptorObject();
}
}
_sizeOfClass = contents;
_sizeOfSizeField = PVA_FF_AtomUtils::getNumberOfBytesUsedToStoreSizeOfClass(contents);
// Have the parent descriptor recompute its size based on this update
if (_pparent != NULL)
{
_pparent->recomputeSize();
}
}
void
PVA_FF_DecoderConfigDescriptor::writeMaxSampleSize(MP4_AUTHOR_FF_FILE_IO_WRAP *_afp)
{
if (NULL != _afp->_filePtr)
{
PVA_FF_AtomUtils::seekFromStart(_afp, iCurrFilePos);
PVA_FF_AtomUtils::render24(_afp, _bufferSizeDB);
}
}