Show black picture, if no video stream available.

New audio ring code.
New audio filters (first part).
This commit is contained in:
Johns 2012-04-17 16:45:27 +02:00
parent c9ef8b759a
commit 79e78bf235
9 changed files with 1323 additions and 128 deletions

View File

@ -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.

View File

@ -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

1194
audio.c

File diff suppressed because it is too large Load Diff

View File

@ -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
View File

@ -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);
}
}
} }
/** /**

View File

@ -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;

View File

@ -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
View File

@ -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.
/// ///

View File

@ -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);