mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Auto-crop improvement and nicer a-v sync display.
This commit is contained in:
parent
3585f1df19
commit
ab4e89132e
@ -1,6 +1,11 @@
|
|||||||
User johns
|
User johns
|
||||||
Date:
|
Date:
|
||||||
|
|
||||||
|
Release Version 0.4.6
|
||||||
|
Increase audio buffer, if bigger audio delay is used.
|
||||||
|
Makes SkipLines configure in setup menu.
|
||||||
|
Auto-crop only enabled with normal 4:3 display mode.
|
||||||
|
Vaapi updates OSD when cropping changes.
|
||||||
Add A-V info output and compile time option.
|
Add A-V info output and compile time option.
|
||||||
Fix bug: VA-API intel software decoder broken by aspect commit.
|
Fix bug: VA-API intel software decoder broken by aspect commit.
|
||||||
Add support for 4:3 output modes.
|
Add support for 4:3 output modes.
|
||||||
|
8
Todo
8
Todo
@ -21,12 +21,10 @@ $Id: $
|
|||||||
missing:
|
missing:
|
||||||
software deinterlace (yadif, ...)
|
software deinterlace (yadif, ...)
|
||||||
software decoder with software deinterlace
|
software decoder with software deinterlace
|
||||||
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 and restart X11
|
suspend output / energie saver: stop and restart X11
|
||||||
suspend plugin didn't restore full-screen (is this wanted?)
|
suspend plugin didn't restore full-screen (is this wanted?)
|
||||||
Option deinterlace off / deinterlace force!
|
Option deinterlace off / deinterlace force!
|
||||||
Make output drivers better modular (under construction).
|
|
||||||
|
|
||||||
crash:
|
crash:
|
||||||
AudioPlayHandlerThread -> pthread_cond_wait
|
AudioPlayHandlerThread -> pthread_cond_wait
|
||||||
@ -40,8 +38,6 @@ video:
|
|||||||
(must detect video format to show image)
|
(must detect video format to show image)
|
||||||
hard channel switch
|
hard channel switch
|
||||||
skip lines not configurable from setup menu.
|
skip lines not configurable from setup menu.
|
||||||
software decoder path didn't support auto-crop
|
|
||||||
software decoder path didn't support correct 4:3 16:9
|
|
||||||
OSD can only be shown after some stream could be shown
|
OSD can only be shown after some stream could be shown
|
||||||
|
|
||||||
vdpau:
|
vdpau:
|
||||||
@ -60,6 +56,7 @@ libva: branch vaapi-ext
|
|||||||
add support for vaapi-ext
|
add support for vaapi-ext
|
||||||
|
|
||||||
libva-intel-driver:
|
libva-intel-driver:
|
||||||
|
deinterlace only supported with vaapi-ext
|
||||||
1080i does no v-sync (sometimes correct working with vaapi-ext)
|
1080i does no v-sync (sometimes correct working with vaapi-ext)
|
||||||
OSD has sometimes wrong size (workaround written)
|
OSD has sometimes wrong size (workaround written)
|
||||||
sometimes software decoder deinterlace isn't working and 1080i channels
|
sometimes software decoder deinterlace isn't working and 1080i channels
|
||||||
@ -69,10 +66,9 @@ libva-vdpau-driver:
|
|||||||
G210/GT520 OSD update too slow (needs hardware problem workaround)
|
G210/GT520 OSD update too slow (needs hardware problem workaround)
|
||||||
hangup on exit (VaapiDelDecoder -> VaapiCleanup
|
hangup on exit (VaapiDelDecoder -> VaapiCleanup
|
||||||
-> vaDestroyContext -> pthread_rwlock_wrlock)
|
-> vaDestroyContext -> pthread_rwlock_wrlock)
|
||||||
with auto-crop OSD has wrong position
|
OSD still has some problems with auto-crop and 4:3 zoom.
|
||||||
|
|
||||||
libva-xvba-driver:
|
libva-xvba-driver:
|
||||||
with auto-crop OSD has wrong position
|
|
||||||
|
|
||||||
x11:
|
x11:
|
||||||
disable screensaver
|
disable screensaver
|
||||||
|
69
video.c
69
video.c
@ -296,7 +296,7 @@ static int VideoSharpen[VideoResolutionMax];
|
|||||||
static VideoScalingModes VideoScaling[VideoResolutionMax];
|
static VideoScalingModes VideoScaling[VideoResolutionMax];
|
||||||
|
|
||||||
/// Default audio/video delay
|
/// Default audio/video delay
|
||||||
static int VideoAudioDelay;
|
int VideoAudioDelay;
|
||||||
|
|
||||||
/// Default zoom mode
|
/// Default zoom mode
|
||||||
static VideoZoomModes Video4to3ZoomMode;
|
static VideoZoomModes Video4to3ZoomMode;
|
||||||
@ -344,20 +344,22 @@ static void VideoThreadUnlock(void); ///< unlock video thread
|
|||||||
///
|
///
|
||||||
static const char *VideoTimeStampString(int64_t ts)
|
static const char *VideoTimeStampString(int64_t ts)
|
||||||
{
|
{
|
||||||
static char buf[64];
|
static char buf[2][32];
|
||||||
|
static int idx;
|
||||||
int hh;
|
int hh;
|
||||||
int mm;
|
int mm;
|
||||||
int ss;
|
int ss;
|
||||||
int uu;
|
int uu;
|
||||||
|
|
||||||
|
idx ^= 1; // support two static buffers
|
||||||
ts = ts / 90;
|
ts = ts / 90;
|
||||||
uu = ts % 1000;
|
uu = ts % 1000;
|
||||||
ss = (ts / 1000) % 60;
|
ss = (ts / 1000) % 60;
|
||||||
mm = (ts / 60000) % 60;
|
mm = (ts / 60000) % 60;
|
||||||
hh = ts / 3600000;
|
hh = ts / 3600000;
|
||||||
snprintf(buf, sizeof(buf), "%2d:%02d:%02d.%03d", hh, mm, ss, uu);
|
snprintf(buf[idx], sizeof(buf[idx]), "%2d:%02d:%02d.%03d", hh, mm, ss, uu);
|
||||||
|
|
||||||
return buf;
|
return buf[idx];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1335,10 +1337,8 @@ static void VaapiDestroyDeinterlaceImages(VaapiDecoder *);
|
|||||||
/// Associate OSD with surface.
|
/// Associate OSD with surface.
|
||||||
///
|
///
|
||||||
/// @param decoder VA-API decoder
|
/// @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)
|
static void VaapiAssociate(VaapiDecoder * decoder)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
@ -1374,18 +1374,19 @@ static void VaapiAssociate(VaapiDecoder * decoder, int width, int height)
|
|||||||
Error(_("video/vaapi: can't associate subpicture\n"));
|
Error(_("video/vaapi: can't associate subpicture\n"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// FIXME: auto-crop wrong position
|
|
||||||
if (decoder->SurfaceFreeN
|
if (decoder->SurfaceFreeN
|
||||||
&& vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
&& vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
||||||
decoder->SurfacesFree, decoder->SurfaceFreeN, x, y, w, h, 0, 0,
|
decoder->SurfacesFree, decoder->SurfaceFreeN, x, y, w, h,
|
||||||
width, height, 0)
|
decoder->CropX, decoder->CropY / 2, decoder->CropWidth,
|
||||||
|
decoder->CropHeight, 0)
|
||||||
!= VA_STATUS_SUCCESS) {
|
!= VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't associate subpicture\n"));
|
Error(_("video/vaapi: can't associate subpicture\n"));
|
||||||
}
|
}
|
||||||
if (decoder->SurfaceUsedN
|
if (decoder->SurfaceUsedN
|
||||||
&& vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
&& vaAssociateSubpicture(VaDisplay, VaOsdSubpicture,
|
||||||
decoder->SurfacesUsed, decoder->SurfaceUsedN, x, y, w, h, 0, 0,
|
decoder->SurfacesUsed, decoder->SurfaceUsedN, x, y, w, h,
|
||||||
width, height, 0)
|
decoder->CropX, decoder->CropY / 2, decoder->CropWidth,
|
||||||
|
decoder->CropHeight, 0)
|
||||||
!= VA_STATUS_SUCCESS) {
|
!= VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't associate subpicture\n"));
|
Error(_("video/vaapi: can't associate subpicture\n"));
|
||||||
}
|
}
|
||||||
@ -1445,10 +1446,6 @@ static void VaapiCreateSurfaces(VaapiDecoder * decoder, int width, int height)
|
|||||||
decoder->SurfaceFreeN);
|
decoder->SurfaceFreeN);
|
||||||
// FIXME: write error handler / fallback
|
// FIXME: write error handler / fallback
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// update OSD associate
|
|
||||||
//
|
|
||||||
VaapiAssociate(decoder, width, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -2185,6 +2182,10 @@ static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
|
|||||||
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
||||||
VaapiUpdateOutput(decoder);
|
VaapiUpdateOutput(decoder);
|
||||||
|
|
||||||
|
//
|
||||||
|
// update OSD associate
|
||||||
|
//
|
||||||
|
VaapiAssociate(decoder);
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
if (GlxEnabled) {
|
if (GlxEnabled) {
|
||||||
GlxSetupDecoder(decoder);
|
GlxSetupDecoder(decoder);
|
||||||
@ -2486,6 +2487,7 @@ static int VaapiFindImageFormat(VaapiDecoder * decoder,
|
|||||||
/// @param decoder VA-API decoder
|
/// @param decoder VA-API decoder
|
||||||
///
|
///
|
||||||
/// @note called only for software decoder.
|
/// @note called only for software decoder.
|
||||||
|
/// @note FIXME: combine with hardware decoder setup.
|
||||||
///
|
///
|
||||||
static void VaapiSetup(VaapiDecoder * decoder,
|
static void VaapiSetup(VaapiDecoder * decoder,
|
||||||
const AVCodecContext * video_ctx)
|
const AVCodecContext * video_ctx)
|
||||||
@ -2542,6 +2544,12 @@ static void VaapiSetup(VaapiDecoder * decoder,
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
VaapiUpdateOutput(decoder);
|
||||||
|
|
||||||
|
//
|
||||||
|
// update OSD associate
|
||||||
|
//
|
||||||
|
VaapiAssociate(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_AUTOCROP
|
#ifdef USE_AUTOCROP
|
||||||
@ -2711,6 +2719,12 @@ static void VaapiAutoCrop(VaapiDecoder * decoder)
|
|||||||
VaapiUpdateOutput(decoder);
|
VaapiUpdateOutput(decoder);
|
||||||
}
|
}
|
||||||
decoder->AutoCrop->Count = 0;
|
decoder->AutoCrop->Count = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// update OSD associate
|
||||||
|
//
|
||||||
|
VaapiDeassociate(decoder);
|
||||||
|
VaapiAssociate(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -2719,11 +2733,13 @@ static void VaapiAutoCrop(VaapiDecoder * decoder)
|
|||||||
/// @param decoder VA-API hw decoder
|
/// @param decoder VA-API hw decoder
|
||||||
///
|
///
|
||||||
/// @note a copy of VdpauCheckAutoCrop
|
/// @note a copy of VdpauCheckAutoCrop
|
||||||
|
/// @note auto-crop only supported with normal 4:3 display mode
|
||||||
///
|
///
|
||||||
static void VaapiCheckAutoCrop(VaapiDecoder * decoder)
|
static void VaapiCheckAutoCrop(VaapiDecoder * decoder)
|
||||||
{
|
{
|
||||||
// reduce load, check only n frames
|
// reduce load, check only n frames
|
||||||
if (AutoCropInterval && !(decoder->FrameCounter % AutoCropInterval)) {
|
if (Video4to3ZoomMode == VideoNormal && AutoCropInterval
|
||||||
|
&& !(decoder->FrameCounter % AutoCropInterval)) {
|
||||||
AVRational display_aspect_ratio;
|
AVRational display_aspect_ratio;
|
||||||
|
|
||||||
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
|
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
|
||||||
@ -3548,7 +3564,6 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
|
|||||||
decoder->InputHeight = height;
|
decoder->InputHeight = height;
|
||||||
|
|
||||||
VaapiSetup(decoder, video_ctx);
|
VaapiSetup(decoder, video_ctx);
|
||||||
VaapiUpdateOutput(decoder);
|
|
||||||
}
|
}
|
||||||
// FIXME: Need to insert software deinterlace here
|
// FIXME: Need to insert software deinterlace here
|
||||||
// FIXME: can/must insert auto-crop here (is done after upload)
|
// FIXME: can/must insert auto-crop here (is done after upload)
|
||||||
@ -3842,6 +3857,7 @@ static void VaapiSyncDisplayFrame(VaapiDecoder * decoder)
|
|||||||
// FIXME: audio not known assume 333ms delay
|
// FIXME: audio not known assume 333ms delay
|
||||||
|
|
||||||
if (decoder->DupNextFrame) {
|
if (decoder->DupNextFrame) {
|
||||||
|
++decoder->FramesDuped;
|
||||||
decoder->DupNextFrame--;
|
decoder->DupNextFrame--;
|
||||||
} else if ((uint64_t) audio_clock != AV_NOPTS_VALUE
|
} else if ((uint64_t) audio_clock != AV_NOPTS_VALUE
|
||||||
&& (uint64_t) video_clock != AV_NOPTS_VALUE) {
|
&& (uint64_t) video_clock != AV_NOPTS_VALUE) {
|
||||||
@ -3852,7 +3868,7 @@ static void VaapiSyncDisplayFrame(VaapiDecoder * decoder)
|
|||||||
} else if (video_clock > audio_clock + VideoAudioDelay + 80 * 90) {
|
} else if (video_clock > audio_clock + VideoAudioDelay + 80 * 90) {
|
||||||
Debug(3, "video: slow down video\n");
|
Debug(3, "video: slow down video\n");
|
||||||
decoder->DupNextFrame += 2;
|
decoder->DupNextFrame += 2;
|
||||||
} else if (video_clock > audio_clock + VideoAudioDelay + 40 * 90) {
|
} else if (video_clock > audio_clock + VideoAudioDelay + 30 * 90) {
|
||||||
Debug(3, "video: slow down video\n");
|
Debug(3, "video: slow down video\n");
|
||||||
decoder->DupNextFrame++;
|
decoder->DupNextFrame++;
|
||||||
} else if (audio_clock + VideoAudioDelay > video_clock + 40 * 90
|
} else if (audio_clock + VideoAudioDelay > video_clock + 40 * 90
|
||||||
@ -4048,10 +4064,9 @@ static void VaapiOsdClear(void)
|
|||||||
if (OsdDirtyWidth && OsdDirtyHeight) {
|
if (OsdDirtyWidth && OsdDirtyHeight) {
|
||||||
int o;
|
int o;
|
||||||
|
|
||||||
Debug(3, "video/vaapi: handle osd dirty area\n");
|
|
||||||
for (o = 0; o < OsdDirtyHeight; ++o) {
|
for (o = 0; o < OsdDirtyHeight; ++o) {
|
||||||
memset(image_buffer + (OsdDirtyX + (o +
|
memset(image_buffer + (OsdDirtyX + (o +
|
||||||
OsdDirtyY) * VaOsdImage.width) * 4, 0,
|
OsdDirtyY) * VaOsdImage.width) * 4, 0x00,
|
||||||
OsdDirtyWidth * 4);
|
OsdDirtyWidth * 4);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -4204,9 +4219,9 @@ static void VaapiOsdInit(int width, int height)
|
|||||||
|
|
||||||
// restore osd association
|
// restore osd association
|
||||||
for (i = 0; i < VaapiDecoderN; ++i) {
|
for (i = 0; i < VaapiDecoderN; ++i) {
|
||||||
|
// only if input already setup
|
||||||
if (VaapiDecoders[i]->InputWidth && VaapiDecoders[i]->InputHeight) {
|
if (VaapiDecoders[i]->InputWidth && VaapiDecoders[i]->InputHeight) {
|
||||||
VaapiAssociate(VaapiDecoders[i], VaapiDecoders[i]->InputWidth,
|
VaapiAssociate(VaapiDecoders[i]);
|
||||||
VaapiDecoders[i]->InputHeight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6091,11 +6106,13 @@ static void VdpauAutoCrop(VdpauDecoder * decoder)
|
|||||||
/// @param decoder VDPAU hw decoder
|
/// @param decoder VDPAU hw decoder
|
||||||
///
|
///
|
||||||
/// @note a copy of VaapiCheckAutoCrop
|
/// @note a copy of VaapiCheckAutoCrop
|
||||||
|
/// @note auto-crop only supported with normal 4:3 display mode
|
||||||
///
|
///
|
||||||
static void VdpauCheckAutoCrop(VdpauDecoder * decoder)
|
static void VdpauCheckAutoCrop(VdpauDecoder * decoder)
|
||||||
{
|
{
|
||||||
// reduce load, check only n frames
|
// reduce load, check only n frames
|
||||||
if (AutoCropInterval && !(decoder->FrameCounter % AutoCropInterval)) {
|
if (Video4to3ZoomMode == VideoNormal && AutoCropInterval
|
||||||
|
&& !(decoder->FrameCounter % AutoCropInterval)) {
|
||||||
AVRational display_aspect_ratio;
|
AVRational display_aspect_ratio;
|
||||||
|
|
||||||
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
|
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
|
||||||
@ -6785,7 +6802,7 @@ static void VdpauSyncDisplayFrame(VdpauDecoder * decoder)
|
|||||||
} else if (video_clock > audio_clock + VideoAudioDelay + 80 * 90) {
|
} else if (video_clock > audio_clock + VideoAudioDelay + 80 * 90) {
|
||||||
Debug(3, "video: slow down video\n");
|
Debug(3, "video: slow down video\n");
|
||||||
decoder->DupNextFrame += 2;
|
decoder->DupNextFrame += 2;
|
||||||
} else if (video_clock > audio_clock + VideoAudioDelay + 40 * 90) {
|
} else if (video_clock > audio_clock + VideoAudioDelay + 30 * 90) {
|
||||||
Debug(3, "video: slow down video\n");
|
Debug(3, "video: slow down video\n");
|
||||||
decoder->DupNextFrame++;
|
decoder->DupNextFrame++;
|
||||||
} else if (audio_clock + VideoAudioDelay > video_clock + 40 * 90
|
} else if (audio_clock + VideoAudioDelay > video_clock + 40 * 90
|
||||||
@ -7481,6 +7498,8 @@ void VideoOsdExit(void)
|
|||||||
if (VideoThread) {
|
if (VideoThread) {
|
||||||
VideoThreadUnlock();
|
VideoThreadUnlock();
|
||||||
}
|
}
|
||||||
|
OsdDirtyWidth = 0;
|
||||||
|
OsdDirtyHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
Loading…
Reference in New Issue
Block a user