]> git.vomp.tv Git - vompclient.git/blob - demuxer.cc
Widescreen support, segfault fix on livetv interrupt
[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   callback = NULL;
33 }
34
35 Demuxer::~Demuxer()
36 {
37   shutdown();
38   instance = NULL;
39 }
40
41 Demuxer* Demuxer::getInstance()
42 {
43   return instance;
44 }
45
46 int Demuxer::init(Callback* tcallback)
47 {
48   if (!initted)
49   {
50     if ( !videostream.init(demuxMemory) ||
51          !audiostream.init(demuxMemory) ||
52          !(local_frame = (UCHAR *) malloc(0x10000)))
53     {
54       printf("failed to initialize demuxer\n");
55       shutdown();
56       return 0;
57     }
58   }
59
60   reset();
61   initted = 1;
62   callback = tcallback;
63   return 1;
64 }
65
66 void Demuxer::reset()
67 {
68   flush();
69   video_current = audio_current = -1;
70   horizontal_size = vertical_size = 0;
71   aspect_ratio = (enum AspectRatio) 0;
72   cbAspectRatio = frame_rate = bit_rate = 0;
73 }
74
75 int Demuxer::shutdown()
76 {
77   videostream.shutdown();
78   audiostream.shutdown();
79   free(local_frame);
80   initted = 0;
81   return 1;
82 }
83
84 void Demuxer::flush()
85 {
86   videostream.flush();
87   audiostream.flush();
88   state_frametype = state_framepos = 0;
89   seek();
90 }
91
92 void Demuxer::flushAudio()
93 {
94   audiostream.flush();
95 }
96
97 void Demuxer::seek()
98 {
99   seeking = 1;
100 }
101
102 void Demuxer::setAudioStream(int id)
103 {
104   audio_current = id;
105 }
106
107 void Demuxer::setVideoStream(int id)
108 {
109   video_current = id;
110 }
111
112 void Demuxer::setAspectRatio()
113 {
114   if (aspect_ratio != cbAspectRatio)
115   {
116     cbAspectRatio = aspect_ratio;
117     callback->call(this);
118   }
119 }
120
121 int Demuxer::getAspectRatio()
122 {
123   return aspect_ratio;
124 }
125
126 int Demuxer::scan(UCHAR *buf, int len)
127 {
128   // Temporarily, just look for the lowest audio stream and return it
129   int ret = 0;
130   UCHAR byte;
131   int zeros = 0;
132   while (len > 1)
133   {
134     // We are searching for a string of bytes (0,0,1).
135     byte = *(buf++); --len;
136
137     if (byte == 0)
138     {
139       ++zeros; continue;
140     }
141     if (zeros < 2 || byte != 1)
142     {
143       zeros = 0; continue;
144     }
145     zeros = 0;
146     // We have found the pattern (0,0,1).
147     // Check the next byte for the sub-frame type.
148     byte = *(buf++); --len;
149     if (byte >= 0xc0 && byte <= 0xdf) // Audio
150       if (ret == 0 || ret > byte) ret = byte;
151   }
152   return ret;
153 }
154
155 int Demuxer::put(UCHAR* buf, int len)
156 {
157   int ret = 0;    // return number of bytes consumed
158   int parsed = 0; // number of bytes parsed by sub-function
159   int full;       // sub-function sets this to tell us to exit early
160   inbuf = buf;    // Initialize buffer pointer
161
162   while (len)
163   {
164     full = 0;
165     switch (state_frametype)
166     {
167       case 0: // Search for frame
168         parsed = parse_find_frame(len);
169         break;
170       case FRAMETYPE_VID0 ... FRAMETYPE_VIDMAX:
171         parsed = parse_video_frame(len, &full);
172         break;
173       case FRAMETYPE_AUD0 ... FRAMETYPE_AUDMAX:
174         parsed = parse_audio_frame(len, &full);
175         break;
176       case FRAMETYPE_PRIVATE_1:
177         parsed = parse_private1_frame(len, &full);
178         break;
179     }
180     ret += parsed; len -= parsed;
181     if (full) // We have to exit early.
182       break; // out of while loop
183   }
184   //Log::getInstance()->log("Demuxer", Log::DEBUG, "Put %d; took %d", ret + len, ret);
185   return ret;
186 }
187
188 int Demuxer::parse_find_frame(int len)
189 {
190   int ret = 0; // return number of bytes parsed
191   UCHAR byte;
192
193   // In this function, state_framepos represents
194   // the number of fixed header bytes found so far.
195   if (state_framepos > 3 || state_framepos < 0)
196   {
197     // ERROR!
198     state_framepos = 0;
199   }
200
201   while (len)
202   {
203     byte = *inbuf++;
204     ++ret; --len;
205     switch (state_framepos)
206     {
207       case 0:
208       case 1:
209         if (byte == 0)
210           ++state_framepos;
211         else
212           state_framepos = 0;
213         break;
214       case 2:
215         if (byte == 1)
216           ++state_framepos;
217         else if (byte != 0)
218           state_framepos = 0;
219         break;
220       default:
221         state_framepos = 0; // Set initial state for the new frame
222         switch (byte)
223         {
224           case 0:
225             state_framepos = 1; // Count this as a first header byte!
226             break;
227           case FRAMETYPE_VID0 ... FRAMETYPE_VIDMAX:
228           case FRAMETYPE_AUD0 ... FRAMETYPE_AUDMAX:
229           case FRAMETYPE_PRIVATE_1:
230             state_frametype = byte;
231             return ret;
232         }
233         // Not a recognised frame type. Go back to Old Kent Road.
234         break;
235     }
236   }
237   return ret;
238 }
239
240 int Demuxer::parse_video_frame(int len, int* full)
241 {
242   int ret = 0; // return number of bytes consumed
243   int bytes_remaining;
244
245   switch(state_framepos)
246   {
247     case 0: // Brand new video frame. Set initial states.
248       state_stream_fill = 0; state_vid_parsed = 0;
249       // Create a local copy of the frame header
250       local_frame[0] = local_frame[1] = 0; local_frame[2] = 1;
251       local_frame[3] = state_frametype;
252       // If no video stream has been set, use this one.
253       if (video_current == -1) video_current = state_frametype;
254       // Get MSB of frame length and copy to local frame.
255       frame_length = *inbuf << 8;
256       local_frame[4] = *inbuf;
257       ++inbuf; ++state_framepos; ++ret; --len;
258       if (len == 0) return ret;
259       // FALL THROUGH TO NEXT BYTE IN STREAM
260     case 1: // Get LSB of frame length and copy to local frame.
261       frame_length += *inbuf;
262       local_frame[5] = *inbuf;
263       ++inbuf; ++state_framepos; ++ret; --len;
264       if (len == 0) return ret;
265   }
266   // We are in the frame data
267   bytes_remaining = 2 + frame_length - state_framepos;
268   if (video_current != state_frametype)
269   {
270     // We don't want this frame. Throw it away.
271     if (len >= bytes_remaining)
272     {
273       inbuf += bytes_remaining;
274       ret += bytes_remaining;
275       state_frametype = state_framepos = 0;
276       return ret;
277     }
278     else
279     {
280       inbuf += len; ret += len;
281       state_framepos += len;
282       return ret;
283     }
284   } // No fall through here
285
286   if (bytes_remaining)   // There is data yet to copy to local_frame
287   {
288     if (len > bytes_remaining) len = bytes_remaining;
289     memcpy(local_frame + state_framepos + 4, inbuf, len);
290     inbuf += len; ret += len; state_framepos += len;
291     if (len < bytes_remaining)   // Not all arrived yet
292       return ret;
293     parse_video_details(local_frame+6, frame_length);
294   }
295
296   if (!seeking)
297   {
298   // We have the whole frame in local_frame. Send it to the stream.
299   // We still support streams that might not consume all the data.
300     state_stream_fill += videostream.put(local_frame,
301                     6 + frame_length - state_stream_fill);
302     if (state_stream_fill < frame_length + 6)   // stream is full!
303     {
304       *full = 1; return ret;
305     }
306   }
307   state_frametype = state_framepos = 0;
308   return ret;
309 }
310
311 int Demuxer::parse_audio_frame(int len, int* full)
312 {
313   int ret = 0; // return number of bytes consumed
314   int bytes_remaining;
315
316   switch(state_framepos)
317   {
318     case 0: // Brand new audio frame. Set initial states.
319       state_stream_fill = 0;
320       // Create a local copy of the frame header
321       local_frame[0] = local_frame[1] = 0; local_frame[2] = 1;
322       local_frame[3] = state_frametype;
323       // If no audio stream has been set, use this one.
324       if (audio_current == -1) audio_current = state_frametype;
325       // Get MSB of frame length and copy to local frame.
326       frame_length = *inbuf << 8;
327       local_frame[4] = *inbuf;
328       ++inbuf; ++state_framepos; ++ret; --len;
329       if (len == 0) return ret;
330       // FALL THROUGH TO NEXT BYTE IN STREAM
331     case 1: // Get LSB of frame length and copy to local frame.
332       frame_length += *inbuf;
333       local_frame[5] = *inbuf;
334       ++inbuf; ++state_framepos; ++ret; --len;
335       if (len == 0) return ret;
336   }
337   // We are in the frame data
338   bytes_remaining = 2 + frame_length - state_framepos;
339   if (audio_current != state_frametype)
340   {
341     // We don't want this frame. Throw it away.
342     if (len >= bytes_remaining)
343     {
344       inbuf += bytes_remaining;
345       ret += bytes_remaining;
346       state_frametype = state_framepos = 0;
347       return ret;
348     }
349     else
350     {
351       inbuf += len; ret += len;
352       state_framepos += len;
353       return ret;
354     }
355   } // No fall through is allowed here
356
357   if (bytes_remaining)   // There is data yet to copy to local_frame
358   {
359     if (len > bytes_remaining) len = bytes_remaining;
360     memcpy(local_frame + state_framepos + 4, inbuf, len);
361     inbuf += len; ret += len; state_framepos += len;
362     if (len < bytes_remaining)   // Not all arrived yet
363       return ret;
364   }
365
366   // We have the whole frame in local_frame. Send it to the stream.
367   // We still support streams that might not consume all the data.
368   state_stream_fill += audiostream.put(local_frame,
369                   6 + frame_length - state_stream_fill);
370   if (state_stream_fill < frame_length + 6)   // stream is full!
371   {
372     *full = 1; return ret;
373   }
374   state_frametype = state_framepos = 0;
375   return ret;
376 }
377
378 int Demuxer::parse_private1_frame(int len, int* full)
379 {
380   int ret = 0; // return number of bytes consumed
381   int bytes_remaining;
382
383   switch(state_framepos)
384   {
385     case 0: // Brand new frame. Set initial states.
386       // Get MSB of frame length and copy to local frame.
387       frame_length = *inbuf << 8;
388       ++inbuf; ++state_framepos; ++ret; --len;
389       if (len == 0) return ret;
390       // FALL THROUGH TO NEXT BYTE IN STREAM
391     case 1: // Get LSB of frame length and copy to local frame.
392       frame_length += *inbuf;
393       local_frame[5] = *inbuf;
394       ++inbuf; ++state_framepos; ++ret; --len;
395       if (len == 0) return ret;
396   }
397   // We are in the frame data
398   bytes_remaining = 2 + frame_length - state_framepos;
399   // Temporary - just discard the frame.
400   if (len >= bytes_remaining)
401   {
402     inbuf += bytes_remaining;
403     ret += bytes_remaining;
404     state_frametype = state_framepos = 0;
405     return ret;
406   }
407   else
408   {
409     inbuf += len; ret += len;
410     state_framepos += len;
411     return ret;
412   }
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         setAspectRatio();
471         break;
472       case 0xb8: // Group header
473                  // We're not going to bother parsing anything.
474         seeking = 0;
475         buf += 4; // Minimum length of group header
476         len -= 4;
477         break;
478     }
479   }
480 }