libtriple: improve audio stream handling in cPlayback()

use a c++ map instead of arrays to store audio stream data
Side effect: audio streams as returned by findAllPids() are now
sorted by pid, helping default selection for MPEG and VDR streams
This commit is contained in:
Stefan Seyfried
2011-05-15 12:32:01 +02:00
parent 8d7c705587
commit 9222f4d5dc
2 changed files with 44 additions and 63 deletions

View File

@@ -76,9 +76,7 @@ bool cPlayback::Open(playmode_t mode)
playback_speed = 0; playback_speed = 0;
last_size = 0; last_size = 0;
_pts_end = 0; _pts_end = 0;
numpida = 0; astreams.clear();
memset(&apids, 0, sizeof(apids));
memset(&ac3flags, 0, sizeof(ac3flags));
memset(&cc, 0, 256); memset(&cc, 0, 256);
return true; return true;
} }
@@ -311,13 +309,13 @@ void cPlayback::playthread(void)
break; break;
/* autoselect PID for PLAYMODE_FILE */ /* autoselect PID for PLAYMODE_FILE */
if (apid == 0 && numpida > 0) if (apid == 0 && astreams.size() > 0)
{ {
for (int i = 0; i < numpida; i++) for (std::map<uint16_t, AStream>::iterator aI = astreams.begin(); aI != astreams.end(); aI++)
{ {
if (ac3flags[i] == 0) if (!aI->second.ac3)
{ {
apid = apids[i]; apid = aI->first;
lt_info("%s setting Audio pid to 0x%04hx\n", __FUNCTION__, apid); lt_info("%s setting Audio pid to 0x%04hx\n", __FUNCTION__, apid);
SetAPid(apid, 0); SetAPid(apid, 0);
break; break;
@@ -543,13 +541,20 @@ bool cPlayback::SetPosition(int position, bool absolute)
return ret; return ret;
} }
void cPlayback::FindAllPids(uint16_t *_apids, unsigned short *_ac3flags, uint16_t *_numpida, std::string *language) void cPlayback::FindAllPids(uint16_t *apids, unsigned short *ac3flags, uint16_t *numpida, std::string *language)
{ {
lt_info("%s\n", __FUNCTION__); lt_info("%s\n", __FUNCTION__);
memcpy(_apids, &apids, sizeof(apids)); int i = 0;
memcpy(_ac3flags, &ac3flags, sizeof(&ac3flags)); for (std::map<uint16_t, AStream>::iterator aI = astreams.begin(); aI != astreams.end(); aI++)
language = alang; /* TODO: language */ {
*_numpida = numpida; apids[i] = aI->first;
ac3flags[i] = aI->second.ac3 ? 1 : 0;
language[i] = aI->second.lang;
i++;
if (i > 10) /* REC_MAX_APIDS in vcrcontrol.h */
break;
}
*numpida = i;
} }
off_t cPlayback::seek_to_pts(int64_t pts) off_t cPlayback::seek_to_pts(int64_t pts)
@@ -919,8 +924,7 @@ ssize_t cPlayback::read_ts()
} }
/* check for A/V PIDs */ /* check for A/V PIDs */
uint16_t pid; uint16_t pid;
int i, j; int i;
bool pid_new;
int64_t pts; int64_t pts;
//fprintf(stderr, "inbuf_pos: %ld - sync: %ld, inbuf_syc: %ld\n", (long)inbuf_pos, (long)sync, (long)inbuf_sync); //fprintf(stderr, "inbuf_pos: %ld - sync: %ld, inbuf_syc: %ld\n", (long)inbuf_pos, (long)sync, (long)inbuf_sync);
int synccnt = 0; int synccnt = 0;
@@ -944,7 +948,6 @@ ssize_t cPlayback::read_ts()
if (buf[3] & 0x20) /* adaptation field? */ if (buf[3] & 0x20) /* adaptation field? */
off = buf[4] + 1; off = buf[4] + 1;
pid = get_pid(buf + 1); pid = get_pid(buf + 1);
pid_new = true;
/* PES signature is at buf + 4, streamtype is after 00 00 01 */ /* PES signature is at buf + 4, streamtype is after 00 00 01 */
switch (buf[4 + 3 + off]) switch (buf[4 + 3 + off])
{ {
@@ -979,28 +982,20 @@ ssize_t cPlayback::read_ts()
break; break;
case 0xbd: /* private stream 1 - ac3 */ case 0xbd: /* private stream 1 - ac3 */
case 0xc0 ... 0xdf: /* audio stream */ case 0xc0 ... 0xdf: /* audio stream */
if (numpida > 9) if (astreams.find(pid) != astreams.end())
break;
for (j = 0; j < numpida; j++) {
if (apids[j] == pid)
{
pid_new = false;
break;
}
}
if (!pid_new)
break; break;
AStream tmp;
if (buf[7 + off] == 0xbd) if (buf[7 + off] == 0xbd)
{ {
if (buf[12 + off] == 0x24) /* 0x24 == TTX */ if (buf[12 + off] == 0x24) /* 0x24 == TTX */
break; break;
ac3flags[numpida] = 1; tmp.ac3 = true;
} }
else else
ac3flags[numpida] = 0; tmp.ac3 = false;
apids[numpida] = pid; tmp.lang = "";
lt_info("%s found apid #%d 0x%04hx ac3:%d\n", __FUNCTION__, numpida, pid, ac3flags[numpida]); astreams.insert(std::make_pair(pid, tmp));
numpida++; lt_info("%s found apid #%d 0x%04hx ac3:%d\n", __func__, astreams.size(), pid, tmp.ac3);
break; break;
} }
i += 188; i += 188;
@@ -1046,7 +1041,6 @@ ssize_t cPlayback::read_mpeg()
curr_pos += ret; curr_pos += ret;
pthread_mutex_unlock(&currpos_mutex); pthread_mutex_unlock(&currpos_mutex);
int i;
int count = 0; int count = 0;
uint16_t pid = 0; uint16_t pid = 0;
bool resync = true; bool resync = true;
@@ -1096,28 +1090,19 @@ ssize_t cPlayback::read_mpeg()
int off = ppes[8] + 8 + 1; // ppes[8] is often 0 int off = ppes[8] + 8 + 1; // ppes[8] is often 0
if (count + off >= pesbuf_pos) if (count + off >= pesbuf_pos)
break; break;
int subid = ppes[off]; uint16_t subid = ppes[off];
// if (offset == 0x24 && subid == 0x10 ) // TTX? // if (offset == 0x24 && subid == 0x10 ) // TTX?
if (subid < 0x80 || subid > 0x87) if (subid < 0x80 || subid > 0x87)
break; break;
lt_debug("AC3: ofs 0x%02x subid 0x%02x\n", off, subid); lt_debug("AC3: ofs 0x%02x subid 0x%02x\n", off, subid);
//subid -= 0x60; // normalize to 32...39 (hex 0x20..0x27) //subid -= 0x60; // normalize to 32...39 (hex 0x20..0x27)
if (numpida > 9) if (astreams.find(subid) == astreams.end())
break;
bool found = false;
for (i = 0; i < numpida; i++) {
if (apids[i] == subid)
{
found = true;
break;
}
}
if (!found)
{ {
apids[numpida] = subid; AStream tmp;
ac3flags[numpida] = 1; tmp.ac3 = true;
numpida++; tmp.lang = "";
astreams.insert(std::make_pair(subid, tmp));
lt_info("%s found aid: %02x\n", __FUNCTION__, subid); lt_info("%s found aid: %02x\n", __FUNCTION__, subid);
} }
pid = subid; pid = subid;
@@ -1136,20 +1121,13 @@ ssize_t cPlayback::read_mpeg()
case 0xd0 ... 0xdf: case 0xd0 ... 0xdf:
{ {
// fprintf(stderr, "audio stream 0x%02x\n", ppes[3]); // fprintf(stderr, "audio stream 0x%02x\n", ppes[3]);
int id = ppes[3]; // - 0xC0; // normalize to 0...31 (hex 0x0...0x1f) uint16_t id = ppes[3];
bool found = false; if (astreams.find(id) == astreams.end())
for (i = 0; i < numpida; i++) {
if (apids[i] == id)
{
found = true;
break;
}
}
if (!found)
{ {
apids[numpida] = id; AStream tmp;
ac3flags[numpida] = 0; tmp.ac3 = false;
numpida++; tmp.lang = "";
astreams.insert(std::make_pair(id, tmp));
lt_info("%s found aid: %02x\n", __FUNCTION__, id); lt_info("%s found aid: %02x\n", __FUNCTION__, id);
} }
pid = id; pid = id;

View File

@@ -3,6 +3,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <string> #include <string>
#include <map>
#include <vector> #include <vector>
/* almost 256kB */ /* almost 256kB */
@@ -70,10 +71,12 @@ class cPlayback
uint16_t vpid; uint16_t vpid;
uint16_t apid; uint16_t apid;
bool ac3; bool ac3;
uint16_t apids[10]; struct AStream {
unsigned short ac3flags[10]; // uint16_t pid;
std::string alang[10]; bool ac3;
uint16_t numpida; std::string lang; /* not yet really used */
};
std::map<uint16_t, AStream> astreams; /* stores AStream sorted by pid */
int64_t pts_start; int64_t pts_start;
int64_t pts_end; int64_t pts_end;