| /* ------------------------------------------------------------------ |
| * 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 |
| |