Support yaepghd video output position change.

And code and comments cleanups.
This commit is contained in:
Johns 2012-01-07 22:36:06 +01:00
parent 7b6d0ecf94
commit fd60c3c132
6 changed files with 372 additions and 324 deletions

View File

@ -1,5 +1,9 @@
User johns User johns
Data: Sat Jan 7 13:20:07 CET 2012 Date:
Support yaepghd video picture output position change.
Date: Sat Jan 7 13:20:07 CET 2012
Release Version 0.2.0 Release Version 0.2.0
Add support for ac3 audio pass through. Add support for ac3 audio pass through.

1
Todo
View File

@ -79,6 +79,7 @@ audio/oss:
HDMI/SPDIF Passthrough: HDMI/SPDIF Passthrough:
only AC-3 written only AC-3 written
Channels are wrong setup, if changing setting during operation.
playback of recording playback of recording
play back is too fast play back is too fast

View File

@ -62,8 +62,6 @@ static volatile char NewAudioStream; ///< new audio stream
static AudioDecoder *MyAudioDecoder; ///< audio decoder static AudioDecoder *MyAudioDecoder; ///< audio decoder
static enum CodecID AudioCodecID; ///< current codec id static enum CodecID AudioCodecID; ///< current codec id
extern void AudioTest(void); // FIXME:
/** /**
** mpeg bitrate table. ** mpeg bitrate table.
** **
@ -351,8 +349,6 @@ static void VideoPacketInit(void)
{ {
int i; int i;
Debug(4, "[softhddev]: %s\n", __FUNCTION__);
for (i = 0; i < VIDEO_PACKET_MAX; ++i) { for (i = 0; i < VIDEO_PACKET_MAX; ++i) {
AVPacket *avpkt; AVPacket *avpkt;
@ -374,16 +370,10 @@ static void VideoPacketExit(void)
{ {
int i; int i;
Debug(4, "[softhddev]: %s\n", __FUNCTION__);
atomic_set(&VideoPacketsFilled, 0); atomic_set(&VideoPacketsFilled, 0);
for (i = 0; i < VIDEO_PACKET_MAX; ++i) { for (i = 0; i < VIDEO_PACKET_MAX; ++i) {
AVPacket *avpkt; av_free_packet(&VideoPacketRb[i]);
avpkt = &VideoPacketRb[i];
// build a clean ffmpeg av packet
av_free_packet(avpkt);
} }
} }
@ -466,13 +456,13 @@ static void VideoNextPacket(int codec_id)
VideoPacketWrite = (VideoPacketWrite + 1) % VIDEO_PACKET_MAX; VideoPacketWrite = (VideoPacketWrite + 1) % VIDEO_PACKET_MAX;
atomic_inc(&VideoPacketsFilled); atomic_inc(&VideoPacketsFilled);
VideoDisplayWakeup();
// intialize next package to use // intialize next package to use
avpkt = &VideoPacketRb[VideoPacketWrite]; avpkt = &VideoPacketRb[VideoPacketWrite];
avpkt->stream_index = 0; avpkt->stream_index = 0;
avpkt->pts = AV_NOPTS_VALUE; avpkt->pts = AV_NOPTS_VALUE;
avpkt->dts = AV_NOPTS_VALUE; avpkt->dts = AV_NOPTS_VALUE;
VideoDisplayHandler();
} }
/** /**
@ -819,7 +809,9 @@ int Poll(int timeout)
*/ */
void GetOsdSize(int *width, int *height, double *aspect) void GetOsdSize(int *width, int *height, double *aspect)
{ {
#ifdef DEBUG
static char done; static char done;
#endif
// FIXME: should be configured! // FIXME: should be configured!
*width = 1920; *width = 1920;
@ -829,11 +821,13 @@ void GetOsdSize(int *width, int *height, double *aspect)
*aspect = 16.0 / 9.0 / (double)*width * (double)*height; *aspect = 16.0 / 9.0 / (double)*width * (double)*height;
#ifdef DEBUG
if (!done) { if (!done) {
Debug(3, "[softhddev]%s: %dx%d %g\n", __FUNCTION__, *width, *height, Debug(3, "[softhddev]%s: %dx%d %g\n", __FUNCTION__, *width, *height,
*aspect); *aspect);
done = 1; done = 1;
} }
#endif
} }
/** /**
@ -1076,7 +1070,4 @@ void Stop(void)
*/ */
void MainThreadHook(void) void MainThreadHook(void)
{ {
if (!DeviceStopped) {
VideoDisplayHandler();
}
} }

View File

@ -135,6 +135,9 @@ cSoftOsd::~cSoftOsd(void)
//dsyslog("[softhddev]%s:\n", __FUNCTION__); //dsyslog("[softhddev]%s:\n", __FUNCTION__);
SetActive(false); SetActive(false);
if (vidWin.bpp) {
VideoSetOutputPosition(0, 0, 1920, 1080);
}
OsdClose(); OsdClose();
} }
@ -148,7 +151,17 @@ void cSoftOsd::Flush(void)
if (!Active()) { if (!Active()) {
return; return;
} }
//dsyslog("[softhddev]%s:\n", __FUNCTION__);
// support yaepghd, video window
if (vidWin.bpp) {
dsyslog("[softhddev]%s: %dx%d+%d+%d\n", __FUNCTION__,
vidWin.Width(), vidWin.Height(), vidWin.x1, vidWin.y2 );
// FIXME: vidWin is OSD relative not video window.
VideoSetOutputPosition(Left() + vidWin.x1, Top() + vidWin.y1,
vidWin.Width(), vidWin.Height());
}
if (!IsTrueColor()) { if (!IsTrueColor()) {
static char warned; static char warned;
cBitmap *bitmap; cBitmap *bitmap;
@ -255,6 +268,9 @@ bool cSoftOsdProvider::ProvidesTrueColor(void)
return true; return true;
} }
/**
** Create cOsdProvider class.
*/
cSoftOsdProvider::cSoftOsdProvider(void) cSoftOsdProvider::cSoftOsdProvider(void)
: cOsdProvider() : cOsdProvider()
{ {

588
video.c
View File

@ -346,11 +346,11 @@ void GlxSetupDecoder(VaapiDecoder * decoder)
} }
#endif #endif
/** ///
** Render texture. /// Render texture.
** ///
** @param texture 2d texture /// @param texture 2d texture
*/ ///
static inline void GlxRenderTexture(GLuint texture, int x, int y, int width, static inline void GlxRenderTexture(GLuint texture, int x, int y, int width,
int height) int height)
{ {
@ -384,9 +384,9 @@ static inline void GlxRenderTexture(GLuint texture, int x, int y, int width,
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }
/** ///
** Upload texture. /// Upload texture.
*/ ///
static void GlxUploadTexture(int x, int y, int width, int height, static void GlxUploadTexture(int x, int y, int width, int height,
const uint8_t * argb) const uint8_t * argb)
{ {
@ -405,9 +405,9 @@ static void GlxUploadTexture(int x, int y, int width, int height,
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }
/** ///
** Render to glx texture. /// Render to glx texture.
*/ ///
static void GlxRender(int osd_width, int osd_height) static void GlxRender(int osd_width, int osd_height)
{ {
static uint8_t *image; static uint8_t *image;
@ -787,9 +787,9 @@ static int AutoCropIsBlackLineY(const uint8_t * data, int length, int stride)
return r & (~(YBLACK - 1) * M64); return r & (~(YBLACK - 1) * M64);
} }
/** ///
** Auto detect black borders and crop them. /// Auto detect black borders and crop them.
*/ ///
static void AutoCropDetect(int width, int height, void *data[3], static void AutoCropDetect(int width, int height, void *data[3],
uint32_t pitches[3]) uint32_t pitches[3])
{ {
@ -830,6 +830,10 @@ static void AutoCropDetect(int width, int height, void *data[3],
// //
} }
//----------------------------------------------------------------------------
// software - deinterlace
//----------------------------------------------------------------------------
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// VA-API // VA-API
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1225,14 +1229,6 @@ static VaapiDecoder *VaapiNewDecoder(void)
decoder->OutputWidth = VideoWindowWidth; decoder->OutputWidth = VideoWindowWidth;
decoder->OutputHeight = VideoWindowHeight; decoder->OutputHeight = VideoWindowHeight;
#ifdef noDEBUG
// FIXME: for play
decoder->OutputX = 40;
decoder->OutputY = 40;
decoder->OutputWidth = VideoWindowWidth - 40 * 2;
decoder->OutputHeight = VideoWindowHeight - 40 * 2;
#endif
VaapiDecoders[VaapiDecoderN++] = decoder; VaapiDecoders[VaapiDecoderN++] = decoder;
return decoder; return decoder;
@ -1360,11 +1356,11 @@ static void VaapiDelDecoder(VaapiDecoder * decoder)
free(decoder); free(decoder);
} }
/** ///
** VA-API setup. /// VA-API setup.
** ///
** @param display_name x11/xcb display name /// @param display_name x11/xcb display name
*/ ///
static void VideoVaapiInit(const char *display_name) static void VideoVaapiInit(const char *display_name)
{ {
int major; int major;
@ -1510,7 +1506,7 @@ static void VaapiUpdateOutput(VaapiDecoder * decoder)
break; break;
} }
} }
// FIXME: this overwrites user choosen output position
decoder->OutputX = 0; decoder->OutputX = 0;
decoder->OutputY = 0; decoder->OutputY = 0;
decoder->OutputWidth = (VideoWindowHeight * display_aspect_ratio.num) decoder->OutputWidth = (VideoWindowHeight * display_aspect_ratio.num)
@ -1520,7 +1516,7 @@ static void VaapiUpdateOutput(VaapiDecoder * decoder)
if ((unsigned)decoder->OutputWidth > VideoWindowWidth) { if ((unsigned)decoder->OutputWidth > VideoWindowWidth) {
decoder->OutputWidth = VideoWindowWidth; decoder->OutputWidth = VideoWindowWidth;
decoder->OutputY = (VideoWindowHeight - decoder->OutputHeight) / 2; decoder->OutputY = (VideoWindowHeight - decoder->OutputHeight) / 2;
} else { } else if ((unsigned)decoder->OutputHeight > VideoWindowHeight) {
decoder->OutputHeight = VideoWindowHeight; decoder->OutputHeight = VideoWindowHeight;
decoder->OutputX = (VideoWindowWidth - decoder->OutputWidth) / 2; decoder->OutputX = (VideoWindowWidth - decoder->OutputWidth) / 2;
} }
@ -1528,17 +1524,17 @@ static void VaapiUpdateOutput(VaapiDecoder * decoder)
decoder->OutputHeight, decoder->OutputX, decoder->OutputY); decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
} }
/** ///
** Find VA-API profile. /// Find VA-API profile.
** ///
** Check if the requested profile is supported by VA-API. /// Check if the requested profile is supported by VA-API.
** ///
** @param profiles a table of all supported profiles /// @param profiles a table of all supported profiles
** @param n number of supported profiles /// @param n number of supported profiles
** @param profile requested profile /// @param profile requested profile
** ///
** @returns the profile if supported, -1 if unsupported. /// @returns the profile if supported, -1 if unsupported.
*/ ///
static VAProfile VaapiFindProfile(const VAProfile * profiles, unsigned n, static VAProfile VaapiFindProfile(const VAProfile * profiles, unsigned n,
VAProfile profile) VAProfile profile)
{ {
@ -1552,17 +1548,17 @@ static VAProfile VaapiFindProfile(const VAProfile * profiles, unsigned n,
return -1; return -1;
} }
/** ///
** Find VA-API entry point. /// Find VA-API entry point.
** ///
** Check if the requested entry point is supported by VA-API. /// Check if the requested entry point is supported by VA-API.
** ///
** @param entrypoints a table of all supported entrypoints /// @param entrypoints a table of all supported entrypoints
** @param n number of supported entrypoints /// @param n number of supported entrypoints
** @param entrypoint requested entrypoint /// @param entrypoint requested entrypoint
** ///
** @returns the entry point if supported, -1 if unsupported. /// @returns the entry point if supported, -1 if unsupported.
*/ ///
static VAEntrypoint VaapiFindEntrypoint(const VAEntrypoint * entrypoints, static VAEntrypoint VaapiFindEntrypoint(const VAEntrypoint * entrypoints,
unsigned n, VAEntrypoint entrypoint) unsigned n, VAEntrypoint entrypoint)
{ {
@ -1576,13 +1572,13 @@ static VAEntrypoint VaapiFindEntrypoint(const VAEntrypoint * entrypoints,
return -1; return -1;
} }
/** ///
** Callback to negotiate the PixelFormat. /// Callback to negotiate the PixelFormat.
** ///
** @param fmt is the list of formats which are supported by the codec, /// @param fmt is the list of formats which are supported by the codec,
** it is terminated by -1 as 0 is a valid format, the /// it is terminated by -1 as 0 is a valid format, the
** formats are ordered by quality. /// formats are ordered by quality.
*/ ///
static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder, static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
AVCodecContext * video_ctx, const enum PixelFormat *fmt) AVCodecContext * video_ctx, const enum PixelFormat *fmt)
{ {
@ -1775,17 +1771,17 @@ static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
return avcodec_default_get_format(video_ctx, fmt); return avcodec_default_get_format(video_ctx, fmt);
} }
/** ///
** Draw surface of the VA-API decoder with x11. /// Draw surface of the VA-API decoder with x11.
** ///
** vaPutSurface with intel backend does sync on v-sync. /// vaPutSurface with intel backend does sync on v-sync.
** ///
** @param decoder VA-API decoder /// @param decoder VA-API decoder
** @param surface VA-API surface id /// @param surface VA-API surface id
** @param interlaced flag interlaced source /// @param interlaced flag interlaced source
** @param top_field_first flag top_field_first for interlaced source /// @param top_field_first flag top_field_first for interlaced source
** @param field interlaced draw: 0 first field, 1 second field /// @param field interlaced draw: 0 first field, 1 second field
*/ ///
static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface, static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
int interlaced, int top_field_first, int field) int interlaced, int top_field_first, int field)
{ {
@ -1862,11 +1858,11 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
#ifdef USE_GLX #ifdef USE_GLX
/** ///
** Render texture. /// Render texture.
** ///
** @param texture 2d texture /// @param texture 2d texture
*/ ///
static inline void VideoRenderTexture(GLuint texture, int x, int y, int width, static inline void VideoRenderTexture(GLuint texture, int x, int y, int width,
int height) int height)
{ {
@ -1900,15 +1896,15 @@ static inline void VideoRenderTexture(GLuint texture, int x, int y, int width,
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} }
/** ///
** Draw surface of the VA-API decoder with glx. /// Draw surface of the VA-API decoder with glx.
** ///
** @param decoder VA-API decoder /// @param decoder VA-API decoder
** @param surface VA-API surface id /// @param surface VA-API surface id
** @param interlaced flag interlaced source /// @param interlaced flag interlaced source
** @param top_field_first flag top_field_first for interlaced source /// @param top_field_first flag top_field_first for interlaced source
** @param field interlaced draw: 0 first field, 1 second field /// @param field interlaced draw: 0 first field, 1 second field
*/ ///
static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface, static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface,
int interlaced, int top_field_first, int field) int interlaced, int top_field_first, int field)
{ {
@ -1951,16 +1947,16 @@ static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface,
#endif #endif
/** ///
** Find VA-API image format. /// Find VA-API image format.
** ///
** @param decoder VA-API decoder /// @param decoder VA-API decoder
** @param pix_fmt ffmpeg pixel format /// @param pix_fmt ffmpeg pixel format
** @param[out] format image format /// @param[out] format image format
** ///
** FIXME: can fallback from I420 to YV12, if not supported /// FIXME: can fallback from I420 to YV12, if not supported
** FIXME: must check if put/get with this format is supported (see intel) /// FIXME: must check if put/get with this format is supported (see intel)
*/ ///
static int VaapiFindImageFormat(VaapiDecoder * decoder, static int VaapiFindImageFormat(VaapiDecoder * decoder,
enum PixelFormat pix_fmt, VAImageFormat * format) enum PixelFormat pix_fmt, VAImageFormat * format)
{ {
@ -2281,6 +2277,8 @@ static void VaapiBlackSurface(VaapiDecoder * decoder)
/// ///
/// Vaapi bob deinterlace. /// Vaapi bob deinterlace.
/// ///
/// @note FIXME: use common software deinterlace functions.
///
static void VaapiBob(VaapiDecoder * decoder, VAImage * src, VAImage * dst1, static void VaapiBob(VaapiDecoder * decoder, VAImage * src, VAImage * dst1,
VAImage * dst2) VAImage * dst2)
{ {
@ -2685,11 +2683,11 @@ static void VaapiAdvanceFrame(void)
} }
} }
/** ///
** Display a video frame. /// Display a video frame.
** ///
** @todo FIXME: add detection of missed frames /// @todo FIXME: add detection of missed frames
*/ ///
static void VaapiDisplayFrame(void) static void VaapiDisplayFrame(void)
{ {
struct timespec nowtime; struct timespec nowtime;
@ -2959,11 +2957,11 @@ static int64_t VaapiGetClock(const VaapiDecoder * decoder)
#ifdef USE_VIDEO_THREAD #ifdef USE_VIDEO_THREAD
/** ///
** Handle a va-api display. /// Handle a va-api display.
** ///
** @todo FIXME: only a single decoder supported. /// @todo FIXME: only a single decoder supported.
*/ ///
static void VaapiDisplayHandlerThread(void) static void VaapiDisplayHandlerThread(void)
{ {
int err; int err;
@ -3300,8 +3298,8 @@ static VdpGetErrorString *VdpauGetErrorString;
static VdpDeviceDestroy *VdpauDeviceDestroy; static VdpDeviceDestroy *VdpauDeviceDestroy;
static VdpGenerateCSCMatrix *VdpauGenerateCSCMatrix; static VdpGenerateCSCMatrix *VdpauGenerateCSCMatrix;
static VdpVideoSurfaceQueryCapabilities *VdpauVideoSurfaceQueryCapabilities; static VdpVideoSurfaceQueryCapabilities *VdpauVideoSurfaceQueryCapabilities;
static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities * static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities
VdpauVideoSurfaceQueryGetPutBitsYCbCrCapabilities; *VdpauVideoSurfaceQueryGetPutBitsYCbCrCapabilities;
static VdpVideoSurfaceCreate *VdpauVideoSurfaceCreate; static VdpVideoSurfaceCreate *VdpauVideoSurfaceCreate;
static VdpVideoSurfaceDestroy *VdpauVideoSurfaceDestroy; static VdpVideoSurfaceDestroy *VdpauVideoSurfaceDestroy;
static VdpVideoSurfaceGetParameters *VdpauVideoSurfaceGetParameters; static VdpVideoSurfaceGetParameters *VdpauVideoSurfaceGetParameters;
@ -3319,10 +3317,10 @@ static VdpBitmapSurfaceDestroy *VdpauBitmapSurfaceDestroy;
static VdpBitmapSurfacePutBitsNative *VdpauBitmapSurfacePutBitsNative; static VdpBitmapSurfacePutBitsNative *VdpauBitmapSurfacePutBitsNative;
static VdpOutputSurfaceRenderOutputSurface static VdpOutputSurfaceRenderOutputSurface *
*VdpauOutputSurfaceRenderOutputSurface; VdpauOutputSurfaceRenderOutputSurface;
static VdpOutputSurfaceRenderBitmapSurface static VdpOutputSurfaceRenderBitmapSurface *
*VdpauOutputSurfaceRenderBitmapSurface; VdpauOutputSurfaceRenderBitmapSurface;
static VdpDecoderQueryCapabilities *VdpauDecoderQueryCapabilities; static VdpDecoderQueryCapabilities *VdpauDecoderQueryCapabilities;
static VdpDecoderCreate *VdpauDecoderCreate; static VdpDecoderCreate *VdpauDecoderCreate;
@ -3331,8 +3329,8 @@ static VdpDecoderDestroy *VdpauDecoderDestroy;
static VdpDecoderRender *VdpauDecoderRender; static VdpDecoderRender *VdpauDecoderRender;
static VdpVideoMixerQueryFeatureSupport *VdpauVideoMixerQueryFeatureSupport; static VdpVideoMixerQueryFeatureSupport *VdpauVideoMixerQueryFeatureSupport;
static VdpVideoMixerQueryAttributeSupport static VdpVideoMixerQueryAttributeSupport *
*VdpauVideoMixerQueryAttributeSupport; VdpauVideoMixerQueryAttributeSupport;
static VdpVideoMixerCreate *VdpauVideoMixerCreate; static VdpVideoMixerCreate *VdpauVideoMixerCreate;
static VdpVideoMixerSetFeatureEnables *VdpauVideoMixerSetFeatureEnables; static VdpVideoMixerSetFeatureEnables *VdpauVideoMixerSetFeatureEnables;
@ -3343,18 +3341,18 @@ static VdpVideoMixerRender *VdpauVideoMixerRender;
static VdpPresentationQueueTargetDestroy *VdpauPresentationQueueTargetDestroy; static VdpPresentationQueueTargetDestroy *VdpauPresentationQueueTargetDestroy;
static VdpPresentationQueueCreate *VdpauPresentationQueueCreate; static VdpPresentationQueueCreate *VdpauPresentationQueueCreate;
static VdpPresentationQueueDestroy *VdpauPresentationQueueDestroy; static VdpPresentationQueueDestroy *VdpauPresentationQueueDestroy;
static VdpPresentationQueueSetBackgroundColor * static VdpPresentationQueueSetBackgroundColor
VdpauPresentationQueueSetBackgroundColor; *VdpauPresentationQueueSetBackgroundColor;
static VdpPresentationQueueGetTime *VdpauPresentationQueueGetTime; static VdpPresentationQueueGetTime *VdpauPresentationQueueGetTime;
static VdpPresentationQueueDisplay *VdpauPresentationQueueDisplay; static VdpPresentationQueueDisplay *VdpauPresentationQueueDisplay;
static VdpPresentationQueueBlockUntilSurfaceIdle static VdpPresentationQueueBlockUntilSurfaceIdle *
*VdpauPresentationQueueBlockUntilSurfaceIdle; VdpauPresentationQueueBlockUntilSurfaceIdle;
static VdpPresentationQueueQuerySurfaceStatus static VdpPresentationQueueQuerySurfaceStatus *
*VdpauPresentationQueueQuerySurfaceStatus; VdpauPresentationQueueQuerySurfaceStatus;
static VdpPresentationQueueTargetCreateX11 * static VdpPresentationQueueTargetCreateX11
VdpauPresentationQueueTargetCreateX11; *VdpauPresentationQueueTargetCreateX11;
///@} ///@}
/// ///
@ -3753,14 +3751,6 @@ static VdpauDecoder *VdpauNewDecoder(void)
decoder->Procamp.saturation = 1.0; decoder->Procamp.saturation = 1.0;
decoder->Procamp.hue = 0.0; // default values decoder->Procamp.hue = 0.0; // default values
#ifdef noDEBUG
// FIXME: for play
decoder->OutputX = 40;
decoder->OutputY = 40;
decoder->OutputWidth -= 40 * 2;
decoder->OutputHeight -= 40 * 2;
#endif
// FIXME: hack // FIXME: hack
VdpauDecoderN = 1; VdpauDecoderN = 1;
VdpauDecoders[0] = decoder; VdpauDecoders[0] = decoder;
@ -4320,7 +4310,7 @@ static void VdpauUpdateOutput(VdpauDecoder * decoder)
break; break;
} }
} }
// FIXME: this overwrites user choosen output position
decoder->OutputX = 0; decoder->OutputX = 0;
decoder->OutputY = 0; decoder->OutputY = 0;
decoder->OutputWidth = (VideoWindowHeight * display_aspect_ratio.num) decoder->OutputWidth = (VideoWindowHeight * display_aspect_ratio.num)
@ -4921,7 +4911,7 @@ static void VdpauMixOsd(void)
/// ///
/// Render video surface to output surface. /// Render video surface to output surface.
/// ///
/// @param decoder VDPAU hw decoder /// @param decoder VDPAU hw decoder
/// ///
static void VdpauMixVideo(VdpauDecoder * decoder) static void VdpauMixVideo(VdpauDecoder * decoder)
{ {
@ -5358,11 +5348,11 @@ static int64_t VdpauGetClock(const VdpauDecoder * decoder)
#ifdef USE_VIDEO_THREAD #ifdef USE_VIDEO_THREAD
/** ///
** Handle a VDPAU display. /// Handle a VDPAU display.
** ///
** @todo FIXME: only a single decoder supported. /// @todo FIXME: only a single decoder supported.
*/ ///
static void VdpauDisplayHandlerThread(void) static void VdpauDisplayHandlerThread(void)
{ {
int err; int err;
@ -5370,8 +5360,9 @@ static void VdpauDisplayHandlerThread(void)
struct timespec nowtime; struct timespec nowtime;
VdpauDecoder *decoder; VdpauDecoder *decoder;
decoder = VdpauDecoders[0]; if (!(decoder = VdpauDecoders[0])) { // no stream available
return;
}
// //
// fill frame output ring buffer // fill frame output ring buffer
// //
@ -5405,6 +5396,28 @@ static void VdpauDisplayHandlerThread(void)
#endif #endif
///
/// Set video output position.
///
/// @param decoder VDPAU hw decoder
/// @param x video output x coordinate inside the window
/// @param y video output y coordinate inside the window
/// @param width video output width
/// @param height video output height
///
/// @note FIXME: need to know which stream.
///
static void VdpauSetOutputPosition(VdpauDecoder * decoder, int x, int y,
int width, int height)
{
decoder->OutputX = x;
decoder->OutputY = y;
decoder->OutputWidth = width;
decoder->OutputHeight = height;
// next video pictures are automatic rendered to correct position
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// VDPAU OSD // VDPAU OSD
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -5584,9 +5597,9 @@ static void VdpauOsdInit(int width, int height)
VdpauOsdClear(); VdpauOsdClear();
} }
/** ///
** Cleanup osd. /// Cleanup osd.
*/ ///
static void VdpauOsdExit(void) static void VdpauOsdExit(void)
{ {
Debug(3, "FIXME: %s\n", __FUNCTION__); Debug(3, "FIXME: %s\n", __FUNCTION__);
@ -5687,12 +5700,12 @@ void VideoOsdDrawARGB(int x, int y, int height, int width,
VideoThreadUnlock(); VideoThreadUnlock();
} }
/** ///
** Setup osd. /// Setup osd.
** ///
** FIXME: looking for BGRA, but this fourcc isn't supported by the /// FIXME: looking for BGRA, but this fourcc isn't supported by the
** drawing functions yet. /// drawing functions yet.
*/ ///
void VideoOsdInit(void) void VideoOsdInit(void)
{ {
OsdWidth = 1920 / 1; OsdWidth = 1920 / 1;
@ -5746,9 +5759,9 @@ void VideoOsdInit(void)
#endif #endif
} }
/** ///
** Cleanup OSD. /// Cleanup OSD.
*/ ///
void VideoOsdExit(void) void VideoOsdExit(void)
{ {
#ifdef USE_VAAPI #ifdef USE_VAAPI
@ -5771,9 +5784,9 @@ void VideoOsdExit(void)
// Overlay // Overlay
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** ///
** Render osd surface. /// Render osd surface.
*/ ///
void VideoRenderOverlay(void) void VideoRenderOverlay(void)
{ {
#ifdef USE_GLX #ifdef USE_GLX
@ -5785,9 +5798,9 @@ void VideoRenderOverlay(void)
} }
} }
/** ///
** Display overlay surface. /// Display overlay surface.
*/ ///
void VideoDisplayOverlay(void) void VideoDisplayOverlay(void)
{ {
#ifdef USE_GLX #ifdef USE_GLX
@ -5849,9 +5862,9 @@ void VideoDisplayOverlay(void)
#if 0 #if 0
/** ///
** Display a single frame. /// Display a single frame.
*/ ///
static void VideoDisplayFrame(void) static void VideoDisplayFrame(void)
{ {
#ifdef USE_GLX #ifdef USE_GLX
@ -5890,11 +5903,11 @@ static void VideoDisplayFrame(void)
/// C callback feed key press /// C callback feed key press
extern void FeedKeyPress(const char *, const char *, int, int); extern void FeedKeyPress(const char *, const char *, int, int);
/** ///
** Handle X11 events. /// Handle X11 events.
** ///
** @todo Signal WmDeleteMessage to application. /// @todo Signal WmDeleteMessage to application.
*/ ///
static void VideoEvent(void) static void VideoEvent(void)
{ {
XEvent event; XEvent event;
@ -5962,9 +5975,9 @@ static void VideoEvent(void)
} }
} }
/** ///
** Poll all x11 events. /// Poll all x11 events.
*/ ///
void VideoPollEvent(void) void VideoPollEvent(void)
{ {
while (XPending(XlibDisplay)) { while (XPending(XlibDisplay)) {
@ -5982,9 +5995,9 @@ void VideoPollEvent(void)
static GLXContext GlxThreadContext; ///< our gl context for the thread static GLXContext GlxThreadContext; ///< our gl context for the thread
#endif #endif
/** ///
** Lock video thread. /// Lock video thread.
*/ ///
static void VideoThreadLock(void) static void VideoThreadLock(void)
{ {
if (pthread_mutex_lock(&VideoLockMutex)) { if (pthread_mutex_lock(&VideoLockMutex)) {
@ -5992,9 +6005,9 @@ static void VideoThreadLock(void)
} }
} }
/** ///
** Unlock video thread. /// Unlock video thread.
*/ ///
static void VideoThreadUnlock(void) static void VideoThreadUnlock(void)
{ {
if (pthread_mutex_unlock(&VideoLockMutex)) { if (pthread_mutex_unlock(&VideoLockMutex)) {
@ -6002,9 +6015,9 @@ static void VideoThreadUnlock(void)
} }
} }
/** ///
** Video render thread. /// Video render thread.
*/ ///
static void *VideoDisplayHandlerThread(void *dummy) static void *VideoDisplayHandlerThread(void *dummy)
{ {
Debug(3, "video: display thread started\n"); Debug(3, "video: display thread started\n");
@ -6056,44 +6069,28 @@ static void *VideoDisplayHandlerThread(void *dummy)
return dummy; return dummy;
} }
/** ///
** Video render. /// Initialize video threads.
*/ ///
void VideoDisplayHandler(void) static void VideoThreadInit(void)
{ {
if (!XlibDisplay) { // not yet started pthread_mutex_init(&VideoMutex, NULL);
return; pthread_mutex_init(&VideoLockMutex, NULL);
} pthread_cond_init(&VideoWakeupCond, NULL);
#ifdef USE_GLX pthread_create(&VideoThread, NULL, VideoDisplayHandlerThread, NULL);
glFinish(); // wait for all execution finished pthread_setname_np(VideoThread, "softhddev video");
Debug(3, "video: %p <-> %p\n", glXGetCurrentContext(), GlxContext); //pthread_detach(VideoThread);
#endif
if (!VideoThread) {
#ifdef USE_GLX
if (GlxEnabled) { // other thread renders
// glXMakeCurrent(XlibDisplay, None, NULL);
}
#endif
pthread_mutex_init(&VideoMutex, NULL);
pthread_mutex_init(&VideoLockMutex, NULL);
pthread_cond_init(&VideoWakeupCond, NULL);
pthread_create(&VideoThread, NULL, VideoDisplayHandlerThread, NULL);
pthread_setname_np(VideoThread, "softhddev video");
//pthread_detach(VideoThread);
}
} }
/** ///
** Exit and cleanup video threads. /// Exit and cleanup video threads.
*/ ///
static void VideoThreadExit(void) static void VideoThreadExit(void)
{ {
void *retval;
Debug(3, "video: video thread canceled\n");
if (VideoThread) { if (VideoThread) {
void *retval;
Debug(3, "video: video thread canceled\n");
if (pthread_cancel(VideoThread)) { if (pthread_cancel(VideoThread)) {
Error(_("video: can't queue cancel video display thread\n")); Error(_("video: can't queue cancel video display thread\n"));
} }
@ -6107,6 +6104,22 @@ static void VideoThreadExit(void)
} }
} }
///
/// Video display wakeup.
///
/// New video arrived, wakeup video thread.
///
void VideoDisplayWakeup(void)
{
if (!XlibDisplay) { // not yet started
return;
}
if (!VideoThread) { // start video thread, if needed
VideoThreadInit();
}
}
#endif #endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -6153,7 +6166,7 @@ VideoHwDecoder *VideoNewHwDecoder(void)
/// ///
/// Get a free hardware decoder surface. /// Get a free hardware decoder surface.
/// ///
/// @param decoder video hardware decoder /// @param decoder VDPAU video hardware decoder
/// ///
unsigned VideoGetSurface(VideoHwDecoder * decoder) unsigned VideoGetSurface(VideoHwDecoder * decoder)
{ {
@ -6174,7 +6187,7 @@ unsigned VideoGetSurface(VideoHwDecoder * decoder)
/// ///
/// Release a hardware decoder surface. /// Release a hardware decoder surface.
/// ///
/// @param decoder video hardware decoder /// @param decoder VDPAU video hardware decoder
/// @param surface surface no longer used /// @param surface surface no longer used
/// ///
void VideoReleaseSurface(VideoHwDecoder * decoder, unsigned surface) void VideoReleaseSurface(VideoHwDecoder * decoder, unsigned surface)
@ -6266,7 +6279,7 @@ static void VideoSetPts(int64_t * pts_p, int interlaced, const AVFrame * frame)
/// ///
/// Display a ffmpeg frame /// Display a ffmpeg frame
/// ///
/// @param decoder video hardware decoder /// @param decoder VDPAU video hardware decoder
/// @param video_ctx ffmpeg video codec context /// @param video_ctx ffmpeg video codec context
/// @param frame frame to display /// @param frame frame to display
/// ///
@ -6316,7 +6329,7 @@ struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder * decoder)
/// ///
/// Draw ffmpeg vdpau render state. /// Draw ffmpeg vdpau render state.
/// ///
/// @param decoder VDPAU decoder /// @param decoder VDPAU hw decoder
/// @param vrs vdpau render state /// @param vrs vdpau render state
/// ///
void VideoDrawRenderState(VideoHwDecoder * decoder, void VideoDrawRenderState(VideoHwDecoder * decoder,
@ -6354,9 +6367,9 @@ void VideoDrawRenderState(VideoHwDecoder * decoder,
#ifndef USE_VIDEO_THREAD #ifndef USE_VIDEO_THREAD
/** ///
** Video render. /// Video render.
*/ ///
void VideoDisplayHandler(void) void VideoDisplayHandler(void)
{ {
uint32_t now; uint32_t now;
@ -6392,13 +6405,13 @@ void VideoDisplayHandler(void)
#endif #endif
/** ///
** Get video clock. /// Get video clock.
** ///
** @note this isn't monoton, decoding reorders frames, /// @note this isn't monoton, decoding reorders frames,
** setter keeps it monotonic /// setter keeps it monotonic
** @todo we have multiple clocks, for multiple stream /// @todo we have multiple clocks, for multiple stream
*/ ///
int64_t VideoGetClock(void) int64_t VideoGetClock(void)
{ {
#ifdef USE_VAAPI #ifdef USE_VAAPI
@ -6418,13 +6431,13 @@ int64_t VideoGetClock(void)
// Setup // Setup
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** ///
** Create main window. /// Create main window.
** ///
** @param parent parent of new window /// @param parent parent of new window
** @param visual visual of parent /// @param visual visual of parent
** @param depth depth of parent /// @param depth depth of parent
*/ ///
static void VideoCreateWindow(xcb_window_t parent, xcb_visualid_t visual, static void VideoCreateWindow(xcb_window_t parent, xcb_visualid_t visual,
uint8_t depth) uint8_t depth)
{ {
@ -6514,11 +6527,11 @@ static void VideoCreateWindow(xcb_window_t parent, xcb_visualid_t visual,
// FIXME: free cursor/pixmap needed? // FIXME: free cursor/pixmap needed?
} }
/** ///
** Set video geometry. /// Set video geometry.
** ///
** @param geometry [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>] /// @param geometry [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]
*/ ///
int VideoSetGeometry(const char *geometry) int VideoSetGeometry(const char *geometry)
{ {
int flags; int flags;
@ -6530,61 +6543,88 @@ int VideoSetGeometry(const char *geometry)
return 0; return 0;
} }
/** ///
** Set deinterlace mode. /// Set video output position.
*/ ///
/// @param x video output x coordinate inside the window
/// @param y video output y coordinate inside the window
/// @param width video output width
/// @param height video output height
///
/// @note FIXME: need to know which stream.
///
void VideoSetOutputPosition(int x, int y, int width, int height)
{
// FIXME: high level, currently works osd relative
if (!OsdWidth || !OsdHeight) {
return;
}
x = (x * VideoWindowWidth) / OsdWidth;
y = (y * VideoWindowHeight) / OsdHeight;
width = (width * VideoWindowWidth) / OsdWidth;
height = (height * VideoWindowHeight) / OsdHeight;
#ifdef USE_VDPAU
if (VideoVdpauEnabled) {
VdpauSetOutputPosition(VdpauDecoders[0], x, y, width, height);
}
#endif
}
///
/// Set deinterlace mode.
///
void VideoSetDeinterlace(int mode) void VideoSetDeinterlace(int mode)
{ {
VideoDeinterlace = mode; VideoDeinterlace = mode;
} }
/** ///
** Set skip chroma deinterlace on/off. /// Set skip chroma deinterlace on/off.
*/ ///
void VideoSetSkipChromaDeinterlace(int onoff) void VideoSetSkipChromaDeinterlace(int onoff)
{ {
VideoSkipChromaDeinterlace = onoff; VideoSkipChromaDeinterlace = onoff;
} }
/** ///
** Set denoise level (0 .. 1000). /// Set denoise level (0 .. 1000).
*/ ///
void VideoSetDenoise(int level) void VideoSetDenoise(int level)
{ {
VideoDenoise = level; VideoDenoise = level;
} }
/** ///
** Set sharpness level (-1000 .. 1000). /// Set sharpness level (-1000 .. 1000).
*/ ///
void VideoSetSharpen(int level) void VideoSetSharpen(int level)
{ {
VideoSharpen = level; VideoSharpen = level;
} }
/** ///
** Set scaling mode. /// Set scaling mode.
*/ ///
void VideoSetScaling(int mode) void VideoSetScaling(int mode)
{ {
VideoScaling = mode; VideoScaling = mode;
} }
/** ///
** Set audio delay. /// Set audio delay.
** ///
** @param ms delay in ms /// @param ms delay in ms
*/ ///
void VideoSetAudioDelay(int ms) void VideoSetAudioDelay(int ms)
{ {
VideoAudioDelay = ms * 90; VideoAudioDelay = ms * 90;
} }
/** ///
** Initialize video output module. /// Initialize video output module.
** ///
** @param display_name X11 display name /// @param display_name X11 display name
*/ ///
void VideoInit(const char *display_name) void VideoInit(const char *display_name)
{ {
int screen_nr; int screen_nr;
@ -6698,9 +6738,9 @@ void VideoInit(const char *display_name)
xcb_flush(Connection); xcb_flush(Connection);
} }
/** ///
** Cleanup video output module. /// Cleanup video output module.
*/ ///
void VideoExit(void) void VideoExit(void)
{ {
if (!XlibDisplay) { // no init or failed if (!XlibDisplay) { // no init or failed
@ -6745,9 +6785,9 @@ void VideoExit(void)
int SysLogLevel; ///< show additional debug informations int SysLogLevel; ///< show additional debug informations
/** ///
** Print version. /// Print version.
*/ ///
static void PrintVersion(void) static void PrintVersion(void)
{ {
printf("video_test: video tester Version " VERSION printf("video_test: video tester Version " VERSION
@ -6758,9 +6798,9 @@ static void PrintVersion(void)
"\tLicense AGPLv3: GNU Affero General Public License version 3\n"); "\tLicense AGPLv3: GNU Affero General Public License version 3\n");
} }
/** ///
** Print usage. /// Print usage.
*/ ///
static void PrintUsage(void) static void PrintUsage(void)
{ {
printf("Usage: video_test [-?dhv]\n" printf("Usage: video_test [-?dhv]\n"
@ -6769,14 +6809,14 @@ static void PrintUsage(void)
"Only idiots print usage on stderr!\n"); "Only idiots print usage on stderr!\n");
} }
/** ///
** Main entry point. /// Main entry point.
** ///
** @param argc number of arguments /// @param argc number of arguments
** @param argv arguments vector /// @param argv arguments vector
** ///
** @returns -1 on failures, 0 clean exit. /// @returns -1 on failures, 0 clean exit.
*/ ///
int main(int argc, char *const argv[]) int main(int argc, char *const argv[])
{ {
SysLogLevel = 0; SysLogLevel = 0;

60
video.h
View File

@ -30,13 +30,6 @@
/// Video hardware decoder typedef /// Video hardware decoder typedef
typedef struct _video_hw_decoder_ VideoHwDecoder; typedef struct _video_hw_decoder_ VideoHwDecoder;
//----------------------------------------------------------------------------
// Variables
//----------------------------------------------------------------------------
//extern unsigned VideoWindowWidth; ///< current video output width
//extern unsigned VideoWindowHeight; ///< current video output height
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Prototypes // Prototypes
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -47,14 +40,14 @@ extern VideoHwDecoder *VideoNewHwDecoder(void);
/// Get and allocate a video hardware surface. /// Get and allocate a video hardware surface.
extern unsigned VideoGetSurface(VideoHwDecoder *); extern unsigned VideoGetSurface(VideoHwDecoder *);
/// Release a video hardware surface. /// Release a video hardware surface
extern void VideoReleaseSurface(VideoHwDecoder *, unsigned); extern void VideoReleaseSurface(VideoHwDecoder *, unsigned);
#ifdef LIBAVCODEC_VERSION #ifdef LIBAVCODEC_VERSION
/// Render a ffmpeg frame /// Render a ffmpeg frame.
extern void VideoRenderFrame(VideoHwDecoder *, AVCodecContext *, AVFrame *); extern void VideoRenderFrame(VideoHwDecoder *, AVCodecContext *, AVFrame *);
/// Get ffmpeg vaapi context /// Get ffmpeg vaapi context.
extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *); extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *);
/// Callback to negotiate the PixelFormat. /// Callback to negotiate the PixelFormat.
@ -62,57 +55,60 @@ extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
const enum PixelFormat *); const enum PixelFormat *);
#ifdef AVCODEC_VDPAU_H #ifdef AVCODEC_VDPAU_H
/// Draw vdpau render state /// Draw vdpau render state.
extern void VideoDrawRenderState(VideoHwDecoder *, extern void VideoDrawRenderState(VideoHwDecoder *,
struct vdpau_render_state *); struct vdpau_render_state *);
#endif #endif
#endif #endif
/// Display video TEST /// Poll video events.
extern void VideoDisplayHandler(void);
/// Poll video events
extern void VideoPollEvent(void); extern void VideoPollEvent(void);
/// set video mode /// Wakeup display handler.
extern void VideoDisplayWakeup(void);
/// Set video mode.
//extern void VideoSetVideoMode(int, int, int, int); //extern void VideoSetVideoMode(int, int, int, int);
/// set video geometry /// Set video geometry.
extern int VideoSetGeometry(const char *); extern int VideoSetGeometry(const char *);
/// set deinterlace /// Set video output position.
extern void VideoSetOutputPosition(int, int, int, int);
/// Set deinterlace.
extern void VideoSetDeinterlace(int); extern void VideoSetDeinterlace(int);
/// set skip chroma deinterlace /// Set skip chroma deinterlace.
extern void VideoSetSkipChromaDeinterlace(int); extern void VideoSetSkipChromaDeinterlace(int);
/// set scaling /// Set scaling.
extern void VideoSetScaling(int); extern void VideoSetScaling(int);
/// set denoise /// Set denoise.
extern void VideoSetDenoise(int); extern void VideoSetDenoise(int);
/// set sharpen /// Set sharpen.
extern void VideoSetSharpen(int); extern void VideoSetSharpen(int);
/// set audio delay /// Set audio delay.
extern void VideoSetAudioDelay(int); extern void VideoSetAudioDelay(int);
/// Clear OSD /// Clear OSD.
extern void VideoOsdClear(void); extern void VideoOsdClear(void);
/// Draw an OSD ARGB image /// Draw an OSD ARGB image.
extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *); extern void VideoOsdDrawARGB(int, int, int, int, const uint8_t *);
extern int64_t VideoGetClock(void); ///< get video clock extern int64_t VideoGetClock(void); ///< Get video clock.
extern void VideoOsdInit(void); ///< setup osd extern void VideoOsdInit(void); ///< Setup osd.
extern void VideoOsdExit(void); ///< cleanup osd extern void VideoOsdExit(void); ///< Cleanup osd.
extern void VideoInit(const char *); ///< setup video module extern void VideoInit(const char *); ///< Setup video module.
extern void VideoExit(void); ///< cleanup and exit video module extern void VideoExit(void); ///< Cleanup and exit video module.
extern void VideoFlushInput(void); ///< flush codec input buffers extern void VideoFlushInput(void); ///< Flush video input buffers.
extern int VideoDecode(void); ///< decode extern int VideoDecode(void); ///< Decode video input buffers.
/// @} /// @}