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
|
||||
Date:
|
||||
|
||||
Show black picture, if no video stream is available.
|
||||
Setup split into foldable sections.
|
||||
Adds show cursor on pointer move and hide after 200ms.
|
||||
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
|
||||
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
|
||||
0 disables auto-crop
|
||||
n each 'n' frames auto-crop is checked.
|
||||
@ -253,6 +275,9 @@ Keymacros:
|
||||
@softhddevice Blue 2 0 disable fullscreen
|
||||
@softhddevice Blue 2 1 enable 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 1 letter box 4:3 in 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 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 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,
|
||||
audio_decoder->DriftCorr / 10, distance);
|
||||
}
|
||||
Debug(3, "codec/audio: drift(%6d) %8dus %5d\n", audio_decoder->DriftCorr,
|
||||
drift * 1000 / 90, corr);
|
||||
if (1) {
|
||||
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
|
||||
#endif
|
||||
|
||||
extern int ConfigAudioBufferTime; ///< config size ms of audio buffer
|
||||
static char ConfigStartSuspended; ///< flag to start in suspend mode
|
||||
static char ConfigFullscreen; ///< fullscreen modus
|
||||
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) {
|
||||
// this clears the audio ringbuffer indirect, open and setup does it
|
||||
CodecAudioClose(MyAudioDecoder);
|
||||
AudioSetBufferTime(0);
|
||||
AudioFlushBuffers();
|
||||
AudioSetBufferTime(ConfigAudioBufferTime);
|
||||
AudioCodecID = CODEC_ID_NONE;
|
||||
AudioChannelID = -1;
|
||||
NewAudioStream = 0;
|
||||
@ -972,6 +974,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
||||
samplerate = samplerates[p[5] >> 4];
|
||||
channels = (p[5] & 0x7) + 1;
|
||||
|
||||
// FIXME: ConfigAudioBufferTime + x
|
||||
AudioSetBufferTime(400);
|
||||
AudioSetup(&samplerate, &channels, 0);
|
||||
if (samplerate != samplerates[p[5] >> 4]) {
|
||||
@ -1002,6 +1005,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
||||
p += 4;
|
||||
n -= 4; // skip track header
|
||||
if (AudioCodecID == CODEC_ID_NONE) {
|
||||
// FIXME: ConfigAudioBufferTime + x
|
||||
AudioSetBufferTime(400);
|
||||
}
|
||||
}
|
||||
@ -1100,8 +1104,9 @@ int PlayTsAudio(const uint8_t * data, int size)
|
||||
if (NewAudioStream) {
|
||||
// this clears the audio ringbuffer indirect, open and setup does it
|
||||
CodecAudioClose(MyAudioDecoder);
|
||||
AudioFlushBuffers();
|
||||
// max time between audio packets 200ms + 24ms hw buffer
|
||||
AudioSetBufferTime(264);
|
||||
AudioSetBufferTime(ConfigAudioBufferTime);
|
||||
AudioCodecID = CODEC_ID_NONE;
|
||||
AudioChannelID = -1;
|
||||
NewAudioStream = 0;
|
||||
@ -1128,7 +1133,7 @@ int PlayTsAudio(const uint8_t * data, int size)
|
||||
*/
|
||||
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) {
|
||||
last_codec_id = CODEC_ID_NONE;
|
||||
CodecVideoClose(MyVideoDecoder);
|
||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
||||
goto skip;
|
||||
}
|
||||
// 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) {
|
||||
FixPacketForFFMpeg(MyVideoDecoder, avpkt);
|
||||
} else {
|
||||
@ -1639,9 +1638,6 @@ int PlayVideo(const uint8_t * data, int size)
|
||||
}
|
||||
VideoNextPacket(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;
|
||||
NewVideoStream = 0;
|
||||
}
|
||||
@ -1858,6 +1854,8 @@ int SetPlayMode(int play_mode)
|
||||
if (MyVideoDecoder) { // tell video parser we have new stream
|
||||
if (VideoCodecID != CODEC_ID_NONE) {
|
||||
NewVideoStream = 1;
|
||||
// tell hw decoder we are closing stream
|
||||
VideoSetClosing(MyHwDecoder);
|
||||
#ifdef DEBUG
|
||||
VideoSwitch = GetMsTicks();
|
||||
#endif
|
||||
@ -1873,11 +1871,9 @@ int SetPlayMode(int play_mode)
|
||||
break;
|
||||
case 2: // audio only
|
||||
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
||||
break;
|
||||
case 3: // audio only, black screen
|
||||
Debug(3, "softhddev: FIXME: audio only, silence video errors\n");
|
||||
VideoSetClock(MyHwDecoder, AV_NOPTS_VALUE);
|
||||
break;
|
||||
case 4: // video only
|
||||
break;
|
||||
|
129
softhddevice.cpp
129
softhddevice.cpp
@ -35,10 +35,10 @@
|
||||
#include "softhddevice.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "audio.h"
|
||||
#include "video.h"
|
||||
extern const char *X11DisplayName; ///< x11 display name
|
||||
|
||||
extern void AudioPoller(void);
|
||||
extern void CodecSetAudioPassthrough(int);
|
||||
extern void CodecSetAudioDownmix(int);
|
||||
}
|
||||
@ -121,6 +121,7 @@ static int ConfigAudioMaxNormalize; ///< config max normalize factor
|
||||
static char ConfigAudioCompression; ///< config use volume compression
|
||||
static int ConfigAudioMaxCompression; ///< config max volume compression
|
||||
static int ConfigAudioStereoDescent; ///< config reduce stereo loudness
|
||||
int ConfigAudioBufferTime; ///< config size ms of audio buffer
|
||||
|
||||
static volatile int DoMakePrimary; ///< switch primary device to this
|
||||
|
||||
@ -482,6 +483,8 @@ class cMenuSetupSoft:public cMenuSetupPage
|
||||
int SuspendX11;
|
||||
|
||||
int Video;
|
||||
int VideoFormat;
|
||||
int VideoDisplayFormat;
|
||||
uint32_t Background;
|
||||
uint32_t BackgroundAlpha;
|
||||
int StudioLevels;
|
||||
@ -512,6 +515,7 @@ class cMenuSetupSoft:public cMenuSetupPage
|
||||
int AudioCompression;
|
||||
int AudioMaxCompression;
|
||||
int AudioStereoDescent;
|
||||
int AudioBufferTime;
|
||||
/// @}
|
||||
private:
|
||||
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)
|
||||
{
|
||||
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[] = {
|
||||
"Bob", "Weave/None", "Temporal", "TemporalSpatial", "Software Bob",
|
||||
"Software Spatial",
|
||||
@ -598,26 +608,36 @@ void cMenuSetupSoft::Create(void)
|
||||
// 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")));
|
||||
Add(new cMenuEditBoolItem(tr("suspend stops x11"), &SuspendX11,
|
||||
Add(new cMenuEditBoolItem(tr("Suspend stops x11"), &SuspendX11,
|
||||
trVDR("no"), trVDR("yes")));
|
||||
}
|
||||
//
|
||||
// video
|
||||
//
|
||||
Add(CollapsedItem(tr("Video"), 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));
|
||||
Add(new cMenuEditIntItem(tr("video background color (Alpha)"),
|
||||
Add(new cMenuEditIntItem(tr("Video background color (Alpha)"),
|
||||
(int *)&BackgroundAlpha, 0, 0xFF));
|
||||
Add(new cMenuEditBoolItem(tr("Use studio levels (vdpau only)"),
|
||||
&StudioLevels, trVDR("no"), trVDR("yes")));
|
||||
Add(new cMenuEditBoolItem(tr("60hz display mode"), &_60HzMode,
|
||||
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")));
|
||||
|
||||
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||
@ -648,11 +668,11 @@ void cMenuSetupSoft::Create(void)
|
||||
// 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")));
|
||||
Add(new cMenuEditIntItem(tr("autocrop delay (n * interval)"),
|
||||
Add(new cMenuEditIntItem(tr("Autocrop delay (n * interval)"),
|
||||
&AutoCropDelay, 0, 200));
|
||||
Add(new cMenuEditIntItem(tr("autocrop tolerance (pixel)"),
|
||||
Add(new cMenuEditIntItem(tr("Autocrop tolerance (pixel)"),
|
||||
&AutoCropTolerance, 0, 32));
|
||||
}
|
||||
//
|
||||
@ -667,6 +687,20 @@ void cMenuSetupSoft::Create(void)
|
||||
2, passthrough));
|
||||
Add(new cMenuEditBoolItem(tr("Enable AC-3 downmix"), &AudioDownmix,
|
||||
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
|
||||
@ -682,19 +716,22 @@ eOSState cMenuSetupSoft::ProcessKey(eKeys key)
|
||||
int old_general;
|
||||
int old_video;
|
||||
int old_audio;
|
||||
int old_video_format;
|
||||
int old_resolution_shown[RESOLUTIONS];
|
||||
int i;
|
||||
|
||||
old_general = General;
|
||||
old_video = Video;
|
||||
old_audio = Audio;
|
||||
old_video_format = VideoFormat;
|
||||
memcpy(old_resolution_shown, ResolutionShown, sizeof(ResolutionShown));
|
||||
state = cMenuSetupPage::ProcessKey(key);
|
||||
|
||||
if (key != kNone) {
|
||||
// update menu only, if something on the structure has changed
|
||||
// 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
|
||||
} else {
|
||||
for (i = 0; i < RESOLUTIONS; ++i) {
|
||||
@ -734,6 +771,8 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
||||
// video
|
||||
//
|
||||
Video = 0;
|
||||
VideoFormat = Setup.VideoFormat;
|
||||
VideoDisplayFormat = Setup.VideoDisplayFormat;
|
||||
// no unsigned int menu item supported, split background color/alpha
|
||||
Background = ConfigVideoBackground >> 8;
|
||||
BackgroundAlpha = ConfigVideoBackground & 0xFF;
|
||||
@ -773,6 +812,7 @@ cMenuSetupSoft::cMenuSetupSoft(void)
|
||||
AudioCompression = ConfigAudioCompression;
|
||||
AudioMaxCompression = ConfigAudioMaxCompression;
|
||||
AudioStereoDescent = ConfigAudioStereoDescent;
|
||||
AudioBufferTime = ConfigAudioBufferTime;
|
||||
|
||||
Create();
|
||||
}
|
||||
@ -789,6 +829,20 @@ void cMenuSetupSoft::Store(void)
|
||||
HideMainMenuEntry);
|
||||
SetupStore("Suspend.Close", ConfigSuspendClose = SuspendClose);
|
||||
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);
|
||||
SetupStore("Background", ConfigVideoBackground);
|
||||
@ -838,7 +892,7 @@ void cMenuSetupSoft::Store(void)
|
||||
AutoCropTolerance);
|
||||
VideoSetAutoCrop(ConfigAutoCropInterval, ConfigAutoCropDelay,
|
||||
ConfigAutoCropTolerance);
|
||||
ConfigAutoCropEnabled = ConfigAutoCropInterval;
|
||||
ConfigAutoCropEnabled = ConfigAutoCropInterval != 0;
|
||||
|
||||
SetupStore("AudioDelay", ConfigVideoAudioDelay = AudioDelay);
|
||||
VideoSetAudioDelay(ConfigVideoAudioDelay);
|
||||
@ -846,7 +900,17 @@ void cMenuSetupSoft::Store(void)
|
||||
CodecSetAudioPassthrough(ConfigAudioPassthrough);
|
||||
SetupStore("AudioDownmix", ConfigAudioDownmix = AudioDownmix);
|
||||
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"));
|
||||
break;
|
||||
case 25: // toggle auto-crop
|
||||
ConfigAutoCropEnabled = !ConfigAutoCropEnabled;
|
||||
ConfigAutoCropEnabled ^= 1;
|
||||
// no interval configured, use some default
|
||||
if (!ConfigAutoCropInterval) {
|
||||
ConfigAutoCropInterval = 50;
|
||||
@ -1283,6 +1347,7 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode play_mode)
|
||||
return true;
|
||||
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
||||
dsyslog("[softhddev] play mode external\n");
|
||||
// FIXME: what if already suspended?
|
||||
Suspend(1, 1, 0);
|
||||
SuspendMode = SUSPEND_EXTERNAL;
|
||||
return true;
|
||||
@ -1916,7 +1981,7 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
if (!strcasecmp(name, "AutoCrop.Interval")) {
|
||||
VideoSetAutoCrop(ConfigAutoCropInterval =
|
||||
atoi(value), ConfigAutoCropDelay, ConfigAutoCropTolerance);
|
||||
ConfigAutoCropEnabled = ConfigAutoCropInterval;
|
||||
ConfigAutoCropEnabled = ConfigAutoCropInterval != 0;
|
||||
return true;
|
||||
}
|
||||
if (!strcasecmp(name, "AutoCrop.Delay")) {
|
||||
@ -1942,7 +2007,39 @@ bool cPluginSoftHdDevice::SetupParse(const char *name, const char *value)
|
||||
CodecSetAudioDownmix(ConfigAudioDownmix = atoi(value));
|
||||
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;
|
||||
}
|
||||
|
59
video.c
59
video.c
@ -356,7 +356,7 @@ static xcb_atom_t NetWmStateFullscreen; ///< fullscreen wm-state message atom
|
||||
#ifdef DEBUG
|
||||
extern uint32_t VideoSwitch; ///< ticks for channel switch
|
||||
#endif
|
||||
extern void AudioVideoReady(void); ///< tell audio video is ready
|
||||
extern void AudioVideoReady(int64_t); ///< tell audio video is ready
|
||||
|
||||
#ifdef USE_VIDEO_THREAD
|
||||
|
||||
@ -427,6 +427,8 @@ static void VideoSetPts(int64_t * pts_p, int interlaced, const AVFrame * frame)
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else { // first new clock value
|
||||
AudioVideoReady(pts);
|
||||
}
|
||||
if (*pts_p != pts) {
|
||||
Debug(4,
|
||||
@ -1334,6 +1336,7 @@ struct _vaapi_decoder_
|
||||
int TrickSpeed; ///< current trick speed
|
||||
int TrickCounter; ///< current trick speed counter
|
||||
struct timespec FrameTime; ///< time of last display
|
||||
int Closing; ///< flag about closing current stream
|
||||
int64_t PTS; ///< video PTS clock
|
||||
|
||||
int SyncCounter; ///< counter to sync frames
|
||||
@ -1856,6 +1859,7 @@ static void VaapiCleanup(VaapiDecoder * decoder)
|
||||
|
||||
decoder->FrameCounter = 0;
|
||||
decoder->FramesDisplayed = 0;
|
||||
decoder->Closing = 0;
|
||||
decoder->PTS = AV_NOPTS_VALUE;
|
||||
VideoDeltaPTS = 0;
|
||||
}
|
||||
@ -4504,6 +4508,9 @@ static void VaapiSyncDecoder(VaapiDecoder * decoder)
|
||||
_("video: decoder buffer empty, "
|
||||
"duping frame (%d/%d) %d v-buf\n"), decoder->FramesDuped,
|
||||
decoder->FrameCounter, VideoGetBuffers());
|
||||
if (decoder->Closing == -1) {
|
||||
atomic_set(&decoder->SurfacesFilled, 0);
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
@ -4600,7 +4607,9 @@ static void VaapiSyncRenderFrame(VaapiDecoder * decoder,
|
||||
VaapiSyncDisplayFrame();
|
||||
}
|
||||
|
||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
||||
if (!decoder->Closing) {
|
||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
||||
}
|
||||
VaapiRenderFrame(decoder, video_ctx, frame);
|
||||
#ifdef USE_AUTOCROP
|
||||
VaapiCheckAutoCrop(decoder);
|
||||
@ -4661,6 +4670,10 @@ static void VaapiDisplayHandlerThread(void)
|
||||
if (err) {
|
||||
// FIXME: sleep on wakeup
|
||||
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);
|
||||
@ -5002,6 +5015,7 @@ typedef struct _vdpau_decoder_
|
||||
int TrickSpeed; ///< current trick speed
|
||||
int TrickCounter; ///< current trick speed counter
|
||||
struct timespec FrameTime; ///< time of last display
|
||||
int Closing; ///< flag about closing current stream
|
||||
int64_t PTS; ///< video PTS clock
|
||||
|
||||
int SyncCounter; ///< counter to sync frames
|
||||
@ -5721,6 +5735,7 @@ static void VdpauCleanup(VdpauDecoder * decoder)
|
||||
|
||||
decoder->FrameCounter = 0;
|
||||
decoder->FramesDisplayed = 0;
|
||||
decoder->Closing = 0;
|
||||
decoder->PTS = AV_NOPTS_VALUE;
|
||||
VideoDeltaPTS = 0;
|
||||
}
|
||||
@ -7711,6 +7726,9 @@ static void VdpauSyncDecoder(VdpauDecoder * decoder)
|
||||
_("video: decoder buffer empty, "
|
||||
"duping frame (%d/%d) %d v-buf\n"), decoder->FramesDuped,
|
||||
decoder->FrameCounter, VideoGetBuffers());
|
||||
if (decoder->Closing == -1) {
|
||||
atomic_set(&decoder->SurfacesFilled, 0);
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
@ -7782,7 +7800,9 @@ static void VdpauSyncRenderFrame(VdpauDecoder * decoder,
|
||||
#endif
|
||||
|
||||
if (VdpauPreemption) { // display preempted
|
||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
||||
if (!decoder->Closing) {
|
||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// if video output buffer is full, wait and display surface.
|
||||
@ -7821,7 +7841,9 @@ static void VdpauSyncRenderFrame(VdpauDecoder * decoder,
|
||||
VdpauSyncDisplayFrame();
|
||||
}
|
||||
|
||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
||||
if (!decoder->Closing) {
|
||||
VideoSetPts(&decoder->PTS, decoder->Interlaced, frame);
|
||||
}
|
||||
VdpauRenderFrame(decoder, video_ctx, frame);
|
||||
}
|
||||
|
||||
@ -7944,6 +7966,10 @@ static void VdpauDisplayHandlerThread(void)
|
||||
if (err) {
|
||||
// FIXME: sleep on wakeup
|
||||
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);
|
||||
@ -9001,7 +9027,7 @@ enum PixelFormat Video_get_format(VideoHwDecoder * hw_decoder,
|
||||
|
||||
Debug(3, "video: ready %s %dms/frame\n",
|
||||
Timestamp2String(VideoGetClock(hw_decoder)), ms_delay);
|
||||
AudioVideoReady();
|
||||
AudioVideoReady(VideoGetClock(hw_decoder));
|
||||
return VideoUsedModule->get_format(hw_decoder, video_ctx, fmt);
|
||||
}
|
||||
|
||||
@ -9126,6 +9152,29 @@ int64_t VideoGetClock(const VideoHwDecoder * hw_decoder)
|
||||
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.
|
||||
///
|
||||
|
3
video.h
3
video.h
@ -153,6 +153,9 @@ extern void VideoSetClock(VideoHwDecoder *, int64_t);
|
||||
/// Get video clock.
|
||||
extern int64_t VideoGetClock(const VideoHwDecoder *);
|
||||
|
||||
/// Set closing flag.
|
||||
extern void VideoSetClosing(VideoHwDecoder *);
|
||||
|
||||
/// Set trick play speed.
|
||||
extern void VideoSetTrickSpeed(VideoHwDecoder *, int);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user