libtriple: implement fast forward in cPlayback()

First try at implementing fast forward. Needs more love.
Reverse does not work yet, setting speed to negative values
right now simply resets to "play" mode.
This commit is contained in:
Stefan Seyfried
2010-08-14 16:10:45 +02:00
parent 8542cd14aa
commit fe6666cda7
3 changed files with 138 additions and 27 deletions

View File

@@ -329,15 +329,30 @@ bool cPlayback::SetAPid(unsigned short pid, bool _ac3)
bool cPlayback::SetSpeed(int speed) bool cPlayback::SetSpeed(int speed)
{ {
INFO("speed = %d\n", speed); INFO("speed = %d\n", speed);
if (speed != 0 && playback_speed == 0) if (speed < 0)
speed = 1; /* fast rewind not yet implemented... */
if (speed == 1 && playback_speed != 1)
{
if (playback_speed == 0)
{ {
videoDemux->Stop(); videoDemux->Stop();
videoDemux->Start(); videoDemux->Start();
audioDemux->Start(); audioDemux->Start();
}
else
{
audioDecoder->Stop();
videoDecoder->Stop();
}
audioDecoder->Start(); audioDecoder->Start();
videoDecoder->Start(); videoDecoder->Start();
playstate = STATE_PLAY; playstate = STATE_PLAY;
} }
if (playback_speed == 1 && speed > 1)
{
audioDecoder->mute(false);
videoDecoder->FastForwardMode();
}
playback_speed = speed; playback_speed = speed;
if (playback_speed == 0) if (playback_speed == 0)
{ {
@@ -698,9 +713,97 @@ ssize_t cPlayback::read_ts()
ssize_t toread, ret = 0, sync, off; ssize_t toread, ret = 0, sync, off;
toread = INBUF_SIZE - inbuf_pos; toread = INBUF_SIZE - inbuf_pos;
bool retry = true; bool retry = true;
uint8_t *buf;
/* fprintf(stderr, "%s:%d curr_pos %lld, inbuf_pos: %ld, toread: %ld\n", /* fprintf(stderr, "%s:%d curr_pos %lld, inbuf_pos: %ld, toread: %ld\n",
__FUNCTION__, __LINE__, (long long)curr_pos, (long)inbuf_pos, (long)toread); */ __FUNCTION__, __LINE__, (long long)curr_pos, (long)inbuf_pos, (long)toread); */
if (playback_speed > 1)
{
sync = 0;
ssize_t tmpread = PESBUF_SIZE / 188 * 188;
int n, skipped = 0;
bool skip = false;
bool eof = true;
while (toread > 0)
{
ssize_t done = 0;
while (done < tmpread)
{
ret = read(in_fd, pesbuf, tmpread - done);
if (ret == 0 && retry) /* EOF */
{
mf_lseek(curr_pos);
retry = false;
continue;
}
if (ret < 0)
{
INFO("failed: %m\n");
return ret;
}
if (ret == 0 && eof)
goto out;
eof = false;
done += ret;
curr_pos += ret;
}
sync = sync_ts(pesbuf, ret);
if (sync != 0)
{
INFO("out of sync: %d\n", sync);
if (sync < 0)
{
return -1;
}
memmove(pesbuf, pesbuf + sync, ret - sync);
if (pesbuf[0] != 0x47)
INFO("??????????????????????????????\n");
}
for (n = 0; n < done / 188 * 188; n += 188)
{
buf = pesbuf + n;
if (buf[1] & 0x40) // PUSI
{
/* only video packets... */
int of = 4;
if (buf[3] & 0x20) // adaptation field
of += buf[4] + 1;
if ((buf[of + 3] & 0xF0) == 0xE0 && // Video stream
buf[of + 2] == 0x01 && buf[of + 1] == 0x00 && buf[of] == 0x00) // PES
{
skip = true;
skipped++;
if (skipped >= playback_speed)
{
skipped = 0;
skip = false;
}
}
}
if (! skip)
{
memcpy(inbuf + inbuf_pos, buf, 188);
inbuf_pos += 188;
toread -= 188;
if (toread <= 0)
{
/* the output buffer is full, discard the input :-( */
if (done - n > 0)
{
DBG("not done: %d, resetting filepos\n", done - n);
mf_lseek(curr_pos - (done - n));
}
break;
}
}
}
}
out:
if (eof)
return 0;
}
else
{
while(true) while(true)
{ {
ret = read(in_fd, inbuf + inbuf_pos, toread); ret = read(in_fd, inbuf + inbuf_pos, toread);
@@ -729,15 +832,16 @@ ssize_t cPlayback::read_ts()
return ret; return ret;
} }
inbuf_sync += sync; inbuf_sync += sync;
}
/* check for A/V PIDs */ /* check for A/V PIDs */
uint16_t pid; uint16_t pid;
int i, j; int i, j;
bool pid_new; bool pid_new;
int64_t pts; int64_t pts;
// fprintf(stderr, "inbuf_pos: %ld - sync: %ld\n", (long)inbuf_pos, (long)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;
for (i = 0; i < inbuf_pos - inbuf_sync - 13;) { for (i = 0; i < inbuf_pos - inbuf_sync - 13;) {
uint8_t *buf = inbuf + inbuf_sync + i; buf = inbuf + inbuf_sync + i;
if (*buf != 0x47) if (*buf != 0x47)
{ {
synccnt++; synccnt++;

View File

@@ -644,3 +644,9 @@ void cVideo::routeVideo(int standby)
perror("IOC_AVS_ROUTE_ENC2TV"); perror("IOC_AVS_ROUTE_ENC2TV");
close(avsfd); close(avsfd);
} }
void cVideo::FastForwardMode(int mode)
{
lt_debug("cVideo::%s\n", __FUNCTION__);
fop(ioctl, MPEG_VID_FASTFORWARD, mode);
}

View File

@@ -179,6 +179,7 @@ class cVideo
void SetVideoMode(analog_mode_t mode); void SetVideoMode(analog_mode_t mode);
void SetDBDR(int) { return; }; void SetDBDR(int) { return; };
void SetAudioHandle(void *) { return; }; void SetAudioHandle(void *) { return; };
void FastForwardMode(int mode = 0);
void SetAutoModes(int [VIDEO_STD_MAX]) { return; }; void SetAutoModes(int [VIDEO_STD_MAX]) { return; };
int OpenVBI(int) { return 0; }; int OpenVBI(int) { return 0; };
int CloseVBI(void) { return 0; }; int CloseVBI(void) { return 0; };