mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Show black picture, if no video stream available.
New audio ring code. New audio filters (first part).
This commit is contained in:
parent
c9ef8b759a
commit
79e78bf235
@ -1,6 +1,7 @@
|
|||||||
User johns
|
User johns
|
||||||
Date:
|
Date:
|
||||||
|
|
||||||
|
Show black picture, if no video stream is available.
|
||||||
Setup split into foldable sections.
|
Setup split into foldable sections.
|
||||||
Adds show cursor on pointer move and hide after 200ms.
|
Adds show cursor on pointer move and hide after 200ms.
|
||||||
Adds Hot-key support for auto-crop enable/disable/toggle.
|
Adds Hot-key support for auto-crop enable/disable/toggle.
|
||||||
|
25
README.txt
25
README.txt
@ -157,6 +157,28 @@ Setup: /etc/vdr/setup.conf
|
|||||||
0 = none, 1 = downmix
|
0 = none, 1 = downmix
|
||||||
downmix AC-3 to stero.
|
downmix AC-3 to stero.
|
||||||
|
|
||||||
|
softhddevice.AudioSoftvol
|
||||||
|
FIXME:
|
||||||
|
|
||||||
|
softhddevice.AudioNormalize
|
||||||
|
FIXME:
|
||||||
|
|
||||||
|
softhddevice.AudioMaxNormalize
|
||||||
|
FIXME:
|
||||||
|
|
||||||
|
softhddevice.AudioCompression
|
||||||
|
FIXME:
|
||||||
|
|
||||||
|
softhddevice.AudioMaxCompression
|
||||||
|
FIXME:
|
||||||
|
|
||||||
|
softhddevice.AudioStereoDescent
|
||||||
|
FIXME:
|
||||||
|
|
||||||
|
softhddevice.AudioBufferTime
|
||||||
|
FIXME:
|
||||||
|
|
||||||
|
|
||||||
softhddevice.AutoCrop.Interval = 0
|
softhddevice.AutoCrop.Interval = 0
|
||||||
0 disables auto-crop
|
0 disables auto-crop
|
||||||
n each 'n' frames auto-crop is checked.
|
n each 'n' frames auto-crop is checked.
|
||||||
@ -253,6 +275,9 @@ Keymacros:
|
|||||||
@softhddevice Blue 2 0 disable fullscreen
|
@softhddevice Blue 2 0 disable fullscreen
|
||||||
@softhddevice Blue 2 1 enable fullscreen
|
@softhddevice Blue 2 1 enable fullscreen
|
||||||
@softhddevice Blue 2 2 toggle fullscreen
|
@softhddevice Blue 2 2 toggle fullscreen
|
||||||
|
@softhddevice Blue 2 3 disable auto-crop
|
||||||
|
@softhddevice Blue 2 4 enable auto-crop
|
||||||
|
@softhddevice Blue 2 5 toggle auto-crop
|
||||||
@softhddevice Blue 3 0 stretch 4:3 to 16:9
|
@softhddevice Blue 3 0 stretch 4:3 to 16:9
|
||||||
@softhddevice Blue 3 1 letter box 4:3 in 16:9
|
@softhddevice Blue 3 1 letter box 4:3 in 16:9
|
||||||
@softhddevice Blue 3 2 center cut-out 4:3 to 16:9
|
@softhddevice Blue 3 2 center cut-out 4:3 to 16:9
|
||||||
|
4
audio.h
4
audio.h
@ -42,6 +42,10 @@ extern void AudioPlay(void); ///< play audio
|
|||||||
extern void AudioPause(void); ///< pause audio
|
extern void AudioPause(void); ///< pause audio
|
||||||
|
|
||||||
extern void AudioSetBufferTime(int); ///< set audio buffer time
|
extern void AudioSetBufferTime(int); ///< set audio buffer time
|
||||||
|
extern void AudioSetSoftvol(int); ///< enable/disable softvol
|
||||||
|
extern void AudioSetNormalize(int, int); ///< set normalize parameters
|
||||||
|
extern void AudioSetCompression(int, int); ///< set compression parameters
|
||||||
|
extern void AudioSetStereoDescent(int); ///< set stereo loudness descent
|
||||||
|
|
||||||
extern void AudioSetDevice(const char *); ///< set PCM audio device
|
extern void AudioSetDevice(const char *); ///< set PCM audio device
|
||||||
extern void AudioSetDeviceAC3(const char *); ///< set pass-through device
|
extern void AudioSetDeviceAC3(const char *); ///< set pass-through device
|
||||||
|
10
codec.c
10
codec.c
@ -949,8 +949,14 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
|
|||||||
av_resample_compensate(audio_decoder->AvResample,
|
av_resample_compensate(audio_decoder->AvResample,
|
||||||
audio_decoder->DriftCorr / 10, distance);
|
audio_decoder->DriftCorr / 10, distance);
|
||||||
}
|
}
|
||||||
Debug(3, "codec/audio: drift(%6d) %8dus %5d\n", audio_decoder->DriftCorr,
|
if (1) {
|
||||||
drift * 1000 / 90, corr);
|
static int c;
|
||||||
|
|
||||||
|
if (!(c++ % 10)) {
|
||||||
|
Debug(3, "codec/audio: drift(%6d) %8dus %5d\n",
|
||||||
|
audio_decoder->DriftCorr, drift * 1000 / 90, corr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
24
softhddev.c
24
softhddev.c
@ -61,6 +61,7 @@ static char ConfigVdpauDecoder = 1; ///< use vdpau decoder, if possible
|
|||||||
#define ConfigVdpauDecoder 0 ///< no vdpau decoder configured
|
#define ConfigVdpauDecoder 0 ///< no vdpau decoder configured
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern int ConfigAudioBufferTime; ///< config size ms of audio buffer
|
||||||
static char ConfigStartSuspended; ///< flag to start in suspend mode
|
static char ConfigStartSuspended; ///< flag to start in suspend mode
|
||||||
static char ConfigFullscreen; ///< fullscreen modus
|
static char ConfigFullscreen; ///< fullscreen modus
|
||||||
static char ConfigStartX11Server; ///< flag start the x11 server
|
static char ConfigStartX11Server; ///< flag start the x11 server
|
||||||
@ -887,7 +888,8 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
if (NewAudioStream) {
|
if (NewAudioStream) {
|
||||||
// this clears the audio ringbuffer indirect, open and setup does it
|
// this clears the audio ringbuffer indirect, open and setup does it
|
||||||
CodecAudioClose(MyAudioDecoder);
|
CodecAudioClose(MyAudioDecoder);
|
||||||
AudioSetBufferTime(0);
|
AudioFlushBuffers();
|
||||||
|
AudioSetBufferTime(ConfigAudioBufferTime);
|
||||||
AudioCodecID = CODEC_ID_NONE;
|
AudioCodecID = CODEC_ID_NONE;
|
||||||
AudioChannelID = -1;
|
AudioChannelID = -1;
|
||||||
NewAudioStream = 0;
|
NewAudioStream = 0;
|
||||||
@ -972,6 +974,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
samplerate = samplerates[p[5] >> 4];
|
samplerate = samplerates[p[5] >> 4];
|
||||||
channels = (p[5] & 0x7) + 1;
|
channels = (p[5] & 0x7) + 1;
|
||||||
|
|
||||||
|
// FIXME: ConfigAudioBufferTime + x
|
||||||
AudioSetBufferTime(400);
|
AudioSetBufferTime(400);
|
||||||
AudioSetup(&samplerate, &channels, 0);
|
AudioSetup(&samplerate, &channels, 0);
|
||||||
if (samplerate != samplerates[p[5] >> 4]) {
|
if (samplerate != samplerates[p[5] >> 4]) {
|
||||||
@ -1002,6 +1005,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
|||||||
p += 4;
|
p += 4;
|
||||||
n -= 4; // skip track header
|
n -= 4; // skip track header
|
||||||
if (AudioCodecID == CODEC_ID_NONE) {
|
if (AudioCodecID == CODEC_ID_NONE) {
|
||||||
|
// FIXME: ConfigAudioBufferTime + x
|
||||||
AudioSetBufferTime(400);
|
AudioSetBufferTime(400);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1100,8 +1104,9 @@ int PlayTsAudio(const uint8_t * data, int size)
|
|||||||
if (NewAudioStream) {
|
if (NewAudioStream) {
|
||||||
// this clears the audio ringbuffer indirect, open and setup does it
|
// this clears the audio ringbuffer indirect, open and setup does it
|
||||||
CodecAudioClose(MyAudioDecoder);
|
CodecAudioClose(MyAudioDecoder);
|
||||||
|
AudioFlushBuffers();
|
||||||
// max time between audio packets 200ms + 24ms hw buffer
|
// max time between audio packets 200ms + 24ms hw buffer
|
||||||
AudioSetBufferTime(264);
|
AudioSetBufferTime(ConfigAudioBufferTime);
|
||||||
AudioCodecID = CODEC_ID_NONE;
|
AudioCodecID = CODEC_ID_NONE;
|
||||||
AudioChannelID = -1;
|
AudioChannelID = -1;
|
||||||
NewAudioStream = 0;
|
NewAudioStream = 0;
|
||||||
@ -1128,7 +1133,7 @@ int PlayTsAudio(const uint8_t * data, int size)
|
|||||||
*/
|
*/
|
||||||
void SetVolumeDevice(int volume)
|
void SetVolumeDevice(int volume)
|
||||||
{
|
{
|
||||||
AudioSetVolume((volume * 100) / 255);
|
AudioSetVolume((volume * 1000) / 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1408,7 +1413,6 @@ int VideoDecode(void)
|
|||||||
if (last_codec_id != CODEC_ID_NONE) {
|
if (last_codec_id != CODEC_ID_NONE) {
|
||||||
last_codec_id = CODEC_ID_NONE;
|
last_codec_id = CODEC_ID_NONE;
|
||||||
CodecVideoClose(MyVideoDecoder);
|
CodecVideoClose(MyVideoDecoder);
|
||||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
// FIXME: look if more close are in the queue
|
// FIXME: look if more close are in the queue
|
||||||
@ -1461,11 +1465,6 @@ int VideoDecode(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ClosingVideoStream) { // closing don't sync
|
|
||||||
avpkt->pts = AV_NOPTS_VALUE;
|
|
||||||
avpkt->dts = AV_NOPTS_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_codec_id == CODEC_ID_MPEG2VIDEO) {
|
if (last_codec_id == CODEC_ID_MPEG2VIDEO) {
|
||||||
FixPacketForFFMpeg(MyVideoDecoder, avpkt);
|
FixPacketForFFMpeg(MyVideoDecoder, avpkt);
|
||||||
} else {
|
} else {
|
||||||
@ -1639,9 +1638,6 @@ int PlayVideo(const uint8_t * data, int size)
|
|||||||
}
|
}
|
||||||
VideoNextPacket(CODEC_ID_NONE);
|
VideoNextPacket(CODEC_ID_NONE);
|
||||||
VideoCodecID = CODEC_ID_NONE;
|
VideoCodecID = CODEC_ID_NONE;
|
||||||
// clear clock until new stream starts
|
|
||||||
// FIXME: still reordered frames in queue
|
|
||||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
|
||||||
ClosingVideoStream = 1;
|
ClosingVideoStream = 1;
|
||||||
NewVideoStream = 0;
|
NewVideoStream = 0;
|
||||||
}
|
}
|
||||||
@ -1858,6 +1854,8 @@ int SetPlayMode(int play_mode)
|
|||||||
if (MyVideoDecoder) { // tell video parser we have new stream
|
if (MyVideoDecoder) { // tell video parser we have new stream
|
||||||
if (VideoCodecID != CODEC_ID_NONE) {
|
if (VideoCodecID != CODEC_ID_NONE) {
|
||||||
NewVideoStream = 1;
|
NewVideoStream = 1;
|
||||||
|
// tell hw decoder we are closing stream
|
||||||
|
VideoSetClosing(MyHwDecoder);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
VideoSwitch = GetMsTicks();
|
VideoSwitch = GetMsTicks();
|
||||||
#endif
|
#endif
|
||||||
@ -1873,11 +1871,9 @@ int SetPlayMode(int play_mode)
|
|||||||
break;
|
break;
|
||||||
case 2: // audio only
|
case 2: // audio only
|
||||||
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
||||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
|
||||||
break;
|
break;
|
||||||
case 3: // audio only, black screen
|
case 3: // audio only, black screen
|
||||||
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
||||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
|
||||||
break;
|
break;
|
||||||
case 4: // video only
|
case 4: // video only
|
||||||
break;
|
break;
|
||||||
|
129
softhddevice.cpp
129
softhddevice.cpp
@ -35,10 +35,10 @@
|
|||||||
#include "softhddevice.h"
|
#include "softhddevice.h"
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
#include "audio.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
extern const char *X11DisplayName; ///< x11 display name
|
extern const char *X11DisplayName; ///< x11 display name
|
||||||
|
|
||||||
extern void AudioPoller(void);
|
|
||||||
extern void CodecSetAudioPassthrough(int);
|
extern void CodecSetAudioPassthrough(int);
|
||||||
extern void CodecSetAudioDownmix(int);
|
extern void CodecSetAudioDownmix(int);
|
||||||
}
|
}
|
||||||
@ -121,6 +121,7 @@ static int ConfigAudioMaxNormalize; ///< config max normalize factor
|
|||||||
static char ConfigAudioCompression; ///< config use volume compression
|
static char ConfigAudioCompression; ///< config use volume compression
|
||||||
static int ConfigAudioMaxCompression; ///< config max volume compression
|
static int ConfigAudioMaxCompression; ///< config max volume compression
|
||||||
static int ConfigAudioStereoDescent; ///< config reduce stereo loudness
|
static int ConfigAudioStereoDescent; ///< config reduce stereo loudness
|
||||||
|
int ConfigAudioBufferTime; ///< config size ms of audio buffer
|
||||||
|
|
||||||
static volatile int DoMakePrimary; ///< switch primary device to this
|
static volatile int DoMakePrimary; ///< switch primary device to this
|
||||||
|
|
||||||
@ -482,6 +483,8 @@ class cMenuSetupSoft:public cMenuSetupPage
|
|||||||
int SuspendX11;
|
int SuspendX11;
|
||||||
|
|
||||||
int Video;
|
int Video;
|
||||||
|
int VideoFormat;
|
||||||
|
int VideoDisplayFormat;
|
||||||
uint32_t Background;
|
uint32_t Background;
|
||||||
uint32_t BackgroundAlpha;
|
uint32_t BackgroundAlpha;
|
||||||
int StudioLevels;
|
int StudioLevels;
|
||||||
@ -512,6 +515,7 @@ class cMenuSetupSoft:public cMenuSetupPage
|
|||||||
int AudioCompression;
|
int AudioCompression;
|
||||||
int AudioMaxCompression;
|
int AudioMaxCompression;
|
||||||
int AudioStereoDescent;
|
int AudioStereoDescent;
|
||||||
|
int AudioBufferTime;
|
||||||
/// @}
|
/// @}
|
||||||
private:
|
private:
|
||||||
inline cOsdItem * CollapsedItem(const char *, int &, const char * = NULL);
|
inline cOsdItem * CollapsedItem(const char *, int &, const char * = NULL);
|
||||||
@ -562,6 +566,12 @@ inline cOsdItem *cMenuSetupSoft::CollapsedItem(const char *label, int &flag,
|
|||||||
*/
|
*/
|
||||||
void cMenuSetupSoft::Create(void)
|
void cMenuSetupSoft::Create(void)
|
||||||
{
|
{
|
||||||
|
static const char *const video_display_formats_4_3[] = {
|
||||||
|
"pan&scan", "letterbox", "center cut-out",
|
||||||
|
};
|
||||||
|
static const char *const video_display_formats_16_9[] = {
|
||||||
|
"pan&scan", "pillarbox", "center cut-out",
|
||||||
|
};
|
||||||
static const char *const deinterlace[] = {
|
static const char *const deinterlace[] = {
|
||||||
"Bob", "Weave/None", "Temporal", "TemporalSpatial", "Software Bob",
|
"Bob", "Weave/None", "Temporal", "TemporalSpatial", "Software Bob",
|
||||||
"Software Spatial",
|
"Software Spatial",
|
||||||
@ -598,26 +608,36 @@ void cMenuSetupSoft::Create(void)
|
|||||||
// suspend
|
// suspend
|
||||||
//
|
//
|
||||||
Add(SeparatorItem(tr("Suspend")));
|
Add(SeparatorItem(tr("Suspend")));
|
||||||
Add(new cMenuEditBoolItem(tr("suspend closes video+audio"),
|
Add(new cMenuEditBoolItem(tr("Suspend closes video+audio"),
|
||||||
&SuspendClose, trVDR("no"), trVDR("yes")));
|
&SuspendClose, trVDR("no"), trVDR("yes")));
|
||||||
Add(new cMenuEditBoolItem(tr("suspend stops x11"), &SuspendX11,
|
Add(new cMenuEditBoolItem(tr("Suspend stops x11"), &SuspendX11,
|
||||||
trVDR("no"), trVDR("yes")));
|
trVDR("no"), trVDR("yes")));
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// video
|
// video
|
||||||
//
|
//
|
||||||
Add(CollapsedItem(tr("Video"), Video));
|
Add(CollapsedItem(tr("Video"), Video));
|
||||||
|
|
||||||
if (Video) {
|
if (Video) {
|
||||||
Add(new cMenuEditIntItem(tr("video background color (RGB)"),
|
Add(new cMenuEditBoolItem(trVDR("Setup.DVB$Video format"),
|
||||||
|
&VideoFormat, "4:3", "16:9"));
|
||||||
|
if (VideoFormat) {
|
||||||
|
Add(new cMenuEditStraItem(trVDR("Setup.DVB$Video display format"),
|
||||||
|
&VideoDisplayFormat, 3, video_display_formats_16_9));
|
||||||
|
} else {
|
||||||
|
Add(new cMenuEditStraItem(trVDR("Setup.DVB$Video display format"),
|
||||||
|
&VideoDisplayFormat, 3, video_display_formats_4_3));
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: switch config gray/color configuration
|
||||||
|
Add(new cMenuEditIntItem(tr("Video background color (RGB)"),
|
||||||
(int *)&Background, 0, 0x00FFFFFF));
|
(int *)&Background, 0, 0x00FFFFFF));
|
||||||
Add(new cMenuEditIntItem(tr("video background color (Alpha)"),
|
Add(new cMenuEditIntItem(tr("Video background color (Alpha)"),
|
||||||
(int *)&BackgroundAlpha, 0, 0xFF));
|
(int *)&BackgroundAlpha, 0, 0xFF));
|
||||||
Add(new cMenuEditBoolItem(tr("Use studio levels (vdpau only)"),
|
Add(new cMenuEditBoolItem(tr("Use studio levels (vdpau only)"),
|
||||||
&StudioLevels, trVDR("no"), trVDR("yes")));
|
&StudioLevels, trVDR("no"), trVDR("yes")));
|
||||||
Add(new cMenuEditBoolItem(tr("60hz display mode"), &_60HzMode,
|
Add(new cMenuEditBoolItem(tr("60hz display mode"), &_60HzMode,
|
||||||
trVDR("no"), trVDR("yes")));
|
trVDR("no"), trVDR("yes")));
|
||||||
Add(new cMenuEditBoolItem(tr("soft start a/v sync"), &SoftStartSync,
|
Add(new cMenuEditBoolItem(tr("Soft start a/v sync"), &SoftStartSync,
|
||||||
trVDR("no"), trVDR("yes")));
|
trVDR("no"), trVDR("yes")));
|
||||||
|
|
||||||
for (i = 0; i < RESOLUTIONS; ++i) {
|
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||||
@ -648,11 +668,11 @@ void cMenuSetupSoft::Create(void)
|
|||||||
// auto-crop
|
// auto-crop
|
||||||
//
|
//
|
||||||
Add(SeparatorItem(tr("Auto-crop")));
|
Add(SeparatorItem(tr("Auto-crop")));
|
||||||
Add(new cMenuEditIntItem(tr("autocrop interval (frames)"),
|
Add(new cMenuEditIntItem(tr("Autocrop interval (frames)"),
|
||||||
&AutoCropInterval, 0, 200, tr("off")));
|
&AutoCropInterval, 0, 200, tr("off")));
|
||||||
Add(new cMenuEditIntItem(tr("autocrop delay (n * interval)"),
|
Add(new cMenuEditIntItem(tr("Autocrop delay (n * interval)"),
|
||||||
&AutoCropDelay, 0, 200));
|
&AutoCropDelay, 0, 200));
|
||||||
Add(new cMenuEditIntItem(tr("autocrop tolerance (pixel)"),
|
Add(new cMenuEditIntItem(tr("Autocrop tolerance (pixel)"),
|
||||||
&AutoCropTolerance, 0, 32));
|
&AutoCropTolerance, 0, 32));
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -667,6 +687,20 @@ void cMenuSetupSoft::Create(void)
|
|||||||
2, passthrough));
|
2, passthrough));
|
||||||
Add(new cMenuEditBoolItem(tr("Enable AC-3 downmix"), &AudioDownmix,
|
Add(new cMenuEditBoolItem(tr("Enable AC-3 downmix"), &AudioDownmix,
|
||||||
trVDR("no"), trVDR("yes")));
|
trVDR("no"), trVDR("yes")));
|
||||||
|
Add(new cMenuEditBoolItem(tr("Volume control"), &AudioSoftvol,
|
||||||
|
tr("Hardware"), tr("Software")));
|
||||||
|
Add(new cMenuEditBoolItem(tr("Enable normalize volume"),
|
||||||
|
&AudioMaxNormalize, trVDR("no"), trVDR("yes")));
|
||||||
|
Add(new cMenuEditIntItem(tr(" Max normalize factor (/1000)"),
|
||||||
|
&AudioMaxNormalize, 0, 5000));
|
||||||
|
Add(new cMenuEditBoolItem(tr("Enable volume compression"),
|
||||||
|
&AudioCompression, trVDR("no"), trVDR("yes")));
|
||||||
|
Add(new cMenuEditIntItem(tr(" Max compression factor (/1000)"),
|
||||||
|
&AudioMaxCompression, 0, 10000));
|
||||||
|
Add(new cMenuEditIntItem(tr("Reduce stereo volume (/1000)"),
|
||||||
|
&AudioStereoDescent, 0, 1000));
|
||||||
|
Add(new cMenuEditIntItem(tr("Audio buffer size (ms)"),
|
||||||
|
&AudioBufferTime, 0, 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCurrent(Get(current)); // restore selected menu entry
|
SetCurrent(Get(current)); // restore selected menu entry
|
||||||
@ -682,19 +716,22 @@ eOSState cMenuSetupSoft::ProcessKey(eKeys key)
|
|||||||
int old_general;
|
int old_general;
|
||||||
int old_video;
|
int old_video;
|
||||||
int old_audio;
|
int old_audio;
|
||||||
|
int old_video_format;
|
||||||
int old_resolution_shown[RESOLUTIONS];
|
int old_resolution_shown[RESOLUTIONS];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
old_general = General;
|
old_general = General;
|
||||||
old_video = Video;
|
old_video = Video;
|
||||||
old_audio = Audio;
|
old_audio = Audio;
|
||||||
|
old_video_format = VideoFormat;
|
||||||
memcpy(old_resolution_shown, ResolutionShown, sizeof(ResolutionShown));
|
memcpy(old_resolution_shown, ResolutionShown, sizeof(ResolutionShown));
|
||||||
state = cMenuSetupPage::ProcessKey(key);
|
state = cMenuSetupPage::ProcessKey(key);
|
||||||
|
|
||||||
if (key != kNone) {
|
if (key != kNone) {
|
||||||
// update menu only, if something on the structure has changed
|
// update menu only, if something on the structure has changed
|
||||||
// this needed because VDR menus are evil slow
|
// this needed because VDR menus are evil slow
|
||||||
if (old_general != General || old_video != Video || old_audio != Audio) {
|
if (old_general != General || old_video != Video
|
||||||
|
|| old_audio != Audio || old_video_format != VideoFormat) {
|
||||||
Create(); // update menu
|
Create(); // update menu
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < RESOLUTIONS; ++i) {
|
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||||
@ -734,6 +771,8 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
|||||||
// video
|
// video
|
||||||
//
|
//
|
||||||
Video = 0;
|
Video = 0;
|
||||||
|
VideoFormat = Setup.VideoFormat;
|
||||||
|
VideoDisplayFormat = Setup.VideoDisplayFormat;
|
||||||
// no unsigned int menu item supported, split background color/alpha
|
// no unsigned int menu item supported, split background color/alpha
|
||||||
Background = ConfigVideoBackground >> 8;
|
Background = ConfigVideoBackground >> 8;
|
||||||
BackgroundAlpha = ConfigVideoBackground & 0xFF;
|
BackgroundAlpha = ConfigVideoBackground & 0xFF;
|
||||||
@ -773,6 +812,7 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
|||||||
AudioCompression = ConfigAudioCompression;
|
AudioCompression = ConfigAudioCompression;
|
||||||
AudioMaxCompression = ConfigAudioMaxCompression;
|
AudioMaxCompression = ConfigAudioMaxCompression;
|
||||||
AudioStereoDescent = ConfigAudioStereoDescent;
|
AudioStereoDescent = ConfigAudioStereoDescent;
|
||||||
|
AudioBufferTime = ConfigAudioBufferTime;
|
||||||
|
|
||||||
Create();
|
Create();
|
||||||
}
|
}
|
||||||
@ -789,6 +829,20 @@ void cMenuSetupSoft::Store(void)
|
|||||||
HideMainMenuEntry);
|
HideMainMenuEntry);
|
||||||
SetupStore("Suspend.Close", ConfigSuspendClose = SuspendClose);
|
SetupStore("Suspend.Close", ConfigSuspendClose = SuspendClose);
|
||||||
SetupStore("Suspend.X11", ConfigSuspendX11 = SuspendX11);
|
SetupStore("Suspend.X11", ConfigSuspendX11 = SuspendX11);
|
||||||
|
// FIXME: this is also in VDR-DVB setup
|
||||||
|
if (Setup.VideoFormat != VideoFormat) {
|
||||||
|
Setup.VideoFormat = VideoFormat;
|
||||||
|
cDevice::PrimaryDevice()->SetVideoFormat(Setup.VideoFormat);
|
||||||
|
printf("video-format\n");
|
||||||
|
}
|
||||||
|
SetupStore("VideoFormat", Setup.VideoFormat);
|
||||||
|
if (Setup.VideoDisplayFormat != VideoDisplayFormat) {
|
||||||
|
Setup.VideoDisplayFormat = VideoDisplayFormat;
|
||||||
|
cDevice::PrimaryDevice()->SetVideoDisplayFormat(
|
||||||
|
eVideoDisplayFormat(Setup.VideoDisplayFormat));
|
||||||
|
printf("video-display-format\n");
|
||||||
|
}
|
||||||
|
SetupStore("VideoDisplayFormat", Setup.VideoDisplayFormat);
|
||||||
|
|
||||||
ConfigVideoBackground = Background << 8 | (BackgroundAlpha & 0xFF);
|
ConfigVideoBackground = Background << 8 | (BackgroundAlpha & 0xFF);
|
||||||
SetupStore("Background", ConfigVideoBackground);
|
SetupStore("Background", ConfigVideoBackground);
|
||||||
@ -838,7 +892,7 @@ void cMenuSetupSoft::Store(void)
|
|||||||
AutoCropTolerance);
|
AutoCropTolerance);
|
||||||
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay,
|
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay,
|
||||||
ConfigAutoCropTolerance);
|
ConfigAutoCropTolerance);
|
||||||
ConfigAutoCropEnabled = ConfigAutoCropInterval;
|
ConfigAutoCropEnabled = ConfigAutoCropInterval != 0;
|
||||||
|
|
||||||
SetupStore("AudioDelay", ConfigVideoAudioDelay = AudioDelay);
|
SetupStore("AudioDelay", ConfigVideoAudioDelay = AudioDelay);
|
||||||
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
||||||
@ -846,7 +900,17 @@ void cMenuSetupSoft::Store(void)
|
|||||||
CodecSetAudioPassthrough(ConfigAudioPassthrough);
|
CodecSetAudioPassthrough(ConfigAudioPassthrough);
|
||||||
SetupStore("AudioDownmix", ConfigAudioDownmix = AudioDownmix);
|
SetupStore("AudioDownmix", ConfigAudioDownmix = AudioDownmix);
|
||||||
CodecSetAudioDownmix(ConfigAudioDownmix);
|
CodecSetAudioDownmix(ConfigAudioDownmix);
|
||||||
// FIXME: new audio
|
SetupStore("AudioSoftvol", ConfigAudioSoftvol = AudioSoftvol );
|
||||||
|
AudioSetSoftvol(ConfigAudioSoftvol);
|
||||||
|
SetupStore("AudioNormalize", ConfigAudioNormalize = AudioNormalize );
|
||||||
|
SetupStore("AudioMaxNormalize", ConfigAudioMaxNormalize = AudioMaxNormalize );
|
||||||
|
AudioSetNormalize(ConfigAudioNormalize, ConfigAudioMaxNormalize);
|
||||||
|
SetupStore("AudioCompression", ConfigAudioCompression = AudioCompression );
|
||||||
|
SetupStore("AudioMaxCompression", ConfigAudioMaxCompression = AudioMaxCompression );
|
||||||
|
AudioSetCompression(ConfigAudioCompression, ConfigAudioMaxCompression);
|
||||||
|
SetupStore("AudioStereoDescent", ConfigAudioStereoDescent = AudioStereoDescent );
|
||||||
|
AudioSetStereoDescent(ConfigAudioStereoDescent);
|
||||||
|
SetupStore("AudioBufferTime", ConfigAudioBufferTime = AudioBufferTime );
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1039,7 +1103,7 @@ static void HandleHotkey(int code)
|
|||||||
Skins.QueueMessage(mtInfo, tr("auto-crop enabled"));
|
Skins.QueueMessage(mtInfo, tr("auto-crop enabled"));
|
||||||
break;
|
break;
|
||||||
case 25: // toggle auto-crop
|
case 25: // toggle auto-crop
|
||||||
ConfigAutoCropEnabled = !ConfigAutoCropEnabled;
|
ConfigAutoCropEnabled ^= 1;
|
||||||
// no interval configured, use some default
|
// no interval configured, use some default
|
||||||
if (!ConfigAutoCropInterval) {
|
if (!ConfigAutoCropInterval) {
|
||||||
ConfigAutoCropInterval = 50;
|
ConfigAutoCropInterval = 50;
|
||||||
@ -1283,6 +1347,7 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode play_mode)
|
|||||||
return true;
|
return true;
|
||||||
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
||||||
dsyslog("[softhddev] play mode external\n");
|
dsyslog("[softhddev] play mode external\n");
|
||||||
|
// FIXME: what if already suspended?
|
||||||
Suspend(1, 1, 0);
|
Suspend(1, 1, 0);
|
||||||
SuspendMode = SUSPEND_EXTERNAL;
|
SuspendMode = SUSPEND_EXTERNAL;
|
||||||
return true;
|
return true;
|
||||||
@ -1916,7 +1981,7 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
|||||||
if (!strcasecmp(name, "AutoCrop.Interval")) {
|
if (!strcasecmp(name, "AutoCrop.Interval")) {
|
||||||
VideoSetAutoCrop(ConfigAutoCropInterval =
|
VideoSetAutoCrop(ConfigAutoCropInterval =
|
||||||
atoi(value), ConfigAutoCropDelay, ConfigAutoCropTolerance);
|
atoi(value), ConfigAutoCropDelay, ConfigAutoCropTolerance);
|
||||||
ConfigAutoCropEnabled = ConfigAutoCropInterval;
|
ConfigAutoCropEnabled = ConfigAutoCropInterval != 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!strcasecmp(name, "AutoCrop.Delay")) {
|
if (!strcasecmp(name, "AutoCrop.Delay")) {
|
||||||
@ -1942,7 +2007,39 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
|||||||
CodecSetAudioDownmix(ConfigAudioDownmix = atoi(value));
|
CodecSetAudioDownmix(ConfigAudioDownmix = atoi(value));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// FIXME: new audio
|
if (!strcasecmp(name, "AudioSoftvol")) {
|
||||||
|
AudioSetSoftvol(ConfigAudioSoftvol = atoi(value));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(name, "AudioNormalize")) {
|
||||||
|
ConfigAudioNormalize = atoi(value);
|
||||||
|
AudioSetNormalize(ConfigAudioNormalize, ConfigAudioMaxNormalize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(name, "AudioMaxNormalize")) {
|
||||||
|
ConfigAudioMaxNormalize = atoi(value);
|
||||||
|
AudioSetNormalize(ConfigAudioNormalize, ConfigAudioMaxNormalize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(name, "AudioCompression")) {
|
||||||
|
ConfigAudioCompression = atoi(value);
|
||||||
|
AudioSetCompression(ConfigAudioCompression, ConfigAudioMaxCompression);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(name, "AudioMaxCompression")) {
|
||||||
|
ConfigAudioMaxCompression = atoi(value);
|
||||||
|
AudioSetCompression(ConfigAudioCompression, ConfigAudioMaxCompression);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(name, "AudioStereoDescent")) {
|
||||||
|
ConfigAudioStereoDescent = atoi(value);
|
||||||
|
AudioSetStereoDescent(ConfigAudioStereoDescent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(name, "AudioBufferTime")) {
|
||||||
|
ConfigAudioBufferTime = atoi(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
53
video.c
53
video.c
@ -356,7 +356,7 @@ static xcb_atom_t NetWmStateFullscreen; ///< fullscreen wm-state message atom
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
extern uint32_t VideoSwitch; ///< ticks for channel switch
|
extern uint32_t VideoSwitch; ///< ticks for channel switch
|
||||||
#endif
|
#endif
|
||||||
extern void AudioVideoReady(void); ///< tell audio video is ready
|
extern void AudioVideoReady(int64_t); ///< tell audio video is ready
|
||||||
|
|
||||||
#ifdef USE_VIDEO_THREAD
|
#ifdef USE_VIDEO_THREAD
|
||||||
|
|
||||||
@ -427,6 +427,8 @@ static void VideoSetPts(int64_t * pts_p, int interlaced, const AVFrame * frame)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else { // first new clock value
|
||||||
|
AudioVideoReady(pts);
|
||||||
}
|
}
|
||||||
if (*pts_p != pts) {
|
if (*pts_p != pts) {
|
||||||
Debug(4,
|
Debug(4,
|
||||||
@ -1334,6 +1336,7 @@ struct _vaapi_decoder_
|
|||||||
int TrickSpeed; ///< current trick speed
|
int TrickSpeed; ///< current trick speed
|
||||||
int TrickCounter; ///< current trick speed counter
|
int TrickCounter; ///< current trick speed counter
|
||||||
struct timespec FrameTime; ///< time of last display
|
struct timespec FrameTime; ///< time of last display
|
||||||
|
int Closing; ///< flag about closing current stream
|
||||||
int64_t PTS; ///< video PTS clock
|
int64_t PTS; ///< video PTS clock
|
||||||
|
|
||||||
int SyncCounter; ///< counter to sync frames
|
int SyncCounter; ///< counter to sync frames
|
||||||
@ -1856,6 +1859,7 @@ static void VaapiCleanup(VaapiDecoder * decoder)
|
|||||||
|
|
||||||
decoder->FrameCounter = 0;
|
decoder->FrameCounter = 0;
|
||||||
decoder->FramesDisplayed = 0;
|
decoder->FramesDisplayed = 0;
|
||||||
|
decoder->Closing = 0;
|
||||||
decoder->PTS = AV_NOPTS_VALUE;
|
decoder->PTS = AV_NOPTS_VALUE;
|
||||||
VideoDeltaPTS = 0;
|
VideoDeltaPTS = 0;
|
||||||
}
|
}
|
||||||
@ -4504,6 +4508,9 @@ static void VaapiSyncDecoder(VaapiDecoder * decoder)
|
|||||||
_("video: decoder buffer empty, "
|
_("video: decoder buffer empty, "
|
||||||
"duping frame (%d/%d) %d v-buf\n"), decoder->FramesDuped,
|
"duping frame (%d/%d) %d v-buf\n"), decoder->FramesDuped,
|
||||||
decoder->FrameCounter, VideoGetBuffers());
|
decoder->FrameCounter, VideoGetBuffers());
|
||||||
|
if (decoder->Closing == -1) {
|
||||||
|
atomic_set(&decoder->SurfacesFilled, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -4600,7 +4607,9 @@ static void VaapiSyncRenderFrame(VaapiDecoder * decoder,
|
|||||||
VaapiSyncDisplayFrame();
|
VaapiSyncDisplayFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!decoder->Closing) {
|
||||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
||||||
|
}
|
||||||
VaapiRenderFrame(decoder, video_ctx, frame);
|
VaapiRenderFrame(decoder, video_ctx, frame);
|
||||||
#ifdef USE_AUTOCROP
|
#ifdef USE_AUTOCROP
|
||||||
VaapiCheckAutoCrop(decoder);
|
VaapiCheckAutoCrop(decoder);
|
||||||
@ -4661,6 +4670,10 @@ static void VaapiDisplayHandlerThread(void)
|
|||||||
if (err) {
|
if (err) {
|
||||||
// FIXME: sleep on wakeup
|
// FIXME: sleep on wakeup
|
||||||
usleep(5 * 1000); // nothing buffered
|
usleep(5 * 1000); // nothing buffered
|
||||||
|
if (err == -1 && decoder->Closing > 0) {
|
||||||
|
Debug(3, "video/vaapi: closing eof\n");
|
||||||
|
decoder->Closing = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &nowtime);
|
clock_gettime(CLOCK_REALTIME, &nowtime);
|
||||||
@ -5002,6 +5015,7 @@ typedef struct _vdpau_decoder_
|
|||||||
int TrickSpeed; ///< current trick speed
|
int TrickSpeed; ///< current trick speed
|
||||||
int TrickCounter; ///< current trick speed counter
|
int TrickCounter; ///< current trick speed counter
|
||||||
struct timespec FrameTime; ///< time of last display
|
struct timespec FrameTime; ///< time of last display
|
||||||
|
int Closing; ///< flag about closing current stream
|
||||||
int64_t PTS; ///< video PTS clock
|
int64_t PTS; ///< video PTS clock
|
||||||
|
|
||||||
int SyncCounter; ///< counter to sync frames
|
int SyncCounter; ///< counter to sync frames
|
||||||
@ -5721,6 +5735,7 @@ static void VdpauCleanup(VdpauDecoder * decoder)
|
|||||||
|
|
||||||
decoder->FrameCounter = 0;
|
decoder->FrameCounter = 0;
|
||||||
decoder->FramesDisplayed = 0;
|
decoder->FramesDisplayed = 0;
|
||||||
|
decoder->Closing = 0;
|
||||||
decoder->PTS = AV_NOPTS_VALUE;
|
decoder->PTS = AV_NOPTS_VALUE;
|
||||||
VideoDeltaPTS = 0;
|
VideoDeltaPTS = 0;
|
||||||
}
|
}
|
||||||
@ -7711,6 +7726,9 @@ static void VdpauSyncDecoder(VdpauDecoder * decoder)
|
|||||||
_("video: decoder buffer empty, "
|
_("video: decoder buffer empty, "
|
||||||
"duping frame (%d/%d) %d v-buf\n"), decoder->FramesDuped,
|
"duping frame (%d/%d) %d v-buf\n"), decoder->FramesDuped,
|
||||||
decoder->FrameCounter, VideoGetBuffers());
|
decoder->FrameCounter, VideoGetBuffers());
|
||||||
|
if (decoder->Closing == -1) {
|
||||||
|
atomic_set(&decoder->SurfacesFilled, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -7782,7 +7800,9 @@ static void VdpauSyncRenderFrame(VdpauDecoder * decoder,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (VdpauPreemption) { // display preempted
|
if (VdpauPreemption) { // display preempted
|
||||||
|
if (!decoder->Closing) {
|
||||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if video output buffer is full, wait and display surface.
|
// if video output buffer is full, wait and display surface.
|
||||||
@ -7821,7 +7841,9 @@ static void VdpauSyncRenderFrame(VdpauDecoder * decoder,
|
|||||||
VdpauSyncDisplayFrame();
|
VdpauSyncDisplayFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!decoder->Closing) {
|
||||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
||||||
|
}
|
||||||
VdpauRenderFrame(decoder, video_ctx, frame);
|
VdpauRenderFrame(decoder, video_ctx, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7944,6 +7966,10 @@ static void VdpauDisplayHandlerThread(void)
|
|||||||
if (err) {
|
if (err) {
|
||||||
// FIXME: sleep on wakeup
|
// FIXME: sleep on wakeup
|
||||||
usleep(5 * 1000); // nothing buffered
|
usleep(5 * 1000); // nothing buffered
|
||||||
|
if (err == -1 && decoder->Closing > 0) {
|
||||||
|
Debug(3, "video/vdpau: closing eof\n");
|
||||||
|
decoder->Closing = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &nowtime);
|
clock_gettime(CLOCK_REALTIME, &nowtime);
|
||||||
@ -9001,7 +9027,7 @@ enum PixelFormat Video_get_format(VideoHwDecoder * hw_decoder,
|
|||||||
|
|
||||||
Debug(3, "video: ready %s %dms/frame\n",
|
Debug(3, "video: ready %s %dms/frame\n",
|
||||||
Timestamp2String(VideoGetClock(hw_decoder)), ms_delay);
|
Timestamp2String(VideoGetClock(hw_decoder)), ms_delay);
|
||||||
AudioVideoReady();
|
AudioVideoReady(VideoGetClock(hw_decoder));
|
||||||
return VideoUsedModule->get_format(hw_decoder, video_ctx, fmt);
|
return VideoUsedModule->get_format(hw_decoder, video_ctx, fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9126,6 +9152,29 @@ int64_t VideoGetClock(const VideoHwDecoder * hw_decoder)
|
|||||||
return AV_NOPTS_VALUE;
|
return AV_NOPTS_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Set closing stream flag.
|
||||||
|
///
|
||||||
|
/// @param hw_decoder video hardware decoder
|
||||||
|
///
|
||||||
|
void VideoSetClosing(VideoHwDecoder * hw_decoder)
|
||||||
|
{
|
||||||
|
Debug(3, "video: set closing\n");
|
||||||
|
// FIXME: test to check if working, than make module function
|
||||||
|
#ifdef USE_VDPAU
|
||||||
|
if (VideoUsedModule == &VdpauModule) {
|
||||||
|
hw_decoder->Vdpau.Closing = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_VAPI
|
||||||
|
if (VideoUsedModule == &VaapiModule) {
|
||||||
|
hw_decoder->Vaapi.Closing = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// clear clock to avoid further sync
|
||||||
|
VideoSetClock(hw_decoder, AV_NOPTS_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set trick play speed.
|
/// Set trick play speed.
|
||||||
///
|
///
|
||||||
|
3
video.h
3
video.h
@ -153,6 +153,9 @@ extern void VideoSetClock(VideoHwDecoder *, int64_t);
|
|||||||
/// Get video clock.
|
/// Get video clock.
|
||||||
extern int64_t VideoGetClock(const VideoHwDecoder *);
|
extern int64_t VideoGetClock(const VideoHwDecoder *);
|
||||||
|
|
||||||
|
/// Set closing flag.
|
||||||
|
extern void VideoSetClosing(VideoHwDecoder *);
|
||||||
|
|
||||||
/// Set trick play speed.
|
/// Set trick play speed.
|
||||||
extern void VideoSetTrickSpeed(VideoHwDecoder *, int);
|
extern void VideoSetTrickSpeed(VideoHwDecoder *, int);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user