]> git.vomp.tv Git - vompclient-marten.git/blob - demuxer.cc
Compilation fixes
[vompclient-marten.git] / demuxer.cc
1 /*
2     Copyright 2005-2008 Mark Calderbank
3     Copyright 2007 Marten Richter (AC3 support)
4
5     This file is part of VOMP.
6
7     VOMP is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11
12     VOMP is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with VOMP; if not, write to the Free Software Foundation, Inc.,
19     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21
22 #include "demuxer.h"
23
24 #include "callback.h"
25 #include "dvbsubtitles.h"
26 #include "log.h"
27
28 #include <cstdlib>
29
30 #define DEMUXER_SEQ_HEAD 0x000001B3
31 #define DEMUXER_PIC_HEAD 0x00000101
32 #define SEEK_THRESHOLD 150000 // About 1.5 seconds
33
34 // Statics
35 const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
36 Demuxer* Demuxer::instance = NULL;
37
38 static const int PESPacket_initial_size = 2000;
39
40 // PESPacket methods
41 PESPacket::PESPacket()
42 {
43   data_size = PESPacket_initial_size;
44   data = (UCHAR*)malloc(data_size);
45   data[0] = 0x00;
46   data[1] = 0x00;
47   data[2] = 0x01;
48   init(0);
49 }
50
51 PESPacket::PESPacket(const PESPacket& packet)
52 {
53   copyFrom(packet);
54 }
55
56 PESPacket& PESPacket::operator=(const PESPacket& packet)
57 {
58   if (this != &packet)
59   {
60     if (data) free(data);
61     copyFrom(packet);
62   }
63   return *this;
64 }
65
66 PESPacket::~PESPacket()
67 {
68   if (data) free(data);
69 }
70
71 void PESPacket::copyFrom(const PESPacket& packet)
72 {
73   length = packet.length;
74   size = packet.size;
75   packetType = packet.packetType;
76   substream = packet.substream;
77   seq_header = packet.seq_header;
78   data_size = size;
79   data = (UCHAR*)malloc(data_size);
80   memcpy(data, packet.data, data_size);
81 }
82
83 void PESPacket::init(UCHAR type, UCHAR sub)
84 {
85   length = 0; 
86   size = 6;
87   data[4] = data[5] = 0;
88   data[3] = type;
89   packetType = type;
90   substream = sub;
91   seq_header = 1; // Unknown seq_header status
92 }
93
94 void PESPacket::truncate()
95 {
96   init(packetType,substream);
97 }
98
99 int PESPacket::write(const UCHAR *buf, int len)
100 {
101   if (size + len > 0x10000) return 0;
102   if (size + len > data_size)
103   { // Reallocate
104     UINT new_data_size = max(data_size + data_size / 2, data_size + len);
105     if (new_data_size > 0x10000) new_data_size = 0x10000;
106     data_size = new_data_size;
107     data = (UCHAR*)realloc(data, data_size);
108   }
109   memcpy(data + size, buf, len);
110   length += len;
111   size += len;
112   data[4] = (length >> 8);
113   data[5] = (length & 0xFF);
114   // We have added data - reset seq_header indicator if necessary
115   if (seq_header == 0) seq_header = 1; // Reset to 'unknown'
116   return 1;
117 }
118
119 ULLONG PESPacket::getPTS() const
120 {
121   if ( ( (packetType >= Demuxer::PESTYPE_AUD0 &&
122           packetType <= Demuxer::PESTYPE_AUDMAX)
123          ||
124          (packetType >= Demuxer::PESTYPE_VID0 &&
125           packetType <= Demuxer::PESTYPE_VIDMAX)
126    ||
127           packetType == Demuxer::PESTYPE_PRIVATE_1
128        )
129        && size >= 14 && data[7] & 0x80)
130   {
131     return ( (ULLONG)(data[ 9] & 0x0E) << 29) |
132            ( (ULLONG)(data[10])        << 22 ) |
133            ( (ULLONG)(data[11] & 0xFE) << 14 ) |
134            ( (ULLONG)(data[12])        <<  7 ) |
135            ( (ULLONG)(data[13] & 0xFE) >>  1 );
136   }
137   else return PTS_INVALID;
138 }
139
140 UCHAR PESPacket::operator[] (UINT index) const
141 {
142   if (index >= size)
143     return 0;
144   else
145     return data[index];
146 }
147
148 UINT PESPacket::findPictureHeader() const
149 {
150   if (size < 12) return 0;
151   UINT pattern = ( ((UINT)data[ 8] << 24) |
152                    ((UINT)data[ 9] << 16) |
153                    ((UINT)data[10] <<  8) |
154                     (UINT)data[11]  );
155   UINT pos = 11;
156   while (pattern != DEMUXER_PIC_HEAD)
157   {
158     if (++pos >= size) return 0;
159     pattern = (pattern << 8) | data[pos];
160   }
161   return pos-3;
162 }
163
164 UINT PESPacket::findSeqHeader() const
165 {
166   if (seq_header != 1) return seq_header;
167   if (size < 12) return 0;
168   UINT pattern = ( ((UINT)data[ 8] << 24) |
169                    ((UINT)data[ 9] << 16) |
170                    ((UINT)data[10] <<  8) |
171                     (UINT)data[11]  );
172   UINT pos = 11;
173   while (pattern != DEMUXER_SEQ_HEAD)
174   {
175     if (++pos >= size)
176     {
177       seq_header = 0;
178       return 0;
179     }
180     pattern = (pattern << 8) | data[pos];
181   }
182   seq_header = pos - 3;
183   return seq_header;
184 }
185
186 // Demuxer methods
187 Demuxer::Demuxer()
188 {
189   if (instance) return;
190   instance = this;
191   initted = false;
192   callback = NULL;
193   arcnt = 0;
194   vid_seeking = aud_seeking = false;
195   video_pts = audio_pts = 0;
196   ispre_1_3_19 = false;
197 }
198
199 Demuxer::~Demuxer()
200 {
201   shutdown();
202   instance = NULL;
203 }
204
205 Demuxer* Demuxer::getInstance()
206 {
207   return instance;
208 }
209
210 int Demuxer::init(Callback* tcallback, DrainTarget* audio, DrainTarget* video, DrainTarget* teletext,
211                   ULONG demuxMemoryV, ULONG demuxMemoryA, ULONG demuxMemoryT, DVBSubtitles* tsubtitles)
212 {
213   if (!initted)
214   {
215     if ( !videostream.init(video, demuxMemoryV) ||
216          !audiostream.init(audio, demuxMemoryA) ||
217          !teletextstream.init(teletext, demuxMemoryT))
218     {
219       Log::getInstance()->log("Demuxer", Log::CRIT,
220                               "Failed to initialize demuxer");
221       shutdown();
222       return 0;
223     }
224   }
225   if (teletext) {
226       isteletextdecoded = true;
227   } else {
228       isteletextdecoded = false;
229   }
230
231   reset();
232   initted = true;
233   subtitles = tsubtitles;
234   callback = tcallback;
235   return 1;
236 }
237
238 void Demuxer::reset()
239 {
240   Log::getInstance()->log("Demuxer", Log::DEBUG, "Reset called");
241   flush();
242   video_current = audio_current = teletext_current = subtitle_current = -1;
243   horizontal_size = vertical_size = 0;
244   aspect_ratio = (enum AspectRatio) 0;
245   frame_rate = bit_rate = 0;
246   ispre_1_3_19 = false;
247
248   for (int i = 0; i <= (PESTYPE_AUDMAX - PESTYPE_AUD0); i++)
249   {
250     avail_mpaudchan[i] = false;
251   }
252   for (int i = 0; i <= (PESTYPE_SUBSTREAM_AC3MAX - PESTYPE_SUBSTREAM_AC30); i++)
253   {
254     avail_ac3audchan[i] = false;
255   }
256   for (int i = 0; i <= (PESTYPE_SUBSTREAM_DVBSUBTITLEMAX - PESTYPE_SUBSTREAM_DVBSUBTITLE0); i++)
257   {
258     avail_dvbsubtitlechan[i] = false;
259   }
260 }
261
262 int Demuxer::shutdown()
263 {
264   videostream.shutdown();
265   audiostream.shutdown();
266   teletextstream.shutdown();
267   initted = false;
268   return 1;
269 }
270
271 void Demuxer::flush()
272 {
273   Log::getInstance()->log("Demuxer", Log::DEBUG, "Flush called");
274
275   videostream.flush();
276   audiostream.flush();
277   teletextstream.flush();
278 }
279
280 void Demuxer::flushAudio()
281 {
282   audiostream.flush();
283 }
284
285 void Demuxer::seek()
286 {
287   vid_seeking = aud_seeking = true;
288   video_pts = audio_pts = teletext_pts = 0;
289 }
290
291 void Demuxer::setAudioStream(int id)
292 {
293   audio_current = id;
294 }
295
296 void Demuxer::setVideoStream(int id)
297 {
298   video_current = id;
299 }
300
301 void Demuxer::setTeletextStream(int id)
302 {
303   teletext_current = id;
304 }
305
306 void Demuxer::setDVBSubtitleStream(int id)
307 {
308   subtitle_current = id;
309 }
310
311 void Demuxer::setAspectRatio(enum AspectRatio ar)
312 {
313   if (aspect_ratio != ar)
314   {
315     Log::getInstance()->log("Demux", Log::DEBUG,
316                             "Aspect ratio difference signalled");
317     if (++arcnt > 3) // avoid changing aspect ratio if glitch in signal
318     {
319       arcnt = 0;
320       aspect_ratio = ar;
321       if (callback) callback->call(this);
322     }
323   }
324   else
325     arcnt = 0;
326 }
327
328 bool Demuxer::writeAudio()
329 {
330   return audiostream.drain();
331 }
332
333 bool Demuxer::writeVideo()
334 {
335   return videostream.drain();
336 }
337
338 bool Demuxer::writeTeletext()
339 {
340    return teletextstream.drain();
341 }
342
343 bool Demuxer::submitPacket(PESPacket& packet)
344 {
345   UINT sent = 0;
346   UCHAR packet_type = packet.getPacketType();
347   const UCHAR* packetdata = packet.getData();
348
349   if (packet_type >= PESTYPE_VID0 && packet_type <= PESTYPE_VIDMAX)
350   {
351     if (video_current == -1) video_current = packet_type;
352     if (video_current == packet_type && !vid_seeking)
353       sent = videostream.put(&packetdata[0], packet.getSize(), MPTYPE_VIDEO);
354     else
355       sent = packet.getSize();
356   }
357   else if (packet_type >= PESTYPE_AUD0 && packet_type <= PESTYPE_AUDMAX)
358   {
359     if (audio_current == -1) audio_current = packet_type;
360     avail_mpaudchan[packet_type - PESTYPE_AUD0] = true;
361     if (audio_current == packet_type && !aud_seeking)
362       sent = audiostream.put(&packetdata[0], packet.getSize(), MPTYPE_MPEG_AUDIO);
363     else
364       sent = packet.getSize();
365   }
366   else if (packet_type == PESTYPE_PRIVATE_1 &&
367            packet.getSubstream() >= PESTYPE_SUBSTREAM_AC30 &&
368            packet.getSubstream() <= PESTYPE_SUBSTREAM_AC3MAX)
369   {
370     avail_ac3audchan[packet.getSubstream() - PESTYPE_SUBSTREAM_AC30] = true;
371     if (packet.getSubstream() == audio_current)
372     {
373       sent = audiostream.put(&packetdata[0], packet.getSize(), (ispre_1_3_19)? MPTYPE_AC3_PRE13 : MPTYPE_AC3);
374     }
375     else
376     {
377       sent = packet.getSize();
378     }
379   }
380   else if (packet_type == PESTYPE_PRIVATE_1 &&
381            packet.getSubstream() >= PESTYPE_SUBSTREAM_DVBSUBTITLE0 &&
382            packet.getSubstream() <= PESTYPE_SUBSTREAM_DVBSUBTITLEMAX)
383   {
384     avail_dvbsubtitlechan[packet.getSubstream()-PESTYPE_SUBSTREAM_DVBSUBTITLE0]=true;
385     if (subtitle_current == -1) subtitle_current = packet.getSubstream();
386     if (subtitles && packet.getSubstream()==subtitle_current)
387     {
388          subtitles->put(packet);
389     }
390     sent = packet.getSize();
391   }
392   else if (isteletextdecoded  && packet_type == PESTYPE_PRIVATE_1 &&
393            packet.getSubstream() >= PESTYPE_SUBSTREAM_TELETEXT0 &&
394            packet.getSubstream() <= PESTYPE_SUBSTREAM_TELETEXTMAX)
395   {
396
397     if (teletext_current == -1) teletext_current = packet.getSubstream();
398     if (teletext_current == packet.getSubstream() )
399     {
400         sent = teletextstream.put(&packetdata[0], packet.getSize(), MPTYPE_TELETEXT);
401     }
402     else 
403     {
404         sent = packet.getSize();
405     }
406   }
407   else
408   {
409     sent = packet.getSize();
410   }
411
412   if (sent < packet.getSize()) // Stream is full.
413     return false;
414   else
415     return true;
416 }
417
418 void Demuxer::parsePacketDetails(PESPacket& packet)
419 {
420   if (packet.getPacketType() >= PESTYPE_AUD0 &&
421       packet.getPacketType() <= PESTYPE_AUDMAX)
422   {
423     // Extract audio PTS if it exists
424     if (packet.hasPTS())
425     {
426       audio_pts = packet.getPTS();
427       // We continue to seek on the audio if the video PTS that we
428       // are trying to match is ahead of the audio PTS by at most
429       // SEEK_THRESHOLD. We consider the possibility of PTS wrap.
430       if (aud_seeking && !vid_seeking &&
431           !( (video_pts_seek > audio_pts &&
432               video_pts_seek - audio_pts < SEEK_THRESHOLD)
433               ||
434              (video_pts_seek < audio_pts &&
435               video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
436       {
437         aud_seeking = 0;
438         Log::getInstance()->log("Demuxer", Log::DEBUG,
439             "Leaving  audio sync: Audio PTS = %llu", audio_pts);
440       }
441     }
442   }
443   else if (packet.getPacketType() == PESTYPE_PRIVATE_1) // Private stream
444   {
445     //Inspired by vdr's device.c
446     int payload_begin = packet[8]+9;
447     unsigned char substream_id = packet[payload_begin];
448     unsigned char substream_type = substream_id & 0xF0;
449     unsigned char substream_index = substream_id & 0x1F;
450 pre_1_3_19_Recording: //This is for old recordings stuff and live TV
451     if (ispre_1_3_19)
452     {
453       substream_id = PESTYPE_PRIVATE_1;
454       substream_type = 0x80;
455       substream_index = 0;
456     }
457     switch (substream_type)
458     {
459       case 0x20://SPU
460       case 0x30://SPU
461         packet.setSubstream(substream_id);
462         break;
463       case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there?
464         break;
465       case 0x80: //ac3, currently only one ac3 track per recording supported
466         packet.setSubstream(substream_type+substream_index);
467
468         // Extract audio PTS if it exists
469         if (packet.hasPTS())
470         {
471           audio_pts = packet.getPTS();
472           // We continue to seek on the audio if the video PTS that we
473           // are trying to match is ahead of the audio PTS by at most
474           // SEEK_THRESHOLD. We consider the possibility of PTS wrap.
475           if (aud_seeking && !vid_seeking &&
476               !( (video_pts_seek > audio_pts &&
477                   video_pts_seek - audio_pts < SEEK_THRESHOLD)
478               ||
479               (video_pts_seek < audio_pts &&
480                     video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
481           {
482             aud_seeking = 0;
483             Log::getInstance()->log("Demuxer", Log::DEBUG, "Leaving  audio sync: Audio PTS = %llu", audio_pts);
484           }
485         }
486         break;
487       case 0x10: //Teletext Is this correct?
488           packet.setSubstream(substream_id);
489           // Extract teletxt PTS if it exists
490         if (packet.hasPTS())
491         {
492           teletext_pts = packet.getPTS();
493         }
494         break;
495       default:
496         if (!ispre_1_3_19)
497         {
498           ispre_1_3_19=true; //switching to compat mode and live tv mode
499           goto pre_1_3_19_Recording;
500         }
501         else
502         {
503           packet.setSubstream(0);
504         }
505         break;
506     }
507   }
508   else if (packet.getPacketType() >= PESTYPE_VID0 &&
509            packet.getPacketType() <= PESTYPE_VIDMAX)
510   {
511     // Extract video PTS if it exists
512     if (packet.hasPTS()) video_pts = packet.getPTS();
513
514     // If there is a sequence header, extract information
515     UINT pos = packet.findSeqHeader();
516     if (pos > 1)
517     {
518       pos += 4;
519       if (pos+6 >= packet.getSize()) return;
520       horizontal_size = ((int)packet[pos] << 4) | ((int)packet[pos+1] >> 4);
521       vertical_size = (((int)packet[pos+1] & 0xf) << 8) | (int)packet[pos+2];
522       setAspectRatio((enum AspectRatio)(packet[pos+3] >> 4));
523       frame_rate = packet[pos+3] & 0x0f;
524       if (frame_rate >= 1 && frame_rate <= 8)
525         frame_rate = FrameRates[frame_rate];
526       else
527         frame_rate = 0;
528       bit_rate = ((int)packet[pos+4] << 10) |
529                  ((int)packet[pos+5] << 2) |
530                  ((int)packet[pos+6] >> 6);
531       if (vid_seeking)
532       {
533         vid_seeking = 0;
534         video_pts_seek = video_pts;
535         Log::getInstance()->log("Demuxer", Log::DEBUG,
536             "Entering audio sync: Video PTS = %llu", video_pts);
537         Log::getInstance()->log("Demuxer", Log::DEBUG,
538             "Entering audio sync: Audio PTS = %llu", audio_pts);
539       }
540       return;
541     }
542   }
543 }
544
545 UINT Demuxer::stripAudio(UCHAR* buf, UINT len)
546 {
547   UINT read_pos = 0, write_pos = 0;
548   UINT pattern, packet_length;
549   if (len < 4) return 0;
550   pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
551   while (read_pos + 7 <= len)
552   {
553     pattern = ((pattern & 0xFFFFFF) << 8) | buf[read_pos+3];
554     if (pattern < (0x100|PESTYPE_VID0) || pattern > (0x100|PESTYPE_VIDMAX))
555       read_pos++;
556     else
557     {
558       packet_length = ((buf[read_pos+4] << 8) | (buf[read_pos+5])) + 6;
559       if (read_pos + packet_length > len)
560         read_pos = len;
561       else
562       {
563         if (read_pos != write_pos)
564           memmove(buf+write_pos, buf+read_pos, packet_length);
565         read_pos += packet_length;
566         write_pos += packet_length;
567         pattern = (buf[read_pos] << 16) | (buf[read_pos+1] << 8)
568                                         | (buf[read_pos+2]);
569       }
570     }
571   }
572   return write_pos;
573 }
574
575 bool Demuxer::scanForVideo(UCHAR* buf, UINT len)
576 {
577   UINT pos = 3;
578   UINT pattern;
579   if (len < 4) return false;
580   pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
581   while (pos < len)
582   {
583     pattern = ((pattern & 0xFFFFFF) << 8) | buf[pos++];
584     if (pattern >= (0x100|PESTYPE_VID0) && pattern <= (0x100|PESTYPE_VIDMAX))
585       return true;
586   }
587   return false;
588 }
589
590 bool* Demuxer::getmpAudioChannels()
591 {
592   return avail_mpaudchan;
593 }
594
595 bool* Demuxer::getac3AudioChannels()
596 {
597   return avail_ac3audchan;
598 }
599
600 bool* Demuxer::getSubtitleChannels()
601 {
602   return avail_dvbsubtitlechan;
603 }
604
605 int Demuxer::getselSubtitleChannel()
606 {
607   return subtitle_current;
608 }
609
610 int Demuxer::getselAudioChannel()
611 {
612   return audio_current;
613 }
614
615