blob: 4f6a5b01adc15ab38c6122ca78cfbebca6eef7ba [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.
* -------------------------------------------------------------------
*/
///////////////////////////////////////////////////////////////////////////////
//
// h263_payload_parser.cpp
//
// H.263 payload parser implementation.
//
///////////////////////////////////////////////////////////////////////////////
#include "oscl_mem.h"
#include "virtual_buffer.h"
#include "h263_payload_parser.h"
///////////////////////////////////////////////////////////////////////////////
//
// Constructor/Destructor
//
///////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF H263PayloadParser::H263PayloadParser()
{
}
OSCL_EXPORT_REF H263PayloadParser::~H263PayloadParser()
{
}
///////////////////////////////////////////////////////////////////////////////
//
// Initialization
//
///////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool H263PayloadParser::Init(mediaInfo* config)
{
// \todo: parse here
OSCL_UNUSED_ARG(config);
return false;
}
///////////////////////////////////////////////////////////////////////////////
//
// Payload parsing
//
///////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PayloadParserStatus
H263PayloadParser::Parse(const Payload& inputPacket,
Oscl_Vector<Payload, OsclMemAllocator>& vParsedPayloads)
{
// H263 Payload Header Masks
static const uint8 RR = 0xF8; // Reserved Bits Mask
static const uint8 Pbit = 0x04; // Picture or GOB Start bit mask
static const uint8 Vbit = 0x02; // VRC mask
bool bPBit; // indicates whether picture start code is present or not
bool bVBit; // indicates presence of VRC data
VirtualBuffer<uint8> input = VirtualBuffer<uint8>(inputPacket.vfragments);
VirtualBuffer<uint8> vb(input);
if ((*vb) & (RR))
{
//check for 5 reserved bits to be zero
return PayloadParserStatus_Failure;
}
//check for picture start bit
bPBit = (*vb & Pbit) > 0;
//check for VRC
bVBit = (*vb & Vbit) > 0;
// 1st bit of PLEN in the 1st byte of the payload header
uint8 plenHI = (*vb & 0x01);
// the next 5 bits of PLEN in the 2nd byte of the payload header
uint8 plenLow = (*(vb + 1) & 0xF8);
// reconstruct PLEN
uint16 plen = (((uint16)plenHI << 8) + plenLow) >> 3;
Payload output;
if (bPBit) // Picture or GOB start code present
{
if (plen > 0) // If extra picture header presents in the midlle of the frame
{
// skip the extra picture header from the payload
vb += plen;
// start the output payload from offset plen
input += plen;
}
// we need to prepend the payload with two zero bytes
if (bVBit) // VRC Header present - payload starts at 1
{
// set bytes at offset 1 and 2 to zero
vb++;
*vb = 0;
vb++;
*vb = 0;
// start the output payload from offset 1
input += 1;
if (input.length() > 0)
{
VirtualBuffer<uint8> outFrags;
input.createSubBuffer(outFrags);
outFrags.copy(output.vfragments);
}
}
else // VRC header not present - payload starts at 0
{
// set bytes at offset 0 and 1 to zero
*vb = 0;
vb++;
*vb = 0;
if (input.length() > 0)
{
VirtualBuffer<uint8> outFrags;
input.createSubBuffer(outFrags);
outFrags.copy(output.vfragments);
}
}
}
else
{
if (bVBit) // VRC Header present - payload starts at 3
{
input += 3;
if (input.length() > 0)
{
VirtualBuffer<uint8> outFrags;
input.createSubBuffer(outFrags);
outFrags.copy(output.vfragments);
}
}
else // No VRC Header - payload starts at 2
{
input += 2;
if (input.length() > 0)
{
VirtualBuffer<uint8> outFrags;
input.createSubBuffer(outFrags);
outFrags.copy(output.vfragments);
}
}
}
if (output.vfragments.size() > 0)
{
output.stream = inputPacket.stream;
output.marker = inputPacket.marker;
output.sequence = inputPacket.sequence + 1;
output.timestamp = inputPacket.timestamp;
vParsedPayloads.push_back(output);
}
return PayloadParserStatus_Success;
}
///////////////////////////////////////////////////////////////////////////////
//
// Repositioning related
//
///////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void H263PayloadParser::Reposition(const bool adjustSequence, const uint32 stream, const uint32 seqnum)
{
OSCL_UNUSED_ARG(adjustSequence);
OSCL_UNUSED_ARG(stream);
OSCL_UNUSED_ARG(seqnum);
}
OSCL_EXPORT_REF uint32 H263PayloadParser::GetMinCurrTimestamp()
{
return 0;
}