]> git.vomp.tv Git - vompclient.git/blob - demuxer.cc
Fix some demuxer bugs
[vompclient.git] / demuxer.cc
1 /*
2     Copyright 2005 Mark Calderbank
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "demuxer.h"
22
23 const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
24
25 Demuxer* Demuxer::instance = NULL;
26
27 Demuxer::Demuxer()
28 {
29   if (instance) return;
30   instance = this;
31   initted = 0;
32 }
33
34 Demuxer::~Demuxer()
35 {
36   shutdown();
37   instance = NULL;
38 }
39
40 Demuxer* Demuxer::getInstance()
41 {
42   return instance;
43 }
44
45 int Demuxer::init()
46 {
47   if (!initted)
48   {
49     if ( videostream.init(demuxMemory) ||
50          audiostream.init(demuxMemory) ||
51          !(local_frame = (UCHAR *) malloc(0x10000)))
52     {
53       printf("failed to initialize demuxer\n");
54       shutdown();
55       return 1;
56     }
57   }
58
59   reset();
60   initted = 1;
61   return 0;
62 }
63
64 void Demuxer::reset()
65 {
66   flush();
67   video_current = audio_current = -1;
68   horizontal_size = vertical_size = 0;
69   aspect_ratio = (enum AspectRatio) 0;
70   frame_rate = bit_rate = 0;
71 }
72
73 int Demuxer::shutdown()
74 {
75   videostream.shutdown();
76   audiostream.shutdown();
77   free(local_frame);
78   initted = 0;
79   return 1;
80 }
81
82 void Demuxer::flush()
83 {
84   videostream.flush();
85   audiostream.flush();
86   state_frametype = state_framepos = 0;
87   seek();
88 }
89
90 void Demuxer::flushAudio()
91 {
92   audiostream.flush();
93 }
94
95 void Demuxer::seek()
96 {
97   seeking = 1;
98 }
99
100 void Demuxer::setAudioStream(int id)
101 {
102   audio_current = id;
103 }
104
105 void Demuxer::setVideoStream(int id)
106 {
107   video_current = id;
108 }
109
110 int Demuxer::scan(UCHAR *buf, int len)
111 {
112   // Temporarily, just look for the lowest audio stream and return it
113   int ret = 0;
114   UCHAR byte;
115   int zeros = 0;
116   while (len > 1)
117   {
118     // We are searching for a string of bytes (0,0,1).
119     byte = *(buf++); --len;
120
121     if (byte == 0)
122     {
123       ++zeros; continue;
124     }
125     if (zeros < 2 || byte != 1)
126     {
127       zeros = 0; continue;
128     }
129     zeros = 0;
130     // We have found the pattern (0,0,1).
131     // Check the next byte for the sub-frame type.
132     byte = *(buf++); --len;
133     if (byte >= 0xc0 && byte <= 0xdf) // Audio
134       if (ret == 0 || ret > byte) ret = byte;
135   }
136   return ret;
137 }
138
139 int Demuxer::put(UCHAR* buf, int len)
140 {
141   int ret = 0;    // return number of bytes consumed
142   int parsed = 0; // number of bytes parsed by sub-function
143   int full;       // sub-function sets this to tell us to exit early
144   inbuf = buf;    // Initialize buffer pointer
145
146   while (len)
147   {
148     full = 0;
149     switch (state_frametype)
150     {
151       case 0: // Search for frame
152         parsed = parse_find_frame(len);
153         break;
154       case FRAMETYPE_VID0 ... FRAMETYPE_VIDMAX:
155         parsed = parse_video_frame(len, &full);
156         break;
157       case FRAMETYPE_AUD0 ... FRAMETYPE_AUDMAX:
158         parsed = parse_audio_frame(len, &full);
159         break;
160       case FRAMETYPE_PRIVATE_1:
161         parsed = parse_private1_frame(len, &full);
162         break;
163     }
164     ret += parsed; len -= parsed;
165     if (full) // We have to exit early.
166       break; // out of while loop
167   }
168   Log::getInstance()->log(
169       "Demuxer", Log::DEBUG, "Put %d; took %d", ret + len, ret);
170   return ret;
171 }
172
173 int Demuxer::parse_find_frame(int len)
174 {
175   int ret = 0; // return number of bytes parsed
176   UCHAR byte;
177
178   // In this function, state_framepos represents
179   // the number of fixed header bytes found so far.
180   if (state_framepos > 3 || state_framepos < 0)
181   {
182     // ERROR!
183     state_framepos = 0;
184   }
185
186   while (len)
187   {
188     byte = *inbuf++;
189     ++ret; --len;
190     switch (state_framepos)
191     {
192       case 0:
193       case 1:
194         if (byte == 0)
195           ++state_framepos;
196         else
197           state_framepos = 0;
198         break;
199       case 2:
200         if (byte == 1)
201           ++state_framepos;
202         else if (byte != 0)
203           state_framepos = 0;
204         break;
205       default:
206         state_framepos = 0; // Set initial state for the new frame
207         switch (byte)
208         {
209           case 0:
210             state_framepos = 1; // Count this as a first header byte!
211             break;
212           case FRAMETYPE_VID0 ... FRAMETYPE_VIDMAX:
213           case FRAMETYPE_AUD0 ... FRAMETYPE_AUDMAX:
214           case FRAMETYPE_PRIVATE_1:
215             state_frametype = byte;
216             return ret;
217         }
218         // Not a recognised frame type. Go back to Old Kent Road.
219         break;
220     }
221   }
222   return ret;
223 }
224
225 int Demuxer::parse_video_frame(int len, int* full)
226 {
227   int ret = 0; // return number of bytes consumed
228   int stream_sent, bytes_remaining;
229
230   switch(state_framepos)
231   {
232     case 0: // Brand new video frame. Set initial states.
233       state_stream_fill = 0; state_vid_parsed = 0;
234       // Create a local copy of the frame header
235       local_frame[0] = local_frame[1] = 0; local_frame[2] = 1;
236       local_frame[3] = state_frametype;
237       // If no video stream has been set, use this one.
238       if (video_current == -1) video_current = state_frametype;
239       // Get MSB of frame length and copy to local frame.
240       frame_length = *inbuf << 8;
241       local_frame[4] = *inbuf;
242       ++inbuf; ++state_framepos; ++ret; --len;
243       if (len == 0) return ret;
244       // FALL THROUGH TO NEXT BYTE IN STREAM
245     case 1: // Get LSB of frame length and copy to local frame.
246       frame_length += *inbuf;
247       local_frame[5] = *inbuf;
248       ++inbuf; ++state_framepos; ++ret; --len;
249       if (len == 0) return ret;
250       // FALL THROUGH TO NEXT BYTE IN STREAM
251     case 2: // First data byte
252       if (len >= frame_length     // If we have the entire frame
253           && !state_vid_parsed)   // and haven't parsed it yet
254       {
255         if (video_current == state_frametype) // and we're interested
256           parse_video_details(inbuf, frame_length); // then parse it
257         state_vid_parsed = 1;
258       }
259   }
260   // We are in the frame data
261   bytes_remaining = 2 + frame_length - state_framepos;
262   if (video_current != state_frametype)
263   {
264     // We don't want this frame. Throw it away.
265     if (len >= bytes_remaining)
266     {
267       inbuf += bytes_remaining;
268       ret += bytes_remaining;
269       state_frametype = state_framepos = 0;
270       return ret;
271     }
272     else
273     {
274       inbuf += len; ret += len;
275       state_framepos += len;
276       return ret;
277     }
278   } // No fall through here
279
280   if (state_vid_parsed)
281   {
282     // We have already parsed the whole frame
283     if (seeking)   // Still not found a sync point. Throw this frame away.
284     {
285       if (len >= bytes_remaining)
286       {
287         inbuf += bytes_remaining;
288         ret += bytes_remaining;
289         state_frametype = state_framepos = 0;
290         return ret;
291       }
292       else
293       {
294         inbuf += len; ret += len; return ret;
295       }
296     } // No fall through is allowed here
297     // Send frame header to stream
298     if (state_stream_fill < 6)
299     {
300       state_stream_fill += videostream.put(local_frame,
301                                    6 - state_stream_fill);
302       if (state_stream_fill < 6)   // stream is full!
303       {
304         *full = 1; return ret;
305       }
306     }
307     // Send all frame data we have to stream
308     if (len >= bytes_remaining) len = bytes_remaining;
309     stream_sent = videostream.put(inbuf, len);
310     inbuf += stream_sent; ret += stream_sent;
311     state_framepos += stream_sent;
312     state_stream_fill += stream_sent;
313     if (stream_sent != len)   // stream is full!
314     {
315       *full = 1; return ret;
316     }
317     if (state_framepos == frame_length + 2)   // frame done
318     {
319       state_frametype = state_framepos = 0;
320     }
321     return ret;
322   } // No fall through is allowed here
323
324   // We haven't parsed the frame yet. It's arriving in pieces.
325   if (bytes_remaining)   // There is data yet to copy to local_frame
326   {
327     if (len >= bytes_remaining) len = bytes_remaining;
328     memcpy(local_frame + state_framepos + 4, inbuf, len);
329     inbuf += len; ret += len; state_framepos += len;
330     if (len < bytes_remaining)   // Not all arrived yet
331       return ret;
332     parse_video_details(local_frame+6, frame_length);
333     if (seeking) // Still not found a sync point. Ignore this frame.
334       return ret;
335   }
336   // We have the whole frame in local_frame. Send it to the stream.
337   state_stream_fill += videostream.put(local_frame,
338                   6 + frame_length - state_stream_fill);
339   if (state_stream_fill < frame_length + 6)   // stream is full!
340   {
341     *full = 1; return ret;
342   }
343   state_frametype = state_framepos = 0;
344   return ret;
345 }
346
347 int Demuxer::parse_audio_frame(int len, int* full)
348 {
349   int ret = 0; // return number of bytes consumed
350   int stream_sent, bytes_remaining;
351
352   switch(state_framepos)
353   {
354     case 0: // Brand new audio frame. Set initial states.
355       state_stream_fill = 0;
356       // Create a local copy of the frame header
357       local_frame[0] = local_frame[1] = 0; local_frame[2] = 1;
358       local_frame[3] = state_frametype;
359       // If no audio stream has been set, use this one.
360       if (audio_current == -1) audio_current = state_frametype;
361       // Get MSB of frame length and copy to local frame.
362       frame_length = *inbuf << 8;
363       local_frame[4] = *inbuf;
364       ++inbuf; ++state_framepos; ++ret; --len;
365       if (len == 0) return ret;
366       // FALL THROUGH TO NEXT BYTE IN STREAM
367     case 1: // Get LSB of frame length and copy to local frame.
368       frame_length += *inbuf;
369       local_frame[5] = *inbuf;
370       ++inbuf; ++state_framepos; ++ret; --len;
371       if (len == 0) return ret;
372   }
373   // We are in the frame data
374   bytes_remaining = 2 + frame_length - state_framepos;
375   if (audio_current != state_frametype)
376   {
377     // We don't want this frame. Throw it away.
378     if (len >= bytes_remaining)
379     {
380       inbuf += bytes_remaining;
381       ret += bytes_remaining;
382       state_frametype = state_framepos = 0;
383       return ret;
384     }
385     else
386     {
387       inbuf += len; ret += len;
388       state_framepos += len;
389       return ret;
390     }
391   } // No fall through is allowed here
392
393   // Send frame header to stream
394   if (state_stream_fill < 6)
395   {
396     state_stream_fill += audiostream.put(local_frame,
397                                  6 - state_stream_fill);
398     if (state_stream_fill < 6) // stream is full!
399     {
400       *full = 1; return ret;
401     }
402   }
403   // Send all frame data we have to stream
404   if (len >= bytes_remaining) len = bytes_remaining;
405   stream_sent = audiostream.put(inbuf, len);
406   inbuf += stream_sent; ret += stream_sent;
407   state_framepos += stream_sent;
408   state_stream_fill += stream_sent;
409   if (stream_sent != len) // stream is full!
410   {
411     *full = 1; return ret;
412   }
413   if (state_framepos == frame_length + 2) // frame done
414   {
415     state_frametype = state_framepos = 0;
416   }
417   return ret;
418 }
419
420 int Demuxer::parse_private1_frame(int len, int* full)
421 {
422   int ret = 0; // return number of bytes consumed
423   int bytes_remaining;
424
425   switch(state_framepos)
426   {
427     case 0: // Brand new frame. Set initial states.
428       // Get MSB of frame length and copy to local frame.
429       frame_length = *inbuf << 8;
430       ++inbuf; ++state_framepos; ++ret; --len;
431       if (len == 0) return ret;
432       // FALL THROUGH TO NEXT BYTE IN STREAM
433     case 1: // Get LSB of frame length and copy to local frame.
434       frame_length += *inbuf;
435       local_frame[5] = *inbuf;
436       ++inbuf; ++state_framepos; ++ret; --len;
437       if (len == 0) return ret;
438   }
439   // We are in the frame data
440   bytes_remaining = 2 + frame_length - state_framepos;
441   // Temporary - just discard the frame.
442   if (len >= bytes_remaining)
443   {
444     inbuf += bytes_remaining;
445     ret += bytes_remaining;
446     state_frametype = state_framepos = 0;
447     return ret;
448   }
449   else
450   {
451     inbuf += len; ret += len;
452     state_framepos += len;
453     return ret;
454   }
455 }
456
457 void Demuxer::parse_video_details(UCHAR* buf, int len)
458 {
459   UCHAR byte;
460   int zeros = 0;
461   while (len >= 8) // 8 is length of a GOP header
462   {
463     // We are searching for a string of bytes (0,0,1).
464     byte = *(buf++); --len;
465
466     if (byte == 0)
467     {
468       ++zeros; continue;
469     }
470     if (zeros < 2 || byte != 1)
471     {
472       zeros = 0; continue;
473     }
474     zeros = 0;
475     // We have found the pattern (0,0,1).
476     // Check the next byte for the sub-frame type.
477     byte = *(buf++); --len;
478     switch (byte)
479     {
480       case 0x00: // Picture header
481                  // 10 bits: temporal reference
482                  //  3 bits: coding type (I/P/B)
483                  //  ...
484         if (len < 2) return;
485         if ( (buf[1] & 0x38) == 0x08 ) // I-frame
486           seeking = 0;
487         buf += 4; // Minimum length of picture header
488         len -= 4;
489         break;
490       case 0xb3: // Sequence header
491                  // 12 bits: Horizontal size
492                  // 12 bits: Vertical size
493                  //  4 bits: Aspect ratio
494                  //  4 bits: Frame rate code
495                  // 18 bits: Bit rate value
496                  // ...
497         if (len < 7) return;
498         horizontal_size = ((int)buf[0] << 4) | ((int)buf[1] >> 4);
499         vertical_size = (((int)buf[1] & 0xf) << 8) | (int)buf[2];
500         aspect_ratio = (enum AspectRatio)(buf[3] >> 4);
501         frame_rate = buf[3] & 0x0f;
502         if (frame_rate >= 1 && frame_rate <= 8)
503           frame_rate = FrameRates[frame_rate];
504         else
505           frame_rate = 0;
506         bit_rate = ((int)buf[4] << 10) |
507                    ((int)buf[5] << 2) |
508                    ((int)buf[6] >> 6);
509         seeking = 0;
510         buf += 8; // Minimum length of sequence header
511         len -= 8;
512         break;
513       case 0xb8: // Group header
514                  // We're not going to bother parsing anything.
515         seeking = 0;
516         buf += 4; // Minimum length of group header
517         len -= 4;
518         break;
519     }
520   }
521 }