blob: 575f6dc82d426635791f22ce1b161ad9070c8fa2 [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.
* -------------------------------------------------------------------
*/
#include "rtsp_embedded_rtp.h"
#include "buf_frag_group.h"
inline bool
RtspEmbeddedRtpPacket::checkSanity(RTPPacket * newRtpPacket,
ChannelIdType newChannelId,
LengthType newLength
)
{
if (NULL == newRtpPacket)
{
status = INVALID_RTP_PACKET;
return false;
}
if (newRtpPacket->GetNumFrags() > RTSP_EMB_RTP_MAX_NUM_BUFFER_FRAGMENTS - 1)
{
status = NOT_ENOUGH_BUFFER_FRAGS;
return false;
}
return true;
}
inline void
RtspEmbeddedRtpPacket::buildDollarSequenceBuffer(ChannelIdType newChannelId,
LengthType newLength
)
{
dollarSequenceBuffer[0] = '$';
dollarSequenceBuffer[1] = newChannelId;
dollarSequenceBuffer[2] = uint8((newLength & 0xFF00) >> 8);
dollarSequenceBuffer[3] = uint8((newLength & 0xFF));
fragments[0].ptr = dollarSequenceBuffer;
fragments[0].len = RTSP_EMB_RTP_DOLLAR_SEQUENCE_BUFFER_SIZE;
++totalNumFragments;
}
inline void
RtspEmbeddedRtpPacket::fillOutBufferFragmentGroupFromPacket(RTPPacket * newRtpPacket)
{
BufferFragment * rtpFragments = newRtpPacket->GetFragments();
uint32 numRtpPacketFrags = newRtpPacket->GetNumFrags();
for (uint32 ii = 0; ii < numRtpPacketFrags; ++ii, ++totalNumFragments)
{
fragments[totalNumFragments].ptr = rtpFragments[ii].ptr;
fragments[totalNumFragments].len = rtpFragments[ii].len;
}
// done
}
inline void
RtspEmbeddedRtpPacket::startAccounting()
{
currentBufferFragIdx = 0;
}
bool
RtspEmbeddedRtpPacket::bind(RTPPacket * newRtpPacket,
ChannelIdType newChannelId,
LengthType newLength
)
{
// check args
//
if (! checkSanity(newRtpPacket, newChannelId, newLength))
{
return false;
}
// args are fine
totalNumFragments = 0;
boundaryReached = false;
status = BOUND;
buildDollarSequenceBuffer(newChannelId, newLength);
fillOutBufferFragmentGroupFromPacket(newRtpPacket);
startAccounting();
return true;
}
void
RtspEmbeddedRtpPacket::unbind()
{
status = UNBOUND;
}
bool
RtspEmbeddedRtpPacket::getRemainingFrags(BufferFragment * & bufArrayPointerRef,
uint32 & numFragmentsRef
)
{
if (BOUND != status)
{
return false;
}
if (boundaryReached)
{
bufArrayPointerRef = NULL;
numFragmentsRef = 0;
return false;
}
bufArrayPointerRef = & fragments[ currentBufferFragIdx ];
numFragmentsRef = totalNumFragments - currentBufferFragIdx;
return true;
}
bool
RtspEmbeddedRtpPacket::registerBytesWritten(uint32 bytesWritten)
{
if (BOUND != status)
{
return false;
}
int offset = 0;
uint8 * ptr;
bool seekResult = seekBufFragGroup(fragments,
totalNumFragments,
currentBufferFragIdx,
offset,
ptr,
boundaryReached,
bytesWritten,
0
);
if (false == seekResult)
{
status = SEEK_ERROR;
return false;
}
// hooray
fragments[ currentBufferFragIdx ].ptr =
static_cast<int8*>(fragments[currentBufferFragIdx].ptr) + offset;
fragments[ currentBufferFragIdx ].len -= offset;
if (! boundaryReached)
{
if (1 == totalNumFragments - currentBufferFragIdx
&& 0 == fragments[ currentBufferFragIdx ].len
)
{
boundaryReached = true;
}
}
return true;
}