virtual int unMute()=0;\r
virtual bool supportsAc3()=0;\r
virtual bool maysupportAc3(){return false;}\r
+ virtual bool streamTypeSupported(int streamtype)\r
+ {\r
+ switch (streamtype) {\r
+ case 3:\r
+ case 4:\r
+ return true;\r
+ default:\r
+ return false;\r
+ };\r
+ }\r
\r
int volumeUp();\r
int volumeDown();\r
canpass_ac3=false;
canpass_mp2=false;
canpass_mp3=false;
+ canpass_aac=false;
canpass_pcm_mch=false;
prefered_ac3=0; //0 stereo PCM, 1 passthrough 2 Multichannel PCM
prefered_mp2=0;
prefered_mp3=0;
+ prefered_aac=0;
hdmi=true;
omx_running=false;
return 0;
}
+ aaclatmcodec_libav = avcodec_find_decoder(CODEC_ID_AAC_LATM);
+ if (aaclatmcodec_libav == NULL) {
+ Log::getInstance()->log("Audio", Log::DEBUG,
+ "Find libav aac latm decoder failed");
+ return 0;
+ }
+
int ret;
ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eMPEG1,2,EDID_AudioSampleRate_e48KHz,0);
Log::getInstance()->log("Audio", Log::NOTICE,
"TV hdmi supports AC3");
}
+ ret=vc_tv_hdmi_audio_supported( EDID_AudioFormat_eAAC,6,EDID_AudioSampleRate_e48KHz,0);
+ if (ret==0) {
+ canpass_aac=true;
+ //not implemented
+ Log::getInstance()->log("Audio", Log::NOTICE,
+ "TV hdmi supports AAC");
+ }
+
canpass_pcm_mch=false;
return 1;
}
}
+ name = vdr->configLoad("AudioOMX", "AACDecodingMode");
+
+ if (name != NULL) {
+ if (STRCASECMP(name, "PCM") == 0) {
+ prefered_aac = 0;
+ } else if (STRCASECMP(name, "Passthrough") == 0) {
+ prefered_aac = 1;
+ } else if (STRCASECMP(name, "PCMMultichannel") == 0) {
+ prefered_aac = 2;
+ }
+ }
+
name = vdr->configLoad("AudioOMX", "Mp3DecodingMode");
if (name != NULL) {
}
}
break;
+ case 5: {
+ if (STRCASECMP(option->options[option->userSetChoice], "PCM") == 0) {
+ prefered_aac = 0;
+ } else if (STRCASECMP(option->options[option->userSetChoice],
+ "Passthrough") == 0) {
+ prefered_aac = 1;
+ } else if (STRCASECMP(option->options[option->userSetChoice],
+ "PCMMultichannel") == 0) {
+ prefered_aac = 2;
+ }
+ }
+ break;
};
return false;
break;
};
+ switch (prefered_aac) {
+ case 0:
+ VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode", "PCM");
+ break;
+ case 1:
+ VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
+ "Passthrough");
+ break;
+ case 2:
+ VDR::getInstance()->configSave("AudioOMX", "AACDecodingMode",
+ "PCMMultichannel");
+ break;
+ };
+
switch (prefered_mp2) {
case 0:
VDR::getInstance()->configSave("AudioOMX", "Mp2DecodingMode", "PCM");
options->push_back(option);
pane->addOptionLine(option);
+ /* char **aacopts = new char *[3];
+ i = 0;
+ aacopts[i] = new char[strlen("PCM") + 1];
+ strcpy(mp2opts[i], "PCM");
+ i++;
+ if (canpass_aac) {
+ aacopts[i] = new char[strlen("Passthrough") + 1];
+ strcpy(aacopts[i], "PassThrough");
+ i++;
+ }
+ if (canpass_pcm_mch) {
+ aacopts[i] = new char[strlen("PCMMultichannel") + 1];
+ strcpy(aacopts[i], "PCMMultichannel");
+ i++;
+ }
+ option = new Option(5, tr("Mp2 HDMI Mode"), "AudioOMX",
+ "AACDecodingMode", Option::TYPE_TEXT, i, 0, 0,
+ aacopts, NULL, true, this);
+ options->push_back(option);
+ pane->addOptionLine(option);
+
+
char **mp2opts = new char *[3];
i = 0;
mp2opts[i] = new char[strlen("PCM") + 1];
"Mp2DecodingMode", Option::TYPE_TEXT, i, 0, 0, mp3opts,
NULL, true, this);
options->push_back(option);
- pane->addOptionLine(option);
+ pane->addOptionLine(option);*/
+ // Comment unsupported modes out
}
}
}
break;
+ case MPTYPE_AAC_LATM: {
+ if (prefered_aac == 2 && false) { //not supported yet
+
+ } else {
+ Log::getInstance()->log("Audio", Log::DEBUG,
+ "ChangeAudioPortConfig debug %d %d",prefered_aac,canpass_aac);
+ if (prefered_aac == 1 && canpass_aac) {
+ passthrough = true;
+ encoding=OMX_AUDIO_CodingAAC;
+ } else {
+ passthrough = false;
+ encoding=OMX_AUDIO_CodingPCM;
+ }
+ }
+ }
+ break;
case MPTYPE_AC3_PRE13:
case MPTYPE_AC3: {
if (prefered_ac3 == 2 && false) { //not supported yet
return 0;
}
+ aaclatmcodec_context_libav = avcodec_alloc_context3(aaclatmcodec_libav);
+ if (!aaclatmcodec_context_libav) {
+ Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for aac decoding context failed!");
+ return 0;
+ }
+
+ aaclatmcodec_context_libav->flags |= CODEC_FLAG_TRUNCATED;
+ aaclatmcodec_context_libav->request_channels=2;
+
+ avc_ret = avcodec_open2(aaclatmcodec_context_libav, aaclatmcodec_libav, NULL);
+ if (avc_ret < 0) {
+ Log::getInstance()->log("Audio", Log::DEBUG, "Opening libav codec failed \n");
+ libav_mutex.Unlock();
+ return 0;
+ }
+
+
mp23codec_context_libav = avcodec_alloc_context3(mp23codec_libav);
if (!ac3codec_context_libav) {
Log::getInstance()->log("Audio", Log::DEBUG, "Alloc avcodec for mp23 decoding context failed!");
avcodec_close(ac3codec_context_libav);
av_free(ac3codec_context_libav);
ac3codec_context_libav = NULL;
+
+ avcodec_close(aaclatmcodec_context_libav);
+ av_free(aaclatmcodec_context_libav);
+ aaclatmcodec_context_libav = NULL;
+
av_free(decode_frame_libav);
+
avcodec_close(mp23codec_context_libav);
av_free(mp23codec_context_libav);
mp23codec_context_libav = NULL;
return size;
}
+unsigned int AudioOMX::AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize)
+{
+ if (size<=4) return size; // silly;
+ unsigned int test=0;
+ *framesize=20000; //if we do not find a start code do not decompress
+ while (test+4<size) {
+ if (data[test] ==0x56 && (data[test+1]& 0xe0)==0xe0) {
+ // now figure out the length of the frame
+ unsigned int length= ((0x1f & data[test+1])<<8) | data[test+2];
+ *framesize=length;
+ return test; // probably FrameSync
+ }
+ test++;
+ }
+ return size;
+}
+
void AudioOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
{
haveToCopy,&gotframesize);
}
break;
+
+ case MPTYPE_AAC_LATM: {
+ adv = AdvanceAacLatmAudioSync(buffer+packet.pos_buffer+*samplepos,
+ haveToCopy,&gotframesize);
+ }
+ break;
};
if (adv!=haveToCopy) {
lsync=false;
if (current_context->frame_size<0) framesize=1152; //Maximum framesize
else framesize=current_context->frame_size;
}break;
+ case MPTYPE_AAC_LATM: {
+ current_context = aaclatmcodec_context_libav;
+ } break;
case MPTYPE_AC3:
case MPTYPE_AC3_PRE13: {
current_context = ac3codec_context_libav;
incoming_paket_libav.size,&gotframesize);
}
break;
+ case MPTYPE_AAC_LATM: {
+ adv = AdvanceAacLatmAudioSync(incoming_paket_libav.data,
+ incoming_paket_libav.size,&gotframesize);
+ }
+ break;
};
if (adv > 0) {
incoming_paket_libav.data += adv;
int mute();\r
int unMute();\r
bool supportsAc3() { return true; }\r
- virtual bool maysupportAc3(){return true;}\r
+ bool maysupportAc3(){return true;}\r
+ bool streamTypeSupported(int streamtype)\r
+ {\r
+ switch (streamtype) {\r
+ case 0x11: //AAC LATM packaging\r
+ case 0x6A://ac3\r
+ case 3: //mpeg 1 layer 1 and 2\r
+ case 4:\r
+ return true;\r
+ default:\r
+ return false;\r
+ };\r
+ }\r
+\r
\r
//Writing Data to Audiodevice\r
virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);\r
bool hdmi; // use hdmi as audio output\r
bool passthrough; // use audio passthrough for the current audio type\r
\r
+ bool canpass_aac;\r
bool canpass_ac3;\r
bool canpass_mp2;\r
bool canpass_mp3;\r
bool canpass_pcm_mch;\r
\r
\r
+ int prefered_aac;\r
int prefered_ac3; //0 stereo PCM, 1 passthrough 2 Multichannel PCM\r
int prefered_mp2;\r
int prefered_mp3;\r
\r
\r
unsigned int AdvanceAc3AudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize);\r
+ unsigned int AdvanceAacLatmAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize);\r
unsigned int AdvanceMpAudioSync(const UCHAR *data,unsigned int size,unsigned int *framesize);\r
\r
\r
bool omx_first_frame;\r
Mutex libav_mutex;\r
\r
+ AVCodec *aaclatmcodec_libav;\r
+ AVCodecContext *aaclatmcodec_context_libav;\r
AVCodec *ac3codec_libav;\r
AVCodecContext *ac3codec_context_libav;\r
AVCodec *mp23codec_libav;\r
virtual bool supportsAc3();
virtual bool maysupportAc3(){return true;} // We are not sure maybe we support this, allows the player to select ac3, if there is no other option
+
+ virtual bool streamTypeSupported(int streamtype)
+ {
+ switch (streamtype) {
+ case 0x6A:
+ case 3:
+ case 4:
+ return true;
+ default:
+ return false;
+ };
+ }
+
+
private:
MediaPacket mediapacket;
public:
if (name) delete[] name;
index = -1; // just in case
- for(ULONG i = 0; i < numAPids; i++) delete[] apids[i].name;
- for(ULONG i = 0; i < numDPids; i++) delete[] dpids[i].name;
- for(ULONG i = 0; i < numSPids; i++) delete[] spids[i].name;
}
void Channel::loadPids()
// Clear the list if this is a reload
if (numAPids)
{
- for(ULONG i = 0; i < numAPids; i++) delete[] apids[i].name;
apids.clear();
- for(ULONG i = 0; i < numDPids; i++) delete[] dpids[i].name;
dpids.clear();
- for(ULONG i = 0; i < numSPids; i++) delete[] spids[i].name;
spids.clear();
vpid = 0;
tpid = 0;
number, vpid, numAPids, numDPids, numSPids, tpid);
for (ULONG i = 0; i < numAPids; i++)
{
- Log::getInstance()->log("Channel", Log::DEBUG, "APid %lu %s", apids[i].pid, apids[i].name);
+ Log::getInstance()->log("Channel", Log::DEBUG, "APid %lu %s %d", apids[i].pid, apids[i].desc,apids[i].type);
}
for (ULONG i = 0; i < numDPids; i++)
{
- Log::getInstance()->log("Channel", Log::DEBUG, "DPid %lu %s", dpids[i].pid, dpids[i].name);
+ Log::getInstance()->log("Channel", Log::DEBUG, "DPid %lu %s %d", dpids[i].pid, dpids[i].desc,dpids[i].type);
}
for (ULONG i = 0; i < numSPids; i++)
{
- Log::getInstance()->log("Channel", Log::DEBUG, "SPid %lu %s", spids[i].pid, spids[i].name);
+ Log::getInstance()->log("Channel", Log::DEBUG, "SPid %lu %s %d %d %d", spids[i].pid, spids[i].desc,spids[i].type,spids[i].data1,spids[i].data2);
}
}
typedef struct _apid
{
ULONG pid;
- char* name;
+ char desc[10];
+ ULONG type;
+ ULONG data1;
+ ULONG data2;
} apid;
typedef vector<apid> APidList;
packetnum=0;\r
h264 = false;\r
fps = 25.0;\r
+ astreamtype=4;\r
}\r
\r
Demuxer::~Demuxer()\r
ispre_1_3_19 = false;\r
h264 = false;\r
packetnum=0;\r
+ astreamtype=4;\r
\r
for (int i = 0; i <= (PESTYPE_AUDMAX - PESTYPE_AUD0); i++)\r
{\r
avail_mpaudchan[packet_type - PESTYPE_AUD0] = true;\r
if (audio_current == packet_type && !aud_seeking)\r
{\r
- sent = audiostream.put(&packetdata[0], packet.getSize(), MPTYPE_MPEG_AUDIO,packetnum);\r
+ UCHAR type=MPTYPE_MPEG_AUDIO;\r
+ switch (astreamtype)\r
+ {\r
+ case 3:\r
+ case 4:\r
+ type=MPTYPE_MPEG_AUDIO; break;\r
+ case 0x11:\r
+ type=MPTYPE_AAC_LATM; break;\r
+ };\r
+ sent = audiostream.put(&packetdata[0], packet.getSize(), type,packetnum);\r
if (sent) packetnum++;\r
}\r
else\r
bool aud_seeking;\r
bool h264;\r
int video_current, audio_current, teletext_current, subtitle_current;\r
+ int astreamtype;\r
\r
// Video stream information\r
void setAspectRatio(enum AspectRatio);\r
#include "log.h"\r
#include "video.h"\r
#include "vdr.h"\r
+#include "audio.h"\r
\r
#define PTS_JUMP_MARGIN 10000\r
#define PTS_ALLOWANCE 90000\r
vActive = false;\r
}\r
\r
-void DemuxerTS::setAID(int p_aID, int type)\r
+void DemuxerTS::setAID(int p_aID, int type, int streamtype)\r
{\r
aID = p_aID;\r
atype = type;\r
+ astreamtype = streamtype;\r
switch (atype)\r
{\r
case 1:\r
{\r
foundpid = foundpid & 0x1FFF; //clear upper 3 bits\r
bool notfound=false;\r
+ bool nolang=true;\r
int pos=0;\r
- // Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDPID is %x", foundpid);\r
+ // Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDPID is %x %x", foundpid,streamtype);\r
switch (streamtype)\r
{\r
case 0x1B: //MPEG 4 for future use\r
\r
// Log::getInstance()->log("ProcessTS", Log::DEBUG, "Set video PID to %x", foundpid);\r
}break;\r
+ case 0x0F: //AAC ADTS packaging\r
+ case 0x11: // LATM packaging\r
case 3:\r
case 4: { //audio\r
apid newapid;\r
newapid.pid = foundpid;\r
- newapid.name = NULL; //set it in player\r
+ newapid.desc[0]=0;\r
+ newapid.type=streamtype;\r
+ pos=0;\r
+ nolang=true;\r
+ while (pos< eslength && nolang) {\r
+ switch (buf[p+pos]) {\r
+ case 0x0A: {\r
+ newapid.desc[0]=buf[p+pos+2];\r
+ newapid.desc[1]=buf[p+pos+3];\r
+ newapid.desc[2]=buf[p+pos+4];\r
+ newapid.desc[3]=0;\r
+ nolang=false;\r
+ // Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDLANG is %s", newapid.desc);\r
+ } break;\r
+ };\r
+\r
+ pos+=2+buf[p+pos+1];\r
+ }\r
+\r
new_channelinfo.apids.push_back(newapid);\r
new_channelinfo.numAPids++;\r
- if (getAID() == 0) { //set unset AID to first audio pid that reports itself\r
- setAID(foundpid,0);\r
+ if (getAID() == 0 && Audio::getInstance()->streamTypeSupported(streamtype)) { //set unset AID to first audio pid that reports itself\r
+ setAID(foundpid,0,streamtype);\r
Log::getInstance()->log("ProcessTS", Log::DEBUG, "Set audio PID to %x", foundpid);\r
}\r
} break;\r
case 6: { //Private Data \r
apid newapid;\r
newapid.pid = foundpid;\r
- newapid.name = NULL; //set it in player\r
+ newapid.desc[0]=0; //set it in player\r
pos=0;\r
notfound=true;\r
+ nolang=true;\r
+ int type=0;\r
\r
- while (pos< eslength && notfound) {\r
+ while (pos< eslength && (notfound || nolang)) {\r
switch (buf[p+pos]) {\r
+ case 0x7A: // Enhanced Ac3 Desriptor\r
case 0x6A: {//Ac3 descriptor \r
- new_channelinfo.dpids.push_back(newapid);\r
- new_channelinfo.numDPids++;\r
+ newapid.type=buf[p+pos];\r
+ type=1;\r
+\r
notfound=false;\r
} break; \r
case 0x59: {//SubtitlingDescriptor\r
- new_channelinfo.spids.push_back(newapid);\r
- new_channelinfo.numSPids++;\r
+ type=2;\r
+ newapid.type=buf[p+pos];\r
+ newapid.desc[0]=buf[p+pos+2];\r
+ newapid.desc[1]=buf[p+pos+3];\r
+ newapid.desc[2]=buf[p+pos+4];\r
+ newapid.desc[3]=0;\r
+ newapid.data1=(buf[p+pos+5]<<8) |(buf[p+pos+6]);\r
+ newapid.data2=(buf[p+pos+7]<<8) |(buf[p+pos+8]);\r
+ // Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDSUB is %s", newapid.desc);\r
notfound=false;\r
+ nolang=false;\r
} break;\r
+ case 0x0A: {\r
+ newapid.desc[0]=buf[p+pos+2];\r
+ newapid.desc[1]=buf[p+pos+3];\r
+ newapid.desc[2]=buf[p+pos+4];\r
+ newapid.desc[3]=0;\r
+ nolang=false;\r
+ // Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDLANG is %s", newapid.desc);\r
+ } break;\r
case 0x56: {\r
+ type=3;\r
new_channelinfo.tpid=foundpid;\r
notfound=false;\r
} break;\r
};\r
pos+=2+buf[p+pos+1];\r
}\r
+ if (type==1) {\r
+ new_channelinfo.dpids.push_back(newapid);\r
+ new_channelinfo.numDPids++;\r
+ } else if (type==2) {\r
+ new_channelinfo.spids.push_back(newapid);\r
+ new_channelinfo.numSPids++;\r
+ }\r
\r
} break;\r
default://TODO how about subtitles and second audio pids\r
}\r
}\r
if (! audioPIDpresent) {\r
+ bool found=false;\r
if (channelinfo.numAPids>0) {\r
- setAID(channelinfo.apids[0].pid,0);\r
- } else if (channelinfo.numDPids>0) {\r
- setAID(channelinfo.dpids[0].pid,1);\r
+ int j=0;\r
+ while (j<channelinfo.numAPids && !found) {\r
+ if (Audio::getInstance()->streamTypeSupported(channelinfo.apids[j].type)) {\r
+ found =true;\r
+ setAID(channelinfo.apids[j].pid,0,channelinfo.apids[j].type);\r
+ }\r
+ j++;\r
+ }\r
+\r
+ }\r
+ if (channelinfo.numDPids>0 && !found) {\r
+ int j=0;\r
+ while (j<channelinfo.numDPids && !found) {\r
+ if (Audio::getInstance()->streamTypeSupported(channelinfo.dpids[j].type)) {\r
+ found =true;\r
+ setAID(channelinfo.dpids[j].pid,1,channelinfo.dpids[j].type);\r
+ }\r
+ i++;\r
+ }\r
}\r
}\r
\r
channelinfo=new_channelinfo;\r
+\r
+\r
havechannelinfo=true;\r
\r
return 1;\r
int findPTS(UCHAR* buf, int len, ULLONG* dest);\r
void setVID(int p_vID);\r
void setTID(int p_tID);\r
- void setAID(int p_aID, int type);\r
+ void setAID(int p_aID, int type, int streamtype);\r
void setSubID(int p_subID);\r
int getVID() { return vID; }\r
int getTID() { return tID; }\r
ULONG getPacketNum();\r
UINT stripAudio(UCHAR* buf, UINT len);\r
static bool scanForVideo(UCHAR* buf, UINT len, bool &ish264);\r
- Channel getChannelInfo() {return channelinfo;};\r
+ Channel *getChannelInfo() {return &channelinfo;};\r
\r
\r
private:\r
#define MPTYPE_MPEG_AUDIO_LAYER3 0x04 //for media mp3 playback\r
#define MPTYPE_TELETEXT 0x05 //for EBU VBI teletext\r
#define MPTYPE_VIDEO_H264 0x06\r
+#define MPTYPE_AAC_LATM 0x07\r
\r
\r
\r
return teletext->getSubtitlePages();\r
}\r
\r
-void Player::setAudioChannel(int newChannel, int type)\r
+void Player::setAudioChannel(int newChannel, int type, int streamtype)\r
{\r
if (is_pesrecording) {\r
demuxer->setAudioStream(newChannel);\r
return;\r
} else {\r
- ((DemuxerTS*)demuxer)->setAID(newChannel,type);\r
+ ((DemuxerTS*)demuxer)->setAID(newChannel,type,streamtype);\r
return;\r
}\r
}\r
\r
}\r
\r
-Channel Player::getDemuxerChannel() {\r
+Channel * Player::getDemuxerChannel() {\r
if (!is_pesrecording) {\r
return ((DemuxerTS*) demuxer)->getChannelInfo();\r
} \r
- return Channel(); //Should not happen!\r
+ return NULL; //Should not happen!\r
}\r
\r
\r
void setStartFrame(ULONG frameNum);\r
void setLengthBytes(ULLONG length);\r
void setLengthFrames(ULONG length);\r
- void setAudioChannel(int newChannel, int type);\r
+ void setAudioChannel(int newChannel, int type, int streamtype);\r
void setSubtitleChannel(int newChannel);\r
bool toggleSubtitles();\r
void turnSubtitlesOn(bool ison); \r
int getCurrentAudioChannel();\r
int getCurrentSubtitleChannel();\r
bool isPesRecording() { return is_pesrecording; }\r
- Channel getDemuxerChannel();\r
+ Channel *getDemuxerChannel();\r
\r
TeletextDecoderVBIEBU * getTeletextDecoder() { return teletext; }\r
\r
virtual void go(ULONG index)=0;
virtual void setChannel(ULONG index)=0;
virtual void stop()=0;
- virtual void setAudioChannel(int newChannel,int type)=0;
+ virtual void setAudioChannel(int newChannel,int type,int streamtype)=0;
virtual void setSubtitleChannel(int newChannel)=0;
virtual bool* getDemuxerMpegAudioChannels()=0;
return demuxer->getSubID();\r
}\r
\r
-void PlayerLiveRadio::setAudioChannel(int newChannel, int type)\r
+void PlayerLiveRadio::setAudioChannel(int newChannel, int type,int streamtype)\r
{\r
- demuxer->setAID(newChannel, type);\r
+ demuxer->setAID(newChannel, type,streamtype);\r
}\r
\r
void PlayerLiveRadio::setSubtitleChannel(int newChannel)\r
Channel* chan = (*chanList)[i.channelIndex];\r
chan->loadPids();\r
\r
+ bool found=false;\r
+\r
if (chan->numAPids > 0) \r
{\r
- demuxer->setAID(chan->apids[0].pid,0);\r
- logger->log("PlayerLiveRadio", Log::DEBUG, "Demuxer pids: %u %u", chan->vpid, chan->apids[0].pid);\r
+ int j=0;\r
+ while (j<chan->numAPids && !found) {\r
+ if (Audio::getInstance()->streamTypeSupported(chan->apids[j].type)) {\r
+ demuxer->setAID(chan->apids[j].pid,0,chan->apids[j].type);\r
+ audio->setStreamType(Audio::MPEG2_PES);\r
+ logger->log("PlayerLiveRadio", Log::DEBUG, "Demuxer pids: %u %u %u", chan->vpid, chan->apids[j].pid,chan->apids[j].type);\r
+ found=true;\r
+ }\r
+ j++;\r
+ }\r
}\r
- else \r
+\r
+ if (!found)\r
{\r
- logger->log("PlayerLiveRadio", Log::WARN, "Demuxer no pids!");\r
+ if (chan->numDPids > 0 && audio->maysupportAc3())\r
+ {\r
+ int j=0;\r
+ while (j<chan->numDPids && !found) {\r
+ if (Audio::getInstance()->streamTypeSupported(chan->dpids[j].type)) {\r
+ demuxer->setAID(chan->dpids[j].pid,1,chan->dpids[j].type);\r
+ audio->setStreamType(Audio::MPEG2_PES);\r
+ logger->log("PlayerLiveRadio", Log::DEBUG, "Demuxer pids: %u %u (ac3) %u", chan->vpid, chan->dpids[j].pid,chan->dpids[j].type);\r
+ found=true;\r
+ }\r
+ j++;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ logger->log("PlayerLiveRadio", Log::WARN, "Demuxer no pids!");\r
+ }\r
}\r
\r
+\r
+\r
int streamSuccess = vdr->streamChannel(chan->number, this);\r
if (!checkError() && !streamSuccess)\r
{ \r
virtual void go(ULONG index);
virtual void setChannel(ULONG index);
virtual void stop();
- virtual void setAudioChannel(int newChannel, int type);
+ virtual void setAudioChannel(int newChannel, int type,int streamtype);
virtual void setSubtitleChannel(int newChannel);
virtual bool* getDemuxerMpegAudioChannels();
return demuxer->getAID();\r
}\r
\r
-void PlayerLiveTV::setAudioChannel(int newChannel, int type)\r
+void PlayerLiveTV::setAudioChannel(int newChannel, int type,int streamtype)\r
{\r
- demuxer->setAID(newChannel,type);\r
+ demuxer->setAID(newChannel,type,streamtype);\r
}\r
\r
void PlayerLiveTV::setSubtitleChannel(int newChannel)\r
demuxer->setVID(chan->vpid);\r
video->seth264mode(chan->vstreamtype==0x1b);\r
\r
+ bool found=false;\r
+\r
if (chan->numAPids > 0) \r
{\r
- demuxer->setAID(chan->apids[0].pid,0);\r
- audio->setStreamType(Audio::MPEG2_PES);\r
- logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u", chan->vpid, chan->apids[0].pid);\r
+ int j=0;\r
+ while (j<chan->numAPids && !found) {\r
+ if (Audio::getInstance()->streamTypeSupported(chan->apids[j].type)) {\r
+ demuxer->setAID(chan->apids[j].pid,0,chan->apids[j].type);\r
+ audio->setStreamType(Audio::MPEG2_PES);\r
+ logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u %u", chan->vpid, chan->apids[j].pid,chan->apids[j].type);\r
+ found=true;\r
+ }\r
+ j++;\r
+ }\r
}\r
- else \r
+\r
+ if (!found)\r
{\r
if (chan->numDPids > 0 && audio->maysupportAc3()) \r
{\r
- demuxer->setAID(chan->dpids[0].pid,1);\r
- logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u (ac3)", chan->vpid, chan->dpids[0].pid);\r
+ int j=0;\r
+ while (j<chan->numDPids && !found) {\r
+ if (Audio::getInstance()->streamTypeSupported(chan->dpids[j].type)) {\r
+ demuxer->setAID(chan->dpids[j].pid,1,chan->dpids[j].type);\r
+ audio->setStreamType(Audio::MPEG2_PES);\r
+ logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer pids: %u %u (ac3) %u", chan->vpid, chan->dpids[j].pid,chan->dpids[j].type);\r
+ found=true;\r
+ }\r
+ j++;\r
+ }\r
} \r
else\r
{\r
virtual void go(ULONG index);
virtual void setChannel(ULONG index);
virtual void stop();
- virtual void setAudioChannel(int newChannel,int type);
+ virtual void setAudioChannel(int newChannel,int type,int streamtype);
virtual void setSubtitleChannel(int newChannel);
virtual bool toggleSubtitles();
virtual void turnSubtitlesOn(bool ison);
{
AudioSubtitleChannel* sc = new AudioSubtitleChannel();
sc->type = 0x10;
- sc->name = new char[strlen(channel->spids[i].name) + 1];
- strcpy(sc->name, channel->spids[i].name);
+ sc->name = new char[strlen(channel->spids[i].desc) + 1];
+ strcpy(sc->name, channel->spids[i].desc);
sc->pestype = channel->spids[i].pid;
scl.push_back(sc);
}
{
AudioSubtitleChannel* ac = new AudioSubtitleChannel();
ac->type = 0;
- ac->name = new char[strlen(channel->apids[i].name) + 1];
- strcpy(ac->name, channel->apids[i].name);
+ ac->name = new char[strlen(channel->apids[i].desc) + 1];
+ strcpy(ac->name, channel->apids[i].desc);
ac->pestype = channel->apids[i].pid;
- acl.push_back(ac);
+ ac->streamtype=channel->apids[i].type;
+ if (Audio::getInstance()->streamTypeSupported(ac->streamtype))acl.push_back(ac);
}
if (Audio::getInstance()->supportsAc3())
{
AudioSubtitleChannel* ac = new AudioSubtitleChannel();
ac->type = 1;
- ac->name = new char[strlen(channel->dpids[i].name) + 1];
- strcpy(ac->name, channel->dpids[i].name);
+ ac->name = new char[strlen(channel->dpids[i].desc) + 1];
+ strcpy(ac->name, channel->dpids[i].desc);
ac->pestype = channel->dpids[i].pid;
- acl.push_back(ac);
+ ac->streamtype=channel->dpids[i].type;
+ if (Audio::getInstance()->streamTypeSupported(ac->streamtype))acl.push_back(ac);
}
}
m->from = this;
m->to = parent;
m->message = Message::SUBTITLE_CHANGE_CHANNEL;
- m->parameter = (((AudioSubtitleChannel*)ssl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)ssl.getCurrentOptionData())->type &0xFF)<<16 ;
+ m->parameter = (((AudioSubtitleChannel*)ssl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)ssl.getCurrentOptionData())->type &0xFF)<<16
+ |(((AudioSubtitleChannel*)asl.getCurrentOptionData())->streamtype &0xFF)<<24 ;
Command::getInstance()->postMessageNoLock(m);
} else {
asl.down();
m->from = this;
m->to = parent;
m->message = Message::AUDIO_CHANGE_CHANNEL;
- m->parameter = (((AudioSubtitleChannel*)asl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)asl.getCurrentOptionData())->type &0xFF)<<16 ;
+ m->parameter = (((AudioSubtitleChannel*)asl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)asl.getCurrentOptionData())->type &0xFF)<<16
+ |(((AudioSubtitleChannel*)asl.getCurrentOptionData())->streamtype &0xFF)<<24 ;
Command::getInstance()->postMessageNoLock(m);
}
int type;
char* name;
int pestype;
+ int streamtype;
};
if (success)
{
logger->log("VConnect", Log::DEBUG, "Connected ok, doing login");
- success = vdr->doLogin();
+ unsigned int version_server,version_client;
+ success = vdr->doLogin(&version_server,&version_client);
if (!success)
{
vdr->disconnect();
- setOneLiner(tr("Login failed"));
+ if (version_server!=version_client) {
+ char buffer[1024];
+ sprintf(buffer,"Protocoll mismatch s: %x c: %x",version_server,version_client);
+ setOneLiner(buffer);
+ } else {
+ setOneLiner(tr("Login failed"));
+ }
delay = 3000;
}
}
#include "video.h"\r
#include "osd.h"\r
\r
+#define VOMP_PROTOCOLL_VERSION 0x00000100\r
+\r
VDR* VDR::instance = NULL;\r
//prepare a request\r
//will create a request package from a command variable and fill this\r
\r
/////////////////////////////////////////////////////////////////////////////\r
\r
-int VDR::doLogin()\r
+int VDR::doLogin(unsigned int* v_server,unsigned int* v_client)\r
{\r
VDR_RequestPacket vrp;\r
if (!vrp.init(VDR_LOGIN, true, 6)) return 0;\r
long vdrTimeOffset = vresp->extractLONG();\r
logger->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);\r
\r
+ unsigned int version=vresp->extractULONG();\r
+\r
+ *v_server=version;\r
+ *v_client=VOMP_PROTOCOLL_VERSION;\r
+\r
delete vresp;\r
\r
+ if (version!=VOMP_PROTOCOLL_VERSION) {\r
+\r
+ return 0;\r
+\r
+ }\r
+\r
// Set the time and zone on the MVP only\r
\r
#if !defined(WIN32) && !defined(__ANDROID__)\r
{\r
apid newapid;\r
newapid.pid = vresp->extractULONG();\r
- newapid.name = vresp->extractString();\r
+ char * name=vresp->extractString();\r
+ strncpy(newapid.desc,name,9);\r
+ delete [] name;\r
channel->apids.push_back(newapid);\r
}\r
\r
{\r
apid newdpid;\r
newdpid.pid = vresp->extractULONG();\r
- newdpid.name = vresp->extractString();\r
+ char * name=vresp->extractString();\r
+ strncpy(newdpid.desc,name,9);\r
+ delete [] name;\r
channel->dpids.push_back(newdpid);\r
}\r
\r
{\r
apid newspid;\r
newspid.pid = vresp->extractULONG();\r
- newspid.name = vresp->extractString();\r
+ char * name=vresp->extractString();\r
+ strncpy(newspid.desc,name,9);\r
+ delete [] name;\r
channel->spids.push_back(newspid);\r
}\r
channel->tpid = vresp->extractULONG();\r
+ // extension\r
+ for (ULONG i = 0; i < channel->numAPids; i++)\r
+ {\r
+ channel->apids[i].type = vresp->extractULONG();\r
+ }\r
+ for (ULONG i = 0; i < channel->numDPids; i++)\r
+ {\r
+ channel->dpids[i].type = vresp->extractULONG();\r
+ }\r
+ for (ULONG i = 0; i < channel->numSPids; i++)\r
+ {\r
+ channel->spids[i].type = vresp->extractULONG();\r
+ channel->spids[i].data1 = vresp->extractULONG();\r
+ channel->spids[i].data2 = vresp->extractULONG();\r
+ }\r
\r
delete vresp;\r
\r
// configSave\r
// setEventTimer\r
\r
- int doLogin();\r
+ int doLogin(unsigned int* v_server,unsigned int* v_client);\r
bool getRecordingsList(RecMan* recman);\r
RecInfo* getRecInfo(char* fileName);\r
int deleteRecording(char* fileName);\r
else if (m->message == Message::AUDIO_CHANGE_CHANNEL)\r
{\r
Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change audio channel to %i", m->parameter);\r
- player->setAudioChannel((m->parameter & 0xFFFF),(m->parameter & 0xFF0000)>>16);\r
+ player->setAudioChannel((m->parameter & 0xFFFF),(m->parameter & 0xFF0000)>>16,(m->parameter & 0xFF000000)>>24);\r
} \r
else if (m->message == Message::SUBTITLE_CHANGE_CHANNEL)\r
{\r
else if (m->message == Message::AUDIO_CHANGE_CHANNEL)\r
{\r
Log::getInstance()->log("VVideoRec", Log::DEBUG, "Received change audio channel to %i", m->parameter);\r
- player->setAudioChannel(m->parameter&0xFFFF,(m->parameter&0xFF0000)>> 16 );\r
+ player->setAudioChannel(m->parameter&0xFFFF,(m->parameter&0xFF0000)>> 16,(m->parameter&0xFF000000)>> 24 );\r
}\r
else if (m->message == Message::SUBTITLE_CHANGE_CHANNEL)\r
{\r
subtitleChannel, subtitleType, myRec->recInfo);\r
} else {\r
// Draw the selector\r
- Channel temp_channel=player->getDemuxerChannel();\r
- RecInfo *cur_info= myRec->recInfo;\r
- unsigned char numchan_recinfo = cur_info->numComponents;\r
+ Channel *temp_channel=player->getDemuxerChannel();\r
+ // RecInfo *cur_info= myRec->recInfo;\r
+ /* unsigned char numchan_recinfo = cur_info->numComponents;\r
unsigned char numchan_subtitles_siz = temp_channel.numSPids;\r
ULONG mp_audcounter = 0;\r
ULONG ac3_counter = 0;\r
- int dvb_subcounter = 1;\r
+ int dvb_subcounter = 1;*/\r
+ int i;\r
\r
- unsigned char type;\r
+ /*unsigned char type;\r
char* lang;\r
char* description;\r
- int i;\r
for (i = 0; i < numchan_recinfo; i++)\r
{ \r
apid* ac = NULL;\r
\r
}\r
}\r
- }\r
- for (i=0;i<temp_channel.numAPids;i++) {\r
- apid *ac=&temp_channel.apids[i];\r
- if (ac->name==NULL) {\r
- ac->name = new char[strlen(tr("unknown")) + 1];\r
- strcpy(ac->name, tr("unknown"));\r
+ }*/\r
+ for (i=0;i<temp_channel->numAPids;i++) {\r
+ apid *ac=&temp_channel->apids[i];\r
+ if (ac->desc[0]==0) {\r
+ strncpy(ac->desc, tr("unknown"),9);\r
}\r
}\r
- for (i=0;i<temp_channel.numDPids;i++) {\r
- apid *ac=&temp_channel.dpids[i];\r
- if (ac->name==NULL) {\r
- ac->name = new char[strlen(tr("unknown")) + 1];\r
- strcpy(ac->name, tr("unknown"));\r
+ for (i=0;i<temp_channel->numDPids;i++) {\r
+ apid *ac=&temp_channel->dpids[i];\r
+ if (ac->desc[0]==0) {\r
+ strncpy(ac->desc, tr("unknown"),9);\r
}\r
}\r
- for (i=0;i<temp_channel.numSPids;i++) {\r
- apid *ac=&temp_channel.spids[i];\r
- if (ac->name==NULL) {\r
- ac->name = new char[strlen(tr("unknown")) + 1];\r
- strcpy(ac->name, tr("unknown"));\r
+ for (i=0;i<temp_channel->numSPids;i++) {\r
+ apid *ac=&temp_channel->spids[i];\r
+ if (ac->desc[0]==0) {\r
+ strncpy(ac->desc, tr("unknown"),9);\r
}\r
}\r
\r
- vas = new VAudioSelector(this,&temp_channel , (player)->getCurrentAudioChannel(),\r
+ vas = new VAudioSelector(this,temp_channel , (player)->getCurrentAudioChannel(),\r
subtitleType,subtitleChannel,player->getTeletxtSubtitlePages()); \r
- for (i=0;i<temp_channel.numAPids;i++) {\r
+ /* for (i=0;i<temp_channel.numAPids;i++) {\r
apid *ac=&temp_channel.apids[i];\r
delete[] ac->name;\r
ac->name=NULL;\r
apid *ac=&temp_channel.spids[i];\r
delete[] ac->name;\r
ac->name=NULL;\r
- }\r
+ }*/\r
}\r
\r
\r