1 /* ***** BEGIN LICENSE BLOCK *****
2 *
3 * $Id: dirac_cppparser.cpp,v 1.13 2008/05/02 06:05:04 asuraparaju Exp $ $Name: Dirac_1_0_2 $
4 *
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.1 (the "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14 * the specific language governing rights and limitations under the License.
15 *
16 * The Original Code is BBC Research and Development code.
17 *
18 * The Initial Developer of the Original Code is the British Broadcasting
19 * Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2004.
21 * All Rights Reserved.
22 *
23 * Contributor(s): Anuradha Suraparaju (Original Author),
24 * Andrew Kennedy
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
28 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
29 * the GPL or the LGPL are applicable instead of those above. If you wish to
30 * allow use of your version of this file only under the terms of the either
31 * the GPL or LGPL and not to allow others to use your version of this file
32 * under the MPL, indicate your decision by deleting the provisions above
33 * and replace them with the notice and other provisions required by the GPL
34 * or LGPL. If you do not delete the provisions above, a recipient may use
35 * your version of this file under the terms of any one of the MPL, the GPL
36 * or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
38
39 #include <sstream>
40 #include <cstdio>
41 #include <cstring>
42 #include <libdirac_common/dirac_assertions.h>
43 #include <libdirac_decoder/dirac_cppparser.h>
44 #include <libdirac_decoder/seq_decompress.h>
45 #include <libdirac_common/picture.h>
46 #include <libdirac_byteio/parseunit_byteio.h>
47 #include <sstream>
48 using namespace dirac;
49
50
InputStreamBuffer()51 InputStreamBuffer::InputStreamBuffer()
52 {
53 m_chunk_buffer = new char[m_buffer_size];
54
55 setg (m_chunk_buffer, //beginning of read area
56 m_chunk_buffer, //read position
57 m_chunk_buffer); //end position
58 }
59
Rewind()60 std::ios::pos_type InputStreamBuffer::Rewind()
61 {
62 return Seek(0, std::ios::beg);
63 }
64
Tell()65 std::ios::pos_type InputStreamBuffer::Tell()
66 {
67 return gptr() - eback();
68 }
69
Seek(std::ios::pos_type bytes,std::ios::seekdir dir)70 std::ios::pos_type InputStreamBuffer::Seek(std::ios::pos_type bytes, std::ios::seekdir dir)
71 {
72 char *new_pos;
73
74 switch (dir)
75 {
76 case std::ios::beg:
77 new_pos = eback() + bytes;
78 break;
79 case std::ios::end:
80 new_pos = egptr() + bytes;
81 break;
82 default:
83 new_pos = gptr() + bytes;
84 break;
85 }
86 if (new_pos > egptr() || new_pos < eback())
87 return -1;
88
89 setg(eback(), //start of read
90 new_pos, //current read position
91 egptr()); //end of stream positon
92
93 return 0;
94 }
95
Copy(char * start,int bytes)96 void InputStreamBuffer::Copy(char *start, int bytes)
97 {
98 //std::cerr << "eback=" << m_chunk_buffer - eback()
99 // << "gptr=" << gptr() -m_chunk_buffer
100 // << "egptr=" << egptr() - m_chunk_buffer << endl;
101
102 int bytes_left = m_buffer_size - (egptr() - m_chunk_buffer);
103 if (bytes_left < bytes)
104 {
105 char *temp = new char [m_buffer_size + bytes];
106 memcpy (temp, m_chunk_buffer, m_buffer_size);
107 setg (temp, temp+(gptr()-m_chunk_buffer), temp + (egptr() - m_chunk_buffer));
108 delete [] m_chunk_buffer;
109 m_chunk_buffer = temp;
110 }
111 //std::cerr << "eback=" << m_chunk_buffer - eback()
112 // << "gptr=" << gptr() -m_chunk_buffer
113 // << "egptr=" << egptr() - m_chunk_buffer << endl;
114
115 memcpy (egptr(), start, bytes);
116 setg(m_chunk_buffer, gptr(), egptr()+bytes);
117
118 //std::cerr << "eback=" << m_chunk_buffer - eback()
119 // << "gptr=" << gptr() -m_chunk_buffer
120 // << "egptr=" << egptr() - m_chunk_buffer << endl;
121 }
122
PurgeProcessedData()123 void InputStreamBuffer::PurgeProcessedData()
124 {
125 //std::cerr << "eback=" << m_chunk_buffer - eback()
126 // << "gptr=" << gptr() -m_chunk_buffer
127 // << "egptr=" << egptr() - m_chunk_buffer << endl;
128
129 if (gptr() != m_chunk_buffer)
130 {
131 memmove (m_chunk_buffer, gptr(), egptr() - gptr());
132 setg(m_chunk_buffer, m_chunk_buffer, m_chunk_buffer+(egptr() - gptr()));
133 }
134 //std::cerr << "eback=" << m_chunk_buffer - eback()
135 // << "gptr=" << gptr() -m_chunk_buffer
136 // << "egptr=" << egptr() - m_chunk_buffer << endl;
137 }
138
~InputStreamBuffer()139 InputStreamBuffer::~InputStreamBuffer()
140 {
141 delete [] m_chunk_buffer;
142 }
143
144
DiracParser(bool verbose)145 DiracParser::DiracParser(bool verbose) :
146 m_state(STATE_BUFFER),
147 m_next_state(STATE_SEQUENCE),
148 m_show_pnum(-1),
149 m_decomp(0),
150 m_verbose(verbose)
151 {
152
153
154
155 }
156
~DiracParser()157 DiracParser::~DiracParser()
158 {
159 delete m_decomp;
160 }
161
SetBuffer(char * start,char * end)162 void DiracParser::SetBuffer (char *start, char *end)
163 {
164 TEST (end > start);
165 m_dirac_byte_stream.AddBytes(start, end-start);
166 }
167
Parse()168 DecoderState DiracParser::Parse()
169 {
170 while(true)
171 {
172 ParseUnitByteIO *p_parse_unit=NULL;
173 ParseUnitType pu_type=PU_UNDEFINED;
174
175 // look for end-of-sequence flag
176 if(m_next_state==STATE_SEQUENCE_END)
177 {
178 if (!m_decomp)
179 return STATE_BUFFER;
180
181 // look to see if all pictures have been processed
182 if(m_decomp->Finished())
183 {
184 // if so....delete
185 delete m_decomp;
186 m_decomp=NULL;
187 m_next_state = STATE_BUFFER;
188 return STATE_SEQUENCE_END;
189 }
190 else
191 // otherwise....get remaining pictures from buffer
192 pu_type = PU_CORE_PICTURE;
193 }
194
195 // get next parse unit from stream
196 if(m_next_state!=STATE_SEQUENCE_END)
197 {
198 p_parse_unit=m_dirac_byte_stream.GetNextParseUnit();
199 if(p_parse_unit==NULL)
200 return STATE_BUFFER;
201 pu_type=p_parse_unit->GetType();
202 }
203
204 switch(pu_type)
205 {
206 case PU_SEQ_HEADER:
207
208 if(!m_decomp)
209 {
210 m_decomp = new SequenceDecompressor (*p_parse_unit, m_verbose);
211 m_next_state=STATE_BUFFER;
212 return STATE_SEQUENCE;
213 }
214
215 m_decomp->NewAccessUnit(*p_parse_unit);
216 break;
217
218 case PU_CORE_PICTURE:
219 {
220 if (!m_decomp)
221 continue;
222
223 const Picture *my_picture = m_decomp->DecompressNextPicture(p_parse_unit);
224 if (my_picture)
225 {
226 int picturenum_decoded = my_picture->GetPparams().PictureNum();
227 if (picturenum_decoded != m_show_pnum)
228 {
229 m_show_pnum = my_picture->GetPparams().PictureNum();
230 if (m_verbose)
231 {
232 std::cout << std::endl;
233 std::cout << "Picture ";
234 std::cout<< m_show_pnum << " available";
235 }
236 m_state = STATE_PICTURE_AVAIL;
237 return m_state;
238 }
239 }
240 break;
241 }
242 case PU_END_OF_SEQUENCE:
243 m_next_state = STATE_SEQUENCE_END;
244 break;
245
246 case PU_AUXILIARY_DATA:
247 case PU_PADDING_DATA:
248 if (m_verbose)
249 std::cerr << "Ignoring Auxiliary/Padding data" << std::endl;
250 // Ignore auxiliary and padding data and continue parsing
251 break;
252 case PU_LOW_DELAY_PICTURE:
253 if (m_verbose)
254 std::cerr << "Low delay picture decoding not yet supported" << std::endl;
255 return STATE_INVALID;
256
257 default:
258 return STATE_INVALID;
259 }
260
261 }
262 }
263
GetSourceParams() const264 const SourceParams& DiracParser::GetSourceParams() const
265 {
266 return m_decomp->GetSourceParams();
267 }
268
GetDecoderParams() const269 const DecoderParams& DiracParser::GetDecoderParams() const
270 {
271 return m_decomp->GetDecoderParams();
272 }
273
GetParseParams() const274 const ParseParams& DiracParser::GetParseParams() const
275 {
276 return m_decomp->GetParseParams();
277 }
278
GetNextPictureParams() const279 const PictureParams* DiracParser::GetNextPictureParams() const
280 {
281 return m_decomp->GetNextPictureParams();
282 }
283
GetNextPicture() const284 const Picture* DiracParser::GetNextPicture() const
285 {
286 return m_decomp->GetNextPicture();
287 }
288