[vdr-plugin-softhddevice] 01/03: Imported Upstream version 0.6.0+git20130909
Tobias Grimm
tiber-guest at alioth.debian.org
Mon Sep 9 19:30:21 UTC 2013
This is an automated email from the git hooks/post-receive script.
tiber-guest pushed a commit to branch master
in repository vdr-plugin-softhddevice.
commit 7c7b03f6e4ae4a29f3f10146eb753198ecf19856
Author: etobi <git at e-tobi.net>
Date: Mon Sep 9 21:22:36 2013 +0200
Imported Upstream version 0.6.0+git20130909
---
.gitattributes | 6 +
.gitignore | 10 +
.indent.pro | 37 ++
ChangeLog | 28 ++
Makefile | 24 +-
README.txt | 27 +-
Todo | 8 +-
audio.c | 44 +-
audio.h | 2 +-
codec.c | 52 ++-
codec.h | 4 +-
greater_sync_2.diff | 52 ---
misc.h | 2 +-
po/de_DE.po | 27 +-
ringbuffer.c | 2 +-
ringbuffer.h | 2 +-
softhddev.c | 246 ++++++-----
softhddev.h | 2 +-
softhddevice.cpp | 17 +-
softhddevice.h | 2 +-
vdr-softhddevice | 1 -
vdr-softhddevice-9999.ebuild | 4 +-
video.c | 938 +++++++++++++++++++++++++-----------------
video.h | 6 +-
24 files changed, 935 insertions(+), 608 deletions(-)
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..c6a39fd
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,6 @@
+# gitattributes(5) file
+*.[15] ident
+*.[ch] ident
+*.cpp ident
+*.txt ident
+Makefile ident
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7858ebc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+# gitignore(5) file
+*.[oa]
+*~
+.*.swp
+.gdb_history
+# work directory
+.chaos
+# generated files
+.dependencies
+libvdr-softhddevice.so*
diff --git a/.indent.pro b/.indent.pro
new file mode 100644
index 0000000..1e2b436
--- /dev/null
+++ b/.indent.pro
@@ -0,0 +1,37 @@
+--blank-lines-before-block-comments
+--blank-lines-after-declarations
+--blank-lines-after-procedures
+--no-blank-lines-after-commas
+--braces-on-if-line
+--no-blank-before-sizeof
+--comment-indentation41
+--declaration-comment-column41
+--no-comment-delimiters-on-blank-lines
+--swallow-optional-blank-lines
+--dont-format-comments
+--parameter-indentation4
+--indent-level4
+--line-comments-indentation0
+--cuddle-else
+--cuddle-do-while
+--brace-indent0
+--case-brace-indentation0
+//--start-left-side-of-comments
+--leave-preprocessor-space
+//--continuation-indentation8
+--case-indentation4
+--else-endif-column0
+--no-space-after-casts
+--declaration-indentation1
+--dont-line-up-parentheses
+--no-space-after-function-call-names
+--space-special-semicolon
+--tab-size8
+--use-tabs
+--line-length79
+--comment-line-length79
+--honour-newlines
+--dont-break-procedure-type
+--break-before-boolean-operator
+--continuation-indentation4
+--ignore-newlines
diff --git a/ChangeLog b/ChangeLog
index ad4c4e3..990891c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,32 @@
User johns
+Date:
+
+ Add function GetStats to the video output module.
+ Add function ResetStart to the video output module.
+ Add function SetClosing to the video output module.
+ Generalize GetVaapiContext to GetHwAccelContext.
+ Add compile time configurable trickspeed packets dump.
+ Fix bug #1410: wrong spelled AC-3 and E-AC-3.
+ Add compile time selectable h264 trickspeed workaround.
+ Use ffmpeg new names AVCodecID, AV_CODEC_... .
+ Fix bug: video lagging behind after recording stop.
+ Reduce PES error messages.
+ Fix bug #1392: Wrong value for mixing LFE.
+ Fix bug: wrong grab size, introduced with AMD VDPAU.
+ Use VDR SPU decoder as default.
+ Fix bug: grab image negative quality isn't the default 100.
+ Support AMD VDPAU with surface size != requested size.
+ Add cache for auto-crop buffer.
+ Fix opengl and opengl threads bugs.
+ Initial opengl support with va-api only.
+ Fix "broken driver" message if empty ring buffer.
+ Enable seamless audio track change.
+ Fix bug #1302: Unsupported pixel format crash.
+ Fix the fix, when sillpicture is called in suspend mode.
+ Fix crash, when sillpicture is called in suspend mode.
+ Add workaround for zero width+height and ffmpeg >= 1.2.
+
+User johns
Date: Sun Mar 17 15:52:42 CET 2013
Release Version 0.6.0
diff --git a/Makefile b/Makefile
index f76074c..03a86be 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for a Video Disk Recorder plugin
#
-# $Id: fa415ef17db86f247803e3e3ca8cca8b075189fa $
+# $Id$
# The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin.
@@ -15,10 +15,12 @@ PLUGIN = softhddevice
ALSA ?= $(shell pkg-config --exists alsa && echo 1)
# support OSS audio output module
OSS ?= 1
- # support VDPAU video output modue
+ # support VDPAU video output module
VDPAU ?= $(shell pkg-config --exists vdpau && echo 1)
- # support VA-API video output modue
-VAAPI ?= $(shell pkg-config --exists libva && echo 1)
+ # support VA-API video output module (deprecated)
+#VAAPI ?= $(shell pkg-config --exists libva && echo 1)
+ # support glx output
+#OPENGL ?= $(shell pkg-config --exists gl glu && echo 1)
# screensaver disable/enable
SCREENSAVER ?= 1
# use ffmpeg libswresample
@@ -33,7 +35,10 @@ CONFIG += -DUSE_PIP # PIP support
#CONFIG += -DNO_TS_AUDIO # disable ts audio parser
#CONFIG += -DUSE_TS_VIDEO # build new ts video parser
#CONFIG += -DUSE_MPEG_COMPLETE # support only complete mpeg packets
-#CONFIG += -DUSE_VDR_SPU # use VDR SPU decoder.
+#CONFIG += -DH264_EOS_TRICKSPEED # insert seq end packets for trickspeed
+#CONDIF += -DDUMP_TRICKSPEED # dump trickspeed packets
+CONFIG += -DUSE_VDR_SPU # use VDR SPU decoder.
+#CONFIG += -DUSE_SOFTLIMIT # (tobe removed) limit the buffer fill
ifeq ($(ALSA),1)
CONFIG += -DUSE_ALSA
@@ -52,6 +57,15 @@ ifeq ($(VAAPI),1)
CONFIG += -DUSE_VAAPI
_CFLAGS += $(shell pkg-config --cflags libva-x11 libva)
LIBS += $(shell pkg-config --libs libva-x11 libva)
+ifeq ($(OPENGL),1)
+_CFLAGS += $(shell pkg-config --cflags libva-glx)
+LIBS += $(shell pkg-config --libs libva-glx)
+endif
+endif
+ifeq ($(OPENGL),1)
+CONFIG += -DUSE_GLX
+_CFLAGS += $(shell pkg-config --cflags gl glu)
+LIBS += $(shell pkg-config --libs gl glu)
endif
ifeq ($(SCREENSAVER),1)
CONFIG += -DUSE_SCREENSAVER
diff --git a/README.txt b/README.txt
index ee2e67a..01f9607 100644
--- a/README.txt
+++ b/README.txt
@@ -16,18 +16,18 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-$Id: 026a82b979adeb7d75c829eb8bc05f4594c940e2 $
+$Id$
A software and GPU emulated HD output device plugin for VDR.
- o Video decoder CPU / VA-API / VDPAU
- o Video output VA-API / VDPAU
+ o Video decoder CPU / VDPAU
+ o Video output VDPAU
o Audio FFMpeg / Alsa / Analog
o Audio FFMpeg / Alsa / Digital
o Audio FFMpeg / OSS / Analog
o HDMI/SPDIF pass-through
o Software volume, compression, normalize and channel resample
- o YaepgHD support / new >1.7.33 VDR ScaleVideo API support
+ o VDR ScaleVideo API
o Software deinterlacer Bob (VA-API only)
o Autocrop
o Grab image (VDPAU only)
@@ -36,10 +36,11 @@ A software and GPU emulated HD output device plugin for VDR.
o atmo light support with plugin http://github.com/durchflieger/DFAtmo
o PIP (Picture-in-Picture) (VDPAU only)
- o planned: Video decoder VA-API Branch: vaapi-ext/staging
- o planned: Video output XvBA / Opengl / Xv
- o planned: VA-API grab image
- o planned: Improved Software Deinterlacer (yadif or/and ffmpeg filters)
+ o planned: Remove VA-API decoder and output support
+ o planned: Video decoder OpenMax
+ o planned: Video output Opengl / Xv
+ o planned: Improved software deinterlacer (yadif or/and ffmpeg filters)
+ o XvBa support is no longer planned (use future Radeon UVD VDPAU)
To compile you must have the 'requires' installed.
@@ -83,14 +84,12 @@ Setup: environment
if set don't use the hardware decoders
NO_MPEG_HW=1
if set don't use the hardware decoder for mpeg1/2
- STUDIO_LEVELS=1
- if set use studio levels with vdpau (deprecated use setup)
only if alsa is configured
ALSA_DEVICE=default
alsa PCM device name
ALSA_PASSTHROUGH_DEVICE=
- alsa pass-though (AC3,EAC3,DTS,...) device name
+ alsa pass-though (AC-3,E-AC-3,DTS,...) device name
ALSA_MIXER=default
alsa control device name
ALSA_MIXER_CHANNEL=PCM
@@ -100,7 +99,7 @@ Setup: environment
OSS_AUDIODEV=/dev/dsp
oss dsp device name
OSS_PASSTHROUGHDEV=
- oss pass-though (AC3,EAC3,DTS,...) device name
+ oss pass-though (AC-3,E-AC-3,DTS,...) device name
OSS_MIXERDEV=/dev/mixer
oss mixer device name
OSS_MIXER_CHANNEL=pcm
@@ -130,7 +129,7 @@ Setup: /etc/vdr/setup.conf
softhddevice.<res>.Deinterlace = 0
0 = bob, 1 = weave, 2 = temporal, 3 = temporal_spatial, 4 = software
- (only 0, 1 supported with vaapi)
+ (only 0, 1, 4 supported with VA-API)
softhddevice.<res>.SkipChromaDeinterlace = 0
0 = disabled, 1 = enabled (for slower cards, poor qualit�t)
@@ -361,7 +360,7 @@ Requires:
or
kernel support for oss/oss4 or alsa oss emulation
- x11-libs/libva
+ x11-libs/libva (deprecated)
Video Acceleration (VA) API for Linux
http://www.freedesktop.org/wiki/Software/vaapi
x11-libs/libva-intel-driver
diff --git a/Todo b/Todo
index cc36bcc..863de11 100644
--- a/Todo
+++ b/Todo
@@ -1,6 +1,6 @@
@file Todo @brief A software HD output device for VDR
-Copyright (c) 2011, 2012 by Johns. All Rights Reserved.
+Copyright (c) 2011 - 2013 by Johns. All Rights Reserved.
Contributor(s):
@@ -19,6 +19,9 @@ GNU Affero General Public License for more details.
$Id: $
missing:
+ documentation of the PIP hotkeys.
+ svdrp help page missing PIP hotkeys.
+ svdrp stat: add X11 crashed status.
more software deinterlace (yadif, ...)
more software decoder with software deinterlace
suspend output / energie saver: stop and restart X11
@@ -40,11 +43,14 @@ video:
check start with 24Hz display rate
crash with ffmpeg without vaapi and vdpau.
still-picture of PES recordings should use VideoMpegEnqueue.
+ convert PIX_FMT_... PixelFormat to new names AV_PIX_FMT_..., AVPixelFormat.
+ atmo service support 3D grab
vdpau:
software deinterlace path not working.
OSD looses transparency, during channel switch.
OSD looses transparency, while moving cut marks.
+ ffmpeg >=1.2 supports same API like VA-API.
libva:
yaepghd (VaapiSetOutputPosition) support
diff --git a/audio.c b/audio.c
index 3a1193f..6ad2907 100644
--- a/audio.c
+++ b/audio.c
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: 644c18a88c0714fe51c774b09118cc609d55bcd3 $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
///
@@ -486,7 +486,7 @@ static void AudioSurround2Stereo(const int16_t * in, int in_chan, int frames,
r += in[3] * 200; // Rs
l += in[4] * 300; // C
r += in[4] * 300;
- l += in[5] * 300; // LFE
+ l += in[5] * 100; // LFE
r += in[5] * 100;
break;
case 7: // 7.0
@@ -620,7 +620,7 @@ static void AudioResample(const int16_t * in, int in_chan, int frames,
typedef struct _audio_ring_ring_
{
char FlushBuffers; ///< flag: flush buffers
- char Passthrough; ///< flag: use pass-through (AC3, ...)
+ char Passthrough; ///< flag: use pass-through (AC-3, ...)
int16_t PacketSize; ///< packet size
unsigned HwSampleRate; ///< hardware sample rate in Hz
unsigned HwChannels; ///< hardware number of channels
@@ -642,7 +642,7 @@ static unsigned AudioStartThreshold; ///< start play, if filled
**
** @param sample_rate sample-rate frequency
** @param channels number of channels
-** @param passthrough use /pass-through (AC3, ...) device
+** @param passthrough use /pass-through (AC-3, ...) device
**
** @retval -1 error
** @retval 0 okay
@@ -678,8 +678,7 @@ static int AudioRingAdd(unsigned sample_rate, int channels, int passthrough)
}
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
- // FIXME: don't flush buffers here
- AudioRing[AudioRingWrite].FlushBuffers = 1;
+ AudioRing[AudioRingWrite].FlushBuffers = 0;
AudioRing[AudioRingWrite].Passthrough = passthrough;
AudioRing[AudioRingWrite].PacketSize = 0;
AudioRing[AudioRingWrite].InSampleRate = sample_rate;
@@ -689,6 +688,9 @@ static int AudioRingAdd(unsigned sample_rate, int channels, int passthrough)
AudioRing[AudioRingWrite].PTS = INT64_C(0x8000000000000000);
RingBufferReset(AudioRing[AudioRingWrite].RingBuffer);
+ Debug(3, "audio: %d ring buffer prepared\n",
+ atomic_read(&AudioRingFilled) + 1);
+
atomic_inc(&AudioRingFilled);
#ifdef USE_AUDIO_THREAD
@@ -836,7 +838,7 @@ static int AlsaPlayRingbuffer(void)
if (!avail) { // full or buffer empty
break;
}
- // muting pass-through ac3, can produce disturbance
+ // muting pass-through AC-3, can produce disturbance
if (AudioMute || (AudioSoftVolume
&& !AudioRing[AudioRingRead].Passthrough)) {
// FIXME: quick&dirty cast
@@ -985,7 +987,7 @@ static int AlsaThread(void)
/**
** Open alsa pcm device.
**
-** @param passthrough use pass-through (AC3, ...) device
+** @param passthrough use pass-through (AC-3, ...) device
*/
static snd_pcm_t *AlsaOpenPCM(int passthrough)
{
@@ -1168,7 +1170,7 @@ static int64_t AlsaGetDelay(void)
**
** @param freq sample frequency
** @param channels number of channels
-** @param passthrough use pass-through (AC3, ...) device
+** @param passthrough use pass-through (AC-3, ...) device
**
** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination
@@ -1561,7 +1563,7 @@ static int OssThread(void)
/**
** Open OSS pcm device.
**
-** @param passthrough use pass-through (AC3, ...) device
+** @param passthrough use pass-through (AC-3, ...) device
*/
static int OssOpenPCM(int passthrough)
{
@@ -1725,7 +1727,7 @@ static int64_t OssGetDelay(void)
**
** @param sample_rate sample rate/frequency
** @param channels number of channels
-** @param passthrough use pass-through (AC3, ...) device
+** @param passthrough use pass-through (AC-3, ...) device
**
** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination
@@ -1743,7 +1745,7 @@ static int OssSetup(int *sample_rate, int *channels, int passthrough)
return -1;
}
- if (1) { // close+open for pcm / ac3
+ if (1) { // close+open for pcm / AC-3
int fildes;
fildes = OssPcmFildes;
@@ -1932,7 +1934,7 @@ static void NoopSetVolume( __attribute__ ((unused))
**
** @param freq sample frequency
** @param channels number of channels
-** @param passthrough use pass-through (AC3, ...) device
+** @param passthrough use pass-through (AC-3, ...) device
*/
static int NoopSetup( __attribute__ ((unused))
int *channels, __attribute__ ((unused))
@@ -2031,10 +2033,10 @@ static void *AudioPlayHandlerThread(void *dummy)
pthread_mutex_unlock(&AudioMutex);
Debug(3, "audio: ----> %dms start\n", (AudioUsedBytes() * 1000)
- / (!AudioRing[AudioRingRead].HwSampleRate +
- !AudioRing[AudioRingRead].HwChannels +
- AudioRing[AudioRingRead].HwSampleRate *
- AudioRing[AudioRingRead].HwChannels * AudioBytesProSample));
+ / (!AudioRing[AudioRingWrite].HwSampleRate +
+ !AudioRing[AudioRingWrite].HwChannels +
+ AudioRing[AudioRingWrite].HwSampleRate *
+ AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample));
do {
int filled;
@@ -2067,7 +2069,10 @@ static void *AudioPlayHandlerThread(void *dummy)
Debug(3, "audio: continue after flush\n");
}
// try to play some samples
- err = AudioUsedModule->Thread();
+ err = 0;
+ if (RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer)) {
+ err = AudioUsedModule->Thread();
+ }
// underrun, check if new ring buffer is available
if (!err) {
int passthrough;
@@ -2417,6 +2422,7 @@ void AudioFlushBuffers(void)
int i;
old = AudioRingWrite;
+ // FIXME: check ring buffer overflow
AudioRingWrite = (AudioRingWrite + 1) % AUDIO_RING_MAX;
AudioRing[AudioRingWrite].FlushBuffers = 1;
AudioRing[AudioRingWrite].Passthrough = AudioRing[old].Passthrough;
@@ -2570,7 +2576,7 @@ void AudioSetVolume(int volume)
**
** @param freq sample frequency
** @param channels number of channels
-** @param passthrough use pass-through (AC3, ...) device
+** @param passthrough use pass-through (AC-3, ...) device
**
** @retval 0 everything ok
** @retval 1 didn't support frequency/channels combination
diff --git a/audio.h b/audio.h
index 848567b..4a0ac51 100644
--- a/audio.h
+++ b/audio.h
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: 2393b6f10303c30c8a3a4d689454081e418008fe $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
/// @addtogroup Audio
diff --git a/codec.c b/codec.c
index 441b098..4eea14f 100644
--- a/codec.c
+++ b/codec.c
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: 6e1e942276363ae930aa18f81194e13cbc448d1f $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
///
@@ -56,6 +56,13 @@
#include <alsa/iatomic.h>
#include <libavcodec/avcodec.h>
+// support old ffmpeg versions <1.0
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,18,102)
+#define AVCodecID CodecID
+#define AV_CODEC_ID_AC3 CODEC_ID_AC3
+#define AV_CODEC_ID_EAC3 CODEC_ID_EAC3
+#define AV_CODEC_ID_H264 CODEC_ID_H264
+#endif
#include <libavcodec/vaapi.h>
#ifdef USE_VDPAU
#include <libavcodec/vdpau.h>
@@ -434,7 +441,7 @@ void CodecVideoOpen(VideoDecoder * decoder, const char *name, int codec_id)
decoder->VideoCtx->opaque = decoder; // our structure
Debug(3, "codec: video '%s'\n", decoder->VideoCtx->codec_name);
- if (codec_id == CODEC_ID_H264) {
+ if (codec_id == AV_CODEC_ID_H264) {
// 2.53 Ghz CPU is too slow for this codec at 1080i
//decoder->VideoCtx->skip_loop_filter = AVDISCARD_ALL;
//decoder->VideoCtx->skip_loop_filter = AVDISCARD_BIDIR;
@@ -476,7 +483,7 @@ void CodecVideoOpen(VideoDecoder * decoder, const char *name, int codec_id)
} else {
decoder->VideoCtx->get_format = Codec_get_format;
decoder->VideoCtx->hwaccel_context =
- VideoGetVaapiContext(decoder->HwDecoder);
+ VideoGetHwAccelContext(decoder->HwDecoder);
}
// our pixel format video hardware decoder hook
@@ -515,8 +522,8 @@ void CodecVideoClose(VideoDecoder * video_decoder)
if (video_decoder->VideoCtx) {
pthread_mutex_lock(&CodecLockMutex);
avcodec_close(video_decoder->VideoCtx);
- pthread_mutex_unlock(&CodecLockMutex);
av_freep(&video_decoder->VideoCtx);
+ pthread_mutex_unlock(&CodecLockMutex);
}
}
@@ -703,7 +710,7 @@ enum IEC61937
#ifdef USE_AUDIO_DRIFT_CORRECTION
#define CORRECT_PCM 1 ///< do PCM audio-drift correction
-#define CORRECT_AC3 2 ///< do AC3 audio-drift correction
+#define CORRECT_AC3 2 ///< do AC-3 audio-drift correction
static char CodecAudioDrift; ///< flag: enable audio-drift correction
#else
static const int CodecAudioDrift = 0;
@@ -856,15 +863,15 @@ void CodecAudioClose(AudioDecoder * audio_decoder)
if (audio_decoder->AudioCtx) {
pthread_mutex_lock(&CodecLockMutex);
avcodec_close(audio_decoder->AudioCtx);
- pthread_mutex_unlock(&CodecLockMutex);
av_freep(&audio_decoder->AudioCtx);
+ pthread_mutex_unlock(&CodecLockMutex);
}
}
/**
** Set audio drift correction.
**
-** @param mask enable mask (PCM, AC3)
+** @param mask enable mask (PCM, AC-3)
*/
void CodecSetAudioDrift(int mask)
{
@@ -877,7 +884,7 @@ void CodecSetAudioDrift(int mask)
/**
** Set audio pass-through.
**
-** @param mask enable mask (PCM, AC3, EAC3)
+** @param mask enable mask (PCM, AC-3, E-AC-3)
*/
void CodecSetAudioPassthrough(int mask)
{
@@ -978,8 +985,8 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder,
av_get_sample_fmt_name(audio_ctx->sample_fmt), audio_ctx->sample_rate,
audio_ctx->channels, CodecPassthrough & CodecPCM ? " PCM" : "",
CodecPassthrough & CodecMPA ? " MPA" : "",
- CodecPassthrough & CodecAC3 ? " AC3" : "",
- CodecPassthrough & CodecEAC3 ? " EAC3" : "",
+ CodecPassthrough & CodecAC3 ? " AC-3" : "",
+ CodecPassthrough & CodecEAC3 ? " E-AC-3" : "",
CodecPassthrough ? " pass-through" : "");
*passthrough = 0;
@@ -990,11 +997,11 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder,
audio_decoder->Passthrough = CodecPassthrough;
// SPDIF/HDMI pass-through
- if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == CODEC_ID_AC3)
+ if ((CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3)
|| (CodecPassthrough & CodecEAC3
- && audio_ctx->codec_id == CODEC_ID_EAC3)) {
- if (audio_ctx->codec_id == CODEC_ID_EAC3) {
- // EAC3 over HDMI some receivers need HBR
+ && audio_ctx->codec_id == AV_CODEC_ID_EAC3)) {
+ if (audio_ctx->codec_id == AV_CODEC_ID_EAC3) {
+ // E-AC-3 over HDMI some receivers need HBR
audio_decoder->HwSampleRate *= 4;
}
audio_decoder->HwChannels = 2;
@@ -1007,9 +1014,9 @@ static int CodecAudioUpdateHelper(AudioDecoder * audio_decoder,
AudioSetup(&audio_decoder->HwSampleRate,
&audio_decoder->HwChannels, *passthrough))) {
- // try EAC3 none HBR
+ // try E-AC-3 none HBR
audio_decoder->HwSampleRate /= 4;
- if (audio_ctx->codec_id != CODEC_ID_EAC3
+ if (audio_ctx->codec_id != AV_CODEC_ID_EAC3
|| (err =
AudioSetup(&audio_decoder->HwSampleRate,
&audio_decoder->HwChannels, *passthrough))) {
@@ -1044,7 +1051,7 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder,
audio_ctx = audio_decoder->AudioCtx;
// SPDIF/HDMI passthrough
- if (CodecPassthrough & CodecAC3 && audio_ctx->codec_id == CODEC_ID_AC3) {
+ if (CodecPassthrough & CodecAC3 && audio_ctx->codec_id == AV_CODEC_ID_AC3) {
uint16_t *spdif;
int spdif_sz;
@@ -1094,7 +1101,8 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder,
AudioEnqueue(spdif, spdif_sz);
return 1;
}
- if (CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == CODEC_ID_EAC3) {
+ if (CodecPassthrough & CodecEAC3
+ && audio_ctx->codec_id == AV_CODEC_ID_EAC3) {
uint16_t *spdif;
int spdif_sz;
int repeat;
@@ -1223,9 +1231,9 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
// SPDIF/HDMI passthrough
if ((CodecAudioDrift & CORRECT_AC3) && (!(CodecPassthrough & CodecAC3)
- || audio_decoder->AudioCtx->codec_id != CODEC_ID_AC3)
+ || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3)
&& (!(CodecPassthrough & CodecEAC3)
- || audio_decoder->AudioCtx->codec_id != CODEC_ID_EAC3)) {
+ || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) {
audio_decoder->DriftCorr = -corr;
}
@@ -1625,9 +1633,9 @@ static void CodecAudioSetClock(AudioDecoder * audio_decoder, int64_t pts)
corr = (10 * audio_decoder->HwSampleRate * drift) / (90 * 1000);
// SPDIF/HDMI passthrough
if ((CodecAudioDrift & CORRECT_AC3) && (!(CodecPassthrough & CodecAC3)
- || audio_decoder->AudioCtx->codec_id != CODEC_ID_AC3)
+ || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_AC3)
&& (!(CodecPassthrough & CodecEAC3)
- || audio_decoder->AudioCtx->codec_id != CODEC_ID_EAC3)) {
+ || audio_decoder->AudioCtx->codec_id != AV_CODEC_ID_EAC3)) {
audio_decoder->DriftCorr = -corr;
}
diff --git a/codec.h b/codec.h
index 7eb8abc..995573a 100644
--- a/codec.h
+++ b/codec.h
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: fbc32ec12f605e29deec2b5580f03985bc845ecd $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
/// @addtogroup Codec
@@ -30,7 +30,7 @@
#define CodecPCM 0x01 ///< PCM bit mask
#define CodecMPA 0x02 ///< MPA bit mask (planned)
#define CodecAC3 0x04 ///< AC-3 bit mask
-#define CodecEAC3 0x08 ///< EAC-3 bit mask
+#define CodecEAC3 0x08 ///< E-AC-3 bit mask
#define CodecDTS 0x10 ///< DTS bit mask (planned)
//----------------------------------------------------------------------------
diff --git a/greater_sync_2.diff b/greater_sync_2.diff
deleted file mode 100644
index 76bdf7d..0000000
--- a/greater_sync_2.diff
+++ /dev/null
@@ -1,52 +0,0 @@
-diff --git a/video.c b/video.c
-index 981f5c8..fba9dd5 100644
---- a/video.c
-+++ b/video.c
-@@ -4600,7 +4600,7 @@ static void VaapiSyncDecoder(VaapiDecoder * decoder)
- goto out;
- }
- // both clocks are known
-- if (audio_clock + VideoAudioDelay <= video_clock + 15 * 90) {
-+ if (audio_clock + VideoAudioDelay <= video_clock + 35 * 90) {
- goto out;
- }
- // out of sync: audio before video
-@@ -4644,12 +4644,12 @@ static void VaapiSyncDecoder(VaapiDecoder * decoder)
- ++decoder->FramesDuped;
- decoder->SyncCounter = 1;
- goto out;
-- } else if (video_clock > audio_clock + VideoAudioDelay + 45 * 90) {
-+ } else if (video_clock > audio_clock + VideoAudioDelay + 65 * 90) {
- err = VaapiMessage(3, "video: slow down video, duping frame\n");
- ++decoder->FramesDuped;
- decoder->SyncCounter = 1;
- goto out;
-- } else if (audio_clock + VideoAudioDelay > video_clock + 15 * 90
-+ } else if (audio_clock + VideoAudioDelay > video_clock + 35 * 90
- && filled > 1 + 2 * decoder->Interlaced) {
- err = VaapiMessage(3, "video: speed up video, droping frame\n");
- ++decoder->FramesDropped;
-@@ -8009,7 +8009,7 @@ static void VdpauSyncDecoder(VdpauDecoder * decoder)
- goto out;
- }
- // both clocks are known
-- if (audio_clock + VideoAudioDelay <= video_clock + 15 * 90) {
-+ if (audio_clock + VideoAudioDelay <= video_clock + 35 * 90) {
- goto out;
- }
- // out of sync: audio before video
-@@ -8052,12 +8052,12 @@ static void VdpauSyncDecoder(VdpauDecoder * decoder)
- ++decoder->FramesDuped;
- decoder->SyncCounter = 1;
- goto out;
-- } else if (video_clock > audio_clock + VideoAudioDelay + 45 * 90) {
-+ } else if (video_clock > audio_clock + VideoAudioDelay + 65 * 90) {
- err = VdpauMessage(2, "video: slow down video, duping frame\n");
- ++decoder->FramesDuped;
- decoder->SyncCounter = 1;
- goto out;
-- } else if (audio_clock + VideoAudioDelay > video_clock + 15 * 90
-+ } else if (audio_clock + VideoAudioDelay > video_clock + 35 * 90
- && filled > 1 + 2 * decoder->Interlaced) {
- err = VdpauMessage(2, "video: speed up video, droping frame\n");
- ++decoder->FramesDropped;
diff --git a/misc.h b/misc.h
index a5f0ae7..f5ff4b3 100644
--- a/misc.h
+++ b/misc.h
@@ -18,7 +18,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: f5ff4b300aa33eb721d658c0c9374c8499b67318 $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
/// @addtogroup misc
diff --git a/po/de_DE.po b/po/de_DE.po
index 4a630f0..91867ef 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR \n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2013-03-09 19:20+0100\n"
+"POT-Creation-Date: 2013-08-03 17:21+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: LANGUAGE <LL at li.org>\n"
@@ -384,6 +384,10 @@ msgstr ""
msgid "[softhddev] invalid PES video packet\n"
msgstr ""
+#, c-format
+msgid "[softhddev] %d invalid PES video packet(s)\n"
+msgstr ""
+
msgid "[softhddev] empty video packet\n"
msgstr ""
@@ -587,10 +591,10 @@ msgstr ""
msgid " AC-3 pass-through"
msgstr ""
-msgid " EAC-3 pass-through"
+msgid " E-AC-3 pass-through"
msgstr ""
-msgid "Enable (E)AC-3 (decoder) downmix"
+msgid "Enable (E-)AC-3 (decoder) downmix"
msgstr ""
msgid "Volume control"
@@ -627,7 +631,7 @@ msgid "Pip X (%)"
msgstr "PIP X (%)"
msgid "Pip Y (%)"
-msgstr "PIP X (%)"
+msgstr "PIP Y (%)"
msgid "Pip Width (%)"
msgstr "PIP Breite (%)"
@@ -672,7 +676,7 @@ msgid "Alternative Video Height (%)"
msgstr "Alternative Videohöhe (%)"
#, c-format
-msgid "[softhddev]pip: invalid pes packet %d\n"
+msgid "[softhddev]pip: invalid PES packet %d\n"
msgstr ""
msgid "[softhddev]pip: pes buffer too small\n"
@@ -895,6 +899,9 @@ msgstr ""
msgid "unsupported"
msgstr ""
+msgid "video/glx: glx error\n"
+msgstr ""
+
#, c-format
msgid "video/vaapi: unsupported pixel format %d\n"
msgstr ""
@@ -1265,6 +1272,9 @@ msgstr ""
msgid "video/vdpau: can't put video surface bits: %s\n"
msgstr ""
+msgid "video: get hwaccel context, not supported\n"
+msgstr ""
+
#, c-format
msgid "video/vdpau: can't render bitmap surface: %s\n"
msgstr ""
@@ -1331,9 +1341,6 @@ msgstr ""
msgid "video: repeated pict %d found, but not handled\n"
msgstr ""
-msgid "video/vaapi: get vaapi context, without vaapi enabled\n"
-msgstr ""
-
#, c-format
msgid "video/vdpau: decoder rendering failed: %s\n"
msgstr ""
@@ -1355,6 +1362,10 @@ msgstr ""
msgid "video: Can't connect to X11 server on '%s'\n"
msgstr ""
+#, c-format
+msgid "video: Can't initialize X11 thread support on '%s'\n"
+msgstr ""
+
msgid "video: Can't convert XLIB display to XCB connection\n"
msgstr ""
diff --git a/ringbuffer.c b/ringbuffer.c
index df70c22..9466852 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: 81722e214a141576181f44dfb2d7009f5ce58569 $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
///
diff --git a/ringbuffer.h b/ringbuffer.h
index 80381c4..8a2b4c1 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: a5e8a6894d8406fdbe1c8efc891c8aa44eeb524e $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
/// @addtogroup Ringbuffer
diff --git a/softhddev.c b/softhddev.c
index f8230f2..b11e43a 100644
--- a/softhddev.c
+++ b/softhddev.c
@@ -17,11 +17,12 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: b68b62bc8078d0e6f2f7c2cec5afb7f6e41a7434 $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
#define noUSE_SOFTLIMIT ///< add soft buffer limits to Play..
#define noUSE_PIP ///< include PIP support + new API
+#define noDUMP_TRICKSPEED ///< dump raw trickspeed packets
#include <sys/types.h>
#include <sys/stat.h>
@@ -40,6 +41,19 @@
#define _N(str) str ///< gettext_noop shortcut
#include <libavcodec/avcodec.h>
+// support old ffmpeg versions <1.0
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,18,102)
+#define AVCodecID CodecID
+#define AV_CODEC_ID_AAC CODEC_ID_AAC
+#define AV_CODEC_ID_AAC_LATM CODEC_ID_AAC_LATM
+#define AV_CODEC_ID_AC3 CODEC_ID_AC3
+#define AV_CODEC_ID_EAC3 CODEC_ID_EAC3
+#define AV_CODEC_ID_H264 CODEC_ID_H264
+#define AV_CODEC_ID_MP2 CODEC_ID_MP2
+#define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
+#define AV_CODEC_ID_NONE CODEC_ID_NONE
+#define AV_CODEC_ID_PCM_DVD CODEC_ID_PCM_DVD
+#endif
#ifndef __USE_GNU
#define __USE_GNU
@@ -86,7 +100,7 @@ static volatile char StreamFreezed; ///< stream freezed
static volatile char NewAudioStream; ///< new audio stream
static volatile char SkipAudio; ///< skip audio stream
static AudioDecoder *MyAudioDecoder; ///< audio decoder
-static enum CodecID AudioCodecID; ///< current codec id
+static enum AVCodecID AudioCodecID; ///< current codec id
static int AudioChannelID; ///< current audio channel id
static VideoStream *AudioSyncStream; ///< video stream for audio/video sync
@@ -296,7 +310,7 @@ static int LatmCheck(const uint8_t * data, int size)
}
///
-/// Possible AC3 frame sizes.
+/// Possible AC-3 frame sizes.
///
/// from ATSC A/52 table 5.18 frame size code table.
///
@@ -314,9 +328,9 @@ const uint16_t Ac3FrameSizeTable[38][3] = {
};
///
-/// Fast check for (E)AC3 audio.
+/// Fast check for (E-)AC-3 audio.
///
-/// 5 bytes 0x0B77xxxxxx AC3 audio
+/// 5 bytes 0x0B77xxxxxx AC-3 audio
///
static inline int FastAc3Check(const uint8_t * p)
{
@@ -330,7 +344,7 @@ static inline int FastAc3Check(const uint8_t * p)
}
///
-/// Check for (E)AC-3 audio.
+/// Check for (E-)AC-3 audio.
///
/// 0x0B77xxxxxx already checked.
///
@@ -341,7 +355,7 @@ static inline int FastAc3Check(const uint8_t * p)
/// @retval 0 no valid AC-3 audio
/// @retval >0 valid AC-3 audio
///
-/// o AC3 Header
+/// o AC-3 Header
/// AAAAAAAA AAAAAAAA BBBBBBBB BBBBBBBB CCDDDDDD EEEEEFFF
///
/// o a 16x Frame sync, always 0x0B77
@@ -351,7 +365,7 @@ static inline int FastAc3Check(const uint8_t * p)
/// o e 5x Bitstream ID
/// o f 3x Bitstream mode
///
-/// o EAC3 Header
+/// o E-AC-3 Header
/// AAAAAAAA AAAAAAAA BBCCCDDD DDDDDDDD EEFFGGGH IIIII...
///
/// o a 16x Frame sync, always 0x0B77
@@ -365,17 +379,17 @@ static int Ac3Check(const uint8_t * data, int size)
{
int frame_size;
- if (size < 5) { // need 5 bytes to see if AC3/EAC3
+ if (size < 5) { // need 5 bytes to see if AC-3/E-AC-3
return -5;
}
- if (data[5] > (10 << 3)) { // EAC3
+ if (data[5] > (10 << 3)) { // E-AC-3
if ((data[4] & 0xF0) == 0xF0) { // invalid fscod fscod2
return 0;
}
frame_size = ((data[2] & 0x03) << 8) + data[3] + 1;
frame_size *= 2;
- } else { // AC3
+ } else { // AC-3
int fscod;
int frmsizcod;
@@ -617,7 +631,7 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
#if 0
// Played with PlayAudio
// FIXME: need 0x80 -- 0xA0 state
- if (AudioCodecID == CODEC_ID_NONE) {
+ if (AudioCodecID == AV_CODEC_ID_NONE) {
if ((*p & 0xF0) == 0x80) { // AC-3 & DTS
Debug(3, "pesdemux: dvd ac-3\n");
} else if ((*p & 0xFF) == 0xA0) { // LPCM
@@ -651,8 +665,8 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
unsigned codec_id;
// 4 bytes 0xFFExxxxx Mpeg audio
- // 5 bytes 0x0B77xxxxxx AC3 audio
- // 6 bytes 0x0B77xxxxxxxx EAC3 audio
+ // 5 bytes 0x0B77xxxxxx AC-3 audio
+ // 6 bytes 0x0B77xxxxxxxx E-AC-3 audio
// 3 bytes 0x56Exxx AAC LATM audio
// 7/9 bytes 0xFFFxxxxxxxxxxx ADTS audio
// PCM audio can't be found
@@ -660,22 +674,22 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
r = 0;
if (!r && FastMpegCheck(q)) {
r = MpegCheck(q, n);
- codec_id = CODEC_ID_MP2;
+ codec_id = AV_CODEC_ID_MP2;
}
if (!r && FastAc3Check(q)) {
r = Ac3Check(q, n);
- codec_id = CODEC_ID_AC3;
+ codec_id = AV_CODEC_ID_AC3;
if (r > 0 && q[5] > (10 << 3)) {
- codec_id = CODEC_ID_EAC3;
+ codec_id = AV_CODEC_ID_EAC3;
}
}
if (!r && FastLatmCheck(q)) {
r = LatmCheck(q, n);
- codec_id = CODEC_ID_AAC_LATM;
+ codec_id = AV_CODEC_ID_AAC_LATM;
}
if (!r && FastAdtsCheck(q)) {
r = AdtsCheck(q, n);
- codec_id = CODEC_ID_AAC;
+ codec_id = AV_CODEC_ID_AAC;
}
if (r < 0) { // need more bytes
break;
@@ -705,7 +719,7 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
//pesdx->State = PES_MPEG_DECODE;
break;
}
- if (AudioCodecID != CODEC_ID_NONE) {
+ if (AudioCodecID != AV_CODEC_ID_NONE) {
// shouldn't happen after we have a vaild codec
// detected
Debug(4, "pesdemux: skip @%d %02x\n", pesdx->Skip,
@@ -831,7 +845,7 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
int bits_per_sample;
const uint8_t *q;
- if (AudioCodecID != CODEC_ID_PCM_DVD) {
+ if (AudioCodecID != AV_CODEC_ID_PCM_DVD) {
q = pesdx->Header;
Debug(3, "pesdemux: LPCM %d sr:%d bits:%d chan:%d\n",
@@ -861,8 +875,8 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
(q[5] & 0x7) + 1);
// FIXME: support resample
}
- //CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_PCM_DVD);
- AudioCodecID = CODEC_ID_PCM_DVD;
+ //CodecAudioOpen(MyAudioDecoder, NULL, AV_CODEC_ID_PCM_DVD);
+ AudioCodecID = AV_CODEC_ID_PCM_DVD;
}
pesdx->State = PES_LPCM_PAYLOAD;
pesdx->Index = 0;
@@ -1023,7 +1037,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
CodecAudioClose(MyAudioDecoder);
AudioFlushBuffers();
AudioSetBufferTime(ConfigAudioBufferTime);
- AudioCodecID = CODEC_ID_NONE;
+ AudioCodecID = AV_CODEC_ID_NONE;
AudioChannelID = -1;
NewAudioStream = 0;
}
@@ -1081,7 +1095,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
if (AudioChannelID != id) { // id changed audio track changed
AudioChannelID = id;
- AudioCodecID = CODEC_ID_NONE;
+ AudioCodecID = AV_CODEC_ID_NONE;
}
// Private stream + LPCM ID
if ((id & 0xF0) == 0xA0) {
@@ -1089,7 +1103,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
Error(_("[softhddev] invalid LPCM audio packet %d bytes\n"), size);
return size;
}
- if (AudioCodecID != CODEC_ID_PCM_DVD) {
+ if (AudioCodecID != AV_CODEC_ID_PCM_DVD) {
static int samplerates[] = { 48000, 96000, 44100, 32000 };
int samplerate;
int channels;
@@ -1123,8 +1137,8 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
(p[5] & 0x7) + 1);
// FIXME: support resample
}
- //CodecAudioOpen(MyAudioDecoder, NULL, CODEC_ID_PCM_DVD);
- AudioCodecID = CODEC_ID_PCM_DVD;
+ //CodecAudioOpen(MyAudioDecoder, NULL, AV_CODEC_ID_PCM_DVD);
+ AudioCodecID = AV_CODEC_ID_PCM_DVD;
}
if (AudioAvPkt->pts != (int64_t) AV_NOPTS_VALUE) {
@@ -1140,7 +1154,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
if ((id & 0xF0) == 0x80 && (p[0] & 0xF0) == 0x80) {
p += 4;
n -= 4; // skip track header
- if (AudioCodecID == CODEC_ID_NONE) {
+ if (AudioCodecID == AV_CODEC_ID_NONE) {
// FIXME: ConfigAudioBufferTime + x
AudioSetBufferTime(400);
}
@@ -1157,25 +1171,25 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
// 4 bytes 0xFFExxxxx Mpeg audio
// 3 bytes 0x56Exxx AAC LATM audio
- // 5 bytes 0x0B77xxxxxx AC3 audio
- // 6 bytes 0x0B77xxxxxxxx EAC3 audio
+ // 5 bytes 0x0B77xxxxxx AC-3 audio
+ // 6 bytes 0x0B77xxxxxxxx E-AC-3 audio
// 7/9 bytes 0xFFFxxxxxxxxxxx ADTS audio
// PCM audio can't be found
r = 0;
- codec_id = CODEC_ID_NONE; // keep compiler happy
+ codec_id = AV_CODEC_ID_NONE; // keep compiler happy
if (id != 0xbd && FastMpegCheck(p)) {
r = MpegCheck(p, n);
- codec_id = CODEC_ID_MP2;
+ codec_id = AV_CODEC_ID_MP2;
}
if (id != 0xbd && !r && FastLatmCheck(p)) {
r = LatmCheck(p, n);
- codec_id = CODEC_ID_AAC_LATM;
+ codec_id = AV_CODEC_ID_AAC_LATM;
}
if ((id == 0xbd || (id & 0xF0) == 0x80) && !r && FastAc3Check(p)) {
r = Ac3Check(p, n);
- codec_id = CODEC_ID_AC3;
+ codec_id = AV_CODEC_ID_AC3;
if (r > 0 && p[5] > (10 << 3)) {
- codec_id = CODEC_ID_EAC3;
+ codec_id = AV_CODEC_ID_EAC3;
}
/* faster ac3 detection at end of pes packet (no improvemnts)
if (AudioCodecID == codec_id && -r - 2 == n) {
@@ -1185,7 +1199,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
}
if (id != 0xbd && !r && FastAdtsCheck(p)) {
r = AdtsCheck(p, n);
- codec_id = CODEC_ID_AAC;
+ codec_id = AV_CODEC_ID_AAC;
}
if (r < 0) { // need more bytes
break;
@@ -1253,7 +1267,7 @@ int PlayTsAudio(const uint8_t * data, int size)
AudioFlushBuffers();
// max time between audio packets 200ms + 24ms hw buffer
AudioSetBufferTime(ConfigAudioBufferTime);
- AudioCodecID = CODEC_ID_NONE;
+ AudioCodecID = AV_CODEC_ID_NONE;
AudioChannelID = -1;
NewAudioStream = 0;
PesReset(PesDemuxAudio);
@@ -1303,8 +1317,8 @@ struct __video_stream__
VideoDecoder *Decoder; ///< video decoder
pthread_mutex_t DecoderLockMutex; ///< video decoder lock mutex
- enum CodecID CodecID; ///< current codec id
- enum CodecID LastCodecID; ///< last codec id
+ enum AVCodecID CodecID; ///< current codec id
+ enum AVCodecID LastCodecID; ///< last codec id
volatile char NewStream; ///< flag new video stream
volatile char ClosingStream; ///< flag closing video stream
@@ -1316,6 +1330,9 @@ struct __video_stream__
volatile char ClearBuffers; ///< command clear video buffers
volatile char ClearClose; ///< clear video buffers for close
+ int InvalidPesCounter; ///< counter of invalid PES packets
+
+ enum AVCodecID CodecIDRb[VIDEO_PACKET_MAX]; ///< codec ids in ring buffer
AVPacket PacketRb[VIDEO_PACKET_MAX]; ///< PES packet ring buffer
int StartCodeState; ///< last three bytes start code state
@@ -1442,9 +1459,9 @@ static void VideoResetPacket(VideoStream * stream)
stream->StartCodeState = 0; // reset start code state
+ stream->CodecIDRb[stream->PacketWrite] = AV_CODEC_ID_NONE;
avpkt = &stream->PacketRb[stream->PacketWrite];
avpkt->stream_index = 0;
- avpkt->priv = NULL;
avpkt->pts = AV_NOPTS_VALUE;
avpkt->dts = AV_NOPTS_VALUE;
}
@@ -1461,7 +1478,7 @@ static void VideoNextPacket(VideoStream * stream, int codec_id)
avpkt = &stream->PacketRb[stream->PacketWrite];
if (!avpkt->stream_index) { // ignore empty packets
- if (codec_id != CODEC_ID_NONE) {
+ if (codec_id != AV_CODEC_ID_NONE) {
return;
}
Debug(3, "video: possible stream change loss\n");
@@ -1471,7 +1488,7 @@ static void VideoNextPacket(VideoStream * stream, int codec_id)
// no free slot available drop last packet
Error(_("video: no empty slot in packet ringbuffer\n"));
avpkt->stream_index = 0;
- if (codec_id == CODEC_ID_NONE) {
+ if (codec_id == AV_CODEC_ID_NONE) {
Debug(3, "video: possible stream change loss\n");
}
return;
@@ -1479,7 +1496,7 @@ static void VideoNextPacket(VideoStream * stream, int codec_id)
// clear area for decoder, always enough space allocated
memset(avpkt->data + avpkt->stream_index, 0, FF_INPUT_BUFFER_PADDING_SIZE);
- avpkt->priv = (void *)(size_t) codec_id;
+ stream->CodecIDRb[stream->PacketWrite] = codec_id;
//DumpH264(avpkt->data, avpkt->stream_index);
// advance packet write
@@ -1539,7 +1556,7 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts,
fprintf(stderr, "last: %d start\n", stream->StartCodeState);
#endif
stream->PacketRb[stream->PacketWrite].stream_index -= 3;
- VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
+ VideoNextPacket(stream, AV_CODEC_ID_MPEG2VIDEO);
VideoEnqueue(stream, pts, startcode, 3);
first = p[0] == 0xb3;
p++;
@@ -1556,7 +1573,7 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts,
fprintf(stderr, "last: %d start\n", stream->StartCodeState);
#endif
stream->PacketRb[stream->PacketWrite].stream_index -= 2;
- VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
+ VideoNextPacket(stream, AV_CODEC_ID_MPEG2VIDEO);
VideoEnqueue(stream, pts, startcode, 2);
first = p[1] == 0xb3;
p += 2;
@@ -1573,7 +1590,7 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts,
fprintf(stderr, "last: %d start\n", stream->StartCodeState);
#endif
stream->PacketRb[stream->PacketWrite].stream_index -= 1;
- VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
+ VideoNextPacket(stream, AV_CODEC_ID_MPEG2VIDEO);
VideoEnqueue(stream, pts, startcode, 1);
first = p[2] == 0xb3;
p += 3;
@@ -1606,7 +1623,7 @@ static void VideoMpegEnqueue(VideoStream * stream, int64_t pts,
*/
// first packet goes only upto picture header
VideoEnqueue(stream, pts, data, p - data);
- VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
+ VideoNextPacket(stream, AV_CODEC_ID_MPEG2VIDEO);
#ifdef DEBUG
fprintf(stderr, "fix\r");
#endif
@@ -1756,6 +1773,7 @@ static void VideoStreamClose(VideoStream * stream)
VideoPacketExit(stream);
stream->NewStream = 1;
+ stream->InvalidPesCounter = 0;
}
/**
@@ -1853,9 +1871,8 @@ int VideoDecodeInput(VideoStream * stream)
// flush buffers, if close is in the queue
for (f = 0; f < filled; ++f) {
- avpkt =
- &stream->PacketRb[(stream->PacketRead + f) % VIDEO_PACKET_MAX];
- if ((int)(size_t) avpkt->priv == CODEC_ID_NONE) {
+ if (stream->CodecIDRb[(stream->PacketRead + f) % VIDEO_PACKET_MAX]
+ == AV_CODEC_ID_NONE) {
if (f) {
Debug(3, "video: cleared upto close\n");
atomic_sub(f, &stream->PacketsFilled);
@@ -1874,30 +1891,30 @@ int VideoDecodeInput(VideoStream * stream)
// handle queued commands
//
avpkt = &stream->PacketRb[stream->PacketRead];
- switch ((int)(size_t) avpkt->priv) {
- case CODEC_ID_NONE:
+ switch (stream->CodecIDRb[stream->PacketRead]) {
+ case AV_CODEC_ID_NONE:
stream->ClosingStream = 0;
- if (stream->LastCodecID != CODEC_ID_NONE) {
- stream->LastCodecID = CODEC_ID_NONE;
+ if (stream->LastCodecID != AV_CODEC_ID_NONE) {
+ stream->LastCodecID = AV_CODEC_ID_NONE;
CodecVideoClose(stream->Decoder);
goto skip;
}
// FIXME: look if more close are in the queue
// size can be zero
goto skip;
- case CODEC_ID_MPEG2VIDEO:
- if (stream->LastCodecID != CODEC_ID_MPEG2VIDEO) {
- stream->LastCodecID = CODEC_ID_MPEG2VIDEO;
+ case AV_CODEC_ID_MPEG2VIDEO:
+ if (stream->LastCodecID != AV_CODEC_ID_MPEG2VIDEO) {
+ stream->LastCodecID = AV_CODEC_ID_MPEG2VIDEO;
CodecVideoOpen(stream->Decoder, VideoHardwareDecoder < 0
&& VdpauDecoder ? "mpegvideo_vdpau" : NULL,
- CODEC_ID_MPEG2VIDEO);
+ AV_CODEC_ID_MPEG2VIDEO);
}
break;
- case CODEC_ID_H264:
- if (stream->LastCodecID != CODEC_ID_H264) {
- stream->LastCodecID = CODEC_ID_H264;
+ case AV_CODEC_ID_H264:
+ if (stream->LastCodecID != AV_CODEC_ID_H264) {
+ stream->LastCodecID = AV_CODEC_ID_H264;
CodecVideoOpen(stream->Decoder, VideoHardwareDecoder
- && VdpauDecoder ? "h264_vdpau" : NULL, CODEC_ID_H264);
+ && VdpauDecoder ? "h264_vdpau" : NULL, AV_CODEC_ID_H264);
}
break;
default:
@@ -1926,7 +1943,7 @@ int VideoDecodeInput(VideoStream * stream)
//fprintf(stderr, "]\n");
#else
// old version
- if (stream->LastCodecID == CODEC_ID_MPEG2VIDEO) {
+ if (stream->LastCodecID == AV_CODEC_ID_MPEG2VIDEO) {
FixPacketForFFMpeg(stream->Decoder, avpkt);
} else {
CodecVideoDecode(stream->Decoder, avpkt);
@@ -1972,8 +1989,8 @@ static void StartVideo(void)
VideoOsdInit();
if (!MyVideoStream->Decoder) {
MyVideoStream->SkipStream = 1;
- MyVideoStream->CodecID = CODEC_ID_NONE;
- MyVideoStream->LastCodecID = CODEC_ID_NONE;
+ MyVideoStream->CodecID = AV_CODEC_ID_NONE;
+ MyVideoStream->LastCodecID = AV_CODEC_ID_NONE;
if ((MyVideoStream->HwDecoder = VideoNewHwDecoder(MyVideoStream))) {
MyVideoStream->Decoder =
@@ -2012,6 +2029,7 @@ static void StopVideo(void)
VideoPacketExit(MyVideoStream);
MyVideoStream->NewStream = 1;
+ MyVideoStream->InvalidPesCounter = 0;
}
#ifdef DEBUG
@@ -2133,17 +2151,26 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
Debug(3, "video: new video stream lost\n");
return 0;
}
- VideoNextPacket(stream, CODEC_ID_NONE);
- stream->CodecID = CODEC_ID_NONE;
+ VideoNextPacket(stream, AV_CODEC_ID_NONE);
+ stream->CodecID = AV_CODEC_ID_NONE;
stream->ClosingStream = 1;
stream->NewStream = 0;
}
// must be a PES start code
// FIXME: Valgrind-3.8.1 has a problem with this code
if (size < 9 || !data || data[0] || data[1] || data[2] != 0x01) {
- Error(_("[softhddev] invalid PES video packet\n"));
+ if (!stream->InvalidPesCounter++) {
+ Error(_("[softhddev] invalid PES video packet\n"));
+ }
return size;
}
+ if (stream->InvalidPesCounter) {
+ if (stream->InvalidPesCounter > 1) {
+ Error(_("[softhddev] %d invalid PES video packet(s)\n"),
+ stream->InvalidPesCounter);
+ }
+ stream->InvalidPesCounter = 0;
+ }
// 0xBE, filler, padding stream
if (data[3] == PES_PADDING_STREAM) { // from DVD plugin
return size;
@@ -2197,8 +2224,26 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
if ((data[6] & 0xC0) == 0x80 && z >= 2 && check[0] == 0x01
&& check[1] == 0x09 && !check[3] && !check[4]) {
// old PES HDTV recording z == 2 -> stronger check!
- if (stream->CodecID == CODEC_ID_H264) {
-#if 0
+ if (stream->CodecID == AV_CODEC_ID_H264) {
+#ifdef DUMP_TRICKSPEED
+ if (stream->TrickSpeed) {
+ char buf[1024];
+ int fd;
+ static int FrameCounter;
+
+ snprintf(buf, sizeof(buf), "frame_%06d_%08d.raw", getpid(),
+ FrameCounter++);
+ if ((fd =
+ open(buf, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC,
+ 0666)) >= 0) {
+ if (write(fd, data + 9 + n, size - 9 - n)) {
+ // this construct is to remove the annoying warning
+ }
+ close(fd);
+ }
+ }
+#endif
+#ifdef H264_EOS_TRICKSPEED
// this should improve ffwd+frew, but produce crash in ffmpeg
// with some streams
if (stream->TrickSpeed && pts != (int64_t) AV_NOPTS_VALUE) {
@@ -2209,16 +2254,16 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
// 1-5=SLICE 6=SEI 7=SPS 8=PPS
// NAL SPS sequence parameter set
if ((check[7] & 0x1F) == 0x07) {
- VideoNextPacket(CODEC_ID_H264);
- VideoEnqueue(AV_NOPTS_VALUE, seq_end_h264,
+ VideoNextPacket(stream, AV_CODEC_ID_H264);
+ VideoEnqueue(stream, AV_NOPTS_VALUE, seq_end_h264,
sizeof(seq_end_h264));
}
}
#endif
- VideoNextPacket(stream, CODEC_ID_H264);
+ VideoNextPacket(stream, AV_CODEC_ID_H264);
} else {
Debug(3, "video: h264 detected\n");
- stream->CodecID = CODEC_ID_H264;
+ stream->CodecID = AV_CODEC_ID_H264;
}
// SKIP PES header (ffmpeg supports short start code)
VideoEnqueue(stream, pts, check - 2, l + 2);
@@ -2226,11 +2271,11 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
}
// PES start code 0x00 0x00 0x01 0x00|0xb3
if (z > 1 && check[0] == 0x01 && (!check[1] || check[1] == 0xb3)) {
- if (stream->CodecID == CODEC_ID_MPEG2VIDEO) {
- VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
+ if (stream->CodecID == AV_CODEC_ID_MPEG2VIDEO) {
+ VideoNextPacket(stream, AV_CODEC_ID_MPEG2VIDEO);
} else {
Debug(3, "video: mpeg2 detected ID %02x\n", check[3]);
- stream->CodecID = CODEC_ID_MPEG2VIDEO;
+ stream->CodecID = AV_CODEC_ID_MPEG2VIDEO;
}
#ifdef noDEBUG // pip pes packet has no lenght
if (ValidateMpeg(data, size)) {
@@ -2246,12 +2291,12 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
return size;
}
// this happens when vdr sends incomplete packets
- if (stream->CodecID == CODEC_ID_NONE) {
+ if (stream->CodecID == AV_CODEC_ID_NONE) {
Debug(3, "video: not detected\n");
return size;
}
#ifdef USE_PIP
- if (stream->CodecID == CODEC_ID_MPEG2VIDEO) {
+ if (stream->CodecID == AV_CODEC_ID_MPEG2VIDEO) {
// SKIP PES header
VideoMpegEnqueue(stream, pts, data + 9 + n, size - 9 - n);
#ifndef USE_MPEG_COMPLETE
@@ -2275,10 +2320,10 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
// incomplete packets produce artefacts after channel switch
// packet < 65526 is the last split packet, detect it here for
// better latency
- if (size < 65526 && stream->CodecID == CODEC_ID_MPEG2VIDEO) {
+ if (size < 65526 && stream->CodecID == AV_CODEC_ID_MPEG2VIDEO) {
// mpeg codec supports incomplete packets
// waiting for a full complete packages, increases needed delays
- VideoNextPacket(stream, CODEC_ID_MPEG2VIDEO);
+ VideoNextPacket(stream, AV_CODEC_ID_MPEG2VIDEO);
}
#endif
@@ -2403,13 +2448,15 @@ uint8_t *GrabImage(int *size, int jpeg, int quality, int width, int height)
int SetPlayMode(int play_mode)
{
VideoDisplayWakeup();
- if (MyVideoStream->Decoder) { // tell video parser we have new stream
+ // tell video parser we have new stream
+ if (MyVideoStream->Decoder && !MyVideoStream->SkipStream) {
if (MyVideoStream->ClearClose) { // replay clear buffers on close
Clear(); // flush all buffers
MyVideoStream->ClearClose = 0;
}
- if (MyVideoStream->CodecID != CODEC_ID_NONE) {
+ if (MyVideoStream->CodecID != AV_CODEC_ID_NONE) {
MyVideoStream->NewStream = 1;
+ MyVideoStream->InvalidPesCounter = 0;
// tell hw decoder we are closing stream
VideoSetClosing(MyVideoStream->HwDecoder);
VideoResetStart(MyVideoStream->HwDecoder);
@@ -2419,7 +2466,7 @@ int SetPlayMode(int play_mode)
}
}
if (MyAudioDecoder) { // tell audio parser we have new stream
- if (AudioCodecID != CODEC_ID_NONE) {
+ if (AudioCodecID != AV_CODEC_ID_NONE) {
NewAudioStream = 1;
}
}
@@ -2579,6 +2626,10 @@ void StillPicture(const uint8_t * data, int size)
int i;
int old_video_hardware_decoder;
+ // might be called in Suspended Mode
+ if (!MyVideoStream->Decoder || MyVideoStream->SkipStream) {
+ return;
+ }
// must be a PES start code
if (size < 9 || !data || data[0] || data[1] || data[2] != 0x01) {
Error(_("[softhddev] invalid still video packet\n"));
@@ -2593,10 +2644,10 @@ void StillPicture(const uint8_t * data, int size)
// enable/disable hardware decoder for still picture
if (VideoHardwareDecoder != ConfigStillDecoder) {
VideoHardwareDecoder = ConfigStillDecoder;
- VideoNextPacket(MyVideoStream, CODEC_ID_NONE); // close last stream
+ VideoNextPacket(MyVideoStream, AV_CODEC_ID_NONE); // close last stream
}
- if (MyVideoStream->CodecID == CODEC_ID_NONE) {
+ if (MyVideoStream->CodecID == AV_CODEC_ID_NONE) {
// FIXME: should detect codec, see PlayVideo
Error(_("[softhddev] no codec known for still picture\n"));
}
@@ -2605,7 +2656,7 @@ void StillPicture(const uint8_t * data, int size)
#ifdef STILL_DEBUG
fprintf(stderr, "still-picture\n");
#endif
- for (i = 0; i < (MyVideoStream->CodecID == CODEC_ID_MPEG2VIDEO ? 4 : 4);
+ for (i = 0; i < (MyVideoStream->CodecID == AV_CODEC_ID_MPEG2VIDEO ? 4 : 4);
++i) {
const uint8_t *split;
int n;
@@ -2645,13 +2696,13 @@ void StillPicture(const uint8_t * data, int size)
VideoNextPacket(MyVideoStream, MyVideoStream->CodecID); // terminate last packet
} else { // ES packet
- if (MyVideoStream->CodecID != CODEC_ID_MPEG2VIDEO) {
- VideoNextPacket(MyVideoStream, CODEC_ID_NONE); // close last stream
- MyVideoStream->CodecID = CODEC_ID_MPEG2VIDEO;
+ if (MyVideoStream->CodecID != AV_CODEC_ID_MPEG2VIDEO) {
+ VideoNextPacket(MyVideoStream, AV_CODEC_ID_NONE); // close last stream
+ MyVideoStream->CodecID = AV_CODEC_ID_MPEG2VIDEO;
}
VideoEnqueue(MyVideoStream, AV_NOPTS_VALUE, data, size);
}
- if (MyVideoStream->CodecID == CODEC_ID_H264) {
+ if (MyVideoStream->CodecID == AV_CODEC_ID_H264) {
VideoEnqueue(MyVideoStream, AV_NOPTS_VALUE, seq_end_h264,
sizeof(seq_end_h264));
} else {
@@ -2672,7 +2723,7 @@ void StillPicture(const uint8_t * data, int size)
#endif
if (VideoHardwareDecoder != old_video_hardware_decoder) {
VideoHardwareDecoder = old_video_hardware_decoder;
- VideoNextPacket(MyVideoStream, CODEC_ID_NONE); // close last stream
+ VideoNextPacket(MyVideoStream, AV_CODEC_ID_NONE); // close last stream
}
VideoSetTrickSpeed(MyVideoStream->HwDecoder, 0);
}
@@ -3122,7 +3173,7 @@ int Start(void)
AudioInit();
av_new_packet(AudioAvPkt, AUDIO_BUFFER_SIZE);
MyAudioDecoder = CodecAudioNewDecoder();
- AudioCodecID = CODEC_ID_NONE;
+ AudioCodecID = AV_CODEC_ID_NONE;
AudioChannelID = -1;
if (!ConfigStartX11Server) {
@@ -3275,7 +3326,7 @@ void Resume(void)
AudioInit();
av_new_packet(AudioAvPkt, AUDIO_BUFFER_SIZE);
MyAudioDecoder = CodecAudioNewDecoder();
- AudioCodecID = CODEC_ID_NONE;
+ AudioCodecID = AV_CODEC_ID_NONE;
AudioChannelID = -1;
}
@@ -3376,8 +3427,8 @@ void PipStart(int x, int y, int width, int height, int pip_x, int pip_y,
if (!PipVideoStream->Decoder) {
PipVideoStream->SkipStream = 1;
- PipVideoStream->CodecID = CODEC_ID_NONE;
- PipVideoStream->LastCodecID = CODEC_ID_NONE;
+ PipVideoStream->CodecID = AV_CODEC_ID_NONE;
+ PipVideoStream->LastCodecID = AV_CODEC_ID_NONE;
if ((PipVideoStream->HwDecoder = VideoNewHwDecoder(PipVideoStream))) {
PipVideoStream->Decoder =
@@ -3422,6 +3473,7 @@ void PipStop(void)
VideoPacketExit(PipVideoStream);
PipVideoStream->NewStream = 1;
+ PipVideoStream->InvalidPesCounter = 0;
#else
PipVideoStream->Close = 1;
for (i = 0; PipVideoStream->Close && i < 50; ++i) {
diff --git a/softhddev.h b/softhddev.h
index 46f8d13..6e446dc 100644
--- a/softhddev.h
+++ b/softhddev.h
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: 77181c7dc4a3d5c8ed0115a7db6820e2f9fcf40e $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
diff --git a/softhddevice.cpp b/softhddevice.cpp
index 1b5cddd..c2839ce 100644
--- a/softhddevice.cpp
+++ b/softhddevice.cpp
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: ed5d828fa572616440a5e70c50731fbfd6acb512 $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
#define __STDC_CONSTANT_MACROS ///< needed for ffmpeg UINT64_C
@@ -52,7 +52,7 @@ extern "C"
/// vdr-plugin version number.
/// Makefile extracts the version number for generating the file name
/// for the distribution archive.
-static const char *const VERSION = "0.6.0"
+static const char *const VERSION = "0.6.1rc1"
#ifdef GIT_REV
"-GIT" GIT_REV
#endif
@@ -854,9 +854,9 @@ void cMenuSetupSoft::Create(void)
&AudioPassthroughPCM, trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("\040\040AC-3 pass-through"),
&AudioPassthroughAC3, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditBoolItem(tr("\040\040EAC-3 pass-through"),
+ Add(new cMenuEditBoolItem(tr("\040\040E-AC-3 pass-through"),
&AudioPassthroughEAC3, trVDR("no"), trVDR("yes")));
- Add(new cMenuEditBoolItem(tr("Enable (E)AC-3 (decoder) downmix"),
+ Add(new cMenuEditBoolItem(tr("Enable (E-)AC-3 (decoder) downmix"),
&AudioDownmix, trVDR("no"), trVDR("yes")));
Add(new cMenuEditBoolItem(tr("Volume control"), &AudioSoftvol,
tr("Hardware"), tr("Software")));
@@ -1443,12 +1443,12 @@ static void PipPesParse(const uint8_t * data, int size, int is_start)
if (is_start) { // start of pes packet
if (pes_index) {
if (0) {
- fprintf(stderr, "pip: pes packet %8d %02x%02x\n", pes_index,
+ fprintf(stderr, "pip: PES packet %8d %02x%02x\n", pes_index,
pes_buf[2], pes_buf[3]);
}
if (pes_buf[0] || pes_buf[1] || pes_buf[2] != 0x01) {
// FIXME: first should always fail
- esyslog(tr("[softhddev]pip: invalid pes packet %d\n"),
+ esyslog(tr("[softhddev]pip: invalid PES packet %d\n"),
pes_index);
} else {
PipPlayVideo(pes_buf, pes_index);
@@ -2190,7 +2190,7 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode play_mode)
case pmVideoOnly:
break;
case pmNone:
- return true;
+ break;
case pmExtern_THIS_SHOULD_BE_AVOIDED:
dsyslog("[softhddev] play mode external\n");
// FIXME: what if already suspended?
@@ -2512,6 +2512,9 @@ uchar *cSoftHdDevice::GrabImage(int &size, bool jpeg, int quality, int width,
if (SuspendMode != NOT_SUSPENDED) {
return NULL;
}
+ if (quality < 0) { // caller should care, but fix it
+ quality = 95;
+ }
return::GrabImage(&size, jpeg, quality, width, height);
}
diff --git a/softhddevice.h b/softhddevice.h
index 23c4ac1..1729441 100644
--- a/softhddevice.h
+++ b/softhddevice.h
@@ -17,5 +17,5 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: 172944172364f1837cf05e1776e9e75e59b08bf3 $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
diff --git a/vdr-softhddevice b/vdr-softhddevice
deleted file mode 120000
index 945c9b4..0000000
--- a/vdr-softhddevice
+++ /dev/null
@@ -1 +0,0 @@
-.
\ No newline at end of file
diff --git a/vdr-softhddevice-9999.ebuild b/vdr-softhddevice-9999.ebuild
index 85871d9..2365a52 100644
--- a/vdr-softhddevice-9999.ebuild
+++ b/vdr-softhddevice-9999.ebuild
@@ -20,7 +20,7 @@ HOMEPAGE="http://projects.vdr-developer.org/projects/show/plg-softhddevice"
LICENSE="AGPL-3"
SLOT="0"
-IUSE="alsa oss vaapi vdpau yaepg xscreensaver debug"
+IUSE="alsa oss vaapi vdpau opengl yaepg xscreensaver debug"
RDEPEND=">=media-video/vdr-1.7
>=virtual/ffmpeg-0.7[vdpau?,vaapi?]
@@ -30,6 +30,7 @@ RDEPEND=">=media-video/vdr-1.7
alsa? ( media-libs/alsa-lib )
vdpau? ( x11-libs/libvdpau )
vaapi? ( x11-libs/libva )
+ opengl? ( virtual/opengl )
alsa? ( media-libs/alsa-lib )
yaepg? ( >=media-video/vdr-1.7[yaepg] )"
DEPEND="${RDEPEND}
@@ -44,6 +45,7 @@ src_compile() {
myconf+=" ALSA=$(usex alsa 1 0)"
myconf+=" OSS=$(usex oss 1 0)"
myconf+=" VDPAU=$(usex vdpau 1 0)"
+ myconf+=" OPENGL=$(usex opengl 1 0)"
myconf+=" VAAPI=$(usex vaapi 1 0)"
myconf+=" SCREENSAVER=$(usex xscreensaver 1 0)"
if has_version ">=media-video/ffmpeg-0.8" ; then
diff --git a/video.c b/video.c
index b4aea03..afe5714 100644
--- a/video.c
+++ b/video.c
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: d4c9a5a708d44a17c8f1f84738ebd92f72796f4e $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
///
@@ -43,7 +43,7 @@
#define USE_AUTOCROP ///< compile auto-crop support
#define USE_GRAB ///< experimental grab code
#define noUSE_GLX ///< outdated GLX code
-#define noUSE_DOUBLEBUFFER ///< use GLX double buffers
+#define USE_DOUBLEBUFFER ///< use GLX double buffers
//#define USE_VAAPI ///< enable vaapi support
//#define USE_VDPAU ///< enable vdpau support
#define noUSE_BITMAP ///< use vdpau bitmap surface
@@ -92,7 +92,9 @@
#include <xcb/xcb.h>
//#include <xcb/bigreq.h>
-//#include <xcb/glx.h>
+#ifdef xcb_USE_GLX
+#include <xcb/glx.h>
+#endif
//#include <xcb/randr.h>
#ifdef USE_SCREENSAVER
#include <xcb/screensaver.h>
@@ -137,7 +139,7 @@ typedef enum
#include <va/va_glx.h>
#endif
#ifndef VA_SURFACE_ATTRIB_SETTABLE
-/// make source compatible with old libva
+/// make source compatible with stable libva
#define vaCreateSurfaces(d, f, w, h, s, ns, a, na) \
vaCreateSurfaces(d, w, h, f, ns, s)
#endif
@@ -149,14 +151,26 @@ typedef enum
#endif
#include <libavcodec/avcodec.h>
+// support old ffmpeg versions <1.0
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,18,102)
+#define AVCodecID CodecID
+#define AV_CODEC_ID_H263 CODEC_ID_H263
+#define AV_CODEC_ID_H264 CODEC_ID_H264
+#define AV_CODEC_ID_MPEG1VIDEO CODEC_ID_MPEG1VIDEO
+#define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
+#define AV_CODEC_ID_MPEG4 CODEC_ID_MPEG4
+#define AV_CODEC_ID_VC1 CODEC_ID_VC1
+#define AV_CODEC_ID_WMV3 CODEC_ID_WMV3
+#endif
#include <libavcodec/vaapi.h>
#include <libavutil/pixdesc.h>
-#if LIBAVCODEC_VERSION_INT == AV_VERSION_INT(54,86,100)
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,86,100)
///
/// ffmpeg version 1.1.1 calls get_format with zero width and height
/// for H264 codecs.
/// since version 1.1.3 get_format is called twice.
+ /// ffmpeg 1.2 still buggy
///
#define FFMPEG_BUG1_WORKAROUND ///< get_format bug workaround
#endif
@@ -246,10 +260,14 @@ typedef struct _video_module_
const enum PixelFormat *);
void (*const RenderFrame) (VideoHwDecoder *, const AVCodecContext *,
const AVFrame *);
+ void *(*const GetHwAccelContext)(VideoHwDecoder *);
void (*const SetClock) (VideoHwDecoder *, int64_t);
int64_t(*const GetClock) (const VideoHwDecoder *);
+ void (*const SetClosing) (const VideoHwDecoder *);
+ void (*const ResetStart) (const VideoHwDecoder *);
void (*const SetTrickSpeed) (const VideoHwDecoder *, int);
uint8_t *(*const GrabOutput)(int *, int *, int *);
+ void (*const GetStats) (VideoHwDecoder *, int *, int *, int *, int *);
void (*const SetBackground) (uint32_t);
void (*const SetVideoMode) (void);
void (*const ResetAutoCrop) (void);
@@ -621,10 +639,15 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width,
#ifdef USE_GLX
-static int GlxEnabled = 1; ///< use GLX
-static int GlxVSyncEnabled = 0; ///< enable/disable v-sync
+static int GlxEnabled; ///< use GLX
+static int GlxVSyncEnabled; ///< enable/disable v-sync
static GLXContext GlxSharedContext; ///< shared gl context
static GLXContext GlxContext; ///< our gl context
+
+#ifdef USE_VIDEO_THREAD
+static GLXContext GlxThreadContext; ///< our gl context for the thread
+#endif
+
static XVisualInfo *GlxVisualInfo; ///< our gl visual
static GLuint OsdGlTextures[2]; ///< gl texture for OSD
@@ -680,26 +703,22 @@ static int GlxIsExtensionSupported(const char *ext)
return 0;
}
-#if 0
///
/// Setup GLX decoder
///
-/// @param decoder VA-API decoder
+/// @param width input video textures width
+/// @param height input video textures height
+/// @param[OUT] textures created and prepared textures
///
-void GlxSetupDecoder(VaapiDecoder * decoder)
+static void GlxSetupDecoder(int width, int height, GLuint * textures)
{
- int width;
- int height;
int i;
- width = decoder->InputWidth;
- height = decoder->InputHeight;
-
glEnable(GL_TEXTURE_2D); // create 2d texture
- glGenTextures(2, decoder->GlTexture);
+ glGenTextures(2, textures);
GlxCheck();
for (i = 0; i < 2; ++i) {
- glBindTexture(GL_TEXTURE_2D, decoder->GlTexture[i]);
+ glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -713,12 +732,15 @@ void GlxSetupDecoder(VaapiDecoder * decoder)
GlxCheck();
}
-#endif
///
/// Render texture.
///
/// @param texture 2d texture
+/// @param x window x
+/// @param y window y
+/// @param width window width
+/// @param height window height
///
static inline void GlxRenderTexture(GLuint texture, int x, int y, int width,
int height)
@@ -736,16 +758,6 @@ static inline void GlxRenderTexture(GLuint texture, int x, int y, int width,
glVertex2i(x, y);
glTexCoord2f(1.0f, 0.0f);
glVertex2i(x + width, y);
-#if 0
- glTexCoord2f(0.0f, 0.0f);
- glVertex2i(x, y);
- glTexCoord2f(0.0f, 1.0f);
- glVertex2i(x, y + height);
- glTexCoord2f(1.0f, 1.0f);
- glVertex2i(x + width, y + height);
- glTexCoord2f(1.0f, 0.0f);
- glVertex2i(x + width, y);
-#endif
}
glEnd();
@@ -754,15 +766,20 @@ static inline void GlxRenderTexture(GLuint texture, int x, int y, int width,
}
///
-/// Upload texture.
+/// Upload OSD texture.
///
-static void GlxUploadTexture(int x, int y, int width, int height,
+/// @param x x coordinate texture
+/// @param y y coordinate texture
+/// @param width argb image width
+/// @param height argb image height
+/// @param argb argb image
+///
+static void GlxUploadOsdTexture(int x, int y, int width, int height,
const uint8_t * argb)
{
// FIXME: use other / faster uploads
// ARB_pixelbuffer_object GL_PIXEL_UNPACK_BUFFER glBindBufferARB()
// glMapBuffer() glUnmapBuffer()
- // glTexSubImage2D
glEnable(GL_TEXTURE_2D); // upload 2d texture
@@ -775,59 +792,164 @@ static void GlxUploadTexture(int x, int y, int width, int height,
}
///
-/// Render to glx texture.
+/// GLX initialize OSD.
+///
+/// @param width osd width
+/// @param height osd height
///
-static void GlxRender(int osd_width, int osd_height)
+static void GlxOsdInit(int width, int height)
{
- static uint8_t *image;
- static uint8_t cycle;
- int x;
- int y;
+ int i;
- if (!OsdGlTextures[0] || !OsdGlTextures[1]) {
+#ifdef DEBUG
+ if (!GlxEnabled) {
+ Debug(3, "video/glx: %s called without glx enabled\n", __FUNCTION__);
return;
}
- // render each frame kills performance
+#endif
- // osd 1920 * 1080 * 4 (RGBA) * 50 (HZ) = 396 Mb/s
+ Debug(3, "video/glx: osd init context %p <-> %p\n", glXGetCurrentContext(),
+ GlxContext);
- // too big for alloca
- if (!image) {
- image = malloc(4 * osd_width * osd_height);
- memset(image, 0x00, 4 * osd_width * osd_height);
+ //
+ // create a RGBA texture.
+ //
+ glEnable(GL_TEXTURE_2D); // create 2d texture(s)
+
+ glGenTextures(2, OsdGlTextures);
+ for (i = 0; i < 2; ++i) {
+ glBindTexture(GL_TEXTURE_2D, OsdGlTextures[i]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA,
+ GL_UNSIGNED_BYTE, NULL);
}
- for (y = 0; y < osd_height; ++y) {
- for (x = 0; x < osd_width; ++x) {
- ((uint32_t *) image)[x + y * osd_width] =
- 0x00FFFFFF | (cycle++) << 24;
- }
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+}
+
+///
+/// GLX cleanup osd.
+///
+static void GlxOsdExit(void)
+{
+ if (OsdGlTextures[0]) {
+ glDeleteTextures(2, OsdGlTextures);
+ OsdGlTextures[0] = 0;
+ OsdGlTextures[1] = 0;
}
- cycle++;
+}
- // FIXME: convert is for GLX texture unneeded
- // convert internal osd to image
- //GfxConvert(image, 0, 4 * osd_width);
- //
+///
+/// Upload ARGB image to texture.
+///
+/// @param x x coordinate of image in osd texture
+/// @param y y coordinate of image in osd texture
+/// @param width width of image
+/// @param height height of image
+/// @param argb argb image
+///
+/// @note looked by caller
+///
+static void GlxOsdDrawARGB(int x, int y, int width, int height,
+ const uint8_t * argb)
+{
+#ifdef DEBUG
+ uint32_t start;
+ uint32_t end;
+#endif
+
+#ifdef DEBUG
+ if (!GlxEnabled) {
+ Debug(3, "video/glx: %s called without glx enabled\n", __FUNCTION__);
+ return;
+ }
+ start = GetMsTicks();
+ Debug(3, "video/glx: osd context %p <-> %p\n", glXGetCurrentContext(),
+ GlxContext);
+#endif
+
+ // set glx context
+ if (!glXMakeCurrent(XlibDisplay, VideoWindow, GlxContext)) {
+ Error(_("video/glx: can't make glx context current\n"));
+ return;
+ }
+ GlxUploadOsdTexture(x, y, width, height, argb);
+ glXMakeCurrent(XlibDisplay, None, NULL);
+
+#ifdef DEBUG
+ end = GetMsTicks();
+
+ Debug(3, "video/glx: osd upload %dx%d%+d%+d %dms %d\n", width, height, x,
+ y, end - start, width * height * 4);
+#endif
+}
+
+///
+/// Clear OSD texture.
+///
+/// @note looked by caller
+///
+static void GlxOsdClear(void)
+{
+ void *texbuf;
+
+#ifdef DEBUG
+ if (!GlxEnabled) {
+ Debug(3, "video/glx: %s called without glx enabled\n", __FUNCTION__);
+ return;
+ }
+
+ Debug(3, "video/glx: osd context %p <-> %p\n", glXGetCurrentContext(),
+ GlxContext);
+#endif
+
+ // FIXME: any opengl function to clear an area?
+ // FIXME: if not; use zero buffer
+ // FIXME: if not; use dirty area
+
+ texbuf = calloc(OsdWidth * OsdHeight, 4);
- GlxUploadTexture(0, 0, osd_width, osd_height, image);
+ // set glx context
+ if (!glXMakeCurrent(XlibDisplay, VideoWindow, GlxContext)) {
+ Error(_("video/glx: can't make glx context current\n"));
+ return;
+ }
+ GlxUploadOsdTexture(0, 0, OsdWidth, OsdHeight, texbuf);
+ glXMakeCurrent(XlibDisplay, None, NULL);
+
+ free(texbuf);
}
///
/// Setup GLX window.
///
-static void GlxSetupWindow(xcb_window_t window, int width, int height)
+/// @param window xcb window id
+/// @param width window width
+/// @param height window height
+/// @param context GLX context
+///
+static void GlxSetupWindow(xcb_window_t window, int width, int height,
+ GLXContext context)
{
+#ifdef DEBUG
uint32_t start;
uint32_t end;
int i;
unsigned count;
+#endif
- Debug(3, "video/glx: %s\n %x %dx%d", __FUNCTION__, window, width, height);
+ Debug(3, "video/glx: %s %x %dx%d context:%p", __FUNCTION__, window, width,
+ height, context);
// set glx context
- if (!glXMakeCurrent(XlibDisplay, window, GlxContext)) {
- Fatal(_("video/glx: can't make glx context current\n"));
- // FIXME: disable glx
+ if (!glXMakeCurrent(XlibDisplay, window, context)) {
+ Error(_("video/glx: can't make glx context current\n"));
+ GlxEnabled = 0;
return;
}
@@ -995,7 +1117,8 @@ static void GlxInit(void)
if (!context) {
Error(_("video/glx: can't create glx context\n"));
GlxEnabled = 0;
- // FIXME: destroy GlxSharedContext
+ glXDestroyContext(XlibDisplay, GlxSharedContext);
+ GlxSharedContext = 0;
return;
}
GlxContext = context;
@@ -1092,12 +1215,10 @@ static void GlxExit(void)
if (GlxContext) {
glXDestroyContext(XlibDisplay, GlxContext);
}
-#if 0
if (GlxThreadContext) {
glXDestroyContext(XlibDisplay, GlxThreadContext);
}
// FIXME: must free GlxVisualInfo
-#endif
}
#endif
@@ -1393,8 +1514,8 @@ struct _vaapi_decoder_
AutoCropCtx AutoCrop[1]; ///< auto-crop variables
#endif
#ifdef USE_GLX
- GLuint GlTexture[2]; ///< gl texture for VA-API
- void *GlxSurface[2]; ///< VA-API/GLX surface
+ GLuint GlTextures[2]; ///< gl texture for VA-API
+ void *GlxSurfaces[2]; ///< VA-API/GLX surface
#endif
VASurfaceID BlackSurface; ///< empty black surface
@@ -1851,8 +1972,8 @@ static VaapiDecoder *VaapiNewHwDecoder(VideoStream * stream)
decoder->VaapiContext->context_id = VA_INVALID_ID;
#ifdef USE_GLX
- decoder->GlxSurface[0] = VA_INVALID_ID;
- decoder->GlxSurface[1] = VA_INVALID_ID;
+ decoder->GlxSurfaces[0] = NULL;
+ decoder->GlxSurfaces[1] = NULL;
if (GlxEnabled) {
// FIXME: create GLX context here
}
@@ -2008,20 +2129,22 @@ static void VaapiDelHwDecoder(VaapiDecoder * decoder)
}
}
#ifdef USE_GLX
- if (decoder->GlxSurface[0] != VA_INVALID_ID) {
- if (vaDestroySurfaceGLX(VaDisplay, decoder->GlxSurface[0])
+ if (decoder->GlxSurfaces[0]) {
+ if (vaDestroySurfaceGLX(VaDisplay, decoder->GlxSurfaces[0])
!= VA_STATUS_SUCCESS) {
Error(_("video/vaapi: can't destroy glx surface!\n"));
}
+ decoder->GlxSurfaces[0] = NULL;
}
- if (decoder->GlxSurface[1] != VA_INVALID_ID) {
- if (vaDestroySurfaceGLX(VaDisplay, decoder->GlxSurface[1])
+ if (decoder->GlxSurfaces[1]) {
+ if (vaDestroySurfaceGLX(VaDisplay, decoder->GlxSurfaces[1])
!= VA_STATUS_SUCCESS) {
Error(_("video/vaapi: can't destroy glx surface!\n"));
}
+ decoder->GlxSurfaces[0] = NULL;
}
- if (decoder->GlTexture[0]) {
- glDeleteTextures(2, decoder->GlTexture);
+ if (decoder->GlTextures[0]) {
+ glDeleteTextures(2, decoder->GlTextures);
}
#endif
@@ -2243,6 +2366,33 @@ static int VaapiInit(const char *display_name)
return 1;
}
+#ifdef USE_GLX
+
+///
+/// VA-API GLX setup.
+///
+/// @param display_name x11/xcb display name
+///
+/// @returns true if VA-API could be initialized, false otherwise.
+///
+static int VaapiGlxInit(const char *display_name)
+{
+ GlxEnabled = 1;
+
+ GlxInit();
+ if (GlxEnabled) {
+ GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight,
+ GlxContext);
+ }
+ if (!GlxEnabled) {
+ Error(_("video/glx: glx error\n"));
+ }
+
+ return VaapiInit(display_name);
+}
+
+#endif
+
///
/// VA-API cleanup
///
@@ -2250,7 +2400,7 @@ static void VaapiExit(void)
{
int i;
- // FIXME: more VA-API cleanups...
+// FIXME: more VA-API cleanups...
for (i = 0; i < VaapiDecoderN; ++i) {
if (VaapiDecoders[i]) {
@@ -2310,6 +2460,7 @@ static int VaapiFindImageFormat(VaapiDecoder * decoder,
// intel: I420 is native format for MPEG-2 decoded surfaces
// intel: NV12 is native format for H.264 decoded surfaces
case PIX_FMT_YUV420P:
+ case PIX_FMT_YUVJ420P:
// fourcc = VA_FOURCC_YV12; // YVU
fourcc = VA_FOURCC('I', '4', '2', '0'); // YUV
break;
@@ -2403,16 +2554,18 @@ static void VaapiSetup(VaapiDecoder * decoder,
if (GlxEnabled) {
// FIXME: destroy old context
- GlxSetupDecoder(decoder);
+ GlxSetupDecoder(decoder->InputWidth, decoder->InputHeight,
+ decoder->GlTextures);
// FIXME: try two textures
if (vaCreateSurfaceGLX(decoder->VaDisplay, GL_TEXTURE_2D,
- decoder->GlTexture[0], &decoder->GlxSurface[0])
+ decoder->GlTextures[0], &decoder->GlxSurfaces[0])
!= VA_STATUS_SUCCESS) {
Fatal(_("video/glx: can't create glx surfaces\n"));
+ // FIXME: no fatal here
}
/*
if (vaCreateSurfaceGLX(decoder->VaDisplay, GL_TEXTURE_2D,
- decoder->GlTexture[1], &decoder->GlxSurface[1])
+ decoder->GlTextures[1], &decoder->GlxSurfaces[1])
!= VA_STATUS_SUCCESS) {
Fatal(_("video/glx: can't create glx surfaces\n"));
}
@@ -2424,6 +2577,11 @@ static void VaapiSetup(VaapiDecoder * decoder,
//
// update OSD associate
//
+#ifdef USE_GLX
+ if (GlxEnabled) {
+ return;
+ }
+#endif
VaapiAssociate(decoder);
}
@@ -2544,7 +2702,7 @@ static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
int e;
VAConfigAttrib attrib;
- if (!VideoHardwareDecoder || (video_ctx->codec_id == CODEC_ID_MPEG2VIDEO
+ if (!VideoHardwareDecoder || (video_ctx->codec_id == AV_CODEC_ID_MPEG2VIDEO
&& VideoHardwareDecoder == 1)
) { // hardware disabled by config
Debug(3, "codec: hardware acceleration disabled\n");
@@ -2563,19 +2721,19 @@ static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
// check profile
switch (video_ctx->codec_id) {
- case CODEC_ID_MPEG2VIDEO:
+ case AV_CODEC_ID_MPEG2VIDEO:
decoder->SurfacesNeeded =
CODEC_SURFACES_MPEG2 + VIDEO_SURFACES_MAX + 2;
p = VaapiFindProfile(profiles, profile_n, VAProfileMPEG2Main);
break;
- case CODEC_ID_MPEG4:
- case CODEC_ID_H263:
+ case AV_CODEC_ID_MPEG4:
+ case AV_CODEC_ID_H263:
decoder->SurfacesNeeded =
CODEC_SURFACES_MPEG4 + VIDEO_SURFACES_MAX + 2;
p = VaapiFindProfile(profiles, profile_n,
VAProfileMPEG4AdvancedSimple);
break;
- case CODEC_ID_H264:
+ case AV_CODEC_ID_H264:
decoder->SurfacesNeeded =
CODEC_SURFACES_H264 + VIDEO_SURFACES_MAX + 2;
// try more simple formats, fallback to better
@@ -2593,12 +2751,12 @@ static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
p = VaapiFindProfile(profiles, profile_n, VAProfileH264High);
}
break;
- case CODEC_ID_WMV3:
+ case AV_CODEC_ID_WMV3:
decoder->SurfacesNeeded =
CODEC_SURFACES_VC1 + VIDEO_SURFACES_MAX + 2;
p = VaapiFindProfile(profiles, profile_n, VAProfileVC1Main);
break;
- case CODEC_ID_VC1:
+ case AV_CODEC_ID_VC1:
decoder->SurfacesNeeded =
CODEC_SURFACES_VC1 + VIDEO_SURFACES_MAX + 2;
p = VaapiFindProfile(profiles, profile_n, VAProfileVC1Advanced);
@@ -2826,44 +2984,6 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
#ifdef USE_GLX
///
-/// Render texture.
-///
-/// @param texture 2d texture
-///
-static inline void VideoRenderTexture(GLuint texture, int x, int y, int width,
- int height)
-{
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, texture);
-
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // no color
- glBegin(GL_QUADS); {
- glTexCoord2f(1.0f, 1.0f);
- glVertex2i(x + width, y + height);
- glTexCoord2f(0.0f, 1.0f);
- glVertex2i(x, y + height);
- glTexCoord2f(0.0f, 0.0f);
- glVertex2i(x, y);
- glTexCoord2f(1.0f, 0.0f);
- glVertex2i(x + width, y);
-#if 0
- glTexCoord2f(0.0f, 0.0f);
- glVertex2i(x, y);
- glTexCoord2f(0.0f, 1.0f);
- glVertex2i(x, y + height);
- glTexCoord2f(1.0f, 1.0f);
- glVertex2i(x + width, y + height);
- glTexCoord2f(1.0f, 0.0f);
- glVertex2i(x + width, y);
-#endif
- }
- glEnd();
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
-}
-
-///
/// Draw surface of the VA-API decoder with glx.
///
/// @param decoder VA-API decoder
@@ -2876,12 +2996,14 @@ static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface,
int interlaced, int top_field_first, int field)
{
unsigned type;
- uint32_t start;
- uint32_t copy;
- uint32_t end;
+
+ //uint32_t start;
+ //uint32_t copy;
+ //uint32_t end;
// deinterlace
if (interlaced
+ && VideoDeinterlace[decoder->Resolution] < VideoDeinterlaceSoftBob
&& VideoDeinterlace[decoder->Resolution] != VideoDeinterlaceWeave) {
if (top_field_first) {
if (field) {
@@ -2899,18 +3021,20 @@ static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface,
} else {
type = VA_FRAME_PICTURE;
}
- start = GetMsTicks();
- if (vaCopySurfaceGLX(decoder->VaDisplay, decoder->GlxSurface[0], surface,
+
+ //start = GetMsTicks();
+ if (vaCopySurfaceGLX(decoder->VaDisplay, decoder->GlxSurfaces[0], surface,
type | decoder->SurfaceFlagsTable[decoder->Resolution]) !=
VA_STATUS_SUCCESS) {
Error(_("video/glx: vaCopySurfaceGLX failed\n"));
return;
}
- copy = GetMsTicks();
+ //copy = GetMsTicks();
// hardware surfaces are always busy
- VideoRenderTexture(decoder->GlTexture[0], decoder->OutputX,
+ // FIXME: CropX, ...
+ GlxRenderTexture(decoder->GlTextures[0], decoder->OutputX,
decoder->OutputY, decoder->OutputWidth, decoder->OutputHeight);
- end = GetMsTicks();
+ //end = GetMsTicks();
//Debug(3, "video/vaapi/glx: %d copy %d render\n", copy - start, end - copy);
}
@@ -3264,6 +3388,12 @@ static void VaapiBlackSurface(VaapiDecoder * decoder)
uint32_t sync;
uint32_t put1;
+#ifdef USE_GLX
+ if (GlxEnabled) { // already done
+ return;
+ }
+#endif
+
// wait until we have osd subpicture
if (VaOsdSubpicture == VA_INVALID_ID) {
Warning(_("video/vaapi: no osd subpicture yet\n"));
@@ -4450,6 +4580,16 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
}
///
+/// Get hwaccel context for ffmpeg.
+///
+/// @param decoder VA-API hw decoder
+///
+static void *VaapiGetHwAccelContext(VaapiDecoder * decoder)
+{
+ return decoder->VaapiContext;
+}
+
+///
/// Advance displayed frame of decoder.
///
/// @param decoder VA-API hw decoder
@@ -4575,8 +4715,16 @@ static void VaapiDisplayFrame(void)
put2 = GetMsTicks();
#endif
} else {
- VaapiPutSurfaceX11(decoder, surface, decoder->Interlaced,
- decoder->TopFieldFirst, decoder->SurfaceField);
+#ifdef USE_GLX
+ if (GlxEnabled) {
+ VaapiPutSurfaceGLX(decoder, surface, decoder->Interlaced,
+ decoder->TopFieldFirst, decoder->SurfaceField);
+ } else
+#endif
+ {
+ VaapiPutSurfaceX11(decoder, surface, decoder->Interlaced,
+ decoder->TopFieldFirst, decoder->SurfaceField);
+ }
#ifdef DEBUG
put1 = GetMsTicks();
put2 = put1;
@@ -4609,6 +4757,24 @@ static void VaapiDisplayFrame(void)
decoder->FrameTime = nowtime;
}
+
+#ifdef USE_GLX
+ if (GlxEnabled) {
+ //
+ // add OSD
+ //
+ if (OsdShown) {
+ GlxRenderTexture(OsdGlTextures[OsdIndex], 0, 0, VideoWindowWidth,
+ VideoWindowHeight);
+ // FIXME: toggle osd
+ }
+ //glFinish();
+ glXSwapBuffers(XlibDisplay, VideoWindow);
+ GlxCheck();
+ //glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+#endif
}
///
@@ -4644,6 +4810,26 @@ static int64_t VaapiGetClock(const VaapiDecoder * decoder)
}
///
+/// Set VA-API decoder closing stream flag.
+///
+/// @param decoder VA-API decoder
+///
+static void VaapiSetClosing(VaapiDecoder * decoder)
+{
+ decoder->Closing = 1;
+}
+
+///
+/// Reset start of frame counter.
+///
+/// @param decoder VA-API decoder
+///
+static void VaapiResetStart(VaapiDecoder * decoder)
+{
+ decoder->StartCounter = 0;
+}
+
+///
/// Set trick play speed.
///
/// @param decoder VA-API decoder
@@ -4659,6 +4845,24 @@ static void VaapiSetTrickSpeed(VaapiDecoder * decoder, int speed)
}
///
+/// Get VA-API decoder statistics.
+///
+/// @param decoder VA-API decoder
+/// @param[out] missed missed frames
+/// @param[out] duped duped frames
+/// @param[out] dropped dropped frames
+/// @param[out] count number of decoded frames
+///
+void VaapiGetStats(VaapiDecoder * decoder, int *missed, int *duped,
+ int *dropped, int *counter)
+{
+ *missed = decoder->FramesMissed;
+ *duped = decoder->FramesDuped;
+ *dropped = decoder->FramesDropped;
+ *counter = decoder->FrameCounter;
+}
+
+///
/// Sync decoder output to audio.
///
/// trick-speed show frame <n> times
@@ -4751,7 +4955,7 @@ static void VaapiSyncDecoder(VaapiDecoder * decoder)
Debug(3, "video/vaapi: synced after %d frames %dms\n",
decoder->StartCounter, GetMsTicks() - VideoSwitch);
#else
- Debug(3, "video/vaapi: synced after %d frames\n",
+ Info("video/vaapi: synced after %d frames\n",
decoder->StartCounter);
#endif
decoder->StartCounter += 1000;
@@ -5211,11 +5415,17 @@ static const VideoModule VaapiModule = {
AVCodecContext *, const enum PixelFormat *))Vaapi_get_format,
.RenderFrame = (void (*const) (VideoHwDecoder *,
const AVCodecContext *, const AVFrame *))VaapiSyncRenderFrame,
+ .GetHwAccelContext = (void *(*const)(VideoHwDecoder *))
+ VaapiGetHwAccelContext,
.SetClock = (void (*const) (VideoHwDecoder *, int64_t))VaapiSetClock,
.GetClock = (int64_t(*const) (const VideoHwDecoder *))VaapiGetClock,
+ .SetClosing = (void (*const) (const VideoHwDecoder *))VaapiSetClosing,
+ .ResetStart = (void (*const) (const VideoHwDecoder *))VaapiResetStart,
.SetTrickSpeed =
(void (*const) (const VideoHwDecoder *, int))VaapiSetTrickSpeed,
.GrabOutput = NULL,
+ .GetStats = (void (*const) (VideoHwDecoder *, int *, int *, int *,
+ int *))VaapiGetStats,
.SetBackground = VaapiSetBackground,
.SetVideoMode = VaapiSetVideoMode,
.ResetAutoCrop = VaapiResetAutoCrop,
@@ -5228,6 +5438,50 @@ static const VideoModule VaapiModule = {
.Exit = VaapiExit,
};
+#ifdef USE_GLX
+
+///
+/// VA-API module.
+///
+static const VideoModule VaapiGlxModule = {
+ .Name = "va-api-glx",
+ .Enabled = 1,
+ .NewHwDecoder =
+ (VideoHwDecoder * (*const)(VideoStream *)) VaapiNewHwDecoder,
+ .DelHwDecoder = (void (*const) (VideoHwDecoder *))VaapiDelHwDecoder,
+ .GetSurface = (unsigned (*const) (VideoHwDecoder *,
+ const AVCodecContext *))VaapiGetSurface,
+ .ReleaseSurface =
+ (void (*const) (VideoHwDecoder *, unsigned))VaapiReleaseSurface,
+ .get_format = (enum PixelFormat(*const) (VideoHwDecoder *,
+ AVCodecContext *, const enum PixelFormat *))Vaapi_get_format,
+ .RenderFrame = (void (*const) (VideoHwDecoder *,
+ const AVCodecContext *, const AVFrame *))VaapiSyncRenderFrame,
+ .GetHwAccelContext = (void *(*const)(VideoHwDecoder *))
+ VaapiGetHwAccelContext,
+ .SetClock = (void (*const) (VideoHwDecoder *, int64_t))VaapiSetClock,
+ .GetClock = (int64_t(*const) (const VideoHwDecoder *))VaapiGetClock,
+ .SetClosing = (void (*const) (const VideoHwDecoder *))VaapiSetClosing,
+ .ResetStart = (void (*const) (const VideoHwDecoder *))VaapiResetStart,
+ .SetTrickSpeed =
+ (void (*const) (const VideoHwDecoder *, int))VaapiSetTrickSpeed,
+ .GrabOutput = NULL,
+ .GetStats = (void (*const) (VideoHwDecoder *, int *, int *, int *,
+ int *))VaapiGetStats,
+ .SetBackground = VaapiSetBackground,
+ .SetVideoMode = VaapiSetVideoMode,
+ .ResetAutoCrop = VaapiResetAutoCrop,
+ .DisplayHandlerThread = VaapiDisplayHandlerThread,
+ .OsdClear = GlxOsdClear,
+ .OsdDrawARGB = GlxOsdDrawARGB,
+ .OsdInit = GlxOsdInit,
+ .OsdExit = GlxOsdExit,
+ .Init = VaapiGlxInit,
+ .Exit = VaapiExit,
+};
+
+#endif
+
#endif
//----------------------------------------------------------------------------
@@ -5271,11 +5525,13 @@ typedef struct _vdpau_decoder_
int CropHeight; ///< video crop height
#ifdef USE_AUTOCROP
+ void *AutoCropBuffer; ///< auto-crop buffer cache
+ unsigned AutoCropBufferSize; ///< auto-crop buffer size
AutoCropCtx AutoCrop[1]; ///< auto-crop variables
#endif
#ifdef noyetUSE_GLX
- GLuint GlTexture[2]; ///< gl texture for VDPAU
- void *GlxSurface[2]; ///< VDPAU/GLX surface
+ GLuint GlTextures[2]; ///< gl texture for VDPAU
+ void *GlxSurfaces[2]; ///< VDPAU/GLX surface
#endif
VdpDecoderProfile Profile; ///< vdp decoder profile
@@ -5941,8 +6197,8 @@ static VdpauDecoder *VdpauNewHwDecoder(VideoStream * stream)
}
decoder->Device = VdpauDevice;
decoder->Window = VideoWindow;
- decoder->VideoX = 0;
- decoder->VideoY = 0;
+ //decoder->VideoX = 0; // done by calloc
+ //decoder->VideoY = 0;
decoder->VideoWidth = VideoWindowWidth;
decoder->VideoHeight = VideoWindowHeight;
@@ -5983,6 +6239,11 @@ static VdpauDecoder *VdpauNewHwDecoder(VideoStream * stream)
decoder->PixFmt = PIX_FMT_NONE;
+#ifdef USE_AUTOCROP
+ //decoder->AutoCropBuffer = NULL; // done by calloc
+ //decoder->AutoCropBufferSize = 0;
+#endif
+
decoder->Stream = stream;
if (!VdpauDecoderN) { // FIXME: hack sync on audio
decoder->SyncOnAudio = 1;
@@ -6069,6 +6330,9 @@ static void VdpauDelHwDecoder(VdpauDecoder * decoder)
VdpauCleanup(decoder);
VdpauPrintFrames(decoder);
+#ifdef USE_AUTOCROP
+ free(decoder->AutoCropBuffer);
+#endif
free(decoder);
return;
@@ -6741,7 +7005,7 @@ static void VdpauSetupOutput(VdpauDecoder * decoder)
if (width != (uint32_t) decoder->InputWidth
|| height != (uint32_t) decoder->InputHeight) {
// FIXME: must rewrite the code to support this case
- Fatal(_("video/vdpau: video surface size mismatch\n"));
+ Warning(_("video/vdpau: video surface size mismatch\n"));
}
}
@@ -6831,7 +7095,7 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder,
VdpDecoderProfile profile;
int max_refs;
- if (!VideoHardwareDecoder || (video_ctx->codec_id == CODEC_ID_MPEG2VIDEO
+ if (!VideoHardwareDecoder || (video_ctx->codec_id == AV_CODEC_ID_MPEG2VIDEO
&& VideoHardwareDecoder == 1)
) { // hardware disabled by config
Debug(3, "codec: hardware acceleration disabled\n");
@@ -6866,23 +7130,23 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder,
max_refs = CODEC_SURFACES_DEFAULT;
// check profile
switch (video_ctx->codec_id) {
- case CODEC_ID_MPEG1VIDEO:
+ case AV_CODEC_ID_MPEG1VIDEO:
max_refs = CODEC_SURFACES_MPEG2;
profile = VdpauCheckProfile(decoder, VDP_DECODER_PROFILE_MPEG1);
break;
- case CODEC_ID_MPEG2VIDEO:
+ case AV_CODEC_ID_MPEG2VIDEO:
max_refs = CODEC_SURFACES_MPEG2;
profile =
VdpauCheckProfile(decoder, VDP_DECODER_PROFILE_MPEG2_MAIN);
break;
- case CODEC_ID_MPEG4:
- case CODEC_ID_H263:
+ case AV_CODEC_ID_MPEG4:
+ case AV_CODEC_ID_H263:
/*
p = VaapiFindProfile(profiles, profile_n,
VAProfileMPEG4AdvancedSimple);
*/
goto slow_path;
- case CODEC_ID_H264:
+ case AV_CODEC_ID_H264:
// FIXME: can calculate level 4.1 limits
// vdpau supports only 16 references
max_refs = 16;
@@ -6914,12 +7178,12 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder,
VdpauCheckProfile(decoder, VDP_DECODER_PROFILE_H264_MAIN);
}
break;
- case CODEC_ID_WMV3:
+ case AV_CODEC_ID_WMV3:
/*
p = VaapiFindProfile(profiles, profile_n, VAProfileVC1Main);
*/
goto slow_path;
- case CODEC_ID_VC1:
+ case AV_CODEC_ID_VC1:
/*
p = VaapiFindProfile(profiles, profile_n, VAProfileVC1Advanced);
*/
@@ -7023,6 +7287,7 @@ static void VdpauGrabVideoSurface(VdpauDecoder * decoder)
case VDP_CHROMA_TYPE_444:
size = width * height + ((width + 1) / 2) * ((height + 1) / 2)
+ ((width + 1) / 2) * ((height + 1) / 2);
+ // FIXME: can use auto-crop buffer cache
base = malloc(size);
if (!base) {
Error(_("video/vdpau: out of memory\n"));
@@ -7095,7 +7360,7 @@ static uint8_t *VdpauGrabOutputSurfaceLocked(int *ret_size, int *ret_width,
source_rect.y1 = height;
if (ret_width && ret_height) {
- if (*ret_width <= -64) { // this is a Atmo grab service request
+ if (*ret_width <= -64) { // this is an Atmo grab service request
int overscan;
// calculate aspect correct size of analyze image
@@ -7143,6 +7408,23 @@ static uint8_t *VdpauGrabOutputSurfaceLocked(int *ret_size, int *ret_width,
surface = VdpauGrabRenderSurface;
source_rect = output_rect;
+#if 0
+ // FIXME: what if VdpauGrabRenderSurface has different sizes
+ // get real surface size
+ status =
+ VdpauOutputSurfaceGetParameters(surface, &rgba_format, &width,
+ &height);
+ if (status != VDP_STATUS_OK) {
+ Error(_
+ ("video/vdpau: can't get output surface parameters: %s\n"),
+ VdpauGetErrorString(status));
+ return NULL;
+ }
+ if (width != output_rect.x1 || height != output_rect.y1) {
+ // FIXME: this warning can be removed, is now for debug only
+ Warning(_("video/vdpau: video surface size mismatch\n"));
+ }
+#endif
}
}
@@ -7238,7 +7520,7 @@ static void VdpauAutoCrop(VdpauDecoder * decoder)
surface = decoder->SurfacesRb[(decoder->SurfaceRead + 1)
% VIDEO_SURFACES_MAX];
- // get real surface size
+ // get real surface size (can be different)
status =
VdpauVideoSurfaceGetParameters(surface, &chroma_type, &width, &height);
if (status != VDP_STATUS_OK) {
@@ -7252,7 +7534,13 @@ static void VdpauAutoCrop(VdpauDecoder * decoder)
case VDP_CHROMA_TYPE_444:
size = width * height + ((width + 1) / 2) * ((height + 1) / 2)
+ ((width + 1) / 2) * ((height + 1) / 2);
- base = malloc(size);
+ // cache buffer for reuse
+ base = decoder->AutoCropBuffer;
+ if (size > decoder->AutoCropBufferSize) {
+ free(base);
+ decoder->AutoCropBuffer = malloc(size);
+ base = decoder->AutoCropBuffer;
+ }
if (!base) {
Error(_("video/vdpau: out of memory\n"));
return;
@@ -7277,7 +7565,6 @@ static void VdpauAutoCrop(VdpauDecoder * decoder)
}
AutoCropDetect(decoder->AutoCrop, width, height, data, pitches);
- free(base);
// ignore black frames
if (decoder->AutoCrop->Y1 >= decoder->AutoCrop->Y2) {
@@ -7582,6 +7869,7 @@ static void VdpauRenderFrame(VdpauDecoder * decoder,
//
switch (video_ctx->pix_fmt) {
case PIX_FMT_YUV420P:
+ case PIX_FMT_YUVJ420P: // some streams produce this
break;
case PIX_FMT_YUV422P:
case PIX_FMT_YUV444P:
@@ -7619,6 +7907,20 @@ static void VdpauRenderFrame(VdpauDecoder * decoder,
}
///
+/// Get hwaccel context for ffmpeg.
+///
+/// @param decoder VDPAU hw decoder
+///
+static void *VdpauGetHwAccelContext(VdpauDecoder * decoder)
+{
+ (void)decoder;
+
+ // FIXME: new ffmpeg versions supports struct AVVDPAUContext
+ Error(_("video: get hwaccel context, not supported\n"));
+ return NULL;
+}
+
+///
/// Render osd surface to output surface.
///
static void VdpauMixOsd(void)
@@ -8128,10 +8430,30 @@ static int64_t VdpauGetClock(const VdpauDecoder * decoder)
}
///
+/// Set VDPAU decoder closing stream flag.
+///
+/// @param decoder VDPAU decoder
+///
+static void VdpauSetClosing(VdpauDecoder * decoder)
+{
+ decoder->Closing = 1;
+}
+
+///
+/// Reset start of frame counter.
+///
+/// @param decoder VDPAU decoder
+///
+static void VdpauResetStart(VdpauDecoder * decoder)
+{
+ decoder->StartCounter = 0;
+}
+
+///
/// Set trick play speed.
///
-/// @param decoder VDPAU decoder
-/// @param speed trick speed (0 = normal)
+/// @param decoder VDPAU decoder
+/// @param speed trick speed (0 = normal)
///
static void VdpauSetTrickSpeed(VdpauDecoder * decoder, int speed)
{
@@ -8143,6 +8465,24 @@ static void VdpauSetTrickSpeed(VdpauDecoder * decoder, int speed)
}
///
+/// Get VDPAU decoder statistics.
+///
+/// @param decoder VDPAU decoder
+/// @param[out] missed missed frames
+/// @param[out] duped duped frames
+/// @param[out] dropped dropped frames
+/// @param[out] count number of decoded frames
+///
+void VdpauGetStats(VdpauDecoder * decoder, int *missed, int *duped,
+ int *dropped, int *counter)
+{
+ *missed = decoder->FramesMissed;
+ *duped = decoder->FramesDuped;
+ *dropped = decoder->FramesDropped;
+ *counter = decoder->FrameCounter;
+}
+
+///
/// Sync decoder output to audio.
///
/// trick-speed show frame <n> times
@@ -8240,7 +8580,7 @@ static void VdpauSyncDecoder(VdpauDecoder * decoder)
Debug(3, "video/vdpau: synced after %d frames %dms\n",
decoder->StartCounter, GetMsTicks() - VideoSwitch);
#else
- Debug(3, "video/vdpau: synced after %d frames\n",
+ Info("video/vdpau: synced after %d frames\n",
decoder->StartCounter);
#endif
decoder->StartCounter += 1000;
@@ -8840,11 +9180,17 @@ static const VideoModule VdpauModule = {
AVCodecContext *, const enum PixelFormat *))Vdpau_get_format,
.RenderFrame = (void (*const) (VideoHwDecoder *,
const AVCodecContext *, const AVFrame *))VdpauSyncRenderFrame,
+ .GetHwAccelContext = (void *(*const)(VideoHwDecoder *))
+ VdpauGetHwAccelContext,
.SetClock = (void (*const) (VideoHwDecoder *, int64_t))VdpauSetClock,
.GetClock = (int64_t(*const) (const VideoHwDecoder *))VdpauGetClock,
+ .SetClosing = (void (*const) (const VideoHwDecoder *))VdpauSetClosing,
+ .ResetStart = (void (*const) (const VideoHwDecoder *))VdpauResetStart,
.SetTrickSpeed =
(void (*const) (const VideoHwDecoder *, int))VdpauSetTrickSpeed,
.GrabOutput = VdpauGrabOutputSurface,
+ .GetStats = (void (*const) (VideoHwDecoder *, int *, int *, int *,
+ int *))VdpauGetStats,
.SetBackground = VdpauSetBackground,
.SetVideoMode = VdpauSetVideoMode,
.ResetAutoCrop = VdpauResetAutoCrop,
@@ -8995,11 +9341,17 @@ static const VideoModule NoopModule = {
AVCodecContext *, const enum PixelFormat *))Noop_get_format,
.RenderFrame = (void (*const) (VideoHwDecoder *,
const AVCodecContext *, const AVFrame *))NoopSyncRenderFrame,
+ .GetHwAccelContext = (void *(*const)(VideoHwDecoder *))
+ DummyGetHwAccelContext,
.SetClock = (void (*const) (VideoHwDecoder *, int64_t))NoopSetClock,
.GetClock = (int64_t(*const) (const VideoHwDecoder *))NoopGetClock,
+ .SetClosing = (void (*const) (const VideoHwDecoder *))NoopSetClosing,
+ .ResetStart = (void (*const) (const VideoHwDecoder *))NoopResetStart,
.SetTrickSpeed =
(void (*const) (const VideoHwDecoder *, int))NoopSetTrickSpeed,
.GrabOutput = NoopGrabOutputSurface,
+ .GetStats = (void (*const) (VideoHwDecoder *, int *, int *, int *,
+ int *))NoopGetStats,
#endif
.SetBackground = NoopSetBackground,
.SetVideoMode = NoopVoid,
@@ -9026,26 +9378,9 @@ static const VideoModule NoopModule = {
void VideoOsdClear(void)
{
VideoThreadLock();
-#ifdef USE_GLX
- if (GlxEnabled) {
- void *texbuf;
-
- texbuf = calloc(OsdWidth * OsdHeight, 4);
- glEnable(GL_TEXTURE_2D); // 2d texture
- glBindTexture(GL_TEXTURE_2D, OsdGlTextures[OsdIndex]);
- // upload no image data, clears texture (on some drivers only)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, OsdWidth, OsdHeight, 0,
- GL_BGRA, GL_UNSIGNED_BYTE, texbuf);
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
- GlxCheck();
- free(texbuf);
- }
-#endif
-
VideoUsedModule->OsdClear();
- OsdDirtyX = OsdWidth;
+ OsdDirtyX = OsdWidth; // reset dirty area
OsdDirtyY = OsdHeight;
OsdDirtyWidth = 0;
OsdDirtyHeight = 0;
@@ -9089,14 +9424,6 @@ void VideoOsdDrawARGB(int x, int y, int width, int height,
Debug(4, "video: osd dirty %dx%d%+d%+d -> %dx%d%+d%+d\n", width, height, x,
y, OsdDirtyWidth, OsdDirtyHeight, OsdDirtyX, OsdDirtyY);
-#ifdef USE_GLX
- if (GlxEnabled) {
- Debug(3, "video: %p <-> %p\n", glXGetCurrentContext(), GlxContext);
- GlxUploadTexture(x, y, height, width, argb);
- VideoThreadUnlock();
- return;
- }
-#endif
VideoUsedModule->OsdDrawARGB(x, y, width, height, argb);
OsdShown = 1;
@@ -9160,38 +9487,6 @@ void VideoOsdInit(void)
OsdHeight = VideoWindowHeight;
}
-#ifdef USE_GLX
- // FIXME: make an extra function for this
- if (GlxEnabled) {
- int i;
-
- Debug(3, "video/glx: %p <-> %p\n", glXGetCurrentContext(), GlxContext);
-
- //
- // create a RGBA texture.
- //
- glEnable(GL_TEXTURE_2D); // create 2d texture(s)
-
- glGenTextures(2, OsdGlTextures);
- for (i = 0; i < 2; ++i) {
- glBindTexture(GL_TEXTURE_2D, OsdGlTextures[i]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
- GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
- GL_CLAMP_TO_EDGE);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, OsdWidth, OsdHeight, 0,
- GL_BGRA, GL_UNSIGNED_BYTE, NULL);
- }
- glBindTexture(GL_TEXTURE_2D, 0);
-
- glDisable(GL_TEXTURE_2D);
- return;
- }
-#endif
-
VideoThreadLock();
VideoUsedModule->OsdInit(OsdWidth, OsdHeight);
VideoThreadUnlock();
@@ -9210,84 +9505,6 @@ void VideoOsdExit(void)
OsdDirtyHeight = 0;
}
-#if 0
-
-//----------------------------------------------------------------------------
-// Overlay
-//----------------------------------------------------------------------------
-
-///
-/// Render osd surface.
-///
-void VideoRenderOverlay(void)
-{
-#ifdef USE_GLX
- if (GlxEnabled) {
- GlxRender(OsdWidth, OsdHeight);
- } else
-#endif
- {
- }
-}
-
-///
-/// Display overlay surface.
-///
-void VideoDisplayOverlay(void)
-{
-#ifdef USE_GLX
- if (GlxEnabled) {
- int osd_x1;
- int osd_y1;
-
- osd_x1 = 0;
- osd_y1 = 0;
-#ifdef noDEBUG
- osd_x1 = 100;
- osd_y1 = 100;
-#endif
- GlxRenderTexture(OsdGlTextures[OsdIndex], osd_x1, osd_y1,
- VideoWindowWidth, VideoWindowHeight);
- return;
- }
-#endif
-#ifdef USE_VAAPI
- {
- void *image_buffer;
- static int counter;
-
- // upload needs long time
- if (counter == 5) {
- //return;
- }
- // osd image available?
- if (VaOsdImage.image_id == VA_INVALID_ID) {
- return;
- }
- // FIXME: this version hangups
- //return;
-
- // map osd surface/image into memory.
- if (vaMapBuffer(VaDisplay, VaOsdImage.buf,
- &image_buffer) != VA_STATUS_SUCCESS) {
- Error(_("video/vaapi: can't map osd image buffer\n"));
- return;
- }
- // 100% transparent
- memset(image_buffer, 0x80 | counter++, VaOsdImage.data_size);
-
- // convert internal osd to VA-API image
- //GfxConvert(image_buffer, VaOsdImage.offsets[0], VaOsdImage.pitches[0]);
-
- if (vaUnmapBuffer(VaDisplay, VaOsdImage.buf) != VA_STATUS_SUCCESS) {
- Error(_("video/vaapi: can't unmap osd image buffer\n"));
- }
- }
-#endif
-}
-
-#endif
-
//----------------------------------------------------------------------------
// Events
//----------------------------------------------------------------------------
@@ -9339,7 +9556,9 @@ static void VideoEvent(void)
char buf[64];
uint32_t values[1];
+ VideoThreadLock();
XNextEvent(XlibDisplay, &event);
+ VideoThreadUnlock();
switch (event.type) {
case ClientMessage:
Debug(3, "video/event: ClientMessage\n");
@@ -9352,8 +9571,10 @@ static void VideoEvent(void)
case MapNotify:
Debug(3, "video/event: MapNotify\n");
// �wm workaround
+ VideoThreadLock();
xcb_change_window_attributes(Connection, VideoWindow,
XCB_CW_CURSOR, &VideoBlankCursor);
+ VideoThreadUnlock();
VideoBlankTick = 0;
break;
case Expose:
@@ -9371,13 +9592,17 @@ static void VideoEvent(void)
VideoSetFullscreen(-1);
break;
case KeyPress:
+ VideoThreadLock();
XLookupString(&event.xkey, buf, sizeof(buf), &keysym, NULL);
+ VideoThreadUnlock();
if (keysym == NoSymbol) {
Warning(_("video/event: No symbol for %d\n"),
event.xkey.keycode);
break;
}
+ VideoThreadLock();
keynam = XKeysymToString(keysym);
+ VideoThreadUnlock();
// check for key modifiers (Alt/Ctrl)
if (event.xkey.state & (Mod1Mask | ControlMask)) {
if (event.xkey.state & Mod1Mask) {
@@ -9397,8 +9622,10 @@ static void VideoEvent(void)
break;
case MotionNotify:
values[0] = XCB_NONE;
+ VideoThreadLock();
xcb_change_window_attributes(Connection, VideoWindow,
XCB_CW_CURSOR, values);
+ VideoThreadUnlock();
VideoBlankTick = GetMsTicks();
break;
default:
@@ -9420,11 +9647,19 @@ void VideoPollEvent(void)
// hide cursor, after xx ms
if (VideoBlankTick && VideoWindow != XCB_NONE
&& VideoBlankTick + 200 < GetMsTicks()) {
+ VideoThreadLock();
xcb_change_window_attributes(Connection, VideoWindow, XCB_CW_CURSOR,
&VideoBlankCursor);
+ VideoThreadUnlock();
VideoBlankTick = 0;
}
- while (XlibDisplay && XPending(XlibDisplay)) {
+ while (XlibDisplay) {
+ VideoThreadLock();
+ if (!XPending(XlibDisplay)) {
+ VideoThreadUnlock();
+ break;
+ }
+ VideoThreadUnlock();
VideoEvent();
}
}
@@ -9435,10 +9670,6 @@ void VideoPollEvent(void)
#ifdef USE_VIDEO_THREAD
-#ifdef USE_GLX
-static GLXContext GlxThreadContext; ///< our gl context for the thread
-#endif
-
///
/// Lock video thread.
///
@@ -9472,20 +9703,21 @@ static void *VideoDisplayHandlerThread(void *dummy)
#ifdef USE_GLX
if (GlxEnabled) {
- Debug(3, "video: %p <-> %p\n", glXGetCurrentContext(),
- GlxThreadContext);
+ Debug(3, "video/glx: thread context %p <-> %p\n",
+ glXGetCurrentContext(), GlxThreadContext);
+ Debug(3, "video/glx: context %p <-> %p\n", glXGetCurrentContext(),
+ GlxContext);
+
GlxThreadContext =
- glXCreateContext(XlibDisplay, GlxVisualInfo, GlxContext, GL_TRUE);
+ glXCreateContext(XlibDisplay, GlxVisualInfo, GlxSharedContext,
+ GL_TRUE);
if (!GlxThreadContext) {
Error(_("video/glx: can't create glx context\n"));
return NULL;
}
// set glx context
- if (!glXMakeCurrent(XlibDisplay, VideoWindow, GlxThreadContext)) {
- GlxCheck();
- Error(_("video/glx: can't make glx context current\n"));
- return NULL;
- }
+ GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight,
+ GlxThreadContext);
}
#endif
@@ -9508,6 +9740,9 @@ static void *VideoDisplayHandlerThread(void *dummy)
///
static void VideoThreadInit(void)
{
+#ifdef USE_GLX
+ glXMakeCurrent(XlibDisplay, None, NULL);
+#endif
pthread_mutex_init(&VideoMutex, NULL);
pthread_mutex_init(&VideoLockMutex, NULL);
pthread_cond_init(&VideoWakeupCond, NULL);
@@ -9565,7 +9800,7 @@ void VideoDisplayWakeup(void)
//----------------------------------------------------------------------------
///
-/// Table of all audio modules.
+/// Table of all video modules.
///
static const VideoModule *VideoModules[] = {
#ifdef USE_VDPAU
@@ -9574,6 +9809,9 @@ static const VideoModule *VideoModules[] = {
#ifdef USE_VAAPI
&VaapiModule,
#endif
+#ifdef USE_GLX
+ &VaapiGlxModule, // FIXME: if working, prefer this
+#endif
&NoopModule
};
@@ -9707,20 +9945,15 @@ void VideoRenderFrame(VideoHwDecoder * hw_decoder,
}
///
-/// Get VA-API ffmpeg context
+/// Get hwaccel context for ffmpeg.
+///
+/// FIXME: new ffmpeg supports vdpau hw context
///
/// @param hw_decoder video hardware decoder (must be VA-API)
///
-struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder * hw_decoder)
+void *VideoGetHwAccelContext(VideoHwDecoder * hw_decoder)
{
-#ifdef USE_VAAPI
- if (VideoUsedModule == &VaapiModule) {
- return hw_decoder->Vaapi.VaapiContext;
- }
-#endif
- (void)hw_decoder;
- Error(_("video/vaapi: get vaapi context, without vaapi enabled\n"));
- return NULL;
+ return VideoUsedModule->GetHwAccelContext(hw_decoder);
}
#ifdef USE_VDPAU
@@ -9823,17 +10056,7 @@ int64_t VideoGetClock(const VideoHwDecoder * hw_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_VAAPI
- if (VideoUsedModule == &VaapiModule) {
- hw_decoder->Vaapi.Closing = 1;
- }
-#endif
+ VideoUsedModule->SetClosing(hw_decoder);
// clear clock to avoid further sync
VideoSetClock(hw_decoder, AV_NOPTS_VALUE);
}
@@ -9846,17 +10069,7 @@ void VideoSetClosing(VideoHwDecoder * hw_decoder)
void VideoResetStart(VideoHwDecoder * hw_decoder)
{
Debug(3, "video: reset start\n");
- // FIXME: test to check if working, than make module function
-#ifdef USE_VDPAU
- if (VideoUsedModule == &VdpauModule) {
- hw_decoder->Vdpau.StartCounter = 0;
- }
-#endif
-#ifdef USE_VAAPI
- if (VideoUsedModule == &VaapiModule) {
- hw_decoder->Vaapi.StartCounter = 0;
- }
-#endif
+ VideoUsedModule->ResetStart(hw_decoder);
// clear clock to trigger new video stream
VideoSetClock(hw_decoder, AV_NOPTS_VALUE);
}
@@ -9869,7 +10082,8 @@ void VideoResetStart(VideoHwDecoder * hw_decoder)
///
void VideoSetTrickSpeed(VideoHwDecoder * hw_decoder, int speed)
{
- return VideoUsedModule->SetTrickSpeed(hw_decoder, speed);
+ Debug(3, "video: set trick-speed %d\n", speed);
+ VideoUsedModule->SetTrickSpeed(hw_decoder, speed);
}
///
@@ -10029,23 +10243,7 @@ uint8_t *VideoGrabService(int *size, int *width, int *height)
void VideoGetStats(VideoHwDecoder * hw_decoder, int *missed, int *duped,
int *dropped, int *counter)
{
- // FIXME: test to check if working, than make module function
-#ifdef USE_VDPAU
- if (VideoUsedModule == &VdpauModule) {
- *missed = hw_decoder->Vdpau.FramesMissed;
- *duped = hw_decoder->Vdpau.FramesDuped;
- *dropped = hw_decoder->Vdpau.FramesDropped;
- *counter = hw_decoder->Vdpau.FrameCounter;
- }
-#endif
-#ifdef USE_VAAPI
- if (VideoUsedModule == &VaapiModule) {
- *missed = hw_decoder->Vaapi.FramesMissed;
- *duped = hw_decoder->Vaapi.FramesDuped;
- *dropped = hw_decoder->Vaapi.FramesDropped;
- *counter = hw_decoder->Vaapi.FrameCounter;
- }
-#endif
+ VideoUsedModule->GetStats(hw_decoder, missed, duped, dropped, counter);
}
///
@@ -10413,6 +10611,7 @@ void VideoSetBlackPicture(int onoff)
///
void VideoSetBrightness(int brightness)
{
+ // FIXME: test to check if working, than make module function
#ifdef USE_VDPAU
if (VideoUsedModule == &VdpauModule) {
VdpauDecoders[0]->Procamp.brightness = brightness / 1000;
@@ -10430,6 +10629,7 @@ void VideoSetBrightness(int brightness)
///
void VideoSetContrast(int contrast)
{
+ // FIXME: test to check if working, than make module function
#ifdef USE_VDPAU
if (VideoUsedModule == &VdpauModule) {
VdpauDecoders[0]->Procamp.contrast = contrast / 1000;
@@ -10447,6 +10647,7 @@ void VideoSetContrast(int contrast)
///
void VideoSetSaturation(int saturation)
{
+ // FIXME: test to check if working, than make module function
#ifdef USE_VDPAU
if (VideoUsedModule == &VdpauModule) {
VdpauDecoders[0]->Procamp.saturation = saturation / 1000;
@@ -10464,6 +10665,7 @@ void VideoSetSaturation(int saturation)
///
void VideoSetHue(int hue)
{
+ // FIXME: test to check if working, than make module function
#ifdef USE_VDPAU
if (VideoUsedModule == &VdpauModule) {
VdpauDecoders[0]->Procamp.hue = hue / 1000;
@@ -10861,7 +11063,12 @@ void VideoInit(const char *display_name)
// FIXME: we need to retry connection
return;
}
- //XInitThreads();
+#ifdef USE_GLX_not_needed_done_with_locks
+ if (!XInitThreads()) {
+ Error(_("video: Can't initialize X11 thread support on '%s'\n"),
+ display_name);
+ }
+#endif
// Register error handler
XSetIOErrorHandler(VideoIOErrorHandler);
@@ -10873,7 +11080,9 @@ void VideoInit(const char *display_name)
}
// prefetch extensions
//xcb_prefetch_extension_data(Connection, &xcb_big_requests_id);
- //xcb_prefetch_extension_data(Connection, &xcb_glx_id);
+#ifdef xcb_USE_GLX
+ xcb_prefetch_extension_data(Connection, &xcb_glx_id);
+#endif
//xcb_prefetch_extension_data(Connection, &xcb_randr_id);
#ifdef USE_SCREENSAVER
xcb_prefetch_extension_data(Connection, &xcb_screensaver_id);
@@ -10909,13 +11118,15 @@ void VideoInit(const char *display_name)
// prepare opengl
//
#ifdef USE_GLX
- if (GlxEnabled) {
+ // FIXME: module selected below
+ if (0) {
GlxInit();
// FIXME: use root window?
VideoCreateWindow(screen->root, GlxVisualInfo->visualid,
GlxVisualInfo->depth);
- GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight);
+ GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight,
+ GlxContext);
} else
#endif
@@ -10962,9 +11173,6 @@ void VideoInit(const char *display_name)
if (getenv("NO_HW")) {
VideoHardwareDecoder = 0;
}
- if (getenv("STUDIO_LEVELS")) {
- VideoStudioLevels = 1;
- }
// disable x11 screensaver
X11SuspendScreenSaver(Connection, 1);
X11DPMSDisable(Connection);
@@ -11174,16 +11382,6 @@ int main(int argc, char *const argv[])
start_tick = GetMsTicks();
n = 0;
for (;;) {
-#if 0
- VideoRenderOverlay();
- VideoDisplayOverlay();
- glXSwapBuffers(XlibDisplay, VideoWindow);
- GlxCheck();
- glClear(GL_COLOR_BUFFER_BIT);
-
- XSync(XlibDisplay, False);
- XFlush(XlibDisplay);
-#endif
#ifdef USE_VAAPI
if (VideoVaapiEnabled) {
VaapiDisplayFrame();
diff --git a/video.h b/video.h
index 910b14e..fa3e44f 100644
--- a/video.h
+++ b/video.h
@@ -17,7 +17,7 @@
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU Affero General Public License for more details.
///
-/// $Id: 08681699eb8e70b5bc9dce5e58c79dae5e67f41f $
+/// $Id$
//////////////////////////////////////////////////////////////////////////////
/// @addtogroup Video
@@ -67,8 +67,8 @@ extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
extern void VideoRenderFrame(VideoHwDecoder *, const AVCodecContext *,
const AVFrame *);
- /// Get ffmpeg vaapi context.
-extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
+ /// Get hwaccel context for ffmpeg.
+extern void *VideoGetHwAccelContext(VideoHwDecoder *);
#ifdef AVCODEC_VDPAU_H
/// Draw vdpau render state.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr-plugin-softhddevice.git
More information about the pkg-vdr-dvb-changes
mailing list