2 Copyright 2005-2008 Mark Calderbank
3 Copyright 2007 Marten Richter (AC3 support)
5 This file is part of VOMP.
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.
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.
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.
25 #include "dvbsubtitles.h"
30 #define DEMUXER_SEQ_HEAD 0x000001B3
31 #define DEMUXER_PIC_HEAD 0x00000101
32 #define SEEK_THRESHOLD 150000 // About 1.5 seconds
35 const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
36 Demuxer* Demuxer::instance = NULL;
38 static const int PESPacket_initial_size = 2000;
41 PESPacket::PESPacket()
43 data_size = PESPacket_initial_size;
44 data = (UCHAR*)malloc(data_size);
51 PESPacket::PESPacket(const PESPacket& packet)
56 PESPacket& PESPacket::operator=(const PESPacket& packet)
66 PESPacket::~PESPacket()
71 void PESPacket::copyFrom(const PESPacket& packet)
73 length = packet.length;
75 packetType = packet.packetType;
76 substream = packet.substream;
77 seq_header = packet.seq_header;
79 data = (UCHAR*)malloc(data_size);
80 memcpy(data, packet.data, data_size);
83 void PESPacket::init(UCHAR type, UCHAR sub)
87 data[4] = data[5] = 0;
91 seq_header = 1; // Unknown seq_header status
94 void PESPacket::truncate()
96 init(packetType,substream);
99 int PESPacket::write(const UCHAR *buf, int len)
101 if (size + len > 0x10000) return 0;
102 if (size + len > data_size)
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);
109 memcpy(data + size, buf, 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'
119 ULLONG PESPacket::getPTS() const
121 if ( ( (packetType >= Demuxer::PESTYPE_AUD0 &&
122 packetType <= Demuxer::PESTYPE_AUDMAX)
124 (packetType >= Demuxer::PESTYPE_VID0 &&
125 packetType <= Demuxer::PESTYPE_VIDMAX)
127 packetType == Demuxer::PESTYPE_PRIVATE_1
129 && size >= 14 && data[7] & 0x80)
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 );
137 else return PTS_INVALID;
140 UCHAR PESPacket::operator[] (UINT index) const
148 UINT PESPacket::findPictureHeader() const
150 if (size < 12) return 0;
151 UINT pattern = ( ((UINT)data[ 8] << 24) |
152 ((UINT)data[ 9] << 16) |
153 ((UINT)data[10] << 8) |
156 while (pattern != DEMUXER_PIC_HEAD)
158 if (++pos >= size) return 0;
159 pattern = (pattern << 8) | data[pos];
164 UINT PESPacket::findSeqHeader() const
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) |
173 while (pattern != DEMUXER_SEQ_HEAD)
180 pattern = (pattern << 8) | data[pos];
182 seq_header = pos - 3;
189 if (instance) return;
194 vid_seeking = aud_seeking = false;
195 video_pts = audio_pts = 0;
196 ispre_1_3_19 = false;
205 Demuxer* Demuxer::getInstance()
210 int Demuxer::init(Callback* tcallback, DrainTarget* audio, DrainTarget* video, DrainTarget* teletext,
211 ULONG demuxMemoryV, ULONG demuxMemoryA, ULONG demuxMemoryT, DVBSubtitles* tsubtitles)
215 if ( !videostream.init(video, demuxMemoryV) ||
216 !audiostream.init(audio, demuxMemoryA) ||
217 !teletextstream.init(teletext, demuxMemoryT))
219 Log::getInstance()->log("Demuxer", Log::CRIT,
220 "Failed to initialize demuxer");
226 isteletextdecoded = true;
228 isteletextdecoded = false;
233 subtitles = tsubtitles;
234 callback = tcallback;
238 void Demuxer::reset()
240 Log::getInstance()->log("Demuxer", Log::DEBUG, "Reset called");
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;
248 for (int i = 0; i <= (PESTYPE_AUDMAX - PESTYPE_AUD0); i++)
250 avail_mpaudchan[i] = false;
252 for (int i = 0; i <= (PESTYPE_SUBSTREAM_AC3MAX - PESTYPE_SUBSTREAM_AC30); i++)
254 avail_ac3audchan[i] = false;
256 for (int i = 0; i <= (PESTYPE_SUBSTREAM_DVBSUBTITLEMAX - PESTYPE_SUBSTREAM_DVBSUBTITLE0); i++)
258 avail_dvbsubtitlechan[i] = false;
262 int Demuxer::shutdown()
264 videostream.shutdown();
265 audiostream.shutdown();
266 teletextstream.shutdown();
271 void Demuxer::flush()
273 Log::getInstance()->log("Demuxer", Log::DEBUG, "Flush called");
277 teletextstream.flush();
280 void Demuxer::flushAudio()
287 vid_seeking = aud_seeking = true;
288 video_pts = audio_pts = teletext_pts = 0;
291 void Demuxer::setAudioStream(int id)
296 void Demuxer::setVideoStream(int id)
301 void Demuxer::setTeletextStream(int id)
303 teletext_current = id;
306 void Demuxer::setDVBSubtitleStream(int id)
308 subtitle_current = id;
311 void Demuxer::setAspectRatio(enum AspectRatio ar)
313 if (aspect_ratio != ar)
315 Log::getInstance()->log("Demux", Log::DEBUG,
316 "Aspect ratio difference signalled");
317 if (++arcnt > 3) // avoid changing aspect ratio if glitch in signal
321 if (callback) callback->call(this);
328 bool Demuxer::writeAudio()
330 return audiostream.drain();
333 bool Demuxer::writeVideo()
335 return videostream.drain();
338 bool Demuxer::writeTeletext()
340 return teletextstream.drain();
343 bool Demuxer::submitPacket(PESPacket& packet)
346 UCHAR packet_type = packet.getPacketType();
347 const UCHAR* packetdata = packet.getData();
349 if (packet_type >= PESTYPE_VID0 && packet_type <= PESTYPE_VIDMAX)
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);
355 sent = packet.getSize();
357 else if (packet_type >= PESTYPE_AUD0 && packet_type <= PESTYPE_AUDMAX)
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);
364 sent = packet.getSize();
366 else if (packet_type == PESTYPE_PRIVATE_1 &&
367 packet.getSubstream() >= PESTYPE_SUBSTREAM_AC30 &&
368 packet.getSubstream() <= PESTYPE_SUBSTREAM_AC3MAX)
370 avail_ac3audchan[packet.getSubstream() - PESTYPE_SUBSTREAM_AC30] = true;
371 if (packet.getSubstream() == audio_current)
373 sent = audiostream.put(&packetdata[0], packet.getSize(), (ispre_1_3_19)? MPTYPE_AC3_PRE13 : MPTYPE_AC3);
377 sent = packet.getSize();
380 else if (packet_type == PESTYPE_PRIVATE_1 &&
381 packet.getSubstream() >= PESTYPE_SUBSTREAM_DVBSUBTITLE0 &&
382 packet.getSubstream() <= PESTYPE_SUBSTREAM_DVBSUBTITLEMAX)
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)
388 subtitles->put(packet);
390 sent = packet.getSize();
392 else if (isteletextdecoded && packet_type == PESTYPE_PRIVATE_1 &&
393 packet.getSubstream() >= PESTYPE_SUBSTREAM_TELETEXT0 &&
394 packet.getSubstream() <= PESTYPE_SUBSTREAM_TELETEXTMAX)
397 if (teletext_current == -1) teletext_current = packet.getSubstream();
398 if (teletext_current == packet.getSubstream() )
400 sent = teletextstream.put(&packetdata[0], packet.getSize(), MPTYPE_TELETEXT);
404 sent = packet.getSize();
409 sent = packet.getSize();
412 if (sent < packet.getSize()) // Stream is full.
418 void Demuxer::parsePacketDetails(PESPacket& packet)
420 if (packet.getPacketType() >= PESTYPE_AUD0 &&
421 packet.getPacketType() <= PESTYPE_AUDMAX)
423 // Extract audio PTS if it exists
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)
434 (video_pts_seek < audio_pts &&
435 video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
438 Log::getInstance()->log("Demuxer", Log::DEBUG,
439 "Leaving audio sync: Audio PTS = %llu", audio_pts);
443 else if (packet.getPacketType() == PESTYPE_PRIVATE_1) // Private stream
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
453 substream_id = PESTYPE_PRIVATE_1;
454 substream_type = 0x80;
457 switch (substream_type)
461 packet.setSubstream(substream_id);
463 case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there?
465 case 0x80: //ac3, currently only one ac3 track per recording supported
466 packet.setSubstream(substream_type+substream_index);
468 // Extract audio PTS if it exists
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)
479 (video_pts_seek < audio_pts &&
480 video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
483 Log::getInstance()->log("Demuxer", Log::DEBUG, "Leaving audio sync: Audio PTS = %llu", audio_pts);
487 case 0x10: //Teletext Is this correct?
488 packet.setSubstream(substream_id);
489 // Extract teletxt PTS if it exists
492 teletext_pts = packet.getPTS();
498 ispre_1_3_19=true; //switching to compat mode and live tv mode
499 goto pre_1_3_19_Recording;
503 packet.setSubstream(0);
508 else if (packet.getPacketType() >= PESTYPE_VID0 &&
509 packet.getPacketType() <= PESTYPE_VIDMAX)
511 // Extract video PTS if it exists
512 if (packet.hasPTS()) video_pts = packet.getPTS();
514 // If there is a sequence header, extract information
515 UINT pos = packet.findSeqHeader();
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];
528 bit_rate = ((int)packet[pos+4] << 10) |
529 ((int)packet[pos+5] << 2) |
530 ((int)packet[pos+6] >> 6);
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);
545 UINT Demuxer::stripAudio(UCHAR* buf, UINT len)
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)
553 pattern = ((pattern & 0xFFFFFF) << 8) | buf[read_pos+3];
554 if (pattern < (0x100|PESTYPE_VID0) || pattern > (0x100|PESTYPE_VIDMAX))
558 packet_length = ((buf[read_pos+4] << 8) | (buf[read_pos+5])) + 6;
559 if (read_pos + packet_length > len)
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)
575 bool Demuxer::scanForVideo(UCHAR* buf, UINT len)
579 if (len < 4) return false;
580 pattern = (buf[0] << 16) | (buf[1] << 8) | (buf[2]);
583 pattern = ((pattern & 0xFFFFFF) << 8) | buf[pos++];
584 if (pattern >= (0x100|PESTYPE_VID0) && pattern <= (0x100|PESTYPE_VIDMAX))
590 bool* Demuxer::getmpAudioChannels()
592 return avail_mpaudchan;
595 bool* Demuxer::getac3AudioChannels()
597 return avail_ac3audchan;
600 bool* Demuxer::getSubtitleChannels()
602 return avail_dvbsubtitlechan;
605 int Demuxer::getselSubtitleChannel()
607 return subtitle_current;
610 int Demuxer::getselAudioChannel()
612 return audio_current;