]> git.vomp.tv Git - vompclient.git/blob - demuxer.cc
Removed logging from demuxer.
[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("Demuxer", Log::DEBUG, "Put %d; took %d", ret + len, ret);
169   return ret;
170 }
171
172 int Demuxer::parse_find_frame(int len)
173 {
174   int ret = 0; // return number of bytes parsed
175   UCHAR byte;
176
177   // In this function, state_framepos represents
178   // the number of fixed header bytes found so far.
179   if (state_framepos > 3 || state_framepos < 0)
180   {
181     // ERROR!
182     state_framepos = 0;
183   }
184
185   while (len)
186   {
187     byte = *inbuf++;
188     ++ret; --len;
189     switch (state_framepos)
190     {
191       case 0:
192       case 1:
193         if (byte == 0)
194           ++state_framepos;
195         else
196           state_framepos = 0;
197         break;
198       case 2:
199         if (byte == 1)
200           ++state_framepos;
201         else if (byte != 0)
202           state_framepos = 0;
203         break;
204       default:
205         state_framepos = 0; // Set initial state for the new frame
206         switch (byte)
207         {
208           case 0:
209             state_framepos = 1; // Count this as a first header byte!
210             break;
211           case FRAMETYPE_VID0 ... FRAMETYPE_VIDMAX:
212           case FRAMETYPE_AUD0 ... FRAMETYPE_AUDMAX:
213           case FRAMETYPE_PRIVATE_1:
214             state_frametype = byte;
215             return ret;
216         }
217         // Not a recognised frame type. Go back to Old Kent Road.
218         break;
219     }
220   }
221   return ret;
222 }
223
224 int Demuxer::parse_video_frame(int len, int* full)
225 {
226   int ret = 0; // return number of bytes consumed
227   int stream_sent, bytes_remaining;
228
229   switch(state_framepos)
230   {
231     case 0: // Brand new video frame. Set initial states.
232       state_stream_fill = 0; state_vid_parsed = 0;
233       // Create a local copy of the frame header
234       local_frame[0] = local_frame[1] = 0; local_frame[2] = 1;
235       local_frame[3] = state_frametype;
236       // If no video stream has been set, use this one.
237       if (video_current == -1) video_current = state_frametype;
238       // Get MSB of frame length and copy to local frame.
239       frame_length = *inbuf << 8;
240       local_frame[4] = *inbuf;
241       ++inbuf; ++state_framepos; ++ret; --len;
242       if (len == 0) return ret;
243       // FALL THROUGH TO NEXT BYTE IN STREAM
244     case 1: // Get LSB of frame length and copy to local frame.
245       frame_length += *inbuf;
246       local_frame[5] = *inbuf;
247       ++inbuf; ++state_framepos; ++ret; --len;
248       if (len == 0) return ret;
249       // FALL THROUGH TO NEXT BYTE IN STREAM
250     case 2: // First data byte
251       if (len >= frame_length     // If we have the entire frame
252           && !state_vid_parsed)   // and haven't parsed it yet
253       {
254         if (video_current == state_frametype) // and we're interested
255           parse_video_details(inbuf, frame_length); // then parse it
256         state_vid_parsed = 1;
257       }
258   }
259   // We are in the frame data
260   bytes_remaining = 2 + frame_length - state_framepos;
261   if (video_current != state_frametype)
262   {
263     // We don't want this frame. Throw it away.
264     if (len >= bytes_remaining)
265     {
266       inbuf += bytes_remaining;
267       ret += bytes_remaining;
268       state_frametype = state_framepos = 0;
269       return ret;
270     }
271     else
272     {
273       inbuf += len; ret += len;
274       state_framepos += len;
275       return ret;
276     }
277   } // No fall through here
278
279   if (state_vid_parsed)
280   {
281     // We have already parsed the whole frame
282     if (seeking)   // Still not found a sync point. Throw this frame away.
283     {
284       if (len >= bytes_remaining)
285       {
286         inbuf += bytes_remaining;
287         ret += bytes_remaining;
288         state_frametype = state_framepos = 0;
289         return ret;
290       }
291       else
292       {
293         inbuf += len; ret += len; return ret;
294       }
295     } // No fall through is allowed here
296     // Send frame header to stream
297     if (state_stream_fill < 6)
298     {
299       state_stream_fill += videostream.put(local_frame,
300                                    6 - state_stream_fill);
301       if (state_stream_fill < 6)   // stream is full!
302       {
303         *full = 1; return ret;
304       }
305     }
306     // Send all frame data we have to stream
307     if (len >= bytes_remaining) len = bytes_remaining;
308     stream_sent = videostream.put(inbuf, len);
309     inbuf += stream_sent; ret += stream_sent;
310     state_framepos += stream_sent;
311     state_stream_fill += stream_sent;
312     if (stream_sent != len)   // stream is full!
313     {
314       *full = 1; return ret;
315     }
316     if (state_framepos == frame_length + 2)   // frame done
317     {
318       state_frametype = state_framepos = 0;
319     }
320     return ret;
321   } // No fall through is allowed here
322
323   // We haven't parsed the frame yet. It's arriving in pieces.
324   if (bytes_remaining)   // There is data yet to copy to local_frame
325   {
326     if (len >= bytes_remaining) len = bytes_remaining;
327     memcpy(local_frame + state_framepos + 4, inbuf, len);
328     inbuf += len; ret += len; state_framepos += len;
329     if (len < bytes_remaining)   // Not all arrived yet
330       return ret;
331     parse_video_details(local_frame+6, frame_length);
332     if (seeking) // Still not found a sync point. Ignore this frame.
333       return ret;
334   }
335   // We have the whole frame in local_frame. Send it to the stream.
336   state_stream_fill += videostream.put(local_frame,
337                   6 + frame_length - state_stream_fill);
338   if (state_stream_fill < frame_length + 6)   // stream is full!
339   {
340     *full = 1; return ret;
341   }
342   state_frametype = state_framepos = 0;
343   return ret;
344 }
345
346 int Demuxer::parse_audio_frame(int len, int* full)
347 {
348   int ret = 0; // return number of bytes consumed
349   int stream_sent, bytes_remaining;
350
351   switch(state_framepos)
352   {
353     case 0: // Brand new audio frame. Set initial states.
354       state_stream_fill = 0;
355       // Create a local copy of the frame header
356       local_frame[0] = local_frame[1] = 0; local_frame[2] = 1;
357       local_frame[3] = state_frametype;
358       // If no audio stream has been set, use this one.
359       if (audio_current == -1) audio_current = state_frametype;
360       // Get MSB of frame length and copy to local frame.
361       frame_length = *inbuf << 8;
362       local_frame[4] = *inbuf;
363       ++inbuf; ++state_framepos; ++ret; --len;
364       if (len == 0) return ret;
365       // FALL THROUGH TO NEXT BYTE IN STREAM
366     case 1: // Get LSB of frame length and copy to local frame.
367       frame_length += *inbuf;
368       local_frame[5] = *inbuf;
369       ++inbuf; ++state_framepos; ++ret; --len;
370       if (len == 0) return ret;
371   }
372   // We are in the frame data
373   bytes_remaining = 2 + frame_length - state_framepos;
374   if (audio_current != state_frametype)
375   {
376     // We don't want this frame. Throw it away.
377     if (len >= bytes_remaining)
378     {
379       inbuf += bytes_remaining;
380       ret += bytes_remaining;
381       state_frametype = state_framepos = 0;
382       return ret;
383     }
384     else
385     {
386       inbuf += len; ret += len;
387       state_framepos += len;
388       return ret;
389     }
390   } // No fall through is allowed here
391
392   // Send frame header to stream
393   if (state_stream_fill < 6)
394   {
395     state_stream_fill += audiostream.put(local_frame,
396                                  6 - state_stream_fill);
397     if (state_stream_fill < 6) // stream is full!
398     {
399       *full = 1; return ret;
400     }
401   }
402   // Send all frame data we have to stream
403   if (len >= bytes_remaining) len = bytes_remaining;
404   stream_sent = audiostream.put(inbuf, len);
405   inbuf += stream_sent; ret += stream_sent;
406   state_framepos += stream_sent;
407   state_stream_fill += stream_sent;
408   if (stream_sent != len) // stream is full!
409   {
410     *full = 1; return ret;
411   }
412   if (state_framepos == frame_length + 2) // frame done
413   {
414     state_frametype = state_framepos = 0;
415   }
416   return ret;
417 }
418
419 int Demuxer::parse_private1_frame(int len, int* full)
420 {
421   int ret = 0; // return number of bytes consumed
422   int bytes_remaining;
423
424   switch(state_framepos)
425   {
426     case 0: // Brand new frame. Set initial states.
427       // Get MSB of frame length and copy to local frame.
428       frame_length = *inbuf << 8;
429       ++inbuf; ++state_framepos; ++ret; --len;
430       if (len == 0) return ret;
431       // FALL THROUGH TO NEXT BYTE IN STREAM
432     case 1: // Get LSB of frame length and copy to local frame.
433       frame_length += *inbuf;
434       local_frame[5] = *inbuf;
435       ++inbuf; ++state_framepos; ++ret; --len;
436       if (len == 0) return ret;
437   }
438   // We are in the frame data
439   bytes_remaining = 2 + frame_length - state_framepos;
440   // Temporary - just discard the frame.
441   if (len >= bytes_remaining)
442   {
443     inbuf += bytes_remaining;
444     ret += bytes_remaining;
445     state_frametype = state_framepos = 0;
446     return ret;
447   }
448   else
449   {
450     inbuf += len; ret += len;
451     state_framepos += len;
452     return ret;
453   }
454 }
455
456 void Demuxer::parse_video_details(UCHAR* buf, int len)
457 {
458   UCHAR byte;
459   int zeros = 0;
460   while (len >= 8) // 8 is length of a GOP header
461   {
462     // We are searching for a string of bytes (0,0,1).
463     byte = *(buf++); --len;
464
465     if (byte == 0)
466     {
467       ++zeros; continue;
468     }
469     if (zeros < 2 || byte != 1)
470     {
471       zeros = 0; continue;
472     }
473     zeros = 0;
474     // We have found the pattern (0,0,1).
475     // Check the next byte for the sub-frame type.
476     byte = *(buf++); --len;
477     switch (byte)
478     {
479       case 0x00: // Picture header
480                  // 10 bits: temporal reference
481                  //  3 bits: coding type (I/P/B)
482                  //  ...
483         if (len < 2) return;
484         if ( (buf[1] & 0x38) == 0x08 ) // I-frame
485           seeking = 0;
486         buf += 4; // Minimum length of picture header
487         len -= 4;
488         break;
489       case 0xb3: // Sequence header
490                  // 12 bits: Horizontal size
491                  // 12 bits: Vertical size
492                  //  4 bits: Aspect ratio
493                  //  4 bits: Frame rate code
494                  // 18 bits: Bit rate value
495                  // ...
496         if (len < 7) return;
497         horizontal_size = ((int)buf[0] << 4) | ((int)buf[1] >> 4);
498         vertical_size = (((int)buf[1] & 0xf) << 8) | (int)buf[2];
499         aspect_ratio = (enum AspectRatio)(buf[3] >> 4);
500         frame_rate = buf[3] & 0x0f;
501         if (frame_rate >= 1 && frame_rate <= 8)
502           frame_rate = FrameRates[frame_rate];
503         else
504           frame_rate = 0;
505         bit_rate = ((int)buf[4] << 10) |
506                    ((int)buf[5] << 2) |
507                    ((int)buf[6] >> 6);
508         seeking = 0;
509         buf += 8; // Minimum length of sequence header
510         len -= 8;
511         break;
512       case 0xb8: // Group header
513                  // We're not going to bother parsing anything.
514         seeking = 0;
515         buf += 4; // Minimum length of group header
516         len -= 4;
517         break;
518     }
519   }
520 }