From fd60c3c1325f8254276b70a91eba8d28402a4ddb Mon Sep 17 00:00:00 2001 From: Johns Date: Sat, 7 Jan 2012 22:36:06 +0100 Subject: [PATCH] Support yaepghd video output position change. And code and comments cleanups. --- ChangeLog | 6 +- Todo | 1 + softhddev.c | 23 +- softhddevice.cpp | 18 +- video.c | 588 +++++++++++++++++++++++++---------------------- video.h | 60 +++-- 6 files changed, 372 insertions(+), 324 deletions(-) diff --git a/ChangeLog b/ChangeLog index ab5f26d..30060d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 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 Add support for ac3 audio pass through. diff --git a/Todo b/Todo index a2766dc..a69face 100644 --- a/Todo +++ b/Todo @@ -79,6 +79,7 @@ audio/oss: HDMI/SPDIF Passthrough: only AC-3 written + Channels are wrong setup, if changing setting during operation. playback of recording play back is too fast diff --git a/softhddev.c b/softhddev.c index 78da0b6..1a8e27a 100644 --- a/softhddev.c +++ b/softhddev.c @@ -62,8 +62,6 @@ static volatile char NewAudioStream; ///< new audio stream static AudioDecoder *MyAudioDecoder; ///< audio decoder static enum CodecID AudioCodecID; ///< current codec id -extern void AudioTest(void); // FIXME: - /** ** mpeg bitrate table. ** @@ -351,8 +349,6 @@ static void VideoPacketInit(void) { int i; - Debug(4, "[softhddev]: %s\n", __FUNCTION__); - for (i = 0; i < VIDEO_PACKET_MAX; ++i) { AVPacket *avpkt; @@ -374,16 +370,10 @@ static void VideoPacketExit(void) { int i; - Debug(4, "[softhddev]: %s\n", __FUNCTION__); - atomic_set(&VideoPacketsFilled, 0); for (i = 0; i < VIDEO_PACKET_MAX; ++i) { - AVPacket *avpkt; - - avpkt = &VideoPacketRb[i]; - // build a clean ffmpeg av packet - av_free_packet(avpkt); + av_free_packet(&VideoPacketRb[i]); } } @@ -466,13 +456,13 @@ static void VideoNextPacket(int codec_id) VideoPacketWrite = (VideoPacketWrite + 1) % VIDEO_PACKET_MAX; atomic_inc(&VideoPacketsFilled); + VideoDisplayWakeup(); + // intialize next package to use avpkt = &VideoPacketRb[VideoPacketWrite]; avpkt->stream_index = 0; avpkt->pts = 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) { +#ifdef DEBUG static char done; +#endif // FIXME: should be configured! *width = 1920; @@ -829,11 +821,13 @@ void GetOsdSize(int *width, int *height, double *aspect) *aspect = 16.0 / 9.0 / (double)*width * (double)*height; +#ifdef DEBUG if (!done) { Debug(3, "[softhddev]%s: %dx%d %g\n", __FUNCTION__, *width, *height, *aspect); done = 1; } +#endif } /** @@ -1076,7 +1070,4 @@ void Stop(void) */ void MainThreadHook(void) { - if (!DeviceStopped) { - VideoDisplayHandler(); - } } diff --git a/softhddevice.cpp b/softhddevice.cpp index ec65bf2..2ec1a6c 100644 --- a/softhddevice.cpp +++ b/softhddevice.cpp @@ -135,6 +135,9 @@ cSoftOsd::~cSoftOsd(void) //dsyslog("[softhddev]%s:\n", __FUNCTION__); SetActive(false); + if (vidWin.bpp) { + VideoSetOutputPosition(0, 0, 1920, 1080); + } OsdClose(); } @@ -148,7 +151,17 @@ void cSoftOsd::Flush(void) if (!Active()) { 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()) { static char warned; cBitmap *bitmap; @@ -255,6 +268,9 @@ bool cSoftOsdProvider::ProvidesTrueColor(void) return true; } +/** +** Create cOsdProvider class. +*/ cSoftOsdProvider::cSoftOsdProvider(void) : cOsdProvider() { diff --git a/video.c b/video.c index 5d0e1e2..ce80a7a 100644 --- a/video.c +++ b/video.c @@ -346,11 +346,11 @@ void GlxSetupDecoder(VaapiDecoder * decoder) } #endif -/** -** Render texture. -** -** @param texture 2d texture -*/ +/// +/// Render texture. +/// +/// @param texture 2d texture +/// static inline void GlxRenderTexture(GLuint texture, int x, int y, int width, int height) { @@ -384,9 +384,9 @@ static inline void GlxRenderTexture(GLuint texture, int x, int y, int width, glDisable(GL_TEXTURE_2D); } -/** -** Upload texture. -*/ +/// +/// Upload texture. +/// static void GlxUploadTexture(int x, int y, int width, int height, const uint8_t * argb) { @@ -405,9 +405,9 @@ static void GlxUploadTexture(int x, int y, int width, int height, glDisable(GL_TEXTURE_2D); } -/** -** Render to glx texture. -*/ +/// +/// Render to glx texture. +/// static void GlxRender(int osd_width, int osd_height) { static uint8_t *image; @@ -787,9 +787,9 @@ static int AutoCropIsBlackLineY(const uint8_t * data, int length, int stride) 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], uint32_t pitches[3]) { @@ -830,6 +830,10 @@ static void AutoCropDetect(int width, int height, void *data[3], // } +//---------------------------------------------------------------------------- +// software - deinterlace +//---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- // VA-API //---------------------------------------------------------------------------- @@ -1225,14 +1229,6 @@ static VaapiDecoder *VaapiNewDecoder(void) decoder->OutputWidth = VideoWindowWidth; 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; return decoder; @@ -1360,11 +1356,11 @@ static void VaapiDelDecoder(VaapiDecoder * decoder) free(decoder); } -/** -** VA-API setup. -** -** @param display_name x11/xcb display name -*/ +/// +/// VA-API setup. +/// +/// @param display_name x11/xcb display name +/// static void VideoVaapiInit(const char *display_name) { int major; @@ -1510,7 +1506,7 @@ static void VaapiUpdateOutput(VaapiDecoder * decoder) break; } } - + // FIXME: this overwrites user choosen output position decoder->OutputX = 0; decoder->OutputY = 0; decoder->OutputWidth = (VideoWindowHeight * display_aspect_ratio.num) @@ -1520,7 +1516,7 @@ static void VaapiUpdateOutput(VaapiDecoder * decoder) if ((unsigned)decoder->OutputWidth > VideoWindowWidth) { decoder->OutputWidth = VideoWindowWidth; decoder->OutputY = (VideoWindowHeight - decoder->OutputHeight) / 2; - } else { + } else if ((unsigned)decoder->OutputHeight > VideoWindowHeight) { decoder->OutputHeight = VideoWindowHeight; decoder->OutputX = (VideoWindowWidth - decoder->OutputWidth) / 2; } @@ -1528,17 +1524,17 @@ static void VaapiUpdateOutput(VaapiDecoder * decoder) decoder->OutputHeight, decoder->OutputX, decoder->OutputY); } -/** -** Find VA-API profile. -** -** Check if the requested profile is supported by VA-API. -** -** @param profiles a table of all supported profiles -** @param n number of supported profiles -** @param profile requested profile -** -** @returns the profile if supported, -1 if unsupported. -*/ +/// +/// Find VA-API profile. +/// +/// Check if the requested profile is supported by VA-API. +/// +/// @param profiles a table of all supported profiles +/// @param n number of supported profiles +/// @param profile requested profile +/// +/// @returns the profile if supported, -1 if unsupported. +/// static VAProfile VaapiFindProfile(const VAProfile * profiles, unsigned n, VAProfile profile) { @@ -1552,17 +1548,17 @@ static VAProfile VaapiFindProfile(const VAProfile * profiles, unsigned n, return -1; } -/** -** Find VA-API entry point. -** -** Check if the requested entry point is supported by VA-API. -** -** @param entrypoints a table of all supported entrypoints -** @param n number of supported entrypoints -** @param entrypoint requested entrypoint -** -** @returns the entry point if supported, -1 if unsupported. -*/ +/// +/// Find VA-API entry point. +/// +/// Check if the requested entry point is supported by VA-API. +/// +/// @param entrypoints a table of all supported entrypoints +/// @param n number of supported entrypoints +/// @param entrypoint requested entrypoint +/// +/// @returns the entry point if supported, -1 if unsupported. +/// static VAEntrypoint VaapiFindEntrypoint(const VAEntrypoint * entrypoints, unsigned n, VAEntrypoint entrypoint) { @@ -1576,13 +1572,13 @@ static VAEntrypoint VaapiFindEntrypoint(const VAEntrypoint * entrypoints, return -1; } -/** -** Callback to negotiate the PixelFormat. -** -** @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 -** formats are ordered by quality. -*/ +/// +/// Callback to negotiate the PixelFormat. +/// +/// @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 +/// formats are ordered by quality. +/// static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder, 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); } -/** -** Draw surface of the VA-API decoder with x11. -** -** vaPutSurface with intel backend does sync on v-sync. -** -** @param decoder VA-API decoder -** @param surface VA-API surface id -** @param interlaced flag interlaced source -** @param top_field_first flag top_field_first for interlaced source -** @param field interlaced draw: 0 first field, 1 second field -*/ +/// +/// Draw surface of the VA-API decoder with x11. +/// +/// vaPutSurface with intel backend does sync on v-sync. +/// +/// @param decoder VA-API decoder +/// @param surface VA-API surface id +/// @param interlaced flag interlaced source +/// @param top_field_first flag top_field_first for interlaced source +/// @param field interlaced draw: 0 first field, 1 second field +/// static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface, int interlaced, int top_field_first, int field) { @@ -1862,11 +1858,11 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface, #ifdef USE_GLX -/** -** Render texture. -** -** @param texture 2d texture -*/ +/// +/// Render texture. +/// +/// @param texture 2d texture +/// static inline void VideoRenderTexture(GLuint texture, int x, int y, int width, int height) { @@ -1900,15 +1896,15 @@ static inline void VideoRenderTexture(GLuint texture, int x, int y, int width, glDisable(GL_TEXTURE_2D); } -/** -** Draw surface of the VA-API decoder with glx. -** -** @param decoder VA-API decoder -** @param surface VA-API surface id -** @param interlaced flag interlaced source -** @param top_field_first flag top_field_first for interlaced source -** @param field interlaced draw: 0 first field, 1 second field -*/ +/// +/// Draw surface of the VA-API decoder with glx. +/// +/// @param decoder VA-API decoder +/// @param surface VA-API surface id +/// @param interlaced flag interlaced source +/// @param top_field_first flag top_field_first for interlaced source +/// @param field interlaced draw: 0 first field, 1 second field +/// static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface, int interlaced, int top_field_first, int field) { @@ -1951,16 +1947,16 @@ static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface, #endif -/** -** Find VA-API image format. -** -** @param decoder VA-API decoder -** @param pix_fmt ffmpeg pixel format -** @param[out] format image format -** -** FIXME: can fallback from I420 to YV12, if not supported -** FIXME: must check if put/get with this format is supported (see intel) -*/ +/// +/// Find VA-API image format. +/// +/// @param decoder VA-API decoder +/// @param pix_fmt ffmpeg pixel format +/// @param[out] format image format +/// +/// FIXME: can fallback from I420 to YV12, if not supported +/// FIXME: must check if put/get with this format is supported (see intel) +/// static int VaapiFindImageFormat(VaapiDecoder * decoder, enum PixelFormat pix_fmt, VAImageFormat * format) { @@ -2281,6 +2277,8 @@ static void VaapiBlackSurface(VaapiDecoder * decoder) /// /// Vaapi bob deinterlace. /// +/// @note FIXME: use common software deinterlace functions. +/// static void VaapiBob(VaapiDecoder * decoder, VAImage * src, VAImage * dst1, VAImage * dst2) { @@ -2685,11 +2683,11 @@ static void VaapiAdvanceFrame(void) } } -/** -** Display a video frame. -** -** @todo FIXME: add detection of missed frames -*/ +/// +/// Display a video frame. +/// +/// @todo FIXME: add detection of missed frames +/// static void VaapiDisplayFrame(void) { struct timespec nowtime; @@ -2959,11 +2957,11 @@ static int64_t VaapiGetClock(const VaapiDecoder * decoder) #ifdef USE_VIDEO_THREAD -/** -** Handle a va-api display. -** -** @todo FIXME: only a single decoder supported. -*/ +/// +/// Handle a va-api display. +/// +/// @todo FIXME: only a single decoder supported. +/// static void VaapiDisplayHandlerThread(void) { int err; @@ -3300,8 +3298,8 @@ static VdpGetErrorString *VdpauGetErrorString; static VdpDeviceDestroy *VdpauDeviceDestroy; static VdpGenerateCSCMatrix *VdpauGenerateCSCMatrix; static VdpVideoSurfaceQueryCapabilities *VdpauVideoSurfaceQueryCapabilities; -static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities * - VdpauVideoSurfaceQueryGetPutBitsYCbCrCapabilities; +static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities + *VdpauVideoSurfaceQueryGetPutBitsYCbCrCapabilities; static VdpVideoSurfaceCreate *VdpauVideoSurfaceCreate; static VdpVideoSurfaceDestroy *VdpauVideoSurfaceDestroy; static VdpVideoSurfaceGetParameters *VdpauVideoSurfaceGetParameters; @@ -3319,10 +3317,10 @@ static VdpBitmapSurfaceDestroy *VdpauBitmapSurfaceDestroy; static VdpBitmapSurfacePutBitsNative *VdpauBitmapSurfacePutBitsNative; -static VdpOutputSurfaceRenderOutputSurface - *VdpauOutputSurfaceRenderOutputSurface; -static VdpOutputSurfaceRenderBitmapSurface - *VdpauOutputSurfaceRenderBitmapSurface; +static VdpOutputSurfaceRenderOutputSurface * + VdpauOutputSurfaceRenderOutputSurface; +static VdpOutputSurfaceRenderBitmapSurface * + VdpauOutputSurfaceRenderBitmapSurface; static VdpDecoderQueryCapabilities *VdpauDecoderQueryCapabilities; static VdpDecoderCreate *VdpauDecoderCreate; @@ -3331,8 +3329,8 @@ static VdpDecoderDestroy *VdpauDecoderDestroy; static VdpDecoderRender *VdpauDecoderRender; static VdpVideoMixerQueryFeatureSupport *VdpauVideoMixerQueryFeatureSupport; -static VdpVideoMixerQueryAttributeSupport - *VdpauVideoMixerQueryAttributeSupport; +static VdpVideoMixerQueryAttributeSupport * + VdpauVideoMixerQueryAttributeSupport; static VdpVideoMixerCreate *VdpauVideoMixerCreate; static VdpVideoMixerSetFeatureEnables *VdpauVideoMixerSetFeatureEnables; @@ -3343,18 +3341,18 @@ static VdpVideoMixerRender *VdpauVideoMixerRender; static VdpPresentationQueueTargetDestroy *VdpauPresentationQueueTargetDestroy; static VdpPresentationQueueCreate *VdpauPresentationQueueCreate; static VdpPresentationQueueDestroy *VdpauPresentationQueueDestroy; -static VdpPresentationQueueSetBackgroundColor * - VdpauPresentationQueueSetBackgroundColor; +static VdpPresentationQueueSetBackgroundColor + *VdpauPresentationQueueSetBackgroundColor; static VdpPresentationQueueGetTime *VdpauPresentationQueueGetTime; static VdpPresentationQueueDisplay *VdpauPresentationQueueDisplay; -static VdpPresentationQueueBlockUntilSurfaceIdle - *VdpauPresentationQueueBlockUntilSurfaceIdle; -static VdpPresentationQueueQuerySurfaceStatus - *VdpauPresentationQueueQuerySurfaceStatus; +static VdpPresentationQueueBlockUntilSurfaceIdle * + VdpauPresentationQueueBlockUntilSurfaceIdle; +static VdpPresentationQueueQuerySurfaceStatus * + VdpauPresentationQueueQuerySurfaceStatus; -static VdpPresentationQueueTargetCreateX11 * - VdpauPresentationQueueTargetCreateX11; +static VdpPresentationQueueTargetCreateX11 + *VdpauPresentationQueueTargetCreateX11; ///@} /// @@ -3753,14 +3751,6 @@ static VdpauDecoder *VdpauNewDecoder(void) decoder->Procamp.saturation = 1.0; 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 VdpauDecoderN = 1; VdpauDecoders[0] = decoder; @@ -4320,7 +4310,7 @@ static void VdpauUpdateOutput(VdpauDecoder * decoder) break; } } - + // FIXME: this overwrites user choosen output position decoder->OutputX = 0; decoder->OutputY = 0; decoder->OutputWidth = (VideoWindowHeight * display_aspect_ratio.num) @@ -4921,7 +4911,7 @@ static void VdpauMixOsd(void) /// /// Render video surface to output surface. /// -/// @param decoder VDPAU hw decoder +/// @param decoder VDPAU hw decoder /// static void VdpauMixVideo(VdpauDecoder * decoder) { @@ -5358,11 +5348,11 @@ static int64_t VdpauGetClock(const VdpauDecoder * decoder) #ifdef USE_VIDEO_THREAD -/** -** Handle a VDPAU display. -** -** @todo FIXME: only a single decoder supported. -*/ +/// +/// Handle a VDPAU display. +/// +/// @todo FIXME: only a single decoder supported. +/// static void VdpauDisplayHandlerThread(void) { int err; @@ -5370,8 +5360,9 @@ static void VdpauDisplayHandlerThread(void) struct timespec nowtime; VdpauDecoder *decoder; - decoder = VdpauDecoders[0]; - + if (!(decoder = VdpauDecoders[0])) { // no stream available + return; + } // // fill frame output ring buffer // @@ -5405,6 +5396,28 @@ static void VdpauDisplayHandlerThread(void) #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 //---------------------------------------------------------------------------- @@ -5584,9 +5597,9 @@ static void VdpauOsdInit(int width, int height) VdpauOsdClear(); } -/** -** Cleanup osd. -*/ +/// +/// Cleanup osd. +/// static void VdpauOsdExit(void) { Debug(3, "FIXME: %s\n", __FUNCTION__); @@ -5687,12 +5700,12 @@ void VideoOsdDrawARGB(int x, int y, int height, int width, VideoThreadUnlock(); } -/** -** Setup osd. -** -** FIXME: looking for BGRA, but this fourcc isn't supported by the -** drawing functions yet. -*/ +/// +/// Setup osd. +/// +/// FIXME: looking for BGRA, but this fourcc isn't supported by the +/// drawing functions yet. +/// void VideoOsdInit(void) { OsdWidth = 1920 / 1; @@ -5746,9 +5759,9 @@ void VideoOsdInit(void) #endif } -/** -** Cleanup OSD. -*/ +/// +/// Cleanup OSD. +/// void VideoOsdExit(void) { #ifdef USE_VAAPI @@ -5771,9 +5784,9 @@ void VideoOsdExit(void) // Overlay //---------------------------------------------------------------------------- -/** -** Render osd surface. -*/ +/// +/// Render osd surface. +/// void VideoRenderOverlay(void) { #ifdef USE_GLX @@ -5785,9 +5798,9 @@ void VideoRenderOverlay(void) } } -/** -** Display overlay surface. -*/ +/// +/// Display overlay surface. +/// void VideoDisplayOverlay(void) { #ifdef USE_GLX @@ -5849,9 +5862,9 @@ void VideoDisplayOverlay(void) #if 0 -/** -** Display a single frame. -*/ +/// +/// Display a single frame. +/// static void VideoDisplayFrame(void) { #ifdef USE_GLX @@ -5890,11 +5903,11 @@ static void VideoDisplayFrame(void) /// C callback feed key press extern void FeedKeyPress(const char *, const char *, int, int); -/** -** Handle X11 events. -** -** @todo Signal WmDeleteMessage to application. -*/ +/// +/// Handle X11 events. +/// +/// @todo Signal WmDeleteMessage to application. +/// static void VideoEvent(void) { XEvent event; @@ -5962,9 +5975,9 @@ static void VideoEvent(void) } } -/** -** Poll all x11 events. -*/ +/// +/// Poll all x11 events. +/// void VideoPollEvent(void) { while (XPending(XlibDisplay)) { @@ -5982,9 +5995,9 @@ void VideoPollEvent(void) static GLXContext GlxThreadContext; ///< our gl context for the thread #endif -/** -** Lock video thread. -*/ +/// +/// Lock video thread. +/// static void VideoThreadLock(void) { if (pthread_mutex_lock(&VideoLockMutex)) { @@ -5992,9 +6005,9 @@ static void VideoThreadLock(void) } } -/** -** Unlock video thread. -*/ +/// +/// Unlock video thread. +/// static void VideoThreadUnlock(void) { if (pthread_mutex_unlock(&VideoLockMutex)) { @@ -6002,9 +6015,9 @@ static void VideoThreadUnlock(void) } } -/** -** Video render thread. -*/ +/// +/// Video render thread. +/// static void *VideoDisplayHandlerThread(void *dummy) { Debug(3, "video: display thread started\n"); @@ -6056,44 +6069,28 @@ static void *VideoDisplayHandlerThread(void *dummy) return dummy; } -/** -** Video render. -*/ -void VideoDisplayHandler(void) +/// +/// Initialize video threads. +/// +static void VideoThreadInit(void) { - if (!XlibDisplay) { // not yet started - return; - } -#ifdef USE_GLX - glFinish(); // wait for all execution finished - Debug(3, "video: %p <-> %p\n", glXGetCurrentContext(), GlxContext); -#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); - } + 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) { - void *retval; - - Debug(3, "video: video thread canceled\n"); if (VideoThread) { + void *retval; + + Debug(3, "video: video thread canceled\n"); if (pthread_cancel(VideoThread)) { 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 //---------------------------------------------------------------------------- @@ -6153,7 +6166,7 @@ VideoHwDecoder *VideoNewHwDecoder(void) /// /// Get a free hardware decoder surface. /// -/// @param decoder video hardware decoder +/// @param decoder VDPAU video hardware decoder /// unsigned VideoGetSurface(VideoHwDecoder * decoder) { @@ -6174,7 +6187,7 @@ unsigned VideoGetSurface(VideoHwDecoder * decoder) /// /// Release a hardware decoder surface. /// -/// @param decoder video hardware decoder +/// @param decoder VDPAU video hardware decoder /// @param surface surface no longer used /// 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 /// -/// @param decoder video hardware decoder +/// @param decoder VDPAU video hardware decoder /// @param video_ctx ffmpeg video codec context /// @param frame frame to display /// @@ -6316,7 +6329,7 @@ struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder * decoder) /// /// Draw ffmpeg vdpau render state. /// -/// @param decoder VDPAU decoder +/// @param decoder VDPAU hw decoder /// @param vrs vdpau render state /// void VideoDrawRenderState(VideoHwDecoder * decoder, @@ -6354,9 +6367,9 @@ void VideoDrawRenderState(VideoHwDecoder * decoder, #ifndef USE_VIDEO_THREAD -/** -** Video render. -*/ +/// +/// Video render. +/// void VideoDisplayHandler(void) { uint32_t now; @@ -6392,13 +6405,13 @@ void VideoDisplayHandler(void) #endif -/** -** Get video clock. -** -** @note this isn't monoton, decoding reorders frames, -** setter keeps it monotonic -** @todo we have multiple clocks, for multiple stream -*/ +/// +/// Get video clock. +/// +/// @note this isn't monoton, decoding reorders frames, +/// setter keeps it monotonic +/// @todo we have multiple clocks, for multiple stream +/// int64_t VideoGetClock(void) { #ifdef USE_VAAPI @@ -6418,13 +6431,13 @@ int64_t VideoGetClock(void) // Setup //---------------------------------------------------------------------------- -/** -** Create main window. -** -** @param parent parent of new window -** @param visual visual of parent -** @param depth depth of parent -*/ +/// +/// Create main window. +/// +/// @param parent parent of new window +/// @param visual visual of parent +/// @param depth depth of parent +/// static void VideoCreateWindow(xcb_window_t parent, xcb_visualid_t visual, uint8_t depth) { @@ -6514,11 +6527,11 @@ static void VideoCreateWindow(xcb_window_t parent, xcb_visualid_t visual, // FIXME: free cursor/pixmap needed? } -/** -** Set video geometry. -** -** @param geometry [=][{xX}][{+-}{+-}] -*/ +/// +/// Set video geometry. +/// +/// @param geometry [=][{xX}][{+-}{+-}] +/// int VideoSetGeometry(const char *geometry) { int flags; @@ -6530,61 +6543,88 @@ int VideoSetGeometry(const char *geometry) 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) { VideoDeinterlace = mode; } -/** -** Set skip chroma deinterlace on/off. -*/ +/// +/// Set skip chroma deinterlace on/off. +/// void VideoSetSkipChromaDeinterlace(int onoff) { VideoSkipChromaDeinterlace = onoff; } -/** -** Set denoise level (0 .. 1000). -*/ +/// +/// Set denoise level (0 .. 1000). +/// void VideoSetDenoise(int level) { VideoDenoise = level; } -/** -** Set sharpness level (-1000 .. 1000). -*/ +/// +/// Set sharpness level (-1000 .. 1000). +/// void VideoSetSharpen(int level) { VideoSharpen = level; } -/** -** Set scaling mode. -*/ +/// +/// Set scaling mode. +/// void VideoSetScaling(int mode) { VideoScaling = mode; } -/** -** Set audio delay. -** -** @param ms delay in ms -*/ +/// +/// Set audio delay. +/// +/// @param ms delay in ms +/// void VideoSetAudioDelay(int ms) { VideoAudioDelay = ms * 90; } -/** -** Initialize video output module. -** -** @param display_name X11 display name -*/ +/// +/// Initialize video output module. +/// +/// @param display_name X11 display name +/// void VideoInit(const char *display_name) { int screen_nr; @@ -6698,9 +6738,9 @@ void VideoInit(const char *display_name) xcb_flush(Connection); } -/** -** Cleanup video output module. -*/ +/// +/// Cleanup video output module. +/// void VideoExit(void) { if (!XlibDisplay) { // no init or failed @@ -6745,9 +6785,9 @@ void VideoExit(void) int SysLogLevel; ///< show additional debug informations -/** -** Print version. -*/ +/// +/// Print version. +/// static void PrintVersion(void) { 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"); } -/** -** Print usage. -*/ +/// +/// Print usage. +/// static void PrintUsage(void) { printf("Usage: video_test [-?dhv]\n" @@ -6769,14 +6809,14 @@ static void PrintUsage(void) "Only idiots print usage on stderr!\n"); } -/** -** Main entry point. -** -** @param argc number of arguments -** @param argv arguments vector -** -** @returns -1 on failures, 0 clean exit. -*/ +/// +/// Main entry point. +/// +/// @param argc number of arguments +/// @param argv arguments vector +/// +/// @returns -1 on failures, 0 clean exit. +/// int main(int argc, char *const argv[]) { SysLogLevel = 0; diff --git a/video.h b/video.h index 9962cf3..159d019 100644 --- a/video.h +++ b/video.h @@ -30,13 +30,6 @@ /// Video hardware decoder typedef typedef struct _video_hw_decoder_ VideoHwDecoder; -//---------------------------------------------------------------------------- -// Variables -//---------------------------------------------------------------------------- - -//extern unsigned VideoWindowWidth; ///< current video output width -//extern unsigned VideoWindowHeight; ///< current video output height - //---------------------------------------------------------------------------- // Prototypes //---------------------------------------------------------------------------- @@ -47,14 +40,14 @@ extern VideoHwDecoder *VideoNewHwDecoder(void); /// Get and allocate a video hardware surface. extern unsigned VideoGetSurface(VideoHwDecoder *); - /// Release a video hardware surface. + /// Release a video hardware surface extern void VideoReleaseSurface(VideoHwDecoder *, unsigned); #ifdef LIBAVCODEC_VERSION - /// Render a ffmpeg frame + /// Render a ffmpeg frame. extern void VideoRenderFrame(VideoHwDecoder *, AVCodecContext *, AVFrame *); - /// Get ffmpeg vaapi context + /// Get ffmpeg vaapi context. extern struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder *); /// Callback to negotiate the PixelFormat. @@ -62,57 +55,60 @@ extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *, const enum PixelFormat *); #ifdef AVCODEC_VDPAU_H - /// Draw vdpau render state + /// Draw vdpau render state. extern void VideoDrawRenderState(VideoHwDecoder *, struct vdpau_render_state *); #endif #endif - /// Display video TEST -extern void VideoDisplayHandler(void); - - /// Poll video events + /// Poll video events. extern void VideoPollEvent(void); - /// set video mode + /// Wakeup display handler. +extern void VideoDisplayWakeup(void); + + /// Set video mode. //extern void VideoSetVideoMode(int, int, int, int); - /// set video geometry + /// Set video geometry. extern int VideoSetGeometry(const char *); - /// set deinterlace + /// Set video output position. +extern void VideoSetOutputPosition(int, int, int, int); + + /// Set deinterlace. extern void VideoSetDeinterlace(int); - /// set skip chroma deinterlace + /// Set skip chroma deinterlace. extern void VideoSetSkipChromaDeinterlace(int); - /// set scaling + /// Set scaling. extern void VideoSetScaling(int); - /// set denoise + /// Set denoise. extern void VideoSetDenoise(int); - /// set sharpen + /// Set sharpen. extern void VideoSetSharpen(int); - /// set audio delay + /// Set audio delay. extern void VideoSetAudioDelay(int); - /// Clear OSD + /// Clear OSD. 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 int64_t VideoGetClock(void); ///< get video clock +extern int64_t VideoGetClock(void); ///< Get video clock. -extern void VideoOsdInit(void); ///< setup osd -extern void VideoOsdExit(void); ///< cleanup osd +extern void VideoOsdInit(void); ///< Setup osd. +extern void VideoOsdExit(void); ///< Cleanup osd. -extern void VideoInit(const char *); ///< setup video module -extern void VideoExit(void); ///< cleanup and exit video module +extern void VideoInit(const char *); ///< Setup video module. +extern void VideoExit(void); ///< Cleanup and exit video module. -extern void VideoFlushInput(void); ///< flush codec input buffers -extern int VideoDecode(void); ///< decode +extern void VideoFlushInput(void); ///< Flush video input buffers. +extern int VideoDecode(void); ///< Decode video input buffers. /// @}