mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Version 1.7.6
- cDevice::PlayTs() now syncs on the TS packet sync bytes. - Made MAXFRAMESIZE a multiple of TS_SIZE to avoid breaking up TS packets. - No longer resetting the patPmtParser in cDevice::PlayTs(), because this caused the selected audio and subtitle tracks to fall back to the default. - The SVDRP command PUTE now supports reading the EPG data from a given file (thanks to Helmut Auer). - Added cThread::SetIOPriority() and using it in cRemoveDeletedRecordingsThread (thanks to Rolf Ahrenberg). - Fixed the MEGABYTE() macro to make it correctly handle parameters resulting in values larger than 2GB. - Added cDevice::NumProvidedSystems() to PLUGINS.html (was missing since it had been implemented). - Fixed distortions when switching to the next file during replay. - Fixed detecting the frame rate for streams with PTS distances of 1800, which apparently split one frame over two payload units. - Added missing 'const' to cRecording::FramesPerSecond() (thanks to Joachim Wilke). - Any TS packets in the first "frame" after a cut in an edited recording that don't belong to a payload unit that started in that frame now get their TEI flag set, so that a decoder will ignore them together with any PES data collected for that PID so far (thanks to Oliver Endriss for reporting chirping sound disturbences at editing points in TS recordings). - cDvbPlayer::Empty() subtracts 1 from readIndex, because Action() will first increment it. - Only storing non-zero Pts values in ptsIndex. - Added a note to the INSTALL file about using subdirectories to split a large disk into separate areas for VDR's video data and other stuff (suggested by Udo Richter).
This commit is contained in:
parent
1aadb31fb3
commit
733a2becc4
@ -599,6 +599,7 @@ Helmut Auer <vdr@helmutauer.de>
|
|||||||
currently disabled
|
currently disabled
|
||||||
for suggesting to improve logging system time changes to avoid problems on slow
|
for suggesting to improve logging system time changes to avoid problems on slow
|
||||||
systems under heavy load
|
systems under heavy load
|
||||||
|
for making the SVDRP command PUTE support reading the EPG data from a given file
|
||||||
|
|
||||||
Jeremy Hall <jhall@UU.NET>
|
Jeremy Hall <jhall@UU.NET>
|
||||||
for fixing an incomplete initialization of the filter parameters in eit.c
|
for fixing an incomplete initialization of the filter parameters in eit.c
|
||||||
@ -669,6 +670,7 @@ Oliver Endriss <o.endriss@gmx.de>
|
|||||||
for adding missing AUDIO_PAUSE/AUDIO_CONTINUE calls to cDvbDevice
|
for adding missing AUDIO_PAUSE/AUDIO_CONTINUE calls to cDvbDevice
|
||||||
for reporting that the video type is unnecessarily written into channels.conf if
|
for reporting that the video type is unnecessarily written into channels.conf if
|
||||||
VPID is 0
|
VPID is 0
|
||||||
|
for reporting chirping sound disturbences at editing points in TS recordings
|
||||||
|
|
||||||
Reinhard Walter Buchner <rw.buchner@freenet.de>
|
Reinhard Walter Buchner <rw.buchner@freenet.de>
|
||||||
for adding some satellites to 'sources.conf'
|
for adding some satellites to 'sources.conf'
|
||||||
@ -1069,6 +1071,7 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi>
|
|||||||
for setting the thread name, so that it can be seen in 'top -H'
|
for setting the thread name, so that it can be seen in 'top -H'
|
||||||
for replacing the Finnish language code "smi" with "suo"
|
for replacing the Finnish language code "smi" with "suo"
|
||||||
for adding cap_sys_nice to the capabilities that are not dropped
|
for adding cap_sys_nice to the capabilities that are not dropped
|
||||||
|
for adding cThread::SetIOPriority() and using it in cRemoveDeletedRecordingsThread
|
||||||
|
|
||||||
Ralf Klueber <ralf.klueber@vodafone.com>
|
Ralf Klueber <ralf.klueber@vodafone.com>
|
||||||
for reporting a bug in cutting a recording if there is only a single editing mark
|
for reporting a bug in cutting a recording if there is only a single editing mark
|
||||||
@ -1617,6 +1620,8 @@ Udo Richter <udo_richter@gmx.de>
|
|||||||
for suppressing the automatic shutdown if the remote control is currently disabled
|
for suppressing the automatic shutdown if the remote control is currently disabled
|
||||||
for fixing a problem with calling isyslog() from within the SignalHandler()
|
for fixing a problem with calling isyslog() from within the SignalHandler()
|
||||||
for reporting a problem with handling the maximum video file size
|
for reporting a problem with handling the maximum video file size
|
||||||
|
for suggesting to add a note to the INSTALL file about using subdirectories to
|
||||||
|
split a large disk into separate areas for VDR's video data and other stuff
|
||||||
|
|
||||||
Sven Kreiensen <svenk@kammer.uni-hannover.de>
|
Sven Kreiensen <svenk@kammer.uni-hannover.de>
|
||||||
for his help in keeping 'channels.conf.terr' up to date
|
for his help in keeping 'channels.conf.terr' up to date
|
||||||
@ -1652,6 +1657,7 @@ Joachim Wilke <vdr@joachim-wilke.de>
|
|||||||
one that fits the input
|
one that fits the input
|
||||||
for reporting a problem with cStatus::MsgOsdTextItem() being called without a text
|
for reporting a problem with cStatus::MsgOsdTextItem() being called without a text
|
||||||
for reporting a missing install-i18n in the install target in the Makefile
|
for reporting a missing install-i18n in the install target in the Makefile
|
||||||
|
for adding a missing 'const' to cRecording::FramesPerSecond()
|
||||||
|
|
||||||
Sascha Klek <sklek@gmx.de>
|
Sascha Klek <sklek@gmx.de>
|
||||||
for reporting a problem with the '0' key in the "Day" item of the "Timers" menu
|
for reporting a problem with the '0' key in the "Day" item of the "Timers" menu
|
||||||
|
30
HISTORY
30
HISTORY
@ -6030,3 +6030,33 @@ Video Disk Recorder Revision History
|
|||||||
- No longer writing the video type into channels.conf if VPID is 0 (thanks to
|
- No longer writing the video type into channels.conf if VPID is 0 (thanks to
|
||||||
Oliver Endriss for reporting this).
|
Oliver Endriss for reporting this).
|
||||||
- Improved efficiency of cEIT::cEIT() (thanks to Tobias Bratfisch).
|
- Improved efficiency of cEIT::cEIT() (thanks to Tobias Bratfisch).
|
||||||
|
|
||||||
|
2009-04-26: Version 1.7.6
|
||||||
|
|
||||||
|
- cDevice::PlayTs() now syncs on the TS packet sync bytes.
|
||||||
|
- Made MAXFRAMESIZE a multiple of TS_SIZE to avoid breaking up TS packets.
|
||||||
|
- No longer resetting the patPmtParser in cDevice::PlayTs(), because this
|
||||||
|
caused the selected audio and subtitle tracks to fall back to the default.
|
||||||
|
- The SVDRP command PUTE now supports reading the EPG data from a given file
|
||||||
|
(thanks to Helmut Auer).
|
||||||
|
- Added cThread::SetIOPriority() and using it in cRemoveDeletedRecordingsThread
|
||||||
|
(thanks to Rolf Ahrenberg).
|
||||||
|
- Fixed the MEGABYTE() macro to make it correctly handle parameters resulting in
|
||||||
|
values larger than 2GB.
|
||||||
|
- Added cDevice::NumProvidedSystems() to PLUGINS.html (was missing since it had
|
||||||
|
been implemented).
|
||||||
|
- Fixed distortions when switching to the next file during replay.
|
||||||
|
- Fixed detecting the frame rate for streams with PTS distances of 1800, which
|
||||||
|
apparently split one frame over two payload units.
|
||||||
|
- Added missing 'const' to cRecording::FramesPerSecond() (thanks to Joachim Wilke).
|
||||||
|
- Any TS packets in the first "frame" after a cut in an edited recording that don't
|
||||||
|
belong to a payload unit that started in that frame now get their TEI flag set,
|
||||||
|
so that a decoder will ignore them together with any PES data collected for that
|
||||||
|
PID so far (thanks to Oliver Endriss for reporting chirping sound disturbences at
|
||||||
|
editing points in TS recordings).
|
||||||
|
- cDvbPlayer::Empty() subtracts 1 from readIndex, because Action() will first
|
||||||
|
increment it.
|
||||||
|
- Only storing non-zero Pts values in ptsIndex.
|
||||||
|
- Added a note to the INSTALL file about using subdirectories to split a large
|
||||||
|
disk into separate areas for VDR's video data and other stuff (suggested by
|
||||||
|
Udo Richter).
|
||||||
|
9
INSTALL
9
INSTALL
@ -324,7 +324,14 @@ with the name of the basic directory when running 'vdr':
|
|||||||
Note that you should not copy any non-VDR files into the /videoX directories,
|
Note that you should not copy any non-VDR files into the /videoX directories,
|
||||||
since this might cause a lot of unnecessary disk access when VDR cleans up those
|
since this might cause a lot of unnecessary disk access when VDR cleans up those
|
||||||
directories and there is a large number of files and/or subdirectories in
|
directories and there is a large number of files and/or subdirectories in
|
||||||
there.
|
there. If you have a large disk that you want to use for VDR's video data as
|
||||||
|
well as other stuff, you may want to create a subdirectory for VDR, as in
|
||||||
|
|
||||||
|
/mydisk/video0
|
||||||
|
|
||||||
|
and put your other stuff into, say,
|
||||||
|
|
||||||
|
/mydisk/otherstuff
|
||||||
|
|
||||||
If your video directory is mounted via a Samba share, and you are experiencing
|
If your video directory is mounted via a Samba share, and you are experiencing
|
||||||
problems with replaying in fast forward mode, you can comment out the line
|
problems with replaying in fast forward mode, you can comment out the line
|
||||||
|
@ -1802,6 +1802,9 @@ If the new device can receive, it most likely needs to provide a way of
|
|||||||
selecting which channel it shall tune to:
|
selecting which channel it shall tune to:
|
||||||
|
|
||||||
<p><table><tr><td class="code"><pre>
|
<p><table><tr><td class="code"><pre>
|
||||||
|
<div class="modified">
|
||||||
|
virtual int NumProvidedSystems(void) const;
|
||||||
|
</div modified>
|
||||||
virtual bool ProvidesSource(int Source) const;
|
virtual bool ProvidesSource(int Source) const;
|
||||||
virtual bool ProvidesTransponder(const cChannel *Channel) const;
|
virtual bool ProvidesTransponder(const cChannel *Channel) const;
|
||||||
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
|
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: channels.c 2.5 2009/04/10 11:29:55 kls Exp $
|
* $Id: channels.c 2.6 2009/04/25 13:57:32 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
@ -535,7 +535,7 @@ void cChannel::SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][
|
|||||||
|
|
||||||
void cChannel::SetCaIds(const int *CaIds)
|
void cChannel::SetCaIds(const int *CaIds)
|
||||||
{
|
{
|
||||||
if (caids[0] && caids[0] <= 0x00FF)
|
if (caids[0] && caids[0] <= CA_USER_MAX)
|
||||||
return; // special values will not be overwritten
|
return; // special values will not be overwritten
|
||||||
if (IntArraysDiffer(caids, CaIds)) {
|
if (IntArraysDiffer(caids, CaIds)) {
|
||||||
char OldCaIdsBuf[MAXCAIDS * 5 + 10]; // 5: 4 digits plus delimiting ',', 10: paranoia
|
char OldCaIdsBuf[MAXCAIDS * 5 + 10]; // 5: 4 digits plus delimiting ',', 10: paranoia
|
||||||
@ -864,7 +864,7 @@ bool cChannel::Parse(const char *s)
|
|||||||
while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
|
while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
|
||||||
if (NumCaIds < MAXCAIDS) {
|
if (NumCaIds < MAXCAIDS) {
|
||||||
caids[NumCaIds++] = strtol(q, NULL, 16) & 0xFFFF;
|
caids[NumCaIds++] = strtol(q, NULL, 16) & 0xFFFF;
|
||||||
if (NumCaIds == 1 && caids[0] <= 0x00FF)
|
if (NumCaIds == 1 && caids[0] <= CA_USER_MAX)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
10
config.h
10
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.h 2.7 2009/01/30 16:05:34 kls Exp $
|
* $Id: config.h 2.8 2009/04/12 14:20:52 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
@ -22,13 +22,13 @@
|
|||||||
|
|
||||||
// VDR's own version number:
|
// VDR's own version number:
|
||||||
|
|
||||||
#define VDRVERSION "1.7.5"
|
#define VDRVERSION "1.7.6"
|
||||||
#define VDRVERSNUM 10705 // Version * 10000 + Major * 100 + Minor
|
#define VDRVERSNUM 10706 // Version * 10000 + Major * 100 + Minor
|
||||||
|
|
||||||
// The plugin API's version number:
|
// The plugin API's version number:
|
||||||
|
|
||||||
#define APIVERSION "1.7.5"
|
#define APIVERSION "1.7.6"
|
||||||
#define APIVERSNUM 10705 // Version * 10000 + Major * 100 + Minor
|
#define APIVERSNUM 10706 // Version * 10000 + Major * 100 + Minor
|
||||||
|
|
||||||
// When loading plugins, VDR searches them by their APIVERSION, which
|
// When loading plugins, VDR searches them by their APIVERSION, which
|
||||||
// may be smaller than VDRVERSION in case there have been no changes to
|
// may be smaller than VDRVERSION in case there have been no changes to
|
||||||
|
10
cutter.c
10
cutter.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: cutter.c 2.2 2009/01/24 15:19:26 kls Exp $
|
* $Id: cutter.c 2.3 2009/04/19 10:56:33 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cutter.h"
|
#include "cutter.h"
|
||||||
@ -18,6 +18,7 @@
|
|||||||
class cCuttingThread : public cThread {
|
class cCuttingThread : public cThread {
|
||||||
private:
|
private:
|
||||||
const char *error;
|
const char *error;
|
||||||
|
bool isPesRecording;
|
||||||
cUnbufferedFile *fromFile, *toFile;
|
cUnbufferedFile *fromFile, *toFile;
|
||||||
cFileName *fromFileName, *toFileName;
|
cFileName *fromFileName, *toFileName;
|
||||||
cIndexFile *fromIndex, *toIndex;
|
cIndexFile *fromIndex, *toIndex;
|
||||||
@ -39,7 +40,7 @@ cCuttingThread::cCuttingThread(const char *FromFileName, const char *ToFileName)
|
|||||||
fromFileName = toFileName = NULL;
|
fromFileName = toFileName = NULL;
|
||||||
fromIndex = toIndex = NULL;
|
fromIndex = toIndex = NULL;
|
||||||
cRecording Recording(FromFileName);
|
cRecording Recording(FromFileName);
|
||||||
bool isPesRecording = Recording.IsPesRecording();
|
isPesRecording = Recording.IsPesRecording();
|
||||||
if (fromMarks.Load(FromFileName, Recording.FramesPerSecond(), isPesRecording) && fromMarks.Count()) {
|
if (fromMarks.Load(FromFileName, Recording.FramesPerSecond(), isPesRecording) && fromMarks.Count()) {
|
||||||
fromFileName = new cFileName(FromFileName, false, true, isPesRecording);
|
fromFileName = new cFileName(FromFileName, false, true, isPesRecording);
|
||||||
toFileName = new cFileName(ToFileName, true, true, isPesRecording);
|
toFileName = new cFileName(ToFileName, true, true, isPesRecording);
|
||||||
@ -140,7 +141,10 @@ void cCuttingThread::Action(void)
|
|||||||
LastIFrame = 0;
|
LastIFrame = 0;
|
||||||
|
|
||||||
if (cutIn) {
|
if (cutIn) {
|
||||||
cRemux::SetBrokenLink(buffer, Length);
|
if (isPesRecording)
|
||||||
|
cRemux::SetBrokenLink(buffer, Length);
|
||||||
|
else
|
||||||
|
TsSetTeiOnBrokenPackets(buffer, Length);
|
||||||
cutIn = false;
|
cutIn = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
device.c
16
device.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.c 2.13 2009/04/05 12:15:41 kls Exp $
|
* $Id: device.c 2.16 2009/04/18 09:41:00 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@ -1075,6 +1075,7 @@ bool cDevice::AttachPlayer(cPlayer *Player)
|
|||||||
Detach(player);
|
Detach(player);
|
||||||
DELETENULL(liveSubtitle);
|
DELETENULL(liveSubtitle);
|
||||||
DELETENULL(dvbSubtitleConverter);
|
DELETENULL(dvbSubtitleConverter);
|
||||||
|
patPmtParser.Reset();
|
||||||
player = Player;
|
player = Player;
|
||||||
if (!Transferring())
|
if (!Transferring())
|
||||||
ClrAvailableTracks(false, true);
|
ClrAvailableTracks(false, true);
|
||||||
@ -1099,6 +1100,7 @@ void cDevice::Detach(cPlayer *Player)
|
|||||||
SetPlayMode(pmNone);
|
SetPlayMode(pmNone);
|
||||||
SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat));
|
SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat));
|
||||||
PlayTs(NULL, 0);
|
PlayTs(NULL, 0);
|
||||||
|
patPmtParser.Reset();
|
||||||
Audios.ClearAudio();
|
Audios.ClearAudio();
|
||||||
isPlayingVideo = false;
|
isPlayingVideo = false;
|
||||||
}
|
}
|
||||||
@ -1317,14 +1319,24 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
|
|||||||
{
|
{
|
||||||
int Played = 0;
|
int Played = 0;
|
||||||
if (Data == NULL) {
|
if (Data == NULL) {
|
||||||
patPmtParser.Reset();
|
|
||||||
tsToPesVideo.Reset();
|
tsToPesVideo.Reset();
|
||||||
tsToPesAudio.Reset();
|
tsToPesAudio.Reset();
|
||||||
tsToPesSubtitle.Reset();
|
tsToPesSubtitle.Reset();
|
||||||
}
|
}
|
||||||
|
else if (Length < TS_SIZE) {
|
||||||
|
esyslog("ERROR: skipped %d bytes of TS fragment", Length);
|
||||||
|
return Length;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
cMutexLock MutexLock(&mutexCurrentAudioTrack);
|
cMutexLock MutexLock(&mutexCurrentAudioTrack);
|
||||||
while (Length >= TS_SIZE) {
|
while (Length >= TS_SIZE) {
|
||||||
|
if (Data[0] != TS_SYNC_BYTE) {
|
||||||
|
int Skipped = 1;
|
||||||
|
while (Skipped < Length && (Data[Skipped] != TS_SYNC_BYTE || Length - Skipped > TS_SIZE && Data[Skipped + TS_SIZE] != TS_SYNC_BYTE))
|
||||||
|
Skipped++;
|
||||||
|
esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
|
||||||
|
return Played + Skipped;
|
||||||
|
}
|
||||||
if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload
|
if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload
|
||||||
int PayloadOffset = TsPayloadOffset(Data);
|
int PayloadOffset = TsPayloadOffset(Data);
|
||||||
if (PayloadOffset < TS_SIZE) {
|
if (PayloadOffset < TS_SIZE) {
|
||||||
|
348
dvbplayer.c
348
dvbplayer.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbplayer.c 2.11 2009/04/05 13:04:33 kls Exp $
|
* $Id: dvbplayer.c 2.15 2009/04/19 15:19:10 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbplayer.h"
|
#include "dvbplayer.h"
|
||||||
@ -318,7 +318,7 @@ void cDvbPlayer::Empty(void)
|
|||||||
if (nonBlockingFileReader)
|
if (nonBlockingFileReader)
|
||||||
nonBlockingFileReader->Clear();
|
nonBlockingFileReader->Clear();
|
||||||
if (!firstPacket) // don't set the readIndex twice if Empty() is called more than once
|
if (!firstPacket) // don't set the readIndex twice if Empty() is called more than once
|
||||||
readIndex = ptsIndex.FindIndex(DeviceGetSTC());
|
readIndex = ptsIndex.FindIndex(DeviceGetSTC()) - 1; // Action() will first increment it!
|
||||||
delete readFrame; // might not have been stored in the buffer in Action()
|
delete readFrame; // might not have been stored in the buffer in Action()
|
||||||
readFrame = NULL;
|
readFrame = NULL;
|
||||||
playFrame = NULL;
|
playFrame = NULL;
|
||||||
@ -398,189 +398,191 @@ void cDvbPlayer::Action(void)
|
|||||||
int LastReadIFrame = -1;
|
int LastReadIFrame = -1;
|
||||||
int SwitchToPlayFrame = 0;
|
int SwitchToPlayFrame = 0;
|
||||||
|
|
||||||
while (Running() && (NextFile() || readIndex >= 0 || ringBuffer->Available())) {
|
while (Running()) {
|
||||||
if (Sleep) {
|
if (WaitingForData)
|
||||||
if (WaitingForData)
|
nonBlockingFileReader->WaitForDataMs(3); // this keeps the CPU load low, but reacts immediately on new data
|
||||||
nonBlockingFileReader->WaitForDataMs(3); // this keeps the CPU load low, but reacts immediately on new data
|
else if (Sleep) {
|
||||||
else
|
cPoller Poller;
|
||||||
cCondWait::SleepMs(3); // this keeps the CPU load low
|
DevicePoll(Poller, 10);
|
||||||
Sleep = false;
|
Sleep = false;
|
||||||
}
|
}
|
||||||
cPoller Poller;
|
{
|
||||||
if (DevicePoll(Poller, 100)) {
|
LOCK_THREAD;
|
||||||
|
|
||||||
LOCK_THREAD;
|
// Read the next frame from the file:
|
||||||
|
|
||||||
// Read the next frame from the file:
|
if (playMode != pmStill && playMode != pmPause) {
|
||||||
|
if (!readFrame && (replayFile || readIndex >= 0)) {
|
||||||
|
if (!nonBlockingFileReader->Reading()) {
|
||||||
|
if (!SwitchToPlayFrame && (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward))) {
|
||||||
|
uint16_t FileNumber;
|
||||||
|
off_t FileOffset;
|
||||||
|
bool TimeShiftMode = index->IsStillRecording();
|
||||||
|
int Index = -1;
|
||||||
|
readIndependent = false;
|
||||||
|
if (DeviceHasIBPTrickSpeed() && playDir == pdForward) {
|
||||||
|
if (index->Get(readIndex + 1, &FileNumber, &FileOffset, &readIndependent, &Length))
|
||||||
|
Index = readIndex + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int d = int(round(0.4 * framesPerSecond));
|
||||||
|
if (playDir != pdForward)
|
||||||
|
d = -d;
|
||||||
|
int NewIndex = readIndex + d;
|
||||||
|
if (NewIndex <= 0 && readIndex > 0)
|
||||||
|
NewIndex = 1; // make sure the very first frame is delivered
|
||||||
|
NewIndex = index->GetNextIFrame(NewIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, TimeShiftMode);
|
||||||
|
if (NewIndex < 0 && TimeShiftMode && playDir == pdForward)
|
||||||
|
SwitchToPlayFrame = Index;
|
||||||
|
Index = NewIndex;
|
||||||
|
readIndependent = true;
|
||||||
|
}
|
||||||
|
if (Index >= 0) {
|
||||||
|
readIndex = Index;
|
||||||
|
if (!NextFile(FileNumber, FileOffset))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
eof = true;
|
||||||
|
}
|
||||||
|
else if (index) {
|
||||||
|
uint16_t FileNumber;
|
||||||
|
off_t FileOffset;
|
||||||
|
if (index->Get(readIndex + 1, &FileNumber, &FileOffset, &readIndependent, &Length) && NextFile(FileNumber, FileOffset))
|
||||||
|
readIndex++;
|
||||||
|
else
|
||||||
|
eof = true;
|
||||||
|
}
|
||||||
|
else // allows replay even if the index file is missing
|
||||||
|
Length = MAXFRAMESIZE;
|
||||||
|
if (Length == -1)
|
||||||
|
Length = MAXFRAMESIZE; // this means we read up to EOF (see cIndex)
|
||||||
|
else if (Length > MAXFRAMESIZE) {
|
||||||
|
esyslog("ERROR: frame larger than buffer (%d > %d)", Length, MAXFRAMESIZE);
|
||||||
|
Length = MAXFRAMESIZE;
|
||||||
|
}
|
||||||
|
b = MALLOC(uchar, Length);
|
||||||
|
}
|
||||||
|
if (!eof) {
|
||||||
|
int r = nonBlockingFileReader->Read(replayFile, b, Length);
|
||||||
|
if (r > 0) {
|
||||||
|
WaitingForData = false;
|
||||||
|
uint32_t Pts = 0;
|
||||||
|
if (readIndependent) {
|
||||||
|
Pts = isPesRecording ? PesGetPts(b) : TsGetPts(b, r);
|
||||||
|
LastReadIFrame = readIndex;
|
||||||
|
}
|
||||||
|
readFrame = new cFrame(b, -r, ftUnknown, readIndex, Pts); // hands over b to the ringBuffer
|
||||||
|
b = NULL;
|
||||||
|
}
|
||||||
|
else if (r == 0)
|
||||||
|
eof = true;
|
||||||
|
else if (r < 0 && errno == EAGAIN)
|
||||||
|
WaitingForData = true;
|
||||||
|
else if (r < 0 && FATALERRNO) {
|
||||||
|
LOG_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (playMode != pmStill && playMode != pmPause) {
|
// Store the frame in the buffer:
|
||||||
if (!readFrame && (replayFile || readIndex >= 0)) {
|
|
||||||
if (!nonBlockingFileReader->Reading()) {
|
|
||||||
if (!SwitchToPlayFrame && (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward))) {
|
|
||||||
uint16_t FileNumber;
|
|
||||||
off_t FileOffset;
|
|
||||||
bool TimeShiftMode = index->IsStillRecording();
|
|
||||||
int Index = -1;
|
|
||||||
readIndependent = false;
|
|
||||||
if (DeviceHasIBPTrickSpeed() && playDir == pdForward) {
|
|
||||||
if (index->Get(readIndex + 1, &FileNumber, &FileOffset, &readIndependent, &Length))
|
|
||||||
Index = readIndex + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int d = int(round(0.4 * framesPerSecond));
|
|
||||||
if (playDir != pdForward)
|
|
||||||
d = -d;
|
|
||||||
int NewIndex = readIndex + d;
|
|
||||||
if (NewIndex <= 0 && readIndex > 0)
|
|
||||||
NewIndex = 1; // make sure the very first frame is delivered
|
|
||||||
NewIndex = index->GetNextIFrame(NewIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, TimeShiftMode);
|
|
||||||
if (NewIndex < 0 && TimeShiftMode && playDir == pdForward)
|
|
||||||
SwitchToPlayFrame = Index;
|
|
||||||
Index = NewIndex;
|
|
||||||
readIndependent = true;
|
|
||||||
}
|
|
||||||
if (Index >= 0) {
|
|
||||||
readIndex = Index;
|
|
||||||
if (!NextFile(FileNumber, FileOffset))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
eof = true;
|
|
||||||
}
|
|
||||||
else if (index) {
|
|
||||||
uint16_t FileNumber;
|
|
||||||
off_t FileOffset;
|
|
||||||
if (index->Get(readIndex + 1, &FileNumber, &FileOffset, &readIndependent, &Length) && NextFile(FileNumber, FileOffset))
|
|
||||||
readIndex++;
|
|
||||||
else
|
|
||||||
eof = true;
|
|
||||||
}
|
|
||||||
else // allows replay even if the index file is missing
|
|
||||||
Length = MAXFRAMESIZE / TS_SIZE * TS_SIZE;// FIXME: use a linear ringbuffer in this case, and fix cDevice::PlayPes()
|
|
||||||
if (Length == -1)
|
|
||||||
Length = MAXFRAMESIZE; // this means we read up to EOF (see cIndex)
|
|
||||||
else if (Length > MAXFRAMESIZE) {
|
|
||||||
esyslog("ERROR: frame larger than buffer (%d > %d)", Length, MAXFRAMESIZE);
|
|
||||||
Length = MAXFRAMESIZE;
|
|
||||||
}
|
|
||||||
b = MALLOC(uchar, Length);
|
|
||||||
}
|
|
||||||
if (!eof) {
|
|
||||||
int r = nonBlockingFileReader->Read(replayFile, b, Length);
|
|
||||||
if (r > 0) {
|
|
||||||
WaitingForData = false;
|
|
||||||
uint32_t Pts = 0;
|
|
||||||
if (readIndependent) {
|
|
||||||
Pts = isPesRecording ? PesGetPts(b) : TsGetPts(b, r);
|
|
||||||
LastReadIFrame = readIndex;
|
|
||||||
}
|
|
||||||
readFrame = new cFrame(b, -r, ftUnknown, readIndex, Pts); // hands over b to the ringBuffer
|
|
||||||
b = NULL;
|
|
||||||
}
|
|
||||||
else if (r == 0)
|
|
||||||
eof = true;
|
|
||||||
else if (r < 0 && errno == EAGAIN)
|
|
||||||
WaitingForData = true;
|
|
||||||
else if (r < 0 && FATALERRNO) {
|
|
||||||
LOG_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the frame in the buffer:
|
if (readFrame) {
|
||||||
|
if (ringBuffer->Put(readFrame))
|
||||||
|
readFrame = NULL;
|
||||||
|
else
|
||||||
|
Sleep = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Sleep = true;
|
||||||
|
|
||||||
if (readFrame) {
|
// Get the next frame from the buffer:
|
||||||
if (ringBuffer->Put(readFrame))
|
|
||||||
readFrame = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Sleep = true;
|
|
||||||
|
|
||||||
// Get the next frame from the buffer:
|
if (!playFrame) {
|
||||||
|
playFrame = ringBuffer->Get();
|
||||||
|
p = NULL;
|
||||||
|
pc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!playFrame) {
|
// Play the frame:
|
||||||
playFrame = ringBuffer->Get();
|
|
||||||
p = NULL;
|
|
||||||
pc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Play the frame:
|
if (playFrame) {
|
||||||
|
if (!p) {
|
||||||
|
p = playFrame->Data();
|
||||||
|
pc = playFrame->Count();
|
||||||
|
if (p) {
|
||||||
|
if (playFrame->Index() >= 0 && playFrame->Pts() != 0)
|
||||||
|
ptsIndex.Put(playFrame->Pts(), playFrame->Index());
|
||||||
|
if (firstPacket) {
|
||||||
|
if (isPesRecording) {
|
||||||
|
PlayPes(NULL, 0);
|
||||||
|
cRemux::SetBrokenLink(p, pc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
PlayTs(NULL, 0);
|
||||||
|
firstPacket = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p) {
|
||||||
|
int w;
|
||||||
|
if (isPesRecording)
|
||||||
|
w = PlayPes(p, pc, playMode != pmPlay && !(playMode == pmSlow && playDir == pdForward) && DeviceIsPlayingVideo());
|
||||||
|
else
|
||||||
|
w = PlayTs(p, pc, playMode != pmPlay && !(playMode == pmSlow && playDir == pdForward) && DeviceIsPlayingVideo());
|
||||||
|
if (w > 0) {
|
||||||
|
p += w;
|
||||||
|
pc -= w;
|
||||||
|
}
|
||||||
|
else if (w < 0 && FATALERRNO)
|
||||||
|
LOG_ERROR;
|
||||||
|
else
|
||||||
|
Sleep = true;
|
||||||
|
}
|
||||||
|
if (pc <= 0) {
|
||||||
|
if (!eof || (playDir != pdForward && playFrame->Index() > 0) || (playDir == pdForward && playFrame->Index() < readIndex))
|
||||||
|
ringBuffer->Drop(playFrame); // the very first and last frame are continously repeated to flush data through the device
|
||||||
|
playFrame = NULL;
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Sleep = true;
|
||||||
|
|
||||||
if (playFrame) {
|
// Handle hitting begin/end of recording:
|
||||||
if (!p) {
|
|
||||||
p = playFrame->Data();
|
|
||||||
pc = playFrame->Count();
|
|
||||||
if (p) {
|
|
||||||
if (playFrame->Index() >= 0)
|
|
||||||
ptsIndex.Put(playFrame->Pts(), playFrame->Index());
|
|
||||||
if (firstPacket) {
|
|
||||||
if (isPesRecording) {
|
|
||||||
PlayPes(NULL, 0);
|
|
||||||
cRemux::SetBrokenLink(p, pc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PlayTs(NULL, 0);
|
|
||||||
firstPacket = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (p) {
|
|
||||||
int w;
|
|
||||||
if (isPesRecording)
|
|
||||||
w = PlayPes(p, pc, playMode != pmPlay && !(playMode == pmSlow && playDir == pdForward) && DeviceIsPlayingVideo());
|
|
||||||
else
|
|
||||||
w = PlayTs(p, pc, playMode != pmPlay && !(playMode == pmSlow && playDir == pdForward) && DeviceIsPlayingVideo());
|
|
||||||
if (w > 0) {
|
|
||||||
p += w;
|
|
||||||
pc -= w;
|
|
||||||
}
|
|
||||||
else if (w < 0 && FATALERRNO)
|
|
||||||
LOG_ERROR;
|
|
||||||
}
|
|
||||||
if (pc <= 0) {
|
|
||||||
if (!eof || (playDir != pdForward && playFrame->Index() > 0) || (playDir == pdForward && playFrame->Index() < readIndex))
|
|
||||||
ringBuffer->Drop(playFrame); // the very first and last frame are continously repeated to flush data through the device
|
|
||||||
playFrame = NULL;
|
|
||||||
p = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Sleep = true;
|
|
||||||
|
|
||||||
// Handle hitting begin/end of recording:
|
if (eof || SwitchToPlayFrame) {
|
||||||
|
bool SwitchToPlay = false;
|
||||||
if (eof || SwitchToPlayFrame) {
|
uint32_t Stc = DeviceGetSTC();
|
||||||
bool SwitchToPlay = false;
|
if (Stc != LastStc)
|
||||||
uint32_t Stc = DeviceGetSTC();
|
StuckAtEof = 0;
|
||||||
if (Stc != LastStc)
|
else if (!StuckAtEof)
|
||||||
StuckAtEof = 0;
|
StuckAtEof = time(NULL);
|
||||||
else if (!StuckAtEof)
|
else if (time(NULL) - StuckAtEof > MAXSTUCKATEOF) {
|
||||||
StuckAtEof = time(NULL);
|
if (playDir == pdForward)
|
||||||
else if (time(NULL) - StuckAtEof > MAXSTUCKATEOF) {
|
break; // automatically stop at end of recording
|
||||||
if (playDir == pdForward)
|
SwitchToPlay = true;
|
||||||
break; // automatically stop at end of recording
|
}
|
||||||
SwitchToPlay = true;
|
LastStc = Stc;
|
||||||
}
|
int Index = ptsIndex.FindIndex(Stc);
|
||||||
LastStc = Stc;
|
if (playDir == pdForward && !SwitchToPlayFrame) {
|
||||||
int Index = ptsIndex.FindIndex(Stc);
|
if (Index >= LastReadIFrame)
|
||||||
if (playDir == pdForward && !SwitchToPlayFrame) {
|
break; // automatically stop at end of recording
|
||||||
if (Index >= LastReadIFrame)
|
}
|
||||||
break; // automatically stop at end of recording
|
else if (Index <= 0 || SwitchToPlayFrame && Index >= SwitchToPlayFrame)
|
||||||
}
|
SwitchToPlay = true;
|
||||||
else if (Index <= 0 || SwitchToPlayFrame && Index >= SwitchToPlayFrame)
|
if (SwitchToPlay) {
|
||||||
SwitchToPlay = true;
|
if (!SwitchToPlayFrame)
|
||||||
if (SwitchToPlay) {
|
Empty();
|
||||||
if (!SwitchToPlayFrame)
|
DevicePlay();
|
||||||
Empty();
|
playMode = pmPlay;
|
||||||
DevicePlay();
|
playDir = pdForward;
|
||||||
playMode = pmPlay;
|
SwitchToPlayFrame = 0;
|
||||||
playDir = pdForward;
|
}
|
||||||
SwitchToPlayFrame = 0;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cNonBlockingFileReader *nbfr = nonBlockingFileReader;
|
cNonBlockingFileReader *nbfr = nonBlockingFileReader;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.c 2.9 2009/01/30 16:27:19 kls Exp $
|
* $Id: recording.c 2.12 2009/04/13 13:50:39 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
@ -85,6 +85,7 @@ cRemoveDeletedRecordingsThread::cRemoveDeletedRecordingsThread(void)
|
|||||||
void cRemoveDeletedRecordingsThread::Action(void)
|
void cRemoveDeletedRecordingsThread::Action(void)
|
||||||
{
|
{
|
||||||
SetPriority(19);
|
SetPriority(19);
|
||||||
|
SetIOPriority(7);
|
||||||
// Make sure only one instance of VDR does this:
|
// Make sure only one instance of VDR does this:
|
||||||
cLockFile LockFile(VideoDirectory);
|
cLockFile LockFile(VideoDirectory);
|
||||||
if (LockFile.Lock()) {
|
if (LockFile.Lock()) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.h 2.5 2009/02/28 10:50:12 kls Exp $
|
* $Id: recording.h 2.7 2009/04/19 09:00:45 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __RECORDING_H
|
#ifndef __RECORDING_H
|
||||||
@ -109,7 +109,7 @@ public:
|
|||||||
const char *PrefixFileName(char Prefix);
|
const char *PrefixFileName(char Prefix);
|
||||||
int HierarchyLevels(void) const;
|
int HierarchyLevels(void) const;
|
||||||
void ResetResume(void) const;
|
void ResetResume(void) const;
|
||||||
double FramesPerSecond(void) { return framesPerSecond; }
|
double FramesPerSecond(void) const { return framesPerSecond; }
|
||||||
bool IsNew(void) const { return GetResume() <= 0; }
|
bool IsNew(void) const { return GetResume() <= 0; }
|
||||||
bool IsEdited(void) const;
|
bool IsEdited(void) const;
|
||||||
bool IsPesRecording(void) const { return isPesRecording; }
|
bool IsPesRecording(void) const { return isPesRecording; }
|
||||||
@ -207,7 +207,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// The maximum size of a single frame (up to HDTV 1920x1080):
|
// The maximum size of a single frame (up to HDTV 1920x1080):
|
||||||
#define MAXFRAMESIZE KILOBYTE(512)
|
#define MAXFRAMESIZE (KILOBYTE(512) / TS_SIZE * TS_SIZE) // multiple of TS_SIZE to avoid breaking up TS packets
|
||||||
|
|
||||||
// The maximum file size is limited by the range that can be covered
|
// The maximum file size is limited by the range that can be covered
|
||||||
// with a 40 bit 'unsigned int', which is 1TB. The actual maximum value
|
// with a 40 bit 'unsigned int', which is 1TB. The actual maximum value
|
||||||
|
28
remux.c
28
remux.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remux.c 2.17 2009/04/05 14:07:48 kls Exp $
|
* $Id: remux.c 2.19 2009/04/19 10:59:56 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remux.h"
|
#include "remux.h"
|
||||||
@ -124,6 +124,24 @@ int64_t TsGetPts(const uchar *p, int l)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TsSetTeiOnBrokenPackets(uchar *p, int l)
|
||||||
|
{
|
||||||
|
bool Processed[MAXPID] = { false };
|
||||||
|
while (l >= TS_SIZE) {
|
||||||
|
if (*p != TS_SYNC_BYTE)
|
||||||
|
break;
|
||||||
|
int Pid = TsPid(p);
|
||||||
|
if (!Processed[Pid]) {
|
||||||
|
if (!TsPayloadStart(p))
|
||||||
|
p[1] |= TS_ERROR;
|
||||||
|
else
|
||||||
|
Processed[Pid] = true;
|
||||||
|
}
|
||||||
|
l -= TS_SIZE;
|
||||||
|
p += TS_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- cPatPmtGenerator ------------------------------------------------------
|
// --- cPatPmtGenerator ------------------------------------------------------
|
||||||
|
|
||||||
cPatPmtGenerator::cPatPmtGenerator(cChannel *Channel)
|
cPatPmtGenerator::cPatPmtGenerator(cChannel *Channel)
|
||||||
@ -582,6 +600,10 @@ cTsToPes::~cTsToPes()
|
|||||||
|
|
||||||
void cTsToPes::PutTs(const uchar *Data, int Length)
|
void cTsToPes::PutTs(const uchar *Data, int Length)
|
||||||
{
|
{
|
||||||
|
if (TsError(Data)) {
|
||||||
|
Reset();
|
||||||
|
return; // ignore packets with TEI set, and drop any PES data collected so far
|
||||||
|
}
|
||||||
if (TsPayloadStart(Data))
|
if (TsPayloadStart(Data))
|
||||||
Reset();
|
Reset();
|
||||||
else if (!size)
|
else if (!size)
|
||||||
@ -732,6 +754,10 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
|||||||
frameDuration = 3600; // PAL, 25 fps
|
frameDuration = 3600; // PAL, 25 fps
|
||||||
else if (Delta % 3003 == 0)
|
else if (Delta % 3003 == 0)
|
||||||
frameDuration = 3003; // NTSC, 29.97 fps
|
frameDuration = 3003; // NTSC, 29.97 fps
|
||||||
|
else if (Delta == 1800) {
|
||||||
|
frameDuration = 3600; // PAL, 25 fps
|
||||||
|
framesPerPayloadUnit = -2;
|
||||||
|
}
|
||||||
else if (Delta == 1501) {
|
else if (Delta == 1501) {
|
||||||
frameDuration = 3003; // NTSC, 29.97 fps
|
frameDuration = 3003; // NTSC, 29.97 fps
|
||||||
framesPerPayloadUnit = -2;
|
framesPerPayloadUnit = -2;
|
||||||
|
5
remux.h
5
remux.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remux.h 2.9 2009/03/27 13:38:59 kls Exp $
|
* $Id: remux.h 2.10 2009/04/19 10:57:09 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __REMUX_H
|
#ifndef __REMUX_H
|
||||||
@ -49,6 +49,8 @@ public:
|
|||||||
#define TS_ADAPT_TP_PRIVATE 0x02
|
#define TS_ADAPT_TP_PRIVATE 0x02
|
||||||
#define TS_ADAPT_EXTENSION 0x01
|
#define TS_ADAPT_EXTENSION 0x01
|
||||||
|
|
||||||
|
#define MAXPID 0x2000 // for arrays that use a PID as the index
|
||||||
|
|
||||||
inline bool TsHasPayload(const uchar *p)
|
inline bool TsHasPayload(const uchar *p)
|
||||||
{
|
{
|
||||||
return p[3] & TS_PAYLOAD_EXISTS;
|
return p[3] & TS_PAYLOAD_EXISTS;
|
||||||
@ -104,6 +106,7 @@ inline int TsGetAdaptationField(const uchar *p)
|
|||||||
// The following functions all take a pointer to a sequence of complete TS packets.
|
// The following functions all take a pointer to a sequence of complete TS packets.
|
||||||
|
|
||||||
int64_t TsGetPts(const uchar *p, int l);
|
int64_t TsGetPts(const uchar *p, int l);
|
||||||
|
void TsSetTeiOnBrokenPackets(uchar *p, int l);
|
||||||
|
|
||||||
// Some PES handling tools:
|
// Some PES handling tools:
|
||||||
// The following functions that take a pointer to PES data all assume that
|
// The following functions that take a pointer to PES data all assume that
|
||||||
|
35
svdrp.c
35
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* graphical interface that sits on top of an SVDRP connection.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.c 2.2 2009/01/06 14:35:45 kls Exp $
|
* $Id: svdrp.c 2.3 2009/04/13 13:35:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "svdrp.h"
|
#include "svdrp.h"
|
||||||
@ -288,11 +288,14 @@ const char *HelpPages[] = {
|
|||||||
" If 'help' is followed by a command, the detailed help for that command is\n"
|
" If 'help' is followed by a command, the detailed help for that command is\n"
|
||||||
" given. The keyword 'main' initiates a call to the main menu function of the\n"
|
" given. The keyword 'main' initiates a call to the main menu function of the\n"
|
||||||
" given plugin.\n",
|
" given plugin.\n",
|
||||||
"PUTE\n"
|
"PUTE [ file ]\n"
|
||||||
" Put data into the EPG list. The data entered has to strictly follow the\n"
|
" Put data into the EPG list. The data entered has to strictly follow the\n"
|
||||||
" format defined in vdr(5) for the 'epg.data' file. A '.' on a line\n"
|
" format defined in vdr(5) for the 'epg.data' file. A '.' on a line\n"
|
||||||
" by itself terminates the input and starts processing of the data (all\n"
|
" by itself terminates the input and starts processing of the data (all\n"
|
||||||
" entered data is buffered until the terminating '.' is seen).",
|
" entered data is buffered until the terminating '.' is seen).\n"
|
||||||
|
" If a file name is given, epg data will be read from this file (which\n"
|
||||||
|
" must be accessible under the given name from the machine VDR is running\n"
|
||||||
|
" on). In case of file input, no terminating '.' shall be given.\n",
|
||||||
"REMO [ on | off ]\n"
|
"REMO [ on | off ]\n"
|
||||||
" Turns the remote control on or off. Without a parameter, the current\n"
|
" Turns the remote control on or off. Without a parameter, the current\n"
|
||||||
" status of the remote control is reported.",
|
" status of the remote control is reported.",
|
||||||
@ -1435,11 +1438,27 @@ void cSVDRP::CmdPLUG(const char *Option)
|
|||||||
|
|
||||||
void cSVDRP::CmdPUTE(const char *Option)
|
void cSVDRP::CmdPUTE(const char *Option)
|
||||||
{
|
{
|
||||||
delete PUTEhandler;
|
if (*Option) {
|
||||||
PUTEhandler = new cPUTEhandler;
|
FILE *f = fopen(Option, "r");
|
||||||
Reply(PUTEhandler->Status(), "%s", PUTEhandler->Message());
|
if (f) {
|
||||||
if (PUTEhandler->Status() != 354)
|
if (cSchedules::Read(f)) {
|
||||||
DELETENULL(PUTEhandler);
|
cSchedules::Cleanup(true);
|
||||||
|
Reply(250, "EPG data processed from \"%s\"", Option);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(451, "Error while processing EPG from \"%s\"", Option);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Cannot open file \"%s\"", Option);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete PUTEhandler;
|
||||||
|
PUTEhandler = new cPUTEhandler;
|
||||||
|
Reply(PUTEhandler->Status(), "%s", PUTEhandler->Message());
|
||||||
|
if (PUTEhandler->Status() != 354)
|
||||||
|
DELETENULL(PUTEhandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdREMO(const char *Option)
|
void cSVDRP::CmdREMO(const char *Option)
|
||||||
|
8
thread.c
8
thread.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: thread.c 2.2 2008/09/06 09:39:43 kls Exp $
|
* $Id: thread.c 2.3 2009/04/13 13:50:39 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
@ -226,6 +226,12 @@ void cThread::SetPriority(int Priority)
|
|||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cThread::SetIOPriority(int Priority)
|
||||||
|
{
|
||||||
|
if (syscall(SYS_ioprio_set, 1, 0, (Priority & 0xff) | (2 << 13)) < 0) // best effort class
|
||||||
|
LOG_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
void cThread::SetDescription(const char *Description, ...)
|
void cThread::SetDescription(const char *Description, ...)
|
||||||
{
|
{
|
||||||
free(description);
|
free(description);
|
||||||
|
3
thread.h
3
thread.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: thread.h 2.0 2007/02/24 16:13:28 kls Exp $
|
* $Id: thread.h 2.1 2009/04/13 13:50:39 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __THREAD_H
|
#ifndef __THREAD_H
|
||||||
@ -87,6 +87,7 @@ private:
|
|||||||
static void *StartThread(cThread *Thread);
|
static void *StartThread(cThread *Thread);
|
||||||
protected:
|
protected:
|
||||||
void SetPriority(int Priority);
|
void SetPriority(int Priority);
|
||||||
|
void SetIOPriority(int Priority);
|
||||||
void Lock(void) { mutex.Lock(); }
|
void Lock(void) { mutex.Lock(); }
|
||||||
void Unlock(void) { mutex.Unlock(); }
|
void Unlock(void) { mutex.Unlock(); }
|
||||||
virtual void Action(void) = 0;
|
virtual void Action(void) = 0;
|
||||||
|
4
tools.h
4
tools.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.h 2.1 2008/05/22 10:26:57 kls Exp $
|
* $Id: tools.h 2.2 2009/04/14 20:41:39 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -38,7 +38,7 @@ extern int SysLogLevel;
|
|||||||
#define SECSINDAY 86400
|
#define SECSINDAY 86400
|
||||||
|
|
||||||
#define KILOBYTE(n) ((n) * 1024)
|
#define KILOBYTE(n) ((n) * 1024)
|
||||||
#define MEGABYTE(n) ((n) * 1024 * 1024)
|
#define MEGABYTE(n) ((n) * 1024LL * 1024LL)
|
||||||
|
|
||||||
#define MALLOC(type, size) (type *)malloc(sizeof(type) * (size))
|
#define MALLOC(type, size) (type *)malloc(sizeof(type) * (size))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user