mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
OSD improvements:
Use OSD size equal to video window. Update only dirty area(s) of OSD. Show/mix only used area of OSD. Fix bug: vpdau use previous resolution for deint, ...
This commit is contained in:
parent
19d4eeed82
commit
c6e66e0787
@ -1,6 +1,11 @@
|
|||||||
User johns
|
User johns
|
||||||
Date:
|
Date:
|
||||||
|
|
||||||
|
OSD improvements:
|
||||||
|
Use OSD size equal to video window.
|
||||||
|
Update only dirty area(s) of OSD.
|
||||||
|
Show/mix only used area of OSD.
|
||||||
|
Fix bug: vpdau use previous resolution for deint, ...
|
||||||
Fix software deinterlace with VA-API.
|
Fix software deinterlace with VA-API.
|
||||||
Fix bug: transposed digits 567 should be 576.
|
Fix bug: transposed digits 567 should be 576.
|
||||||
Audio module cleanup:
|
Audio module cleanup:
|
||||||
|
15
Todo
15
Todo
@ -19,23 +19,20 @@ GNU Affero General Public License for more details.
|
|||||||
$Id: $
|
$Id: $
|
||||||
|
|
||||||
missing:
|
missing:
|
||||||
software deinterlace
|
software deinterlace (yadif, ...)
|
||||||
|
software decoder with software deinterlace
|
||||||
auto crop
|
auto crop
|
||||||
zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?)
|
zoom/fit-zoom 4:3 (SetVideoDisplayFormat, SetVideoFormat?)
|
||||||
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)?
|
ITU BT601, ITU BT709 (HD), RGB studio levels (16-235)?
|
||||||
suspend output / energie saver: stop audio, stop video, configurable
|
suspend output / energie saver: stop audio, stop video, configurable
|
||||||
Option deinterlace off / deinterlace force!
|
Option deinterlace off / deinterlace force!
|
||||||
Make output drivers better moduluar.
|
Make output drivers better modular.
|
||||||
|
|
||||||
video:
|
video:
|
||||||
subtitle not cleared
|
subtitle not cleared
|
||||||
subtitle could be asyncron
|
subtitle could be asyncron
|
||||||
|
|
||||||
vdpau:
|
vdpau:
|
||||||
1080i with temporal spatial and level 1 scaling too slow with my GT 520
|
|
||||||
1080i with temporal spatial too slow with my GT 520 on some channels
|
|
||||||
SkipChromaDeinterlace improves performance
|
|
||||||
Improve OSD handling, show only what is used. Big OSD costs performance
|
|
||||||
VdpPreemptionCallback handling
|
VdpPreemptionCallback handling
|
||||||
hard channel switch
|
hard channel switch
|
||||||
suspendoutput didn't show logo or black picture.
|
suspendoutput didn't show logo or black picture.
|
||||||
@ -43,15 +40,15 @@ vdpau:
|
|||||||
libva:
|
libva:
|
||||||
hard channel switch
|
hard channel switch
|
||||||
yaepghd (VaapiSetOutputPosition) support
|
yaepghd (VaapiSetOutputPosition) support
|
||||||
|
can associate ony displayed part of osd
|
||||||
|
|
||||||
libva-intel-driver:
|
libva-intel-driver:
|
||||||
intel still has hangups most with 1080i
|
intel still has hangups most with 1080i
|
||||||
1080i does no v-sync (workaround written)
|
1080i does no v-sync (workaround written)
|
||||||
osd has sometimes wrong size (workaround written)
|
OSD has sometimes wrong size (workaround written)
|
||||||
|
|
||||||
libva-vdpau-driver:
|
libva-vdpau-driver:
|
||||||
G210 osd update too slow (needs hardware problem workaround)
|
G210/GT520 OSD update too slow (needs hardware problem workaround)
|
||||||
OSD update is too slow
|
|
||||||
hangup on exit (VaapiDelDecoder -> VaapiCleanup
|
hangup on exit (VaapiDelDecoder -> VaapiCleanup
|
||||||
-> vaDestroyContext -> pthread_rwlock_wrlock)
|
-> vaDestroyContext -> pthread_rwlock_wrlock)
|
||||||
|
|
||||||
|
15
softhddev.c
15
softhddev.c
@ -913,22 +913,19 @@ int Flush(int timeout)
|
|||||||
void GetOsdSize(int *width, int *height, double *aspect)
|
void GetOsdSize(int *width, int *height, double *aspect)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static char done;
|
static int done_width;
|
||||||
|
static int done_height;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: should be configured!
|
VideoGetOsdSize(width, height);
|
||||||
*width = 1920;
|
|
||||||
*height = 1080;
|
|
||||||
//*width = 768;
|
|
||||||
//*height = 576;
|
|
||||||
|
|
||||||
*aspect = 16.0 / 9.0 / (double)*width * (double)*height;
|
*aspect = 16.0 / 9.0 / (double)*width * (double)*height;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (!done) {
|
if (done_width != *width || done_height != *height) {
|
||||||
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_width = *width;
|
||||||
|
done_height = *height;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ static class cSoftHdDevice *MyDevice;
|
|||||||
|
|
||||||
#define RESOLUTIONS 4 ///< number of resolutions
|
#define RESOLUTIONS 4 ///< number of resolutions
|
||||||
|
|
||||||
|
/// resolutions names
|
||||||
static const char *const Resolution[RESOLUTIONS] = {
|
static const char *const Resolution[RESOLUTIONS] = {
|
||||||
"576i", "720p", "1080i_fake", "1080i"
|
"576i", "720p", "1080i_fake", "1080i"
|
||||||
};
|
};
|
||||||
@ -158,8 +159,15 @@ cSoftOsd::~cSoftOsd(void)
|
|||||||
SetActive(false);
|
SetActive(false);
|
||||||
|
|
||||||
#ifdef USE_YAEPG
|
#ifdef USE_YAEPG
|
||||||
if (vidWin.bpp) {
|
// support yaepghd, video window
|
||||||
VideoSetOutputPosition(0, 0, 1920, 1080);
|
if (vidWin.bpp) { // restore fullsized video
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
double video_aspect;
|
||||||
|
|
||||||
|
::GetOsdSize(&width, &height, &video_aspect);
|
||||||
|
// works osd relative
|
||||||
|
VideoSetOutputPosition(0, 0, width, height);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
OsdClose();
|
OsdClose();
|
||||||
@ -175,8 +183,8 @@ void cSoftOsd::Flush(void)
|
|||||||
if (!Active()) {
|
if (!Active()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// support yaepghd, video window
|
|
||||||
#ifdef USE_YAEPG
|
#ifdef USE_YAEPG
|
||||||
|
// support yaepghd, video window
|
||||||
if (vidWin.bpp) {
|
if (vidWin.bpp) {
|
||||||
dsyslog("[softhddev]%s: %dx%d+%d+%d\n", __FUNCTION__, vidWin.Width(),
|
dsyslog("[softhddev]%s: %dx%d+%d+%d\n", __FUNCTION__, vidWin.Width(),
|
||||||
vidWin.Height(), vidWin.x1, vidWin.y2);
|
vidWin.Height(), vidWin.x1, vidWin.y2);
|
||||||
@ -213,6 +221,7 @@ void cSoftOsd::Flush(void)
|
|||||||
if (!bitmap->Dirty(x1, y1, x2, y2)) {
|
if (!bitmap->Dirty(x1, y1, x2, y2)) {
|
||||||
continue; // nothing dirty continue
|
continue; // nothing dirty continue
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
// FIXME: need only to convert and upload dirty areas
|
// FIXME: need only to convert and upload dirty areas
|
||||||
|
|
||||||
// DrawBitmap(bitmap);
|
// DrawBitmap(bitmap);
|
||||||
@ -225,7 +234,6 @@ void cSoftOsd::Flush(void)
|
|||||||
((uint32_t *) argb)[x + y * w] = bitmap->GetColor(x, y);
|
((uint32_t *) argb)[x + y * w] = bitmap->GetColor(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if subtitles
|
// check if subtitles
|
||||||
if (this->Level == OSD_LEVEL_SUBTITLES) {
|
if (this->Level == OSD_LEVEL_SUBTITLES) {
|
||||||
int video_width;
|
int video_width;
|
||||||
@ -238,12 +246,32 @@ void cSoftOsd::Flush(void)
|
|||||||
video_width = 1920;
|
video_width = 1920;
|
||||||
video_height = 1080;
|
video_height = 1080;
|
||||||
OsdDrawARGB((1920 - video_width) / 2 + Left() + bitmap->X0(),
|
OsdDrawARGB((1920 - video_width) / 2 + Left() + bitmap->X0(),
|
||||||
1080 - video_height + Top() + bitmap->Y0(),
|
1080 - video_height + Top() + bitmap->Y0(), w, h, argb);
|
||||||
bitmap->Width(), bitmap->Height(), argb);
|
|
||||||
} else {
|
} else {
|
||||||
OsdDrawARGB(Left() + bitmap->X0(), Top() + bitmap->Y0(),
|
OsdDrawARGB(Left() + bitmap->X0(), Top() + bitmap->Y0(), w, h,
|
||||||
bitmap->Width(), bitmap->Height(), argb);
|
argb);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// convert and upload only dirty areas
|
||||||
|
w = x2 - x1 + 1;
|
||||||
|
h = y2 - y1 + 1;
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (w > bitmap->Width() || h > bitmap->Height()) {
|
||||||
|
esyslog(tr("softhdev: dirty area too big\n"));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
argb = (uint8_t *) malloc(w * h * sizeof(uint32_t));
|
||||||
|
for (y = y1; y <= y2; ++y) {
|
||||||
|
for (x = x1; x <= x2; ++x) {
|
||||||
|
((uint32_t *) argb)[x - x1 + (y - y1) * w] =
|
||||||
|
bitmap->GetColor(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if subtitles
|
||||||
|
OsdDrawARGB(Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1,
|
||||||
|
w, h, argb);
|
||||||
|
#endif
|
||||||
|
|
||||||
bitmap->Clean();
|
bitmap->Clean();
|
||||||
free(argb);
|
free(argb);
|
||||||
@ -475,12 +503,7 @@ class cSoftHdDevice:public cDevice
|
|||||||
virtual bool Poll(cPoller &, int = 0);
|
virtual bool Poll(cPoller &, int = 0);
|
||||||
virtual bool Flush(int = 0);
|
virtual bool Flush(int = 0);
|
||||||
virtual int64_t GetSTC(void);
|
virtual int64_t GetSTC(void);
|
||||||
virtual void GetVideoSize(int &width, int &height, double &aspect)
|
virtual void GetVideoSize(int &, int &, double &);
|
||||||
{
|
|
||||||
width = 1920;
|
|
||||||
height = 1080;
|
|
||||||
aspect = (double)width / height;
|
|
||||||
}
|
|
||||||
virtual void GetOsdSize(int &, int &, double &);
|
virtual void GetOsdSize(int &, int &, double &);
|
||||||
virtual int PlayVideo(const uchar *, int);
|
virtual int PlayVideo(const uchar *, int);
|
||||||
|
|
||||||
@ -537,8 +560,7 @@ void cSoftHdDevice::MakePrimaryDevice(bool on)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cSoftHdDevice::ProvidesCa(
|
int cSoftHdDevice::ProvidesCa(
|
||||||
__attribute__ ((unused)) const cChannel *
|
__attribute__ ((unused)) const cChannel * channel) const
|
||||||
channel) const
|
|
||||||
{
|
{
|
||||||
//dsyslog("[softhddev]%s: %p\n", __FUNCTION__, channel);
|
//dsyslog("[softhddev]%s: %p\n", __FUNCTION__, channel);
|
||||||
|
|
||||||
@ -697,7 +719,18 @@ bool cSoftHdDevice::Flush(int timeout_ms)
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Returns the With, Height and PixelAspect ratio the OSD.
|
** Returns the width, height and video_aspect ratio of the currently
|
||||||
|
** displayed video material.
|
||||||
|
**
|
||||||
|
** @note the size is used to scale the subtitle.
|
||||||
|
*/
|
||||||
|
void cSoftHdDevice::GetVideoSize(int &width, int &height, double &video_aspect)
|
||||||
|
{
|
||||||
|
::GetOsdSize(&width, &height, &video_aspect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Returns the width, height and pixel_aspect ratio the OSD.
|
||||||
**
|
**
|
||||||
** FIXME: Called every second, for nothing (no OSD displayed)?
|
** FIXME: Called every second, for nothing (no OSD displayed)?
|
||||||
*/
|
*/
|
||||||
|
430
video.c
430
video.c
@ -25,7 +25,7 @@
|
|||||||
///
|
///
|
||||||
/// This module contains all video rendering functions.
|
/// This module contains all video rendering functions.
|
||||||
///
|
///
|
||||||
/// @todo hide mouse cursor support
|
/// @todo disable screen saver support
|
||||||
///
|
///
|
||||||
/// Uses Xlib where it is needed for VA-API or vdpau. XCB is used for
|
/// Uses Xlib where it is needed for VA-API or vdpau. XCB is used for
|
||||||
/// everything else.
|
/// everything else.
|
||||||
@ -36,16 +36,16 @@
|
|||||||
/// - Xrender rendering
|
/// - Xrender rendering
|
||||||
///
|
///
|
||||||
|
|
||||||
#define USE_XLIB_XCB
|
#define USE_XLIB_XCB ///< use xlib/xcb backend
|
||||||
#define noUSE_GRAB
|
#define noUSE_GRAB ///< experimental grab code
|
||||||
#define noUSE_GLX
|
#define noUSE_GLX ///< outdated GLX code
|
||||||
#define noUSE_DOUBLEBUFFER
|
#define noUSE_DOUBLEBUFFER ///< use GLX double buffers
|
||||||
|
|
||||||
//#define USE_VAAPI ///< enable vaapi support
|
//#define USE_VAAPI ///< enable vaapi support
|
||||||
//#define USE_VDPAU ///< enable vdpau support
|
//#define USE_VDPAU ///< enable vdpau support
|
||||||
#define noUSE_BITMAP ///< use vdpau bitmap surface
|
#define noUSE_BITMAP ///< use vdpau bitmap surface
|
||||||
|
|
||||||
#define USE_VIDEO_THREAD
|
#define USE_VIDEO_THREAD ///< run decoder in an own thread
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
@ -275,6 +275,14 @@ static pthread_mutex_t VideoLockMutex; ///< video lock mutex
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static char OsdShown; ///< flag show osd
|
||||||
|
static int OsdWidth; ///< osd width
|
||||||
|
static int OsdHeight; ///< osd height
|
||||||
|
static int OsdDirtyX; ///< osd dirty area x
|
||||||
|
static int OsdDirtyY; ///< osd dirty area y
|
||||||
|
static int OsdDirtyWidth; ///< osd dirty area width
|
||||||
|
static int OsdDirtyHeight; ///< osd dirty area height
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Functions
|
// Functions
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -863,8 +871,9 @@ static void AutoCropDetect(int width, int height, void *data[3],
|
|||||||
{
|
{
|
||||||
const void *data_y;
|
const void *data_y;
|
||||||
unsigned length_y;
|
unsigned length_y;
|
||||||
int x;
|
|
||||||
int y;
|
//int x;
|
||||||
|
//int y;
|
||||||
int x1;
|
int x1;
|
||||||
int x2;
|
int x2;
|
||||||
int y1;
|
int y1;
|
||||||
@ -1009,6 +1018,92 @@ static void VaapiDestroyDeinterlaceImages(VaapiDecoder *);
|
|||||||
|
|
||||||
// Surfaces -------------------------------------------------------------
|
// Surfaces -------------------------------------------------------------
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Associate OSD with surface.
|
||||||
|
///
|
||||||
|
/// @param decoder VA-API decoder
|
||||||
|
/// @param width surface source/video width
|
||||||
|
/// @param height surface source/video height
|
||||||
|
///
|
||||||
|
static void VaapiAssociate(VaapiDecoder * decoder, int width, int height)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
|
||||||
|
if (VaOsdSubpicture == VA_INVALID_ID) {
|
||||||
|
Warning(_("video/vaapi: no osd subpicture yet\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
w = VaOsdImage.width;
|
||||||
|
h = VaOsdImage.height;
|
||||||
|
|
||||||
|
// FIXME: associate only if osd is displayed
|
||||||
|
if (VaapiUnscaledOsd) {
|
||||||
|
if (decoder->SurfaceFreeN
|
||||||
|
&& vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
||||||
|
decoder->SurfacesFree, decoder->SurfaceFreeN, x, y, w, h, 0, 0,
|
||||||
|
VideoWindowWidth, VideoWindowHeight,
|
||||||
|
VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't associate subpicture\n"));
|
||||||
|
}
|
||||||
|
if (decoder->SurfaceUsedN
|
||||||
|
&& vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
||||||
|
decoder->SurfacesUsed, decoder->SurfaceUsedN, x, y, w, h, 0, 0,
|
||||||
|
VideoWindowWidth, VideoWindowHeight,
|
||||||
|
VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't associate subpicture\n"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (decoder->SurfaceFreeN
|
||||||
|
&& vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
||||||
|
decoder->SurfacesFree, decoder->SurfaceFreeN, x, y, w, h, 0, 0,
|
||||||
|
width, height, 0)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't associate subpicture\n"));
|
||||||
|
}
|
||||||
|
if (decoder->SurfaceUsedN
|
||||||
|
&& vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
||||||
|
decoder->SurfacesUsed, decoder->SurfaceUsedN, x, y, w, h, 0, 0,
|
||||||
|
width, height, 0)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't associate subpicture\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Deassociate OSD with surface.
|
||||||
|
///
|
||||||
|
/// @param decoder VA-API decoder
|
||||||
|
///
|
||||||
|
static void VaapiDeassociate(VaapiDecoder * decoder)
|
||||||
|
{
|
||||||
|
if (VaOsdSubpicture != VA_INVALID_ID) {
|
||||||
|
if (decoder->SurfaceFreeN
|
||||||
|
&& vaDeassociateSubpicture(VaDisplay, VaOsdSubpicture,
|
||||||
|
decoder->SurfacesFree, decoder->SurfaceFreeN)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't deassociate %d surfaces\n"),
|
||||||
|
decoder->SurfaceFreeN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoder->SurfaceUsedN
|
||||||
|
&& vaDeassociateSubpicture(VaDisplay, VaOsdSubpicture,
|
||||||
|
decoder->SurfacesUsed, decoder->SurfaceUsedN)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't deassociate %d surfaces\n"),
|
||||||
|
decoder->SurfaceUsedN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Create surfaces for VA-API decoder.
|
/// Create surfaces for VA-API decoder.
|
||||||
///
|
///
|
||||||
@ -1039,27 +1134,7 @@ static void VaapiCreateSurfaces(VaapiDecoder * decoder, int width, int height)
|
|||||||
//
|
//
|
||||||
// update OSD associate
|
// update OSD associate
|
||||||
//
|
//
|
||||||
if (VaOsdSubpicture == VA_INVALID_ID) {
|
VaapiAssociate(decoder, width, height);
|
||||||
Warning(_("video/vaapi: no osd subpicture yet\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// FIXME: associate only if osd is displayed
|
|
||||||
if (VaapiUnscaledOsd) {
|
|
||||||
if (vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
|
||||||
decoder->SurfacesFree, decoder->SurfaceFreeN, 0, 0,
|
|
||||||
VaOsdImage.width, VaOsdImage.height, 0, 0, VideoWindowWidth,
|
|
||||||
VideoWindowHeight, VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD)
|
|
||||||
!= VA_STATUS_SUCCESS) {
|
|
||||||
Error(_("video/vaapi: can't associate subpicture\n"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
|
||||||
decoder->SurfacesFree, decoder->SurfaceFreeN, 0, 0,
|
|
||||||
VaOsdImage.width, VaOsdImage.height, 0, 0, width, height, 0)
|
|
||||||
!= VA_STATUS_SUCCESS) {
|
|
||||||
Error(_("video/vaapi: can't associate subpicture\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -1074,23 +1149,7 @@ static void VaapiDestroySurfaces(VaapiDecoder * decoder)
|
|||||||
//
|
//
|
||||||
// update OSD associate
|
// update OSD associate
|
||||||
//
|
//
|
||||||
if (VaOsdSubpicture != VA_INVALID_ID) {
|
VaapiDeassociate(decoder);
|
||||||
if (decoder->SurfaceFreeN
|
|
||||||
&& vaDeassociateSubpicture(VaDisplay, VaOsdSubpicture,
|
|
||||||
decoder->SurfacesFree, decoder->SurfaceFreeN)
|
|
||||||
!= VA_STATUS_SUCCESS) {
|
|
||||||
Error(_("video/vaapi: can't deassociate %d surfaces\n"),
|
|
||||||
decoder->SurfaceFreeN);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decoder->SurfaceUsedN
|
|
||||||
&& vaDeassociateSubpicture(VaDisplay, VaOsdSubpicture,
|
|
||||||
decoder->SurfacesUsed, decoder->SurfaceUsedN)
|
|
||||||
!= VA_STATUS_SUCCESS) {
|
|
||||||
Error(_("video/vaapi: can't deassociate %d surfaces\n"),
|
|
||||||
decoder->SurfaceUsedN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vaDestroySurfaces(decoder->VaDisplay, decoder->SurfacesFree,
|
if (vaDestroySurfaces(decoder->VaDisplay, decoder->SurfacesFree,
|
||||||
decoder->SurfaceFreeN)
|
decoder->SurfaceFreeN)
|
||||||
@ -1525,23 +1584,6 @@ static void VideoVaapiExit(void)
|
|||||||
}
|
}
|
||||||
VaapiDecoderN = 0;
|
VaapiDecoderN = 0;
|
||||||
|
|
||||||
if (VaOsdImage.image_id != VA_INVALID_ID) {
|
|
||||||
if (vaDestroyImage(VaDisplay,
|
|
||||||
VaOsdImage.image_id) != VA_STATUS_SUCCESS) {
|
|
||||||
Error(_("video/vaapi: can't destroy image!\n"));
|
|
||||||
}
|
|
||||||
VaOsdImage.image_id = VA_INVALID_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VaOsdSubpicture != VA_INVALID_ID) {
|
|
||||||
// still has 35 surfaces associated to it
|
|
||||||
if (vaDestroySubpicture(VaDisplay, VaOsdSubpicture)
|
|
||||||
!= VA_STATUS_SUCCESS) {
|
|
||||||
Error(_("video/vaapi: can't destroy subpicture\n"));
|
|
||||||
}
|
|
||||||
VaOsdSubpicture = VA_INVALID_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!VaDisplay) {
|
if (!VaDisplay) {
|
||||||
vaTerminate(VaDisplay);
|
vaTerminate(VaDisplay);
|
||||||
VaDisplay = NULL;
|
VaDisplay = NULL;
|
||||||
@ -3384,8 +3426,20 @@ static void VaapiOsdClear(void)
|
|||||||
Error(_("video/vaapi: can't map osd image buffer\n"));
|
Error(_("video/vaapi: can't map osd image buffer\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// have dirty area.
|
||||||
|
if (OsdDirtyWidth && OsdDirtyHeight) {
|
||||||
|
int o;
|
||||||
|
|
||||||
|
Debug(3, "video/vaapi: handle osd dirty area\n");
|
||||||
|
for (o = 0; o < OsdDirtyHeight; ++o) {
|
||||||
|
memset(image_buffer + (OsdDirtyX + (o +
|
||||||
|
OsdDirtyY) * VaOsdImage.width) * 4, 0,
|
||||||
|
OsdDirtyWidth * 4);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// 100% transparent
|
// 100% transparent
|
||||||
memset(image_buffer, 0x00, VaOsdImage.data_size);
|
memset(image_buffer, 0x00, VaOsdImage.data_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (vaUnmapBuffer(VaDisplay, VaOsdImage.buf) != VA_STATUS_SUCCESS) {
|
if (vaUnmapBuffer(VaDisplay, VaOsdImage.buf) != VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't unmap osd image buffer\n"));
|
Error(_("video/vaapi: can't unmap osd image buffer\n"));
|
||||||
@ -3406,6 +3460,8 @@ static void VaapiOsdClear(void)
|
|||||||
static void VaapiUploadImage(int x, int y, int width, int height,
|
static void VaapiUploadImage(int x, int y, int width, int height,
|
||||||
const uint8_t * argb)
|
const uint8_t * argb)
|
||||||
{
|
{
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t end;
|
||||||
void *image_buffer;
|
void *image_buffer;
|
||||||
int o;
|
int o;
|
||||||
|
|
||||||
@ -3414,17 +3470,13 @@ static void VaapiUploadImage(int x, int y, int width, int height,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug(3, "video/vaapi: upload image\n");
|
start = GetMsTicks();
|
||||||
|
|
||||||
// map osd surface/image into memory.
|
// map osd surface/image into memory.
|
||||||
if (vaMapBuffer(VaDisplay, VaOsdImage.buf, &image_buffer)
|
if (vaMapBuffer(VaDisplay, VaOsdImage.buf, &image_buffer)
|
||||||
!= VA_STATUS_SUCCESS) {
|
!= VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't map osd image buffer\n"));
|
Error(_("video/vaapi: can't map osd image buffer\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 100% transparent
|
|
||||||
//memset(image_buffer, 0x00, VaOsdImage.data_size);
|
|
||||||
|
|
||||||
// FIXME: convert image from ARGB to subpicture format, if not argb
|
// FIXME: convert image from ARGB to subpicture format, if not argb
|
||||||
|
|
||||||
// copy argb to image
|
// copy argb to image
|
||||||
@ -3436,6 +3488,10 @@ static void VaapiUploadImage(int x, int y, int width, int height,
|
|||||||
if (vaUnmapBuffer(VaDisplay, VaOsdImage.buf) != VA_STATUS_SUCCESS) {
|
if (vaUnmapBuffer(VaDisplay, VaOsdImage.buf) != VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't unmap osd image buffer\n"));
|
Error(_("video/vaapi: can't unmap osd image buffer\n"));
|
||||||
}
|
}
|
||||||
|
end = GetMsTicks();
|
||||||
|
|
||||||
|
Debug(3, "video/vaapi: osd upload %dx%d+%d+%d %d ms %d\n", width, height,
|
||||||
|
x, y, end - start, width * height * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -3528,10 +3584,32 @@ static void VaapiOsdInit(int width, int height)
|
|||||||
}
|
}
|
||||||
// FIXME: must store format, to convert ARGB to it.
|
// FIXME: must store format, to convert ARGB to it.
|
||||||
|
|
||||||
VaapiOsdClear();
|
|
||||||
// FIXME: unlock
|
// FIXME: unlock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// VA-API cleanup osd.
|
||||||
|
///
|
||||||
|
static void VaapiOsdExit(void)
|
||||||
|
{
|
||||||
|
if (VaOsdImage.image_id != VA_INVALID_ID) {
|
||||||
|
if (vaDestroyImage(VaDisplay,
|
||||||
|
VaOsdImage.image_id) != VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't destroy image!\n"));
|
||||||
|
}
|
||||||
|
VaOsdImage.image_id = VA_INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VaOsdSubpicture != VA_INVALID_ID) {
|
||||||
|
// FIXME: still has 35 surfaces associated to it
|
||||||
|
if (vaDestroySubpicture(VaDisplay, VaOsdSubpicture)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't destroy subpicture\n"));
|
||||||
|
}
|
||||||
|
VaOsdSubpicture = VA_INVALID_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -3629,10 +3707,6 @@ static int VdpauSkipChroma; ///< skip chroma deint. supported
|
|||||||
static VdpOutputSurface VdpauSurfacesRb[OUTPUT_SURFACES_MAX];
|
static VdpOutputSurface VdpauSurfacesRb[OUTPUT_SURFACES_MAX];
|
||||||
static int VdpauSurfaceIndex; ///< current display surface
|
static int VdpauSurfaceIndex; ///< current display surface
|
||||||
|
|
||||||
static int VdpauOsdWidth; ///< width of osd surface
|
|
||||||
static int VdpauOsdHeight; ///< height of osd surface
|
|
||||||
static int VdpauShowOsd; ///< flag show osd
|
|
||||||
|
|
||||||
#ifdef USE_BITMAP
|
#ifdef USE_BITMAP
|
||||||
/// bitmap surfaces for osd
|
/// bitmap surfaces for osd
|
||||||
static VdpBitmapSurface VdpauOsdBitmapSurface[2] = {
|
static VdpBitmapSurface VdpauOsdBitmapSurface[2] = {
|
||||||
@ -4947,8 +5021,6 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder,
|
|||||||
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
||||||
VdpauUpdateOutput(decoder);
|
VdpauUpdateOutput(decoder);
|
||||||
|
|
||||||
VdpauMixerSetup(decoder);
|
|
||||||
|
|
||||||
// FIXME: need only to create and destroy surfaces for size changes
|
// FIXME: need only to create and destroy surfaces for size changes
|
||||||
// or when number of needed surfaces changed!
|
// or when number of needed surfaces changed!
|
||||||
decoder->Resolution =
|
decoder->Resolution =
|
||||||
@ -4956,6 +5028,8 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder,
|
|||||||
decoder->Interlaced);
|
decoder->Interlaced);
|
||||||
VdpauCreateSurfaces(decoder, video_ctx->width, video_ctx->height);
|
VdpauCreateSurfaces(decoder, video_ctx->width, video_ctx->height);
|
||||||
|
|
||||||
|
VdpauMixerSetup(decoder);
|
||||||
|
|
||||||
Debug(3, "\t%#010x %s\n", fmt_idx[0], av_get_pix_fmt_name(fmt_idx[0]));
|
Debug(3, "\t%#010x %s\n", fmt_idx[0], av_get_pix_fmt_name(fmt_idx[0]));
|
||||||
|
|
||||||
return *fmt_idx;
|
return *fmt_idx;
|
||||||
@ -4983,12 +5057,13 @@ static void VdpauSetup(VdpauDecoder * decoder,
|
|||||||
// decoder->Input... already setup by caller
|
// decoder->Input... already setup by caller
|
||||||
VdpauCleanup(decoder);
|
VdpauCleanup(decoder);
|
||||||
|
|
||||||
VdpauMixerSetup(decoder);
|
|
||||||
decoder->Resolution =
|
decoder->Resolution =
|
||||||
VideoResolutionGroup(video_ctx->width, video_ctx->height,
|
VideoResolutionGroup(video_ctx->width, video_ctx->height,
|
||||||
decoder->Interlaced);
|
decoder->Interlaced);
|
||||||
VdpauCreateSurfaces(decoder, video_ctx->width, video_ctx->height);
|
VdpauCreateSurfaces(decoder, video_ctx->width, video_ctx->height);
|
||||||
|
|
||||||
|
VdpauMixerSetup(decoder);
|
||||||
|
|
||||||
// get real surface size
|
// get real surface size
|
||||||
status =
|
status =
|
||||||
VdpauVideoSurfaceGetParameters(decoder->SurfacesFree[0], &chroma_type,
|
VdpauVideoSurfaceGetParameters(decoder->SurfacesFree[0], &chroma_type,
|
||||||
@ -5323,15 +5398,30 @@ static void VdpauMixOsd(void)
|
|||||||
blend_state.blend_equation_alpha =
|
blend_state.blend_equation_alpha =
|
||||||
VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD;
|
VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD;
|
||||||
|
|
||||||
|
// FIXME: use dirty area
|
||||||
|
if (OsdDirtyWidth && OsdDirtyHeight) {
|
||||||
|
source_rect.x0 = OsdDirtyX;
|
||||||
|
source_rect.y0 = OsdDirtyY;
|
||||||
|
source_rect.x1 = source_rect.x0 + OsdDirtyWidth;
|
||||||
|
source_rect.y1 = source_rect.y0 + OsdDirtyHeight;
|
||||||
|
|
||||||
|
output_rect.x0 = (OsdDirtyX * VideoWindowWidth) / OsdWidth;
|
||||||
|
output_rect.y0 = (OsdDirtyY * VideoWindowHeight) / OsdHeight;
|
||||||
|
output_rect.x1 =
|
||||||
|
output_rect.x0 + (OsdDirtyWidth * VideoWindowWidth) / OsdWidth;
|
||||||
|
output_rect.y1 =
|
||||||
|
output_rect.y0 + (OsdDirtyHeight * VideoWindowHeight) / OsdHeight;
|
||||||
|
} else {
|
||||||
source_rect.x0 = 0;
|
source_rect.x0 = 0;
|
||||||
source_rect.y0 = 0;
|
source_rect.y0 = 0;
|
||||||
source_rect.x1 = VdpauOsdWidth;
|
source_rect.x1 = OsdWidth;
|
||||||
source_rect.y1 = VdpauOsdHeight;
|
source_rect.y1 = OsdHeight;
|
||||||
|
|
||||||
output_rect.x0 = 0;
|
output_rect.x0 = 0;
|
||||||
output_rect.y0 = 0;
|
output_rect.y0 = 0;
|
||||||
output_rect.x1 = VideoWindowWidth;
|
output_rect.x1 = VideoWindowWidth;
|
||||||
output_rect.y1 = VideoWindowHeight;
|
output_rect.y1 = VideoWindowHeight;
|
||||||
|
}
|
||||||
|
|
||||||
//start = GetMsTicks();
|
//start = GetMsTicks();
|
||||||
|
|
||||||
@ -5645,7 +5735,7 @@ static void VdpauDisplayFrame(void)
|
|||||||
//
|
//
|
||||||
// add osd to surface
|
// add osd to surface
|
||||||
//
|
//
|
||||||
if (VdpauShowOsd) { // showing costs performance
|
if (OsdShown) { // showing costs performance
|
||||||
VdpauMixOsd();
|
VdpauMixOsd();
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -5879,6 +5969,8 @@ static void VdpauSetOutputPosition(VdpauDecoder * decoder, int x, int y,
|
|||||||
// VDPAU OSD
|
// VDPAU OSD
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static const uint8_t OsdZeros[1920 * 1080 * 4]; ///< 0 for clear osd
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Clear subpicture image.
|
/// Clear subpicture image.
|
||||||
///
|
///
|
||||||
@ -5887,7 +5979,6 @@ static void VdpauSetOutputPosition(VdpauDecoder * decoder, int x, int y,
|
|||||||
static void VdpauOsdClear(void)
|
static void VdpauOsdClear(void)
|
||||||
{
|
{
|
||||||
VdpStatus status;
|
VdpStatus status;
|
||||||
void *image;
|
|
||||||
void const *data[1];
|
void const *data[1];
|
||||||
uint32_t pitches[1];
|
uint32_t pitches[1];
|
||||||
VdpRect dst_rect;
|
VdpRect dst_rect;
|
||||||
@ -5903,16 +5994,27 @@ static void VdpauOsdClear(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Debug(3, "video/vdpau: clear image\n");
|
if (OsdWidth * OsdHeight > 1920 * 1080) {
|
||||||
|
Error(_("video/vdpau: osd too big: unsupported\n"));
|
||||||
image = calloc(4, VdpauOsdWidth * VdpauOsdHeight);
|
return;
|
||||||
|
}
|
||||||
|
// have dirty area.
|
||||||
|
if (OsdDirtyWidth && OsdDirtyHeight) {
|
||||||
|
Debug(3, "video/vdpau: osd clear dirty %dx%d+%d+%d\n", OsdDirtyWidth,
|
||||||
|
OsdDirtyHeight, OsdDirtyX, OsdDirtyY);
|
||||||
|
dst_rect.x0 = OsdDirtyX;
|
||||||
|
dst_rect.y0 = OsdDirtyY;
|
||||||
|
dst_rect.x1 = dst_rect.x0 + OsdDirtyWidth;
|
||||||
|
dst_rect.y1 = dst_rect.y0 + OsdDirtyHeight;
|
||||||
|
} else {
|
||||||
|
Debug(3, "video/vdpau: osd clear image\n");
|
||||||
dst_rect.x0 = 0;
|
dst_rect.x0 = 0;
|
||||||
dst_rect.y0 = 0;
|
dst_rect.y0 = 0;
|
||||||
dst_rect.x1 = dst_rect.x0 + VdpauOsdWidth;
|
dst_rect.x1 = dst_rect.x0 + OsdWidth;
|
||||||
dst_rect.y1 = dst_rect.y0 + VdpauOsdHeight;
|
dst_rect.y1 = dst_rect.y0 + OsdHeight;
|
||||||
data[0] = image;
|
}
|
||||||
pitches[0] = VdpauOsdWidth * 4;
|
data[0] = OsdZeros;
|
||||||
|
pitches[0] = OsdWidth * 4;
|
||||||
|
|
||||||
#ifdef USE_BITMAP
|
#ifdef USE_BITMAP
|
||||||
status =
|
status =
|
||||||
@ -5931,9 +6033,6 @@ static void VdpauOsdClear(void)
|
|||||||
VdpauGetErrorString(status));
|
VdpauGetErrorString(status));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free(image);
|
|
||||||
VdpauShowOsd = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -5954,6 +6053,8 @@ static void VdpauUploadImage(int x, int y, int width, int height,
|
|||||||
void const *data[1];
|
void const *data[1];
|
||||||
uint32_t pitches[1];
|
uint32_t pitches[1];
|
||||||
VdpRect dst_rect;
|
VdpRect dst_rect;
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t end;
|
||||||
|
|
||||||
// osd image available?
|
// osd image available?
|
||||||
#ifdef USE_BITMAP
|
#ifdef USE_BITMAP
|
||||||
@ -5966,7 +6067,7 @@ static void VdpauUploadImage(int x, int y, int width, int height,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Debug(3, "video/vdpau: upload image\n");
|
start = GetMsTicks();
|
||||||
|
|
||||||
dst_rect.x0 = x;
|
dst_rect.x0 = x;
|
||||||
dst_rect.y0 = y;
|
dst_rect.y0 = y;
|
||||||
@ -5992,7 +6093,10 @@ static void VdpauUploadImage(int x, int y, int width, int height,
|
|||||||
VdpauGetErrorString(status));
|
VdpauGetErrorString(status));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
VdpauShowOsd = 1;
|
end = GetMsTicks();
|
||||||
|
|
||||||
|
Debug(3, "video/vdpau: osd upload %dx%d+%d+%d %d ms %d\n", width, height,
|
||||||
|
x, y, end - start, width * height * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -6010,16 +6114,12 @@ static void VdpauOsdInit(int width, int height)
|
|||||||
Debug(3, "video/vdpau: vdpau not setup\n");
|
Debug(3, "video/vdpau: vdpau not setup\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VdpauOsdWidth = width;
|
|
||||||
VdpauOsdHeight = height;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// create bitmap/surface for osd
|
// create bitmap/surface for osd
|
||||||
//
|
//
|
||||||
#ifdef USE_BITMAP
|
#ifdef USE_BITMAP
|
||||||
if (VdpauOsdBitmapSurface[0] == VDP_INVALID_HANDLE) {
|
if (VdpauOsdBitmapSurface[0] == VDP_INVALID_HANDLE) {
|
||||||
for (i = 0; i < 2; ++i) {
|
for (i = 0; i < 1; ++i) {
|
||||||
status =
|
status =
|
||||||
VdpauBitmapSurfaceCreate(VdpauDevice, VDP_RGBA_FORMAT_B8G8R8A8,
|
VdpauBitmapSurfaceCreate(VdpauDevice, VDP_RGBA_FORMAT_B8G8R8A8,
|
||||||
width, height, VDP_TRUE, VdpauOsdBitmapSurface + i);
|
width, height, VDP_TRUE, VdpauOsdBitmapSurface + i);
|
||||||
@ -6034,7 +6134,7 @@ static void VdpauOsdInit(int width, int height)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (VdpauOsdOutputSurface[0] == VDP_INVALID_HANDLE) {
|
if (VdpauOsdOutputSurface[0] == VDP_INVALID_HANDLE) {
|
||||||
for (i = 0; i < 2; ++i) {
|
for (i = 0; i < 1; ++i) {
|
||||||
status =
|
status =
|
||||||
VdpauOutputSurfaceCreate(VdpauDevice, VDP_RGBA_FORMAT_B8G8R8A8,
|
VdpauOutputSurfaceCreate(VdpauDevice, VDP_RGBA_FORMAT_B8G8R8A8,
|
||||||
width, height, VdpauOsdOutputSurface + i);
|
width, height, VdpauOsdOutputSurface + i);
|
||||||
@ -6048,10 +6148,7 @@ static void VdpauOsdInit(int width, int height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Debug(3, "video/vdpau: osd surfaces created\n");
|
Debug(3, "video/vdpau: osd surfaces created\n");
|
||||||
|
|
||||||
VdpauOsdClear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -6059,7 +6156,38 @@ static void VdpauOsdInit(int width, int height)
|
|||||||
///
|
///
|
||||||
static void VdpauOsdExit(void)
|
static void VdpauOsdExit(void)
|
||||||
{
|
{
|
||||||
Debug(3, "FIXME: %s\n", __FUNCTION__);
|
int i;
|
||||||
|
|
||||||
|
//
|
||||||
|
// destroy osd bitmap/output surfaces
|
||||||
|
//
|
||||||
|
#ifdef USE_BITMAP
|
||||||
|
for (i = 0; i < 1; ++i) {
|
||||||
|
VdpStatus status;
|
||||||
|
|
||||||
|
if (VdpauOsdBitmapSurface[i] != VDP_INVALID_HANDLE) {
|
||||||
|
status = VdpauBitmapSurfaceDestroy(VdpauOsdBitmapSurface[i]);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
Error(_("video/vdpau: can't destroy bitmap surface: %s\n"),
|
||||||
|
VdpauGetErrorString(status));
|
||||||
|
}
|
||||||
|
VdpauOsdBitmapSurface[i] = VDP_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (i = 0; i < 1; ++i) {
|
||||||
|
VdpStatus status;
|
||||||
|
|
||||||
|
if (VdpauOsdOutputSurface[i] != VDP_INVALID_HANDLE) {
|
||||||
|
status = VdpauOutputSurfaceDestroy(VdpauOsdOutputSurface[i]);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
Error(_("video/vdpau: can't destroy output surface: %s\n"),
|
||||||
|
VdpauGetErrorString(status));
|
||||||
|
}
|
||||||
|
VdpauOsdOutputSurface[i] = VDP_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -6068,10 +6196,6 @@ static void VdpauOsdExit(void)
|
|||||||
// OSD
|
// OSD
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
//static int OsdShow; ///< flag show osd
|
|
||||||
static int OsdWidth; ///< osd width
|
|
||||||
static int OsdHeight; ///< osd height
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Clear the OSD.
|
/// Clear the OSD.
|
||||||
///
|
///
|
||||||
@ -6080,6 +6204,10 @@ static int OsdHeight; ///< osd height
|
|||||||
///
|
///
|
||||||
void VideoOsdClear(void)
|
void VideoOsdClear(void)
|
||||||
{
|
{
|
||||||
|
if (!VideoThread) { // thread not yet running
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
VideoThreadLock();
|
VideoThreadLock();
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
if (GlxEnabled) {
|
if (GlxEnabled) {
|
||||||
@ -6100,6 +6228,11 @@ void VideoOsdClear(void)
|
|||||||
#ifdef USE_VAAPI
|
#ifdef USE_VAAPI
|
||||||
if (VideoVaapiEnabled) {
|
if (VideoVaapiEnabled) {
|
||||||
VaapiOsdClear();
|
VaapiOsdClear();
|
||||||
|
OsdDirtyX = OsdWidth;
|
||||||
|
OsdDirtyY = OsdHeight;
|
||||||
|
OsdDirtyWidth = 0;
|
||||||
|
OsdDirtyHeight = 0;
|
||||||
|
OsdShown = 0;
|
||||||
VideoThreadUnlock();
|
VideoThreadUnlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -6107,6 +6240,11 @@ void VideoOsdClear(void)
|
|||||||
#ifdef USE_VDPAU
|
#ifdef USE_VDPAU
|
||||||
if (VideoVdpauEnabled) {
|
if (VideoVdpauEnabled) {
|
||||||
VdpauOsdClear();
|
VdpauOsdClear();
|
||||||
|
OsdDirtyX = OsdWidth;
|
||||||
|
OsdDirtyY = OsdHeight;
|
||||||
|
OsdDirtyWidth = 0;
|
||||||
|
OsdDirtyHeight = 0;
|
||||||
|
OsdShown = 0;
|
||||||
VideoThreadUnlock();
|
VideoThreadUnlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -6123,10 +6261,36 @@ void VideoOsdClear(void)
|
|||||||
/// @param height height of image
|
/// @param height height of image
|
||||||
/// @param argb argb image
|
/// @param argb argb image
|
||||||
///
|
///
|
||||||
void VideoOsdDrawARGB(int x, int y, int height, int width,
|
void VideoOsdDrawARGB(int x, int y, int width, int height,
|
||||||
const uint8_t * argb)
|
const uint8_t * argb)
|
||||||
{
|
{
|
||||||
|
if (!VideoThread) { // thread not yet running
|
||||||
|
return;
|
||||||
|
}
|
||||||
VideoThreadLock();
|
VideoThreadLock();
|
||||||
|
|
||||||
|
// update dirty area
|
||||||
|
if (x < OsdDirtyX) {
|
||||||
|
if (OsdDirtyWidth) {
|
||||||
|
OsdDirtyWidth += OsdDirtyX - x;
|
||||||
|
}
|
||||||
|
OsdDirtyX = x;
|
||||||
|
}
|
||||||
|
if (y < OsdDirtyY) {
|
||||||
|
if (OsdDirtyHeight) {
|
||||||
|
OsdDirtyHeight += OsdDirtyY - y;
|
||||||
|
}
|
||||||
|
OsdDirtyY = y;
|
||||||
|
}
|
||||||
|
if (x + width > OsdDirtyX + OsdDirtyWidth) {
|
||||||
|
OsdDirtyWidth = x + width - OsdDirtyX;
|
||||||
|
}
|
||||||
|
if (y + height > OsdDirtyY + OsdDirtyHeight) {
|
||||||
|
OsdDirtyHeight = y + height - OsdDirtyY;
|
||||||
|
}
|
||||||
|
Debug(3, "video: osd dirty %dx%d+%d+%d -> %dx%d+%d+%d\n", width, height, x,
|
||||||
|
y, OsdDirtyWidth, OsdDirtyHeight, OsdDirtyX, OsdDirtyY);
|
||||||
|
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
if (GlxEnabled) {
|
if (GlxEnabled) {
|
||||||
Debug(3, "video: %p <-> %p\n", glXGetCurrentContext(), GlxContext);
|
Debug(3, "video: %p <-> %p\n", glXGetCurrentContext(), GlxContext);
|
||||||
@ -6137,15 +6301,17 @@ void VideoOsdDrawARGB(int x, int y, int height, int width,
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_VAAPI
|
#ifdef USE_VAAPI
|
||||||
if (VideoVaapiEnabled) {
|
if (VideoVaapiEnabled) {
|
||||||
VaapiUploadImage(x, y, height, width, argb);
|
VaapiUploadImage(x, y, width, height, argb);
|
||||||
VideoThreadUnlock();
|
VideoThreadUnlock();
|
||||||
|
OsdShown = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VDPAU
|
#ifdef USE_VDPAU
|
||||||
if (VideoVdpauEnabled) {
|
if (VideoVdpauEnabled) {
|
||||||
VdpauUploadImage(x, y, height, width, argb);
|
VdpauUploadImage(x, y, width, height, argb);
|
||||||
VideoThreadUnlock();
|
VideoThreadUnlock();
|
||||||
|
OsdShown = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -6157,6 +6323,19 @@ void VideoOsdDrawARGB(int x, int y, int height, int width,
|
|||||||
VideoThreadUnlock();
|
VideoThreadUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Get OSD size.
|
||||||
|
///
|
||||||
|
void VideoGetOsdSize(int *width, int *height)
|
||||||
|
{
|
||||||
|
*width = 1920;
|
||||||
|
*height = 1080; // unknown default
|
||||||
|
if (OsdWidth && OsdHeight) {
|
||||||
|
*width = OsdWidth;
|
||||||
|
*height = OsdHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Setup osd.
|
/// Setup osd.
|
||||||
///
|
///
|
||||||
@ -6165,11 +6344,8 @@ void VideoOsdDrawARGB(int x, int y, int height, int width,
|
|||||||
///
|
///
|
||||||
void VideoOsdInit(void)
|
void VideoOsdInit(void)
|
||||||
{
|
{
|
||||||
OsdWidth = 1920 / 1;
|
OsdWidth = VideoWindowWidth; // FIXME: must be configured
|
||||||
OsdHeight = 1080 / 1; // worst-case
|
OsdHeight = VideoWindowHeight;
|
||||||
|
|
||||||
//OsdWidth = 768;
|
|
||||||
//OsdHeight = VideoWindowHeight; // FIXME: must be configured
|
|
||||||
|
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
// FIXME: make an extra function for this
|
// FIXME: make an extra function for this
|
||||||
@ -6205,12 +6381,14 @@ void VideoOsdInit(void)
|
|||||||
#ifdef USE_VAAPI
|
#ifdef USE_VAAPI
|
||||||
if (VideoVaapiEnabled) {
|
if (VideoVaapiEnabled) {
|
||||||
VaapiOsdInit(OsdWidth, OsdHeight);
|
VaapiOsdInit(OsdWidth, OsdHeight);
|
||||||
|
VideoOsdClear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VDPAU
|
#ifdef USE_VDPAU
|
||||||
if (VideoVdpauEnabled) {
|
if (VideoVdpauEnabled) {
|
||||||
VdpauOsdInit(OsdWidth, OsdHeight);
|
VdpauOsdInit(OsdWidth, OsdHeight);
|
||||||
|
VideoOsdClear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -6223,7 +6401,7 @@ void VideoOsdExit(void)
|
|||||||
{
|
{
|
||||||
#ifdef USE_VAAPI
|
#ifdef USE_VAAPI
|
||||||
if (VideoVaapiEnabled) {
|
if (VideoVaapiEnabled) {
|
||||||
// FIXME: VaapiOsdExit();
|
VaapiOsdExit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -7070,27 +7248,45 @@ void VideoSetVideoMode( __attribute__ ((unused))
|
|||||||
int y, int width, int height)
|
int y, int width, int height)
|
||||||
{
|
{
|
||||||
Debug(3, "video: %s %dx%d%+d%+d\n", __FUNCTION__, width, height, x, y);
|
Debug(3, "video: %s %dx%d%+d%+d\n", __FUNCTION__, width, height, x, y);
|
||||||
|
|
||||||
if ((unsigned)width == VideoWindowWidth
|
if ((unsigned)width == VideoWindowWidth
|
||||||
&& (unsigned)height == VideoWindowHeight) {
|
&& (unsigned)height == VideoWindowHeight) {
|
||||||
return; // same size nothing todo
|
return; // same size nothing todo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!VideoThread) { // thread not yet running
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//VideoThreadLock(); // FIXME: vaapi can crash
|
||||||
|
|
||||||
VideoWindowWidth = width;
|
VideoWindowWidth = width;
|
||||||
VideoWindowHeight = height;
|
VideoWindowHeight = height;
|
||||||
#ifdef USE_VAAPI
|
#ifdef USE_VAAPI
|
||||||
if (VideoVaapiEnabled && VaapiDecoders[0]) {
|
if (VideoVaapiEnabled && VaapiDecoders[0]) {
|
||||||
// FIXME: must update osd surfaces?
|
VaapiDeassociate(VaapiDecoders[0]);
|
||||||
|
VideoOsdExit();
|
||||||
|
VideoOsdInit();
|
||||||
|
if (VaapiDecoders[0]->InputWidth && VaapiDecoders[0]->InputHeight) {
|
||||||
|
VaapiAssociate(VaapiDecoders[0], VaapiDecoders[0]->InputWidth,
|
||||||
|
VaapiDecoders[0]->InputHeight);
|
||||||
|
}
|
||||||
VaapiUpdateOutput(VaapiDecoders[0]);
|
VaapiUpdateOutput(VaapiDecoders[0]);
|
||||||
|
//VideoThreadUnlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VDPAU
|
#ifdef USE_VDPAU
|
||||||
if (VideoVdpauEnabled && VdpauDecoders[0]) {
|
if (VideoVdpauEnabled && VdpauDecoders[0]) {
|
||||||
VdpauExitOutputQueue();
|
VdpauExitOutputQueue();
|
||||||
|
VideoOsdExit();
|
||||||
|
VideoOsdInit();
|
||||||
VdpauInitOutputQueue();
|
VdpauInitOutputQueue();
|
||||||
VdpauUpdateOutput(VdpauDecoders[0]);
|
VdpauUpdateOutput(VdpauDecoders[0]);
|
||||||
|
//VideoThreadUnlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
//VideoThreadUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
3
video.h
3
video.h
@ -103,6 +103,9 @@ 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 *);
|
||||||
|
|
||||||
|
/// Get OSD size.
|
||||||
|
extern void VideoGetOsdSize(int *, int *);
|
||||||
|
|
||||||
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.
|
||||||
|
Loading…
Reference in New Issue
Block a user