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