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

View File

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

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

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

View File

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

View File

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

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

View File

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