// handleCommand(Remote::THREE);
// handleCommand(Remote::DOWN);
// handleCommand(Remote::OK);
-// handleCommand(Remote::OK);
-// handleCommand(Remote::OK);
+// handleCommand(Remote::PLAY);
}
virtual bool isPaused()=0;
virtual bool isFfwd()=0;
virtual bool isFbwd()=0;
+ virtual ULLONG getPositionTS()=0;
+ virtual ULLONG getEndTS()=0;
#ifdef DEV
virtual void test1()=0;
feedMode = MODE_NORMAL;
isRecording = tIsRecording;
lastRescan = 0;
+ startTS = 0;
+ endTS = 0;
threadBuffer = NULL;
if (isRadio)
video->sync();
}
+ULLONG PlayerVideo::getPositionTS()
+{
+ long long currentTS = video->getCurrentTimestamp() - startTS;
+ if (currentTS < 0) currentTS += 7776000000ULL;
+ return (ULLONG)currentTS;
+}
+
+ULLONG PlayerVideo::getEndTS()
+{
+ long long rendTS = endTS - startTS;
+ if (rendTS < 0) rendTS += 7776000000ULL;
+ return (ULLONG)rendTS;
+}
void PlayerVideo::call(void* caller)
{
streamLength = vdr->rescanRecording();
Log::getInstance()->log("PlayerVideo", Log::DEBUG, "Rescanned and reset length: %llu", streamLength);
lastRescan = time(NULL);
+ setEndTS();
}
if (streamLength) // is playing a recording
int a_stream = demuxer.scan(threadBuffer, thisRead);
demuxer.setAudioStream(a_stream);
Log::getInstance()->log("Player", Log::DEBUG, "Startup Audio stream chosen %x", a_stream);
+
+ demuxer.findVideoPTS(threadBuffer, thisRead, &startTS);
+ if (isRecording) setEndTS();
+
startup = 0;
}
}
}
+void PlayerVideo::setEndTS()
+{
+ Log::getInstance()->log("Player", Log::DEBUG, "Setting end TS");
+
+ UINT thisRead;
+ UCHAR* tempBuffer = VDR::getInstance()->getBlock((streamLength - 100000), 100000, &thisRead);
+ if (!tempBuffer) return;
+ if (thisRead) demuxer.findVideoPTS(tempBuffer, thisRead, &endTS);
+ free(tempBuffer);
+ Log::getInstance()->log("Player", Log::DEBUG, "Set end TS");
+}
+
#ifdef DEV
void PlayerVideo::test1()
{
void setPosition(ULLONG position);
void setLength(ULLONG length);
void resyncAudio();
+ ULLONG getPositionTS();
+ ULLONG getEndTS();
bool isPaused() { return paused; }
bool isFfwd() { return ffwd; }
void threadPostStopCleanup();
private:
+ void setEndTS();
+
MessageQueue* commandMessageQueue;
Log* logger;
Video* video;
int startup;
VFeed vfeed;
AFeed afeed;
+
+ ULLONG startTS;
+ ULLONG endTS;
ULLONG feedPosition;
UCHAR feedMode;
UCHAR isRecording;
} vid_pos_regs_t;
//
+/*
typedef struct {
int stc_b32;
int stc_b0;
int pts_b32;
int pts_b0;
} pts_sync_data_t;
+*/
typedef struct {
int parm1;
#define AV_GET_AUD_VOLUME _IOR('a',14,int)
#define AV_SET_AUD_STREAMTYPE _IOW('a',15,int)
#define AV_SET_AUD_FORMAT _IOW('a',16,int)
-#define AV_GET_AUD_SYNC _IOR('a',21,pts_sync_data_t*)
+#define AV_GET_AUD_TIMESTAMPS _IOR('a',21, sync_data_t*)
#define AV_SET_AUD_STC _IOW('a',22,uint64_t *)
#define AV_SET_AUD_SYNC _IOW('a',23,int)
#define AV_SET_AUD_DISABLE_SYNC _IOW('a',24,aud_sync_parms_t*)
#define AV_SET_VID_POSITION _IOW('v',36,vid_pos_regs_t*)
#define AV_SET_VID_SCALE_ON _IOW('v',37,int)
#define AV_SET_VID_SCALE_OFF _IOW('v',38,int)
-#define AV_GET_VID_SYNC _IOR('v',39,int)
+#define AV_GET_VID_TIMESTAMPS _IOR('v',39, sync_data_t*)
#define AV_SET_VID_STC _IOW('v',40,uint64_t *)
#define AV_SET_VID_RATIO _IOW('v',41,int)
#define AV_SET_VID_SYNC _IOW('v',42,int)
return tvsize;
}
+ULLONG Video::getCurrentTimestamp()
+{
+ sync_data_t timestamps;
+ if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, ×tamps) == 0)
+ {
+ // FIXME are these the right way around?
+
+ timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
+ timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
+
+ return timestamps.stc;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
#ifdef DEV
int Video::test()
{
UINT getScreenWidth();
UINT getScreenHeight();
UCHAR getTVsize();
+ ULLONG getCurrentTimestamp();
private:
int checkSCART();
case Remote::FORWARD:
{
player->toggleFastForward();
+ doBar(0);
return 2;
}
case Remote::YELLOW:
else
{
if (player->isPaused()) w.nextSymbol = WSymbol::PAUSE;
- else if (player->isFfwd()) ;
- else if (player->isFbwd()) ;
+ else if (player->isFfwd()) w.nextSymbol = WSymbol::FFWD;
+ else if (player->isFbwd()) w.nextSymbol = WSymbol::FBWD;
else w.nextSymbol = WSymbol::PLAY;
}
w.draw();
+ ULONG currentTS = (player->getPositionTS() / 90000);
+ int chours = currentTS / 3600;
+ int cminutes = (currentTS - (chours * 3600)) / 60;
+ int cseconds = currentTS - (chours * 3600) - (cminutes * 60);
+
+ ULONG endTS = (player->getEndTS() / 90000);
+ int ehours = endTS / 3600;
+ int eminutes = (endTS - (ehours * 3600)) / 60;
+ int eseconds = endTS - (ehours * 3600) - (eminutes * 60);
+
+ char buffer[100];
+ snprintf(buffer, 99, "%01i:%02i:%02i / %01i:%02i:%02i", chours, cminutes, cseconds, ehours, eminutes, eseconds);
+
+ drawText(buffer, barRegion.x + 180, barRegion.y + 12, Colour::LIGHTTEXT);
+
ViewMan::getInstance()->updateView(this, &barRegion);
Timers::getInstance()->setTimer(this, 1, (struct timespec){4, 0});
}
#include "wsymbol.h"
-UCHAR WSymbol::widths[] = { 2, 2, 4, 4, 1, 1, 3, 3, 3, 3, 3, 4, 4, 2, 2, 3, 5, 5};
-UCHAR WSymbol::heights[] = { 8, 8, 12, 12, 24, 4, 18, 18, 18, 18, 18, 30, 30, 16, 16, 18, 18, 18};
+UCHAR WSymbol::widths[] = { 2, 2, 4, 4, 1, 1, 3, 3, 3, 3, 3, 4, 4, 2, 2, 3, 5, 5, 4, 4};
+UCHAR WSymbol::heights[] = { 8, 8, 12, 12, 24, 4, 18, 18, 18, 18, 18, 30, 30, 16, 16, 18, 18, 18, 16, 16};
UCHAR WSymbol::symbols[] = {
0x3C, 0x00, 0x0F, 0x00, 0x03,
0x30, 0x00, 0x0C, 0x00, 0x03,
+/*
+00000000 00000011 00000000 00000011
+00000000 00001111 00000000 00001111
+00000000 00111111 00000000 00111111
+00000000 11111111 00000000 11111111
+00000011 11111111 00000011 11111111
+00001111 11111111 00001111 11111111
+00111111 11111111 00111111 11111111
+11111111 11111111 11111111 11111111
+11111111 11111111 11111111 11111111
+00111111 11111111 00111111 11111111
+00001111 11111111 00001111 11111111
+00000011 11111111 00000011 11111111
+00000000 11111111 00000000 11111111
+00000000 00111111 00000000 00111111
+00000000 00001111 00000000 00001111
+00000000 00000011 00000000 00000011
+*/
+
+0x00, 0x03, 0x00, 0x03,
+0x00, 0x07, 0x00, 0x07,
+0x00, 0x3F, 0x00, 0x3F,
+0x00, 0xFF, 0x00, 0xFF,
+0x03, 0xFF, 0x03, 0xFF,
+0x07, 0xFF, 0x07, 0xFF,
+0x3F, 0xFF, 0x3F, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF,
+0x3F, 0xFF, 0x3F, 0xFF,
+0x07, 0xFF, 0x07, 0xFF,
+0x03, 0xFF, 0x03, 0xFF,
+0x00, 0xFF, 0x00, 0xFF,
+0x00, 0x3F, 0x00, 0x3F,
+0x00, 0x07, 0x00, 0x07,
+0x00, 0x03, 0x00, 0x03,
+
+/*
+11000000 00000000 11000000 00000000
+11110000 00000000 11110000 00000000
+11111100 00000000 11111100 00000000
+11111111 00000000 11111111 00000000
+11111111 11000000 11111111 11000000
+11111111 11110000 11111111 11110000
+11111111 11111100 11111111 11111100
+11111111 11111111 11111111 11111111
+11111111 11111111 11111111 11111111
+11111111 11111100 11111111 11111100
+11111111 11110000 11111111 11110000
+11111111 11000000 11111111 11000000
+11111111 00000000 11111111 00000000
+11111100 00000000 11111100 00000000
+11110000 00000000 11110000 00000000
+11000000 00000000 11000000 00000000
+*/
+
+0xC0, 0x00, 0xC0, 0x00,
+0xF0, 0x00, 0xF0, 0x00,
+0xFC, 0x00, 0xFC, 0x00,
+0xFF, 0x00, 0xFF, 0x00,
+0xFF, 0xC0, 0xFF, 0xC0,
+0xFF, 0xF0, 0xFF, 0xF0,
+0xFF, 0xFC, 0xFF, 0xFC,
+0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFC, 0xFF, 0xFC,
+0xFF, 0xF0, 0xFF, 0xF0,
+0xFF, 0xC0, 0xFF, 0xC0,
+0xFF, 0x00, 0xFF, 0x00,
+0xFC, 0x00, 0xFC, 0x00,
+0xF0, 0x00, 0xF0, 0x00,
+0xC0, 0x00, 0xC0, 0x00,
+
};
WSymbol::WSymbol()
const static UCHAR PAUSE = 15;
const static UCHAR SKIPBACK2 = 16;
const static UCHAR SKIPFORWARD2 = 17;
+ const static UCHAR FBWD = 18;
+ const static UCHAR FFWD = 19;
private:
static UCHAR symbols[];