Auto-crop improvement and nicer a-v sync display.

This commit is contained in:
Johns 2012-02-02 16:01:38 +01:00
parent 3585f1df19
commit ab4e89132e
3 changed files with 51 additions and 31 deletions

View File

@ -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
View File

@ -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
View File

@ -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