• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 
19 #include "rtsp_embedded_rtp.h"
20 #include "buf_frag_group.h"
21 
22 
23 inline bool
checkSanity(RTPPacket * newRtpPacket,ChannelIdType newChannelId,LengthType newLength)24 RtspEmbeddedRtpPacket::checkSanity(RTPPacket *   newRtpPacket,
25                                    ChannelIdType newChannelId,
26                                    LengthType    newLength
27                                   )
28 {
29     if (NULL == newRtpPacket)
30     {
31         status = INVALID_RTP_PACKET;
32         return false;
33     }
34 
35     if (newRtpPacket->GetNumFrags() > RTSP_EMB_RTP_MAX_NUM_BUFFER_FRAGMENTS - 1)
36     {
37         status = NOT_ENOUGH_BUFFER_FRAGS;
38         return false;
39     }
40 
41     return true;
42 }
43 
44 inline void
buildDollarSequenceBuffer(ChannelIdType newChannelId,LengthType newLength)45 RtspEmbeddedRtpPacket::buildDollarSequenceBuffer(ChannelIdType   newChannelId,
46         LengthType      newLength
47                                                 )
48 {
49     dollarSequenceBuffer[0] = '$';
50     dollarSequenceBuffer[1] = newChannelId;
51     dollarSequenceBuffer[2] = uint8((newLength & 0xFF00) >> 8);
52     dollarSequenceBuffer[3] = uint8((newLength & 0xFF));
53 
54     fragments[0].ptr = dollarSequenceBuffer;
55     fragments[0].len = RTSP_EMB_RTP_DOLLAR_SEQUENCE_BUFFER_SIZE;
56 
57     ++totalNumFragments;
58 }
59 
60 inline void
fillOutBufferFragmentGroupFromPacket(RTPPacket * newRtpPacket)61 RtspEmbeddedRtpPacket::fillOutBufferFragmentGroupFromPacket(RTPPacket * newRtpPacket)
62 {
63     BufferFragment * rtpFragments = newRtpPacket->GetFragments();
64     uint32  numRtpPacketFrags     = newRtpPacket->GetNumFrags();
65 
66     for (uint32 ii = 0; ii < numRtpPacketFrags; ++ii, ++totalNumFragments)
67     {
68         fragments[totalNumFragments].ptr = rtpFragments[ii].ptr;
69         fragments[totalNumFragments].len = rtpFragments[ii].len;
70     }
71 
72     // done
73 }
74 
75 inline void
startAccounting()76 RtspEmbeddedRtpPacket::startAccounting()
77 {
78     currentBufferFragIdx = 0;
79 }
80 
81 
82 bool
bind(RTPPacket * newRtpPacket,ChannelIdType newChannelId,LengthType newLength)83 RtspEmbeddedRtpPacket::bind(RTPPacket *     newRtpPacket,
84                             ChannelIdType   newChannelId,
85                             LengthType      newLength
86                            )
87 {
88     // check args
89     //
90 
91     if (! checkSanity(newRtpPacket, newChannelId, newLength))
92     {
93         return false;
94     }
95 
96     // args are fine
97 
98     totalNumFragments = 0;
99     boundaryReached = false;
100     status = BOUND;
101 
102     buildDollarSequenceBuffer(newChannelId, newLength);
103     fillOutBufferFragmentGroupFromPacket(newRtpPacket);
104     startAccounting();
105 
106     return true;
107 }
108 
109 void
unbind()110 RtspEmbeddedRtpPacket::unbind()
111 {
112     status = UNBOUND;
113 }
114 
115 bool
getRemainingFrags(BufferFragment * & bufArrayPointerRef,uint32 & numFragmentsRef)116 RtspEmbeddedRtpPacket::getRemainingFrags(BufferFragment * & bufArrayPointerRef,
117         uint32 &           numFragmentsRef
118                                         )
119 {
120     if (BOUND != status)
121     {
122         return false;
123     }
124 
125     if (boundaryReached)
126     {
127         bufArrayPointerRef = NULL;
128         numFragmentsRef = 0;
129 
130         return false;
131     }
132 
133     bufArrayPointerRef = & fragments[ currentBufferFragIdx ];
134     numFragmentsRef = totalNumFragments - currentBufferFragIdx;
135 
136     return true;
137 }
138 
139 bool
registerBytesWritten(uint32 bytesWritten)140 RtspEmbeddedRtpPacket::registerBytesWritten(uint32 bytesWritten)
141 {
142     if (BOUND != status)
143     {
144         return false;
145     }
146 
147 
148     int offset = 0;
149     uint8 * ptr;
150 
151     bool seekResult = seekBufFragGroup(fragments,
152                                        totalNumFragments,
153                                        currentBufferFragIdx,
154                                        offset,
155                                        ptr,
156                                        boundaryReached,
157                                        bytesWritten,
158                                        0
159                                       );
160     if (false == seekResult)
161     {
162         status = SEEK_ERROR;
163 
164         return false;
165     }
166 
167     // hooray
168 
169     fragments[ currentBufferFragIdx ].ptr =
170         static_cast<int8*>(fragments[currentBufferFragIdx].ptr) + offset;
171     fragments[ currentBufferFragIdx ].len -= offset;
172 
173     if (! boundaryReached)
174     {
175         if (1 == totalNumFragments - currentBufferFragIdx
176                 &&  0 == fragments[ currentBufferFragIdx ].len
177            )
178         {
179             boundaryReached = true;
180         }
181     }
182 
183     return true;
184 }
185