From e155f8b9e9dfaed378372f78b88f73e08d793b56 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sat, 1 Dec 2012 12:38:46 +0100 Subject: [PATCH] Fix live TV ac3 playback, probably a very old bug --- demuxer.cc | 146 +++++++++++++++++++++++---------------------- demuxer.h | 1 + demuxerts.cc | 9 +-- demuxerts.h | 3 +- player.cc | 2 +- playerliveradio.cc | 6 +- playerlivetv.cc | 6 +- vvideolivetv.cc | 4 +- 8 files changed, 92 insertions(+), 85 deletions(-) diff --git a/demuxer.cc b/demuxer.cc index c9f27b8..ea1bc8f 100644 --- a/demuxer.cc +++ b/demuxer.cc @@ -426,6 +426,7 @@ Demuxer::Demuxer() h264 = false; fps = 25.0; astreamtype=4; + livetv=false; } Demuxer::~Demuxer() @@ -482,6 +483,7 @@ void Demuxer::reset() h264 = false; packetnum=0; astreamtype=4; + livetv=false; for (int i = 0; i <= (PESTYPE_AUDMAX - PESTYPE_AUD0); i++) { @@ -625,7 +627,7 @@ bool Demuxer::submitPacket(PESPacket& packet) avail_ac3audchan[packet.getSubstream() - PESTYPE_SUBSTREAM_AC30] = true; if (packet.getSubstream() == audio_current) { - sent = audiostream.put(&packetdata[0], packet.getSize(), (ispre_1_3_19)? MPTYPE_AC3_PRE13 : MPTYPE_AC3,packetnum); + sent = audiostream.put(&packetdata[0], packet.getSize(), (ispre_1_3_19 || livetv)? MPTYPE_AC3_PRE13 : MPTYPE_AC3,packetnum); if (sent) packetnum++; } else @@ -698,76 +700,78 @@ void Demuxer::parsePacketDetails(PESPacket& packet) } else if (packet.getPacketType() == PESTYPE_PRIVATE_1) // Private stream { - //Inspired by vdr's device.c - int payload_begin = packet[8]+9; - unsigned char substream_id = packet[payload_begin]; - unsigned char substream_type = substream_id & 0xF0; - unsigned char substream_index = substream_id & 0x1F; -pre_1_3_19_Recording: //This is for old recordings stuff and live TV - if (ispre_1_3_19) - { - int old_substream=packet.getSubstream(); - if (old_substream){ //someone else already set it, this is live tv - substream_id = old_substream; - substream_type = substream_id & 0xF0; - substream_index = substream_id & 0x1F; - } else { - substream_id = PESTYPE_PRIVATE_1; - substream_type = 0x80; - substream_index = 0; - } - - } - switch (substream_type) - { - case 0x20://SPU - case 0x30://SPU - packet.setSubstream(substream_id); - break; - case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there? - break; - case 0x80: //ac3, currently only one ac3 track per recording supported - packet.setSubstream(substream_type+substream_index); - - // Extract audio PTS if it exists - if (packet.hasPTS()) - { - audio_pts = packet.getPTS(); - // We continue to seek on the audio if the video PTS that we - // are trying to match is ahead of the audio PTS by at most - // SEEK_THRESHOLD. We consider the possibility of PTS wrap. - if (aud_seeking && !vid_seeking && - !( (video_pts_seek > audio_pts && - video_pts_seek - audio_pts < SEEK_THRESHOLD) - || - (video_pts_seek < audio_pts && - video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) )) - { - aud_seeking = 0; - Log::getInstance()->log("Demuxer", Log::DEBUG, "Leaving audio sync: Audio PTS = %llu", audio_pts); - } - } - break; - case 0x10: //Teletext Is this correct? - packet.setSubstream(substream_id); - // Extract teletxt PTS if it exists - if (packet.hasPTS()) - { - teletext_pts = packet.getPTS(); - } - break; - default: - if (!ispre_1_3_19) - { - ispre_1_3_19=true; //switching to compat mode and live tv mode - goto pre_1_3_19_Recording; - } - else - { - packet.setSubstream(0); - } - break; - } + if (!livetv) { + //Inspired by vdr's device.c + int payload_begin = packet[8]+9; + unsigned char substream_id = packet[payload_begin]; + unsigned char substream_type = substream_id & 0xF0; + unsigned char substream_index = substream_id & 0x1F; + pre_1_3_19_Recording: //This is for old recordings stuff and live TV + if (ispre_1_3_19) + { + int old_substream=packet.getSubstream(); + if (old_substream){ //someone else already set it, this is live tv + substream_id = old_substream; + substream_type = substream_id & 0xF0; + substream_index = substream_id & 0x1F; + } else { + substream_id = PESTYPE_PRIVATE_1; + substream_type = 0x80; + substream_index = 0; + } + + } + switch (substream_type) + { + case 0x20://SPU + case 0x30://SPU + packet.setSubstream(substream_id); + break; + case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there? + break; + case 0x80: //ac3, currently only one ac3 track per recording supported + packet.setSubstream(substream_type+substream_index); + + // Extract audio PTS if it exists + if (packet.hasPTS()) + { + audio_pts = packet.getPTS(); + // We continue to seek on the audio if the video PTS that we + // are trying to match is ahead of the audio PTS by at most + // SEEK_THRESHOLD. We consider the possibility of PTS wrap. + if (aud_seeking && !vid_seeking && + !( (video_pts_seek > audio_pts && + video_pts_seek - audio_pts < SEEK_THRESHOLD) + || + (video_pts_seek < audio_pts && + video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) )) + { + aud_seeking = 0; + Log::getInstance()->log("Demuxer", Log::DEBUG, "Leaving audio sync: Audio PTS = %llu", audio_pts); + } + } + break; + case 0x10: //Teletext Is this correct? + packet.setSubstream(substream_id); + // Extract teletxt PTS if it exists + if (packet.hasPTS()) + { + teletext_pts = packet.getPTS(); + } + break; + default: + if (!ispre_1_3_19) + { + ispre_1_3_19=true; //switching to compat mode and live tv mode + goto pre_1_3_19_Recording; + } + else + { + packet.setSubstream(0); + } + break; + } + } } else if (packet.getPacketType() >= PESTYPE_VID0 && packet.getPacketType() <= PESTYPE_VIDMAX) diff --git a/demuxer.h b/demuxer.h index d34612b..856703d 100644 --- a/demuxer.h +++ b/demuxer.h @@ -208,6 +208,7 @@ class Demuxer bool h264; int video_current, audio_current, teletext_current, subtitle_current; int astreamtype; + bool livetv; // Video stream information void setAspectRatio(enum AspectRatio, int taspectx, int taspecty); diff --git a/demuxerts.cc b/demuxerts.cc index 70375b4..defd432 100644 --- a/demuxerts.cc +++ b/demuxerts.cc @@ -106,11 +106,12 @@ void DemuxerTS::setVID(int p_vID) vActive = false; } -void DemuxerTS::setAID(int p_aID, int type, int streamtype) +void DemuxerTS::setAID(int p_aID, int type, int streamtype, bool slivetv) { aID = p_aID; atype = type; astreamtype = streamtype; + livetv=slivetv; switch (atype) { case 1: @@ -443,7 +444,7 @@ int DemuxerTS::processTS(UCHAR* buf) new_channelinfo.apids.push_back(newapid); new_channelinfo.numAPids++; if (getAID() == 0 && Audio::getInstance()->streamTypeSupported(streamtype)) { //set unset AID to first audio pid that reports itself - setAID(foundpid,0,streamtype); + setAID(foundpid,0,streamtype,false); Log::getInstance()->log("ProcessTS", Log::DEBUG, "Set audio PID to %x", foundpid); } } break; @@ -532,7 +533,7 @@ int DemuxerTS::processTS(UCHAR* buf) while (jstreamTypeSupported(channelinfo.apids[j].type)) { found =true; - setAID(channelinfo.apids[j].pid,0,channelinfo.apids[j].type); + setAID(channelinfo.apids[j].pid,0,channelinfo.apids[j].type,false); } j++; } @@ -543,7 +544,7 @@ int DemuxerTS::processTS(UCHAR* buf) while (jstreamTypeSupported(channelinfo.dpids[j].type)) { found =true; - setAID(channelinfo.dpids[j].pid,1,channelinfo.dpids[j].type); + setAID(channelinfo.dpids[j].pid,1,channelinfo.dpids[j].type,false); } i++; } diff --git a/demuxerts.h b/demuxerts.h index 90a1d90..5e0cab3 100644 --- a/demuxerts.h +++ b/demuxerts.h @@ -40,7 +40,7 @@ class DemuxerTS : public Demuxer int findPTS(UCHAR* buf, int len, ULLONG* dest); void setVID(int p_vID); void setTID(int p_tID); - void setAID(int p_aID, int type, int streamtype); + void setAID(int p_aID, int type, int streamtype,bool slivetv); void setSubID(int p_subID); int getVID() { return vID; } int getTID() { return tID; } @@ -89,6 +89,7 @@ class DemuxerTS : public Demuxer PTSMap pts_map; Mutex pts_map_mutex; void parseTSPacketDetails(PESPacket &packet); + }; diff --git a/player.cc b/player.cc index 790ed9a..0aeac2f 100644 --- a/player.cc +++ b/player.cc @@ -231,7 +231,7 @@ void Player::setAudioChannel(int newChannel, int type, int streamtype) demuxer->setAudioStream(newChannel); return; } else { - ((DemuxerTS*)demuxer)->setAID(newChannel,type,streamtype); + ((DemuxerTS*)demuxer)->setAID(newChannel,type,streamtype,false); return; } } diff --git a/playerliveradio.cc b/playerliveradio.cc index 9a4a1bb..c72ea60 100644 --- a/playerliveradio.cc +++ b/playerliveradio.cc @@ -113,7 +113,7 @@ int PlayerLiveRadio::getCurrentSubtitleChannel(){ void PlayerLiveRadio::setAudioChannel(int newChannel, int type,int streamtype) { - demuxer->setAID(newChannel, type,streamtype); + demuxer->setAID(newChannel, type,streamtype,true); } void PlayerLiveRadio::setSubtitleChannel(int newChannel) @@ -411,7 +411,7 @@ void PlayerLiveRadio::threadMethod() int j=0; while (jnumAPids && !found) { if (Audio::getInstance()->streamTypeSupported(chan->apids[j].type)) { - demuxer->setAID(chan->apids[j].pid,0,chan->apids[j].type); + demuxer->setAID(chan->apids[j].pid,0,chan->apids[j].type,true); audio->setStreamType(Audio::MPEG2_PES); logger->log("PlayerLiveRadio", Log::DEBUG, "Demuxer pids: %u %u %u", chan->vpid, chan->apids[j].pid,chan->apids[j].type); found=true; @@ -427,7 +427,7 @@ void PlayerLiveRadio::threadMethod() int j=0; while (jnumDPids && !found) { if (Audio::getInstance()->streamTypeSupported(chan->dpids[j].type)) { - demuxer->setAID(chan->dpids[j].pid,1,chan->dpids[j].type); + demuxer->setAID(chan->dpids[j].pid,1,chan->dpids[j].type,true); audio->setStreamType(Audio::MPEG2_PES); logger->log("PlayerLiveRadio", Log::DEBUG, "Demuxer pids: %u %u (ac3) %u", chan->vpid, chan->dpids[j].pid,chan->dpids[j].type); found=true; diff --git a/playerlivetv.cc b/playerlivetv.cc index 16eff3c..3868638 100644 --- a/playerlivetv.cc +++ b/playerlivetv.cc @@ -137,7 +137,7 @@ int PlayerLiveTV::getCurrentAudioChannel() void PlayerLiveTV::setAudioChannel(int newChannel, int type,int streamtype) { - demuxer->setAID(newChannel,type,streamtype); + demuxer->setAID(newChannel,type,streamtype,true); } void PlayerLiveTV::setSubtitleChannel(int newChannel) @@ -723,7 +723,7 @@ void PlayerLiveTV::threadMethod() int j=0; while (jnumAPids && !found) { if (Audio::getInstance()->streamTypeSupported(chan->apids[j].type)) { - demuxer->setAID(chan->apids[j].pid,0,chan->apids[j].type); + demuxer->setAID(chan->apids[j].pid,0,chan->apids[j].type,true); audio->setStreamType(Audio::MPEG2_PES); logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u %u", chan->vpid, chan->apids[j].pid,chan->apids[j].type); found=true; @@ -739,7 +739,7 @@ void PlayerLiveTV::threadMethod() int j=0; while (jnumDPids && !found) { if (Audio::getInstance()->streamTypeSupported(chan->dpids[j].type)) { - demuxer->setAID(chan->dpids[j].pid,1,chan->dpids[j].type); + demuxer->setAID(chan->dpids[j].pid,1,chan->dpids[j].type,true); audio->setStreamType(Audio::MPEG2_PES); logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u (ac3) %u", chan->vpid, chan->dpids[j].pid,chan->dpids[j].type); found=true; diff --git a/vvideolivetv.cc b/vvideolivetv.cc index e75adef..aad1634 100644 --- a/vvideolivetv.cc +++ b/vvideolivetv.cc @@ -1005,13 +1005,13 @@ void VVideoLiveTV::processMessage(Message* m) } else if (m->message == Message::AUDIO_CHANGE_CHANNEL) { - Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change audio channel to %i", m->parameter); + Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change audio channel to %x", m->parameter); player->setAudioChannel((m->parameter & 0xFFFF),(m->parameter & 0xFF0000)>>16,(m->parameter & 0xFF000000)>>24); } else if (m->message == Message::SUBTITLE_CHANGE_CHANNEL) { if (streamType !=VDR::VIDEO) return; - Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change subtitle channel to %i", m->parameter); + Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change subtitle channel to %x", m->parameter); int type=((m->parameter & 0xFF0000)>>16); switch (type) { case 0x10: { //dvbsubtitle -- 2.39.2