#include "demuxerts.h"
#include "log.h"
+#include "video.h"
+#include "vdr.h"
+
+#define PTS_JUMP_MARGIN 10000
+#define PTS_ALLOWANCE 90000
+
+// TODO: PTS class to handle wrapping arithmetic & comparisons?
+static ULLONG PTSDistance(ULLONG pts1, ULLONG pts2)
+{
+ // Assume pts1, pts2 < 2^33; calculate shortest distance between
+ ULLONG ret = (pts1 > pts2) ? pts1 - pts2 : pts2 - pts1;
+ if (ret > (1LL<<32)) ret = (1LL<<33) - ret;
+ return ret;
+}
+
+static ULLONG PTSDifference(ULLONG pts1, ULLONG pts2)
+{
+ // Assume pts1, pts2 < 2^33; calculate pts1 - pts2
+ if (pts1 > pts2)
+ return pts1 - pts2;
+ else
+ return (1LL<<33) + pts1 - pts2;
+}
DemuxerTS::DemuxerTS(int p_vID, int p_aID, int p_subID, int p_tID)
{
atype = 0;
subLength = 0;
tID = p_tID;
+ havechannelinfo=false;
}
void DemuxerTS::flush()
{
partPacket = 0;
parsed = false;
+ havechannelinfo=false;
Demuxer::flush();
vPacket.init(PESTYPE_VID0);
switch (atype)
}
-int DemuxerTS::findPTS(UCHAR* buf, int len, ULLONG* dest)
-{
- UINT LoPattern = 0x100 | PESTYPE_VID0,
- HiPattern = 0x100 | PESTYPE_VIDMAX;
- while (len >= 14)
- {
- UINT pattern = *(UINT*)buf;
- buf++; len--;
- if (pattern < LoPattern || pattern > HiPattern) continue;
- UINT framelength = ((UINT)buf[3] << 8) | buf[4];
- buf += 5; len -= 5;
- if ( buf[1] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
- {
- *dest = ( (ULLONG)(buf[3] & 0x0E) << 29 ) |
- ( (ULLONG)(buf[4]) << 22 ) |
- ( (ULLONG)(buf[5] & 0xFE) << 14 ) |
- ( (ULLONG)(buf[6]) << 7 ) |
- ( (ULLONG)(buf[7] & 0xFE) >> 1 );
- return 1;
- }
+int DemuxerTS::findPTS(UCHAR* buf, int len, ULLONG* dest)
+{
+ int scanaid=0;
- buf += framelength; len -= framelength;
+ while (len >= TS_SIZE)
+ {
+ if (*buf != TS_SIG) {buf++;len--; continue;}
+
+ //Pattern scanning won't work for ts
+
+
+ int datalen = TS_SIZE - 4;
+ int pid = ( (buf[1] & 0x1F) << 8 ) | buf[2];
+ UCHAR payload = buf[1] & 0x40;
+
+ if (buf[3] & 0x20) // Adaptation field is present
+ datalen -= (buf[4] + 1);
+
+ UCHAR* curbuf =buf+ (TS_SIZE - datalen);
+
+
+ if (payload) {
+ if (pid == 0x00) {//PAT, only take first program number, ignore the rest
+ int pmtpid = (*(curbuf+11)<< 8) | *(curbuf+12);
+ if ((pmtpid >> 13) != 0x07)
+ {
+ Log::getInstance()->log("findPTS", Log::DEBUG, "PMTPID=%02x %02x TRAILING 111 not set but %x", *(curbuf+11),*(curbuf+12), (pmtpid >> 13));
+ }
+ else
+ {
+ pmtpid = pmtpid & 0x1FFF; //clear upper 3 bits
+ PMTPID = pmtpid;
+ }
+
+ } else if (pid == PMTPID) { //PMT
+ int sectionlength = ((*(curbuf+2) << 8) & 0x0F ) | *(buf+3);
+ //sectionlength += 4; //include header but subtract crc in the end...
+ int p = 13; //skip fixed part of pmt
+ while ( p < sectionlength) {
+ int streamtype = *(curbuf+p);
+ p++;
+ int foundpid = (*(curbuf+p)<< 8) | *(curbuf+p+1);
+ p += 2; //skip ES Pid
+ int eslength = ((*(curbuf+p) << 8) & 0x0F ) | *(curbuf+p+1);
+ p += 2; //skip ES length
+ if ((foundpid >> 13) != 0x07)
+ {
+ Log::getInstance()->log("findPTS", Log::DEBUG, "FOUNDPID=%02x %02x TRAILING 111 not set but %x", *(buf+p),*(buf+p+1), (foundpid >> 13));
+ }
+ else
+ {
+ foundpid = foundpid & 0x1FFF; //clear upper 3 bits
+ int pos=0;
+ if (streamtype==3 || streamtype ==4) {
+ scanaid=foundpid;
+ }
+ }
+ p += eslength; //skip es descriptor
+ }
+ } else if (pid == scanaid) {
+ UINT framelength = ((UINT)curbuf[4] << 8) | curbuf[5];
+
+ if ( curbuf[7] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
+ {
+ *dest = ( (ULLONG)(curbuf[9] & 0x0E) << 29 ) |
+ ( (ULLONG)(curbuf[10]) << 22 ) |
+ ( (ULLONG)(curbuf[11] & 0xFE) << 14 ) |
+ ( (ULLONG)(curbuf[12]) << 7 ) |
+ ( (ULLONG)(curbuf[13] & 0xFE) >> 1 );
+ return 1;
+ }
+ }
+ }
+ len-=TS_SIZE;
+ buf+=TS_SIZE;
}
// No PTS found.
return 0;
}
+void DemuxerTS::setFrameNum(ULONG frame)
+{
+ frameCounting = true;
+ frameNumber = frame;
+ Log::getInstance()->log("DemuxerTS", Log::DEBUG, "setFrameNum %d", frame);
+}
+
+void DemuxerTS::setPacketNum(ULONG npacket)
+{
+ packetCounting = true;
+ packetNumber = npacket;
+ Log::getInstance()->log("DemuxerTS", Log::DEBUG, "setPacketNum %d", npacket);
+}
+
+
int DemuxerTS::put(UCHAR* buf, int len)
{
int ret = 0; // return number of bytes consumed
int DemuxerTS::processTS(UCHAR* buf)
{
int datalen = TS_SIZE - 4;
+
int pid = ( (buf[1] & 0x1F) << 8 ) | buf[2];
UCHAR payload = buf[1] & 0x40;
if (payload)
{
- int rc = 1;
+ int rc = 1;
+ if (pid == 0x00) {//PAT, only take first program number, ignore the rest
+ int pmtpid = (*(buf+11)<< 8) | *(buf+12);
+ if ((pmtpid >> 13) != 0x07)
+ {
+ Log::getInstance()->log("ProcessTS", Log::DEBUG, "PMTPID=%02x %02x TRAILING 111 not set but %x", *(buf+11),*(buf+12), (pmtpid >> 13));
+ }
+ else
+ {
+ pmtpid = pmtpid & 0x1FFF; //clear upper 3 bits
+ PMTPID = pmtpid;
+ }
+ return 1;
+ }
+ if (pid == PMTPID)
+ { //PMT
+ int sectionlength = ((*(buf+2) << 8) & 0x0F ) | *(buf+3);
+ //sectionlength += 4; //include header but subtract crc in the end...
+ int p = 13; //skip fixed part of pmt
+ Channel new_channelinfo;
+ new_channelinfo.numAPids=0;
+ new_channelinfo.numDPids=0;
+ new_channelinfo.numSPids=0;
+ new_channelinfo.number=0;
+ new_channelinfo.type=VDR::RADIO;
+ new_channelinfo.name=NULL;
+ new_channelinfo.tpid=0xFFFFF; //unused, check this
+ new_channelinfo.vpid=0xFFFFF; //unused, check this
+ new_channelinfo.index=NULL;
+
+ new_channelinfo.apids.clear();
+ new_channelinfo.dpids.clear();
+ new_channelinfo.spids.clear();
+
+ while ( p < sectionlength) {
+ int streamtype = *(buf+p);
+ p++;
+ int foundpid = (*(buf+p)<< 8) | *(buf+p+1);
+ p += 2; //skip ES Pid
+ int eslength = ((*(buf+p) << 8) & 0x0F ) | *(buf+p+1);
+ p += 2; //skip ES length
+ if ((foundpid >> 13) != 0x07)
+ {
+ Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDPID=%02x %02x TRAILING 111 not set but %x", *(buf+p),*(buf+p+1), (foundpid >> 13));
+ }
+ else
+ {
+ foundpid = foundpid & 0x1FFF; //clear upper 3 bits
+ bool notfound=false;
+ int pos=0;
+ // Log::getInstance()->log("ProcessTS", Log::DEBUG, "FOUNDPID is %x", foundpid);
+ switch (streamtype)
+ {
+ // case 0x1B: //MPEG 4 for future use
+ case 1:
+ case 2: { //video
+ if (foundpid != getVID())
+ setVID(foundpid);
+ new_channelinfo.type=VDR::VIDEO;
+ new_channelinfo.vpid=foundpid;
+
+ // Log::getInstance()->log("ProcessTS", Log::DEBUG, "Set video PID to %x", foundpid);
+ }break;
+ case 3:
+ case 4: { //audio
+ apid newapid;
+ newapid.pid = foundpid;
+ newapid.name = NULL; //set it in player
+ new_channelinfo.apids.push_back(newapid);
+ new_channelinfo.numAPids++;
+ if (getAID() == 0) { //set unset AID to first audio pid that reports itself
+ setAID(foundpid,0);
+ Log::getInstance()->log("ProcessTS", Log::DEBUG, "Set audio PID to %x", foundpid);
+ }
+ } break;
+ case 5:
+ case 6: { //Private Data
+ apid newapid;
+ newapid.pid = foundpid;
+ newapid.name = NULL; //set it in player
+ pos=0;
+ notfound=true;
+
+ while (pos< eslength && notfound) {
+ switch (buf[p+pos]) {
+ case 0x6A: {//Ac3 descriptor
+ new_channelinfo.dpids.push_back(newapid);
+ new_channelinfo.numDPids++;
+ notfound=false;
+ } break;
+ case 0x59: {//SubtitlingDescriptor
+ new_channelinfo.spids.push_back(newapid);
+ new_channelinfo.numSPids++;
+ notfound=false;
+ } break;
+ case 0x56: {
+ new_channelinfo.tpid=foundpid;
+ notfound=false;
+ } break;
+ };
+ pos+=2+buf[p+pos+1];
+ }
+
+ } break;
+ default://TODO how about subtitles and second audio pids
+ break;
+ }
+ }
+
+ p += eslength; //skip es descriptor
+
+
+ }
+ bool audioPIDpresent=false; //Check if pids chnages
+ int i;
+ for (i=0;i<channelinfo.numAPids;i++) {
+ if (aID ==channelinfo.apids[i].pid) {
+ audioPIDpresent=true;
+ }
+ }
+ for (i=0;i<channelinfo.numDPids && (! audioPIDpresent);i++) {
+ if (aID ==channelinfo.dpids[i].pid) {
+ audioPIDpresent=true;
+ }
+ }
+ if (! audioPIDpresent) {
+ if (channelinfo.numAPids>0) {
+ setAID(channelinfo.apids[0].pid,0);
+ } else if (channelinfo.numDPids>0) {
+ setAID(channelinfo.dpids[0].pid,1);
+ }
+ }
+
+ channelinfo=new_channelinfo;
+ havechannelinfo=true;
+
+ return 1;
+ }
+
+
+
if (pid == vID)
{
{
if (!parsed)
{
- parsePacketDetails(vPacket);
+ parseTSPacketDetails(vPacket);
parsed = true;
}
rc = submitPacket(vPacket);
{
if (!parsed)
{
- parsePacketDetails(aPacket);
+ parseTSPacketDetails(aPacket);
parsed = true;
}
rc = submitPacket(aPacket);
{
if (!parsed)
{
- parsePacketDetails(subPacket);
+ parseTSPacketDetails(subPacket);
parsed = true;
}
rc = submitPacket(subPacket);
{
if (!parsed)
{
- parsePacketDetails(tPacket);
+ parseTSPacketDetails(tPacket);
parsed = true;
}
rc = submitPacket(tPacket);
{ // Writing to packet failed. It has overflowed.
if (!parsed)
{
- parsePacketDetails(*packet);
+ parseTSPacketDetails(*packet);
parsed = true;
}
if (submitPacket(*packet) == 0) return 0;
return 1;
}
+
+ULONG DemuxerTS::getPacketNum()
+{
+ return packetNumber;
+}
+
+ULONG DemuxerTS::getFrameNumFromPTS(ULLONG pts)
+{
+ ULLONG difference = (1LL<<33);
+ ULONG ref_frame = 0;
+ int total = 0, actual = 0;
+ pts_map_mutex.Lock();
+ PTSMap::iterator iter = pts_map.begin();
+ while (iter != pts_map.end())
+ {
+ ++total;
+ if (PTSDifference(iter->pts, pts) < PTS_ALLOWANCE)
+ {
+ difference = 0;
+ ref_frame = iter->frame;
+ actual = total;
+ break;
+ }
+ ULLONG newdiff = PTSDifference(pts, iter->pts);
+ if (newdiff < difference)
+ {
+ difference = newdiff;
+ ref_frame = iter->frame;
+ actual = total;
+ }
+ ++iter;
+ }
+ if (total > 1 && actual == 1) // We are using the most recent PTS ref.
+ { // Delete the rest.
+ iter = pts_map.begin(); iter++;
+ pts_map.erase(iter, pts_map.end());
+ }
+ pts_map_mutex.Unlock();
+
+ if (difference == (1LL<<33))
+ return 0; // We cannot make sense of the pts
+ else
+ return ref_frame + difference * Video::getInstance()->getFPS() / 90000;
+}
+
+
+void DemuxerTS::parseTSPacketDetails(PESPacket packet) // Only important stuff for paket counting reminas
+{
+ parsePacketDetails(packet);
+ if (packetCounting && packet.getPacketType() >= PESTYPE_AUD0 &&
+ packet.getPacketType() <= PESTYPE_AUDMAX)
+ {
+ packetNumber++;
+ }
+
+ if (frameCounting && packet.findPictureHeader() &&
+ packet.getPacketType() >= PESTYPE_VID0 &&
+ packet.getPacketType() <= PESTYPE_VIDMAX)
+ {
+ ULONG frame_num = (frameNumber)++;
+ if (packet.findSeqHeader() > 1 && packet.hasPTS())
+ {
+ PTSMapEntry me;
+ pts_map_mutex.Lock();
+ if (pts_map.empty())
+ {
+ me.pts = packet.getPTS();
+ me.frame = frame_num;
+ pts_map_mutex.Unlock();
+ pts_map_mutex.Lock();
+ pts_map.push_front(me);
+ }
+ me = pts_map.front();
+ pts_map_mutex.Unlock();
+
+ UINT fps = Video::getInstance()->getFPS();
+ ULLONG pts_expected = me.pts + 90000*(frame_num - me.frame) / fps;
+ while (pts_expected > (1LL<<33)) pts_expected -= (1LL<<33);
+
+ if (PTSDistance(pts_expected, packet.getPTS()) > PTS_JUMP_MARGIN) // PTS jump!
+ {
+ me.pts = packet.getPTS();
+ me.frame = frame_num;
+ pts_map_mutex.Lock();
+ pts_map.push_front(me);
+ pts_map_mutex.Unlock();
+ }
+ }
+ }
+}
+
+
+bool DemuxerTS::scanForVideo(UCHAR* buf, UINT len)
+{
+ int pmtpidy=0;
+
+ while (len >= TS_SIZE)
+ {
+ if (*buf != TS_SIG) {buf++;len--; continue;}
+
+ //Pattern scanning won't work for ts
+
+
+ int datalen = TS_SIZE - 4;
+ int pid = ( (buf[1] & 0x1F) << 8 ) | buf[2];
+ UCHAR payload = buf[1] & 0x40;
+
+ if (buf[3] & 0x20) // Adaptation field is present
+ datalen -= (buf[4] + 1);
+
+ UCHAR* curbuf =buf+ (TS_SIZE - datalen);
+
+ if (payload) {
+ if (pid == 0x00) {//PAT, only take first program number, ignore the rest
+ int pmtpid = (*(curbuf+11)<< 8) | *(curbuf+12);
+ if ((pmtpid >> 13) != 0x07)
+ {
+ Log::getInstance()->log("findPTS", Log::DEBUG, "PMTPID=%02x %02x TRAILING 111 not set but %x", *(curbuf+11),*(curbuf+12), (pmtpid >> 13));
+ }
+ else
+ {
+ pmtpid = pmtpid & 0x1FFF; //clear upper 3 bits
+ pmtpidy = pmtpid;
+ }
+
+ } else if (pid == pmtpidy) { //PMT
+ int sectionlength = ((*(curbuf+2) << 8) & 0x0F ) | *(buf+3);
+ //sectionlength += 4; //include header but subtract crc in the end...
+ int p = 13; //skip fixed part of pmt
+ while ( p < sectionlength) {
+ int streamtype = *(curbuf+p);
+ p++;
+ int foundpid = (*(curbuf+p)<< 8) | *(curbuf+p+1);
+ p += 2; //skip ES Pid
+ int eslength = ((*(curbuf+p) << 8) & 0x0F ) | *(curbuf+p+1);
+ p += 2; //skip ES length
+ if ((foundpid >> 13) != 0x07)
+ {
+ Log::getInstance()->log("findPTS", Log::DEBUG, "FOUNDPID=%02x %02x TRAILING 111 not set but %x", *(buf+p),*(buf+p+1), (foundpid >> 13));
+ }
+ else
+ {
+ foundpid = foundpid & 0x1FFF; //clear upper 3 bits
+ int pos=0;
+ if (streamtype==1 || streamtype ==2) {
+ return true;
+ }
+ }
+ p += eslength; //skip es descriptor
+ }
+ return false;
+ }
+ }
+ len-=TS_SIZE;
+ buf+=TS_SIZE;
+ }
+ return false;
+}
+
+UINT DemuxerTS::stripAudio(UCHAR* buf, UINT len) //it has to be adapted
+{
+ //This function strips all TS Headers and non video payload
+ UINT readpos=0;
+ UINT writepos=0;
+ PESPacket destpaket;
+ bool started=true;
+ while (readpos < len ) {
+ if (buf[readpos] != TS_SIG) {readpos++; continue;}
+ UINT oldreadpos=readpos;
+
+ int datalen = TS_SIZE - 4;
+ int pid = ( (buf[readpos+1] & 0x1F) << 8 ) | buf[readpos+2];
+ UCHAR payload = buf[readpos+1] & 0x40;
+ if (buf[readpos+3] & 0x20) { // Adaptation field is present
+ datalen -= (buf[readpos+4] + 1);
+ }
+ if (datalen < 0) {// Error in stream TODO log this
+ return 0;
+ }
+ if (datalen == 0) {// Null packet
+ readpos=oldreadpos+TS_SIZE;
+ continue;
+ }
+ readpos += (TS_SIZE - datalen);
+ UINT towrite=min(datalen,len-readpos);
+ if (pid == vID) {
+ if (payload) {
+ if (started) {
+ parsePacketDetails(destpaket);
+ memcpy(buf+writepos,destpaket.getData(),destpaket.getSize());
+ writepos+=destpaket.getSize();
+ }
+ destpaket.init(PESTYPE_VID0);
+ readpos += 6; towrite -= 6;
+ started=true;
+ }
+
+ if (started) {
+ if (!destpaket.write(buf+readpos,towrite)) {
+ parsePacketDetails(destpaket);
+ memcpy(buf+writepos,destpaket.getData(),destpaket.getSize());
+ writepos+=destpaket.getSize();
+ destpaket.truncate();
+ destpaket.write((UCHAR*)"\200\000\000", 3);
+ destpaket.write(buf+readpos,towrite);
+
+ }
+ }
+
+
+
+ }
+ readpos=oldreadpos+TS_SIZE;
+ }
+ parsePacketDetails(destpaket);
+ memcpy(buf+writepos,destpaket.getData(),destpaket.getSize());
+ writepos+=destpaket.getSize();
+
+ return writepos;
+}
+
+
+
#include "bitmap.h"
#include "recinfo.h"
#include "log.h"
+#include "channel.h"
VVideoRec::VVideoRec(Recording* rec)
{
vas = NULL;
vsummary = NULL;
- player = new Player(Command::getInstance(), this, this);
- player->init();
-
videoMode = video->getMode();
myRec = rec;
+ player = new Player(Command::getInstance(), this, this);
+ player->init(myRec->IsPesRecording);
+
playing = false;
startMargin = 0;
Log::getInstance()->log("VVideoRec", Log::DEBUG, "Starting stream: %s at frame: %lu", myRec->getFileName(), startFrameNum);
ULONG lengthFrames = 0;
- ULLONG lengthBytes = vdr->streamRecording(myRec->getFileName(), &lengthFrames);
+ bool isPesRecording;
+ ULLONG lengthBytes = vdr->streamRecording(myRec->getFileName(), &lengthFrames, &isPesRecording);
+ myRec->IsPesRecording = isPesRecording;
if (lengthBytes)
{
player->setLengthBytes(lengthBytes);
void VVideoRec::doAudioSelector()
{
- bool* availableMpegAudioChannels = player->getDemuxerMpegAudioChannels();
- bool* availableAc3AudioChannels = NULL;
- bool* availableSubtitleChannels = player->getDemuxerSubtitleChannels();
- int *availableTTxtpages = player->getTeletxtSubtitlePages();
- int currentAudioChannel = player->getCurrentAudioChannel();
- if (Audio::getInstance()->supportsAc3())
- {
- availableAc3AudioChannels = player->getDemuxerAc3AudioChannels();
- }
- int subtitleChannel=player->getCurrentSubtitleChannel();
- int subtitleType=0x10;
- if (!(player)->isSubtitlesOn()) {
- if ((player)->getTeletextDecoder()->getTeletxtView() &&
- (player)->getTeletextDecoder()->getTeletxtView()->isInSubtitleMode()
- ) {
- subtitleChannel=(player)->getTeletextDecoder()->getPage();
- subtitleType=0x11;
-
- } else {
- subtitleType=0xFF; //turnedOff
- subtitleChannel=0;
- }
- }
+ int subtitleChannel=player->getCurrentSubtitleChannel();
+ int subtitleType=0x10;
+ if (!(player)->isSubtitlesOn()) {
+ if ((player)->getTeletextDecoder()->getTeletxtView() &&
+ (player)->getTeletextDecoder()->getTeletxtView()->isInSubtitleMode()
+ ) {
+ subtitleChannel=(player)->getTeletextDecoder()->getPage();
+ subtitleType=0x11;
+
+ } else {
+ subtitleType=0xFF; //turnedOff
+ subtitleChannel=0;
+ }
+ }
+ if (player->isPesRecording()) {
+ bool* availableMpegAudioChannels = player->getDemuxerMpegAudioChannels();
+ bool* availableAc3AudioChannels = NULL;
+ bool* availableSubtitleChannels = player->getDemuxerSubtitleChannels();
+ int *availableTTxtpages = player->getTeletxtSubtitlePages();
+ int currentAudioChannel = player->getCurrentAudioChannel();
+ if (Audio::getInstance()->supportsAc3())
+ {
+ availableAc3AudioChannels = player->getDemuxerAc3AudioChannels();
+ }
+
+ vas = new VAudioSelector(this, availableMpegAudioChannels, availableAc3AudioChannels, currentAudioChannel,availableSubtitleChannels, availableTTxtpages,
+ subtitleChannel, subtitleType, myRec->recInfo);
+ } else {
+ // Draw the selector
+ Channel temp_channel=player->getDemuxerChannel();
+ RecInfo *cur_info= myRec->recInfo;
+ unsigned char numchan_recinfo = cur_info->numComponents;
+ unsigned char numchan_subtitles_siz = temp_channel.numSPids;
+ int mp_audcounter = 0;
+ int ac3_counter = 0;
+ int dvb_subcounter = 1;
+
+ unsigned char type;
+ char* lang;
+ char* description;
+ int i;
+ for (i = 0; i < numchan_recinfo; i++)
+ {
+ apid *ac=NULL;
+ type = cur_info->types[i];
+ lang = cur_info->languages[i];
+ description = cur_info->descriptions[i];
+
+
+ if (cur_info->streams[i] == 2) {
+ switch (type)
+ {
+ case 1: //mpaudio mono
+ case 3: //mpaudio stereo
+ if (mp_audcounter < temp_channel.numAPids) ac = &temp_channel.apids[mp_audcounter];
+
+ mp_audcounter++;
+ break;
+ case 5: //ac3
+ if (ac3_counter < temp_channel.numDPids) ac = &temp_channel.dpids[ac3_counter];
+ ac3_counter++;
+ break;
+ }
+ } else if (cur_info->streams[i] == 3){
+ if (dvb_subcounter < numchan_subtitles_siz) ac = &temp_channel.spids[dvb_subcounter];
+ } else continue; //neither audio nor subtitle
+ if (ac)
+ {
+ if (description && (strlen(description) > 0))
+ {
+ ac->name = new char[strlen(description) + 1];
+ strcpy(ac->name, description);
+
+ } else if (lang && strlen(lang) > 0)
+ {
+ ac->name = new char[strlen(lang) + 1];
+ strcpy(ac->name, lang);
+
+ }
+ }
+ }
+ for (i=0;i<temp_channel.numAPids;i++) {
+ apid *ac=&temp_channel.apids[i];
+ if (ac->name==NULL) {
+ ac->name = new char[strlen(tr("unknown")) + 1];
+ strcpy(ac->name, tr("unknown"));
+ }
+ }
+ for (i=0;i<temp_channel.numDPids;i++) {
+ apid *ac=&temp_channel.dpids[i];
+ if (ac->name==NULL) {
+ ac->name = new char[strlen(tr("unknown")) + 1];
+ strcpy(ac->name, tr("unknown"));
+ }
+ }
+ for (i=0;i<temp_channel.numSPids;i++) {
+ apid *ac=&temp_channel.spids[i];
+ if (ac->name==NULL) {
+ ac->name = new char[strlen(tr("unknown")) + 1];
+ strcpy(ac->name, tr("unknown"));
+ }
+ }
+
+ vas = new VAudioSelector(this,&temp_channel , (player)->getCurrentAudioChannel(),
+ subtitleType,subtitleChannel,player->getTeletxtSubtitlePages());
+ for (i=0;i<temp_channel.numAPids;i++) {
+ apid *ac=&temp_channel.apids[i];
+ delete[] ac->name;
+ ac->name=NULL;
+ }
+ for (i=0;i<temp_channel.numDPids;i++) {
+ apid *ac=&temp_channel.dpids[i];
+ delete[] ac->name;
+ ac->name=NULL;
+ }
+ for (i=0;i<temp_channel.numSPids;i++) {
+ apid *ac=&temp_channel.spids[i];
+ delete[] ac->name;
+ ac->name=NULL;
+ }
+ }
- vas = new VAudioSelector(this, availableMpegAudioChannels, availableAc3AudioChannels, currentAudioChannel,availableSubtitleChannels, availableTTxtpages,
- subtitleChannel, subtitleType, myRec->recInfo);
vas->setBackgroundColour(barBlue);
vas->setPosition(0, barRegion.y - 120);