player: seek fixes

This commit is contained in:
Peter Wu 2012-08-26 14:29:34 +02:00
parent 923d116afa
commit 96f0ade4ca
2 changed files with 21 additions and 11 deletions

View file

@ -34,6 +34,11 @@ namespace Player{
fileSrc.open(filename.c_str(), std::ifstream::in | std::ifstream::binary); fileSrc.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
setBlocking(STDIN_FILENO, false);//prevent reading from stdin from blocking setBlocking(STDIN_FILENO, false);//prevent reading from stdin from blocking
std::cout.setf(std::ios::unitbuf);//do not choke std::cout.setf(std::ios::unitbuf);//do not choke
fileSrc.seekg(0, std::ios::end);
fileSize = fileSrc.tellg();
fileSrc.seekg(0);
nextPacket();// initial read always returns nothing nextPacket();// initial read always returns nothing
if (!nextPacket()){//parse metadata if (!nextPacket()){//parse metadata
std::cout << stream->outHeader(); std::cout << stream->outHeader();
@ -53,7 +58,8 @@ namespace Player{
char buff[1024 * 10]; char buff[1024 * 10];
if (fileSrc.good()){ if (fileSrc.good()){
fileSrc.read(buff, sizeof(buff)); fileSrc.read(buff, sizeof(buff));
inBuffer.append(buff, fileSrc.gcount()); if (fileSrc.eof()) return -1;
buffer.append(buff, fileSrc.gcount());
return fileSrc.gcount(); return fileSrc.gcount();
} }
return -1; return -1;
@ -69,24 +75,25 @@ namespace Player{
} }
void File::seek(unsigned int miliseconds){ void File::seek(unsigned int miliseconds){
DTSC::Stream * tmpStream = new DTSC::Stream(1); DTSC::Stream * tmpStream = new DTSC::Stream(1);
int leftByte = 1, rightByte = INT_MAX; unsigned long leftByte = 1, rightByte = fileSize;
int leftMS = 0, rightMS = INT_MAX; unsigned int leftMS = 0, rightMS = INT_MAX;
/// \todo set last packet as last byte, consider metadata /// \todo set last packet as last byte, consider metadata
while (rightMS - leftMS >= 100){ while (rightMS - leftMS >= 100 && leftMS + 100 <= miliseconds){
std::string buffer; std::string buffer;
// binary search: pick the first packet on the right // binary search: pick the first packet on the right
unsigned int medByte = leftByte + (rightByte - leftByte) / 2; unsigned long medByte = leftByte + (rightByte - leftByte) / 2;
fileSrc.clear();// clear previous IO errors fileSrc.clear();// clear previous IO errors
fileSrc.seekg(medByte); fileSrc.seekg(medByte);
do{ // find first occurrence of packet do{ // find first occurrence of packet
unsigned int header_pos, read_bytes; int read_bytes = fillBuffer(buffer);
read_bytes = fillBuffer(buffer); if (read_bytes < 0){// EOF? O noes! EOF!
/// \todo handle EOF goto seekDone;
header_pos = buffer.find(DTSC::Magic_Packet); }
unsigned long header_pos = buffer.find(DTSC::Magic_Packet);
if (header_pos == std::string::npos){ if (header_pos == std::string::npos){
// it is possible that the magic packet is partially shown, e.g. "DTP" // it is possible that the magic packet is partially shown, e.g. "DTP"
if (read_bytes > strlen(DTSC::Magic_Packet) - 1){ if ((unsigned)read_bytes > strlen(DTSC::Magic_Packet) - 1){
read_bytes -= strlen(DTSC::Magic_Packet) - 1; read_bytes -= strlen(DTSC::Magic_Packet) - 1;
buffer.erase(0, read_bytes); buffer.erase(0, read_bytes);
medByte += read_bytes; medByte += read_bytes;
@ -107,6 +114,7 @@ namespace Player{
leftMS = medMS; leftMS = medMS;
} }
} }
seekDone:
// clear the buffer and adjust file pointer // clear the buffer and adjust file pointer
inBuffer.clear(); inBuffer.clear();
fileSrc.seekg(leftByte); fileSrc.seekg(leftByte);

View file

@ -12,6 +12,8 @@ namespace Player{
std::string inBuffer; ///<Buffer of unprocessed bytes read from input. std::string inBuffer; ///<Buffer of unprocessed bytes read from input.
DTSC::Stream * stream; DTSC::Stream * stream;
DTSC::Ring * ring; DTSC::Ring * ring;
long fileSize; ///< Input size in bytes.
bool playing; ///< Whether the stream can be sent or not.
bool nextPacket(); ///<Pulls the next packet into the queue. bool nextPacket(); ///<Pulls the next packet into the queue.
bool getPacketFromInput(); ///<Attempts to retrieve a packet from input. bool getPacketFromInput(); ///<Attempts to retrieve a packet from input.
bool readCommand(); bool readCommand();
@ -23,4 +25,4 @@ namespace Player{
void seek(unsigned int miliseconds); void seek(unsigned int miliseconds);
std::string & getPacket(); std::string & getPacket();
}; };
}; };