blob: 643540768067f1bda5e9a3b168f0d58ce1f84cfa [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.
* -------------------------------------------------------------------
*/
#ifndef H264_PAYLOAD_PARSER_UTILITY_H
#define H264_PAYLOAD_PARSER_UTILITY_H
#ifndef OSCL_MEM_H_INCLUDED
#include "oscl_mem.h"
#endif
#ifndef PVMF_POOL_BUFFER_ALLOCATOR_H_INCLUDED
#include "pvmf_pool_buffer_allocator.h"
#endif
#ifndef PAYLOAD_PARSER_H_INCLUDED
#include "payload_parser.h"
#endif
#ifndef H264_PAYLOAD_PARSER_MACROS_H_INCLUDED
#include "h264_payload_parser_macros.h"
#endif
///////////////////////////////////////////////////////////////////////////////////////////
// The following data structures are designed to remove conditional(e.g.long switch or //
// if-else statments) using polymorphism, or remove type code with class //
///////////////////////////////////////////////////////////////////////////////////////////
class H264PayloadParser;
////// Base class //////////////////
class H264PayloadParserUtility
{
public:
virtual ~H264PayloadParserUtility() { };
/**
* Note: for the following APIs, setMarkerInfo() must be called at first, because generateMemFrag()
* could ovewrite something that needs to be saved in setMarkerInfo(), and will be used in
* setMediaDataTimestamp(). Adding a flag to check this is not a good option.
* But setSeqNum() is independent, and can be called any time
**/
/**
* Generate the output memory fragments for the given input memory fragment and output media data impl object
* The function is designed to be non-pure virtual because we want to put in the default implementation to be
* shared with the derived classes
*
* @param aMediaDataOut, output media data impl object
* @param nal_type, input nal type to avoid uncessary parsing operation
* @param aMemFragIn, input memory fragment
* @param rtp_payload_ptr_offset, the offset of rtp payload pointer for the input memory fragment, which can be modified
* @return RTP_PAYLOAD_PARSER_RET_CODE return code
**/
virtual PayloadParserStatus generateMemFrag(const IPayloadParser::Payload& aIn,
IPayloadParser::Payload& aOut,
const uint8 nal_type,
uint32 &rtp_payload_ptr_offset);
/**
* Set the marker info for the output media data impl object
* The function is designed to be non-pure virtual and the base classe provides the default implementation.
*
* @param aMediaDataOut, output media data impl object
* @param nal_type, input nal type to avoid uncessary parsing operation
* @param aMemFragIn, input memory fragment
**/
virtual void setMarkerInfo(IPayloadParser::Payload& aIn, IPayloadParser::Payload& aOut, const uint8 nal_type);
/**
* Set the timestamp for the output media data object
* The function is designed to be non-pure virtual and the base class provides the default implementation.
*
* @param accessUnit, output media data object
* @param nal_type, input nal type to avoid uncessary parsing operation
* @param rtp_timestamp, input RTP timestamp
**/
virtual void setMediaDataTimestamp(IPayloadParser::Payload& aOut, const uint8 nal_type, const uint32 rtp_timestamp);
/**
* Set the sequence number for the output media data object
* The function is designed to be non-pure virtual and the base class provides the default implementation.
*
* @param accessUnit, output media data object
* @param nal_type, input nal type to avoid uncessary parsing operation
* @param rtp_timestamp, input RTP timestamp
**/
virtual void setSeqNum(IPayloadParser::Payload& aOut, const uint8 nal_type, const uint32 seq_number)
{
OSCL_UNUSED_ARG(nal_type); // no use at this time
aOut.sequence = seq_number;
}
// constructor
H264PayloadParserUtility(H264PayloadParser *aParser, InterleaveModeProcessing *aIMP = NULL) :
iParser(aParser), iIMP(aIMP)
{
;
}
void setIMPObject(InterleaveModeProcessing *aIMP)
{
iIMP = aIMP;
}
protected:
/**
* Get the pointer and length of the output memory fragment for the given input memory fragment
* The function is designed to be pure virtual so that each derived classes must implement this function
*
* @param aMemFragIn, input memory fragment
* @param nal_type, input nal type to avoid uncessary parsing operation
* @param aMemFragPtr, output memory fragment pointer
* @param aMemFragLen, output memory fragment length
* @param rtp_payload_ptr_offset, the offset of rtp payload pointer for the input memory fragment, which can be modified
* @return RTP_PAYLOAD_PARSER_RET_CODE return code
**/
virtual PayloadParserStatus getMemFragPtrLen(OsclRefCounterMemFrag &aMemFragIn, const uint8 nal_type,
uint8* &aMemFragPtr, uint32 &aMemFragLen,
uint32 &rtp_payload_ptr_offset) = 0;
protected:
H264PayloadParser *iParser;
InterleaveModeProcessing *iIMP;
};
////// Derived classes //////////////////
// NALU type based parser utility, NAL type = 0-23, 30, 31
class H264PayloadParserUtilityForNALU : public H264PayloadParserUtility
{
public:
// constructor
H264PayloadParserUtilityForNALU(H264PayloadParser *aParser, InterleaveModeProcessing *aIMP = NULL) :
H264PayloadParserUtility(aParser, aIMP)
{
;
}
private:
// derived APIs
PayloadParserStatus getMemFragPtrLen(OsclRefCounterMemFrag &aMemFragIn, const uint8 nal_type,
uint8* &aMemFragPtr, uint32 &aMemFragLen,
uint32 &rtp_payload_ptr_offset);
};
// FU type based parser utility, NAL type = 28 and 29, FU-A and FU-B
// For H264PayloadParserUtilityForFU, setMarkerInfo() and setMediaDataTimestamp() are special due to marker bit(S or E bit)
class H264PayloadParserUtilityForFU : public H264PayloadParserUtility
{
public:
// derived APIs
void setMarkerInfo(IPayloadParser::Payload& aIn, IPayloadParser::Payload& aOut, const uint8 nal_type);
void setMediaDataTimestamp(IPayloadParser::Payload& aOut, const uint8 nal_type, const uint32 rtp_timestamp);
// constructor
H264PayloadParserUtilityForFU(H264PayloadParser *aParser, InterleaveModeProcessing *aIMP = NULL) :
H264PayloadParserUtility(aParser, aIMP)
{
;
}
private:
// derived API
PayloadParserStatus getMemFragPtrLen(OsclRefCounterMemFrag &aMemFragIn, const uint8 nal_type,
uint8* &aMemFragPtr, uint32 &aMemFragLen,
uint32 &rtp_payload_ptr_offset);
private:
bool validateFU(uint8* rtp_payload_ptr, uint8 nal_type)
{
if (nal_type == H264_RTP_PAYLOAD_FU_B &&
(rtp_payload_ptr[1] & FU_S_BIT_MASK) == 0)
{
return false; // FU-B must be the starting FU
}
return true;
}
};
// MTAP type based parser utility, NAL type = 26 and 27, MTAP16 and MTAP24
// For H264PayloadParserUtilityForMTAP, setMediaDataTimestamp() is special due to 16/24-bit TS offset
class H264PayloadParserUtilityForMTAP : public H264PayloadParserUtility
{
public:
// derived API
void setMediaDataTimestamp(IPayloadParser::Payload& aOut, const uint8 nal_type, const uint32 rtp_timestamp);
// constructor
H264PayloadParserUtilityForMTAP(H264PayloadParser *aParser, InterleaveModeProcessing *aIMP = NULL) :
H264PayloadParserUtility(aParser, aIMP)
{
;
}
private:
// derived API
PayloadParserStatus getMemFragPtrLen(OsclRefCounterMemFrag &aMemFragIn, const uint8 nal_type,
uint8* &aMemFragPtr, uint32 &aMemFragLen,
uint32 &rtp_payload_ptr_offset);
};
// STAP type based parser utility, NAL type = 24 and 25, STAP-A and STAP-B
// For H264PayloadParserUtilityForSTAP, API generateMemFrag() is kinda different from others, because each input RTP packet needs to generate
// mulitple memory fragments for one output media message. Instead, other types of RTP packet only generate one
// memory fragment per media message.
class H264PayloadParserUtilityForSTAP : public H264PayloadParserUtility
{
public:
// derived APIs
PayloadParserStatus generateMemFrag(const IPayloadParser::Payload& aIn,
IPayloadParser::Payload& aOut,
const uint8 nal_type,
uint32 &rtp_payload_ptr_offset);
// constructor
H264PayloadParserUtilityForSTAP(H264PayloadParser *aParser, InterleaveModeProcessing *aIMP = NULL) :
H264PayloadParserUtility(aParser, aIMP),
iMemFragmentAlloc(NULL)
{
;
}
// destructor
virtual ~H264PayloadParserUtilityForSTAP()
{
OSCL_DELETE(iMemFragmentAlloc);
iMemFragmentAlloc = NULL;
}
private:
// derived API
PayloadParserStatus getMemFragPtrLen(OsclRefCounterMemFrag &aMemFragIn, const uint8 nal_type,
uint8* &aMemFragPtr, uint32 &aMemFragLen,
uint32 &rtp_payload_ptr_offset)
{
OSCL_UNUSED_ARG(aMemFragIn);
OSCL_UNUSED_ARG(nal_type);
OSCL_UNUSED_ARG(aMemFragPtr);
OSCL_UNUSED_ARG(aMemFragLen);
OSCL_UNUSED_ARG(rtp_payload_ptr_offset);
return PayloadParserStatus_Success;
}
// Create iMemFragmentAlloc
PayloadParserStatus CreateMemFragmentAlloc();
private:
// Fragment pool for OsclRefCounterMemFrag
PVMFBufferPoolAllocator *iMemFragmentAlloc;
};
#endif // H264_PAYLOAD_PARSER_UTILITY_H