From 89d00b9f8d3e3b5a3deeb87b6f6aafd6ec11c7ca Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sun, 12 Oct 2014 19:34:48 +0200 Subject: [PATCH] Get preferred audio and subtitle languages from vdr including subtitle status and use it for playback --- command.cc | 34 +++++++++ command.h | 16 +++++ demuxerts.cc | 84 ++++++++++++++++++----- player.cc | 6 ++ playerlivetv.cc | 179 +++++++++++++++++++++++++++++------------------- vconnect.cc | 4 +- vdr.cc | 16 ++++- vdr.h | 3 +- vvideolivetv.cc | 8 +-- 9 files changed, 255 insertions(+), 95 deletions(-) diff --git a/command.cc b/command.cc index a8db30e..f2afbd4 100644 --- a/command.cc +++ b/command.cc @@ -737,6 +737,40 @@ void Command::buildCrashedBox() boxstack->update(crash); } +int Command::getLangPref(bool subtitle,const char* langcode) +{ + vector::iterator itty=langcodes.begin(); + char templangcode[4]; + templangcode[0]=langcode[0]; + templangcode[1]=langcode[1]; + templangcode[2]=langcode[2]; + templangcode[3]='\0'; + int langpos =0; + while (itty != langcodes.end()) { + size_t pos=(*itty).langcode.find(templangcode); + if (pos != string::npos) { + vector::iterator itty2=langcodes.begin(); + for (int i=0; i +#include class VConnect; class Message; @@ -47,6 +49,14 @@ class Log; class VInfo; class WJpeg; +struct ASLPref { + std::string langcode; + int audiopref; + int subtitlepref; +}; + +typedef vector ASLPrefList; + class Command : public MessageQueue { public: @@ -68,6 +78,10 @@ class Command : public MessageQueue void setAdvMenues(bool adv) {advmenues=adv;}; bool advMenues() { return advmenues;}; + int getLangPref(bool subtitle,const char* langcode); + void setSubDefault(int subon) {subdefault=subon;}; + int getSubDefault() { return subdefault;}; + ASLPrefList &getASLList(){return langcodes;}; private: void handleCommand(int); @@ -102,6 +116,8 @@ class Command : public MessageQueue char* server; bool advmenues; + ASLPrefList langcodes; + int subdefault; UDP udp; diff --git a/demuxerts.cc b/demuxerts.cc index 9299aa6..c5e086a 100644 --- a/demuxerts.cc +++ b/demuxerts.cc @@ -448,10 +448,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,false); - Log::getInstance()->log("ProcessTS", Log::DEBUG, "Set audio PID to %x", foundpid); - } + } break; case 5: case 6: { //Private Data @@ -519,6 +516,7 @@ int DemuxerTS::processTS(UCHAR* buf) } + bool audioPIDpresent=false; //Check if pids chnages ULONG i; for (i=0;i0) { - int j=0; - while (jstreamTypeSupported(channelinfo.apids[j].type)) { - found =true; - setAID(channelinfo.apids[j].pid,0,channelinfo.apids[j].type,false); + if (! audioPIDpresent || getAID() == 0) { + + bool dolby=false; + int selected=-1; + int prefered=-1; + Command* command = Command::getInstance(); + + if (channelinfo.numDPids > 0 && Audio::getInstance()->maysupportAc3()) + { + ULONG j = 0; + while (j < channelinfo.numDPids) + { + int newpref = command->getLangPref(false, channelinfo.dpids[j].desc); + if (Audio::getInstance()->streamTypeSupported(channelinfo.dpids[j].type) + && (prefered < 0 || newpref < prefered)) + { + selected = j; + dolby=true; + prefered = newpref; } j++; } + } + if (channelinfo.numAPids > 0) + { + ULONG j = 0; + while (j < channelinfo.numAPids) + { + int newpref = command->getLangPref(false, channelinfo.apids[j].desc); + if (Audio::getInstance()->streamTypeSupported(channelinfo.apids[j].type) + && (prefered < 0 || newpref < prefered)) + { + selected = j; + dolby=false; + prefered = newpref; + } + j++; + } + } + if (selected >= 0) { + if (dolby) { + setAID(channelinfo.dpids[selected].pid,1,channelinfo.dpids[selected].type,false); + Audio::getInstance()->setStreamType(Audio::MPEG2_PES); + } else { + setAID(channelinfo.dpids[selected].pid,0,channelinfo.apids[selected].type,false); + Audio::getInstance()->setStreamType(Audio::MPEG2_PES); + } } - if (channelinfo.numDPids>0 && !found) { - int j=0; - while (jstreamTypeSupported(channelinfo.dpids[j].type)) { - found =true; - setAID(channelinfo.dpids[j].pid,1,channelinfo.dpids[j].type,false); + + + selected = -1; + prefered=-1; + if (channelinfo.numSPids) { + ULONG j = 0; + while (j < channelinfo.numSPids) + { + int newpref = command->getLangPref(true, channelinfo.spids[j].desc); + if ( (prefered < 0 || newpref < prefered)) + { + selected = j; + prefered = newpref; } - i++; + j++; } } + + if (selected >= 0) { + setSubID(channelinfo.spids[selected].pid); + + } } channelinfo=new_channelinfo; diff --git a/player.cc b/player.cc index 0aeac2f..671a4ef 100644 --- a/player.cc +++ b/player.cc @@ -115,6 +115,12 @@ int Player::init(bool p_isPesRecording,double framespersecond) video->blank(); audio->stop(); + if (Command::getInstance()->getSubDefault()) { + turnSubtitlesOn(true); + } else { + turnSubtitlesOn(false); + } + initted = true; return 1; } diff --git a/playerlivetv.cc b/playerlivetv.cc index 4d73d41..e44ae56 100644 --- a/playerlivetv.cc +++ b/playerlivetv.cc @@ -710,80 +710,121 @@ void PlayerLiveTV::threadMethod() if (!checkError()) { - Channel* chan = (*chanList)[i.channelIndex]; - chan->loadPids(); - h264=chan->vstreamtype==0x1b; - demuxer->seth264(h264); - video->seth264mode(chan->vstreamtype==0x1b); - demuxer->setVID(chan->vpid); - video->seth264mode(chan->vstreamtype==0x1b); - - bool found=false; - - if (chan->numAPids > 0) - { - ULONG j = 0; - while (j < chan->numAPids && !found) - { - if (Audio::getInstance()->streamTypeSupported(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; - } - j++; - } - } - - if (!found) - { - if (chan->numDPids > 0 && audio->maysupportAc3()) - { - ULONG j = 0; - while (j < chan->numDPids && !found) - { - if (Audio::getInstance()->streamTypeSupported(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; - } - j++; - } - } - else - { - logger->log("PlayerLiveTV", Log::WARN, "Demuxer video pid only: %u", chan->vpid); - } - } - - if (chan->numSPids > 0) - demuxer->setSubID(chan->spids[0].pid); - - demuxer->setTID(chan->tpid); - teletext->ResetDecoder(); - int streamSuccess = vdr->streamChannel(chan->number, this); - if (!checkError() && !streamSuccess) - { - Message* m = new Message(); - m->from = this; - m->to = messageReceiver; - m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveTV::STREAM_END; - messageQueue->postMessageFromOuterSpace(m); - } + Channel* chan = (*chanList)[i.channelIndex]; + chan->loadPids(); + h264=chan->vstreamtype==0x1b; + demuxer->seth264(h264); + video->seth264mode(chan->vstreamtype==0x1b); + demuxer->setVID(chan->vpid); + video->seth264mode(chan->vstreamtype==0x1b); + + bool dolby=false; + int selected=-1; + int prefered=-1; + Command* command = Command::getInstance(); + + if (chan->numDPids > 0 && audio->maysupportAc3()) + { + ULONG j = 0; + while (j < chan->numDPids) + { + int newpref = command->getLangPref(false, chan->dpids[j].desc); + if (Audio::getInstance()->streamTypeSupported(chan->dpids[j].type) + && (prefered < 0 || newpref < prefered)) + { + selected = j; + dolby=true; + prefered = newpref; + } + j++; + } + } + + + + if (chan->numAPids > 0) + { + ULONG j = 0; + while (j < chan->numAPids) + { + int newpref = command->getLangPref(false, chan->apids[j].desc); + if (Audio::getInstance()->streamTypeSupported(chan->apids[j].type) + && (prefered < 0 || newpref < prefered)) + { + selected = j; + dolby=false; + prefered = newpref; + } + j++; + } + } + + + if (selected >= 0) { + if (dolby) { + demuxer->setAID(chan->dpids[selected].pid, 1, chan->dpids[selected].type, true); + audio->setStreamType(Audio::MPEG2_PES); + logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u (ac3) %u", + chan->vpid, chan->dpids[selected].pid, chan->dpids[selected].type); + } else { + demuxer->setAID(chan->apids[selected].pid, 0, chan->apids[selected].type, true); + audio->setStreamType(Audio::MPEG2_PES); + logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u %u", chan->vpid, chan->apids[selected].pid, + chan->apids[selected].type); + } + + } else { + logger->log("PlayerLiveTV", Log::WARN, "Demuxer video pid only: %u", chan->vpid); + } + + + selected = -1; + prefered=-1; + if (chan->numSPids) { + ULONG j = 0; + while (j < chan->numSPids) + { + int newpref = command->getLangPref(true, chan->spids[j].desc); + if ( (prefered < 0 || newpref < prefered)) + { + selected = j; + prefered = newpref; + } + j++; + } + } + + if (selected >= 0) { + demuxer->setSubID(chan->spids[selected].pid); + if (command->getSubDefault()) { + turnSubtitlesOn(true); + } else { + turnSubtitlesOn(false); + } + } + + demuxer->setTID(chan->tpid); + teletext->ResetDecoder(); + int streamSuccess = vdr->streamChannel(chan->number, this); + if (!checkError() && !streamSuccess) + { + Message* m = new Message(); + m->from = this; + m->to = messageReceiver; + m->message = Message::PLAYER_EVENT; + m->parameter = PlayerLiveTV::STREAM_END; + messageQueue->postMessageFromOuterSpace(m); + } } } else if (i.instruction == I_STOP) { - logger->log("PlayerLiveTV", Log::DEBUG, "Stopping"); - switchState(S_STOP); - checkError(); + logger->log("PlayerLiveTV", Log::DEBUG, "Stopping"); + switchState(S_STOP); + checkError(); - stopNow = true; - break; + stopNow = true; + break; } } diff --git a/vconnect.cc b/vconnect.cc index 7755073..50a0469 100644 --- a/vconnect.cc +++ b/vconnect.cc @@ -163,7 +163,9 @@ void VConnect::threadMethod() { logger->log("VConnect", Log::DEBUG, "Connected ok, doing login"); unsigned int version_server_min,version_server_max,version_client; - success = vdr->doLogin(&version_server_min,&version_server_max,&version_client); + int subtitles; + success = vdr->doLogin(&version_server_min,&version_server_max,&version_client, Command::getInstance()->getASLList(), subtitles); + Command::getInstance()->setSubDefault(subtitles); if (!success) { diff --git a/vdr.cc b/vdr.cc index 174e159..fd5cdd5 100644 --- a/vdr.cc +++ b/vdr.cc @@ -636,7 +636,8 @@ bool VDR_PacketReceiver::call(void* userTag, bool & deleteme) ///////////////////////////////////////////////////////////////////////////// -int VDR::doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigned int* v_client) +int VDR::doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigned int* v_client, + ASLPrefList& list, int &subtitles) { VDR_RequestPacket vrp; if (!vrp.init(VDR_LOGIN, true, 6)) return 0; @@ -660,6 +661,19 @@ int VDR::doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigne *v_server_max=version_max; *v_client=VOMP_PROTOCOLL_VERSION; + unsigned int numlangcodes = vresp->extractULONG(); + subtitles = vresp->extractULONG(); + list.clear(); + for (int i=0; iextractLONG(); + newpref.subtitlepref = vresp->extractLONG(); + newpref.langcode = vresp->extractStdString(); + //logger->log("VDR", Log::DEBUG, "Langpref %s %d %d", newpref.langcode.c_str(), newpref.audiopref, newpref.subtitlepref); + list.push_back(newpref); + } + + delete vresp; if ((version_min > VOMP_PROTOCOLL_VERSION) diff --git a/vdr.h b/vdr.h index a233970..502d7cb 100644 --- a/vdr.h +++ b/vdr.h @@ -42,6 +42,7 @@ #include "eventdispatcher.h" #include "i18n.h" #include "log.h" +#include "command.h" class TCP; class Log; @@ -172,7 +173,7 @@ public ExternLogger // configSave // setEventTimer - int doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigned int* v_client); + int doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigned int* v_client, ASLPrefList& list, int &subtitles); bool getRecordingsList(RecMan* recman); RecInfo* getRecInfo(char* fileName); int deleteRecording(char* fileName); diff --git a/vvideolivetv.cc b/vvideolivetv.cc index 2daf14a..91ac9bb 100644 --- a/vvideolivetv.cc +++ b/vvideolivetv.cc @@ -892,11 +892,11 @@ bool VVideoLiveTV::channelChange(UCHAR changeType, UINT newData) { UINT newChannel = 0; if (streamType ==VDR::VIDEO) { - VTeletextView *vtxt=((PlayerLiveTV*)player)->getTeletextDecoder()->getTeletxtView(); - if (vtxt ) { - BoxStack::getInstance()->remove(vtxt); + VTeletextView *vtxt=((PlayerLiveTV*)player)->getTeletextDecoder()->getTeletxtView(); + if (vtxt ) { + BoxStack::getInstance()->remove(vtxt); - } + } } if (changeType == INDEX) { -- 2.39.2