summaryrefslogtreecommitdiff
path: root/receiver/recplayer.cpp
diff options
context:
space:
mode:
authorDenis Loh <denis.loh@gmail.com>2010-01-24 21:28:56 +0100
committerDenis Loh <denis.loh@gmail.com>2010-01-24 21:28:56 +0100
commit2103055b5ebfa389a5bec4c98f414608e959bba4 (patch)
tree791b723044ea16551484ed93991687f7530d702f /receiver/recplayer.cpp
parent60db82604cd0ab407e857b9f11d9588f9076333b (diff)
downloadvdr-plugin-upnp-2103055b5ebfa389a5bec4c98f414608e959bba4.tar.gz
vdr-plugin-upnp-2103055b5ebfa389a5bec4c98f414608e959bba4.tar.bz2
Added (finally) the record streaming function and some other things
Diffstat (limited to 'receiver/recplayer.cpp')
-rw-r--r--receiver/recplayer.cpp168
1 files changed, 60 insertions, 108 deletions
diff --git a/receiver/recplayer.cpp b/receiver/recplayer.cpp
index 954c9c8..8bf73d4 100644
--- a/receiver/recplayer.cpp
+++ b/receiver/recplayer.cpp
@@ -21,27 +21,31 @@ cRecordingPlayer *cRecordingPlayer::newInstance(cRecording* Recording){
return Player;
}
cRecordingPlayer::~cRecordingPlayer() {
- delete this->mOffsets;
+ delete this->mRecordingFile;
+ delete [] this->mLastOffsets;
}
-cRecordingPlayer::cRecordingPlayer(cRecording *Recording) {
+cRecordingPlayer::cRecordingPlayer(cRecording *Recording) : mRecording(Recording) {
MESSAGE(VERBOSE_SDK, "Created Recplayer");
- this->mFile = NULL;
- this->mTotalLenght = 0;
- this->mRecording = Recording;
- this->mOffsets = new off_t[VDR_MAX_FILES_PER_RECORDING];
- this->mOffset = 0;
- this->mIndex = 1;
-
+
+ this->mRecordingFile = new cFileName(this->mRecording->FileName(), false, false, this->mRecording->IsPesRecording());
+ this->mLastOffsets = new off_t[((this->mRecording->IsPesRecording())?VDR_MAX_FILES_PER_PESRECORDING:VDR_MAX_FILES_PER_TSRECORDING)+1];
+ this->scanLastOffsets();
}
void cRecordingPlayer::open(UpnpOpenFileMode){
- this->Scan();
+ // Open() does not work?!
+ this->mCurrentFile = this->mRecordingFile->SetOffset(1);
+ if(this->mCurrentFile){
+ MESSAGE(VERBOSE_RECORDS, "Record player opened");
+ }
+ else {
+ ERROR("Error while opening record player file");
+ }
}
void cRecordingPlayer::close(){
- delete [] this->mOffsets;
- if(this->mFile) fclose(this->mFile);
+ this->mRecordingFile->Close();
}
int cRecordingPlayer::write(char*, size_t){
@@ -50,122 +54,70 @@ int cRecordingPlayer::write(char*, size_t){
}
int cRecordingPlayer::read(char* buf, size_t buflen){
- FILE *File;
- off_t fileEndOffset = this->mOffsets[this->mIndex];
- if(this->mOffset > fileEndOffset){
- File = this->NextFile();
+ if(!this->mCurrentFile){
+ ERROR("Current part of record is not open");
+ return -1;
}
- else {
- File = this->GetFile();
+ MESSAGE(VERBOSE_RECORDS, "Reading %d from record", buflen);
+ int bytesread = 0;
+ while((bytesread = this->mCurrentFile->Read(buf, buflen)) == 0){ // EOF, try next file
+ if(!(this->mCurrentFile = this->mRecordingFile->NextFile())){
+ // no more files to read... finished!
+ break;
+ }
}
- // do not read more bytes than the actual file has
- size_t bytesToRead = ((fileEndOffset - this->mOffset) < (off_t)buflen)? fileEndOffset - this->mOffset : buflen;
- size_t bytesRead = fread((char*)buf, sizeof(char), bytesToRead, File);
-
- this->mOffset += (off_t)bytesRead;
-
- return (int)bytesRead;
+ return bytesread;
}
int cRecordingPlayer::seek(off_t offset, int origin){
- // Calculate the new offset
+ if(!this->mCurrentFile){
+ ERROR("Current part of record is not open");
+ return -1;
+ }
+
+ MESSAGE(VERBOSE_RECORDS, "Seeking...");
+
+ off_t relativeOffset;
+ off_t curpos = this->mCurrentFile->Seek(0, SEEK_CUR); // this should not change anything
+ int index;
+ // recalculate the absolute position in the record
switch(origin){
- case SEEK_CUR:
- if(this->mOffset + offset > this->mTotalLenght){
- ERROR("Can't read behind end of file!");
- return -1;
- }
- this->mOffset += (off_t)offset;
- break;
case SEEK_END:
- if(offset > 0){
- ERROR("Can't read behind end of file!");
- return -1;
- }
- this->mOffset = this->mTotalLenght + offset;
+ offset = this->mLastOffsets[this->mLastFileNumber] + offset;
+ break;
+ case SEEK_CUR:
+ offset = this->mLastOffsets[this->mRecordingFile->Number()-1] + curpos + offset;
break;
case SEEK_SET:
- if(offset > this->mTotalLenght){
- ERROR("Can't read behind end of file!");
- return -1;
- }
- this->mOffset = (off_t)offset;
+ // Nothing to change
break;
default:
- ERROR("Unknown seek mode (%d)!", origin);
+ ERROR("Seek operation invalid");
return -1;
}
- // Seek to the very first file;
- this->SeekInFile(1,0);
- off_t fileEndOffset = this->mOffsets[this->mIndex];
- // Spin until the new offset is in range of a specific file
- while(this->mOffset > (fileEndOffset = this->mOffsets[this->mIndex])){
- // If its not possible to switch to next file, there was an error
- if(!this->NextFile()){
- ERROR("Offset %lld not in the range of a file!", offset);
- return -1;
+ // finally, we can seek
+ // TODO: binary search
+ for(index = 1; this->mLastOffsets[index]; index++){
+ if(this->mLastOffsets[index-1] <= offset && offset <= this->mLastOffsets[index]){
+ relativeOffset = offset - this->mLastOffsets[index-1];
+ break;
}
}
- off_t relativeOffset =
- this->mOffset - (this->mOffsets[this->mIndex-1])
- ? this->mOffsets[this->mIndex-1]
- : 0;
- if(!this->SeekInFile(this->mIndex, relativeOffset)){
- ERROR("Cannot set offset!");
+ if(!(this->mCurrentFile = this->mRecordingFile->SetOffset(index, relativeOffset))){
+ // seeking failed!!! should never happen.
+ this->mCurrentFile = this->mRecordingFile->SetOffset(1);
return -1;
}
- return 0;
-}
-void cRecordingPlayer::Scan(){
- MESSAGE(VERBOSE_RECORDS, "Scanning video files...");
- // Reset the offsets
- int i = 1;
- while(this->mOffsets[i++]) this->mOffsets[i] = 0;
- MESSAGE(VERBOSE_RECORDS, "Offsets reseted.");
-
- i = 0;
- FILE *File;
- while((File = this->GetFile(i))){
- if(VDR_MAX_FILES_PER_RECORDING < i+1){
- ERROR("Maximum file offsets exceeded!");
- break;
- }
- fseek(File, 0, SEEK_END);
- off_t offset = ftell(File);
- MESSAGE(VERBOSE_RECORDS, "File %d has its last offset at %lld", i, offset);
- this->mOffsets[i+1] = this->mOffsets[i] + offset;
- this->mTotalLenght = this->mOffsets[i+1];
- i++;
- }
+ return 0;
}
-FILE *cRecordingPlayer::GetFile(int Index){
- // No Index given: set current index
- if(Index == 0) Index = this->mIndex;
- // Index not changed: return current file
- if(this->mIndex == Index && this->mFile) return this->mFile;
-
- // Index changed: close open file and open new file
- if(this->mFile) fclose(this->mFile);
- char *filename = new char[VDR_FILENAME_BUFSIZE];
- snprintf(filename, VDR_FILENAME_BUFSIZE, VDR_RECORDFILE_PATTERN_TS, this->mRecording->FileName(), Index );
- MESSAGE(VERBOSE_BUFFERS, "Filename: %s", filename);
- this->mFile = NULL;
- if(this->mFile = fopen(filename, "r")){
- this->mIndex = Index;
- return this->mFile;
+void cRecordingPlayer::scanLastOffsets(){
+ // rewind
+ this->mCurrentFile = this->mRecordingFile->SetOffset(1);
+ for(int i = 1; (this->mCurrentFile = this->mRecordingFile->NextFile()); i++){
+ this->mLastOffsets[i] = this->mLastOffsets[i-1] + this->mCurrentFile->Seek(0, SEEK_END);
+ this->mLastFileNumber = this->mRecordingFile->Number();
}
- return NULL;
-}
-
-FILE *cRecordingPlayer::NextFile(void){
- return this->GetFile(this->mIndex++);
-}
-
-int cRecordingPlayer::SeekInFile(int Index, off_t Offset){
- FILE *File = this->GetFile(Index);
- fseek(File, Offset, SEEK_SET);
- return ftell(File);
}