mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Video updates and bug fix.
Check if surface is ready in VaapiGetSurface. Set PTS/DTS only in the first split video packet. Add support for 4:3 output modes. Quicker auto-crop after channel switch. Add auto-crop support for Intel VA-API backend. Fix bug: Auto-Crop logo skip didn't use displayed width.
This commit is contained in:
parent
33e9c71aea
commit
27e9a88e2f
@ -1,6 +1,10 @@
|
|||||||
User johns
|
User johns
|
||||||
Date:
|
Date:
|
||||||
|
|
||||||
|
Add support for 4:3 output modes.
|
||||||
|
Quicker auto-crop after channel switch.
|
||||||
|
Add auto-crop support for Intel VA-API backend.
|
||||||
|
Fix bug: Auto-Crop logo skip didn't use displayed width.
|
||||||
Workaround for mpeg2 FFMpeg + VA-API + Intel GPU hung.
|
Workaround for mpeg2 FFMpeg + VA-API + Intel GPU hung.
|
||||||
Fix bug: Missing vaSyncSurface and vaDestroyImage.
|
Fix bug: Missing vaSyncSurface and vaDestroyImage.
|
||||||
Fix bug: Only black picture with VA-API hw decoder.
|
Fix bug: Only black picture with VA-API hw decoder.
|
||||||
|
1
Todo
1
Todo
@ -127,5 +127,6 @@ future features (not planed for 1.0 - 1.5)
|
|||||||
atmolight support
|
atmolight support
|
||||||
multistream handling
|
multistream handling
|
||||||
pip support
|
pip support
|
||||||
|
save and use auto-crop with channel zapping
|
||||||
|
|
||||||
upmix stereo to AC-3
|
upmix stereo to AC-3
|
||||||
|
@ -507,7 +507,7 @@ void FixPacketForFFMpeg(VideoDecoder * MyVideoDecoder, AVPacket * avpkt)
|
|||||||
|
|
||||||
first = 1;
|
first = 1;
|
||||||
while (n > 4) {
|
while (n > 4) {
|
||||||
// scan for picture header
|
// scan for picture header 0x00000100
|
||||||
if (!p[0] && !p[1] && p[2] == 0x01 && !p[3]) {
|
if (!p[0] && !p[1] && p[2] == 0x01 && !p[3]) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first = 0;
|
first = 0;
|
||||||
@ -518,6 +518,9 @@ void FixPacketForFFMpeg(VideoDecoder * MyVideoDecoder, AVPacket * avpkt)
|
|||||||
// packet has already an picture header
|
// packet has already an picture header
|
||||||
tmp->size = p - tmp->data;
|
tmp->size = p - tmp->data;
|
||||||
CodecVideoDecode(MyVideoDecoder, tmp);
|
CodecVideoDecode(MyVideoDecoder, tmp);
|
||||||
|
// time-stamp only valid for first packet
|
||||||
|
tmp->pts = AV_NOPTS_VALUE;
|
||||||
|
tmp->dts = AV_NOPTS_VALUE;
|
||||||
tmp->data = p;
|
tmp->data = p;
|
||||||
tmp->size = n;
|
tmp->size = n;
|
||||||
}
|
}
|
||||||
|
@ -625,6 +625,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 SetVideoDisplayFormat(eVideoDisplayFormat);
|
||||||
virtual void GetVideoSize(int &, int &, double &);
|
virtual void GetVideoSize(int &, int &, double &);
|
||||||
virtual void GetOsdSize(int &, int &, double &);
|
virtual void GetOsdSize(int &, int &, double &);
|
||||||
virtual int PlayVideo(const uchar *, int);
|
virtual int PlayVideo(const uchar *, int);
|
||||||
@ -847,6 +848,26 @@ bool cSoftHdDevice::Flush(int timeout_ms)
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Sets the video display format to the given one (only useful if this
|
||||||
|
** device has an MPEG decoder).
|
||||||
|
*/
|
||||||
|
void cSoftHdDevice::SetVideoDisplayFormat(
|
||||||
|
eVideoDisplayFormat video_display_format)
|
||||||
|
{
|
||||||
|
static int last = -1;
|
||||||
|
|
||||||
|
cDevice::SetVideoDisplayFormat(video_display_format);
|
||||||
|
|
||||||
|
dsyslog("[softhddev]%s: %d\n", __FUNCTION__, video_display_format);
|
||||||
|
|
||||||
|
// called on every channel switch, no need to kill osd...
|
||||||
|
if (last != video_display_format) {
|
||||||
|
last = video_display_format;
|
||||||
|
::VideoSetDisplayFormat(video_display_format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Returns the width, height and video_aspect ratio of the currently
|
** Returns the width, height and video_aspect ratio of the currently
|
||||||
** displayed video material.
|
** displayed video material.
|
||||||
|
523
video.c
523
video.c
@ -190,7 +190,7 @@ typedef enum _video_zoom_modes_
|
|||||||
{
|
{
|
||||||
VideoNormal, ///< normal
|
VideoNormal, ///< normal
|
||||||
VideoStretch, ///< stretch to all edges
|
VideoStretch, ///< stretch to all edges
|
||||||
VideoZoom, ///< zoom out
|
VideoCenterCutOut, ///< center and cut out
|
||||||
VideoAnamorphic, ///< anamorphic scaled (unsupported)
|
VideoAnamorphic, ///< anamorphic scaled (unsupported)
|
||||||
} VideoZoomModes;
|
} VideoZoomModes;
|
||||||
|
|
||||||
@ -332,14 +332,174 @@ static int OsdDirtyHeight; ///< osd dirty area height
|
|||||||
static int64_t VideoDeltaPTS; ///< FIXME: fix pts
|
static int64_t VideoDeltaPTS; ///< FIXME: fix pts
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Functions
|
// Common Functions
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
static void VideoThreadLock(void); ///< lock video thread
|
static void VideoThreadLock(void); ///< lock video thread
|
||||||
static void VideoThreadUnlock(void); ///< unlock video thread
|
static void VideoThreadUnlock(void); ///< unlock video thread
|
||||||
|
|
||||||
/// update video stream PTS
|
///
|
||||||
static void VideoSetPts(int64_t *, int, const AVFrame *);
|
/// Update video pts.
|
||||||
|
///
|
||||||
|
/// @param pts_p pointer to pts
|
||||||
|
/// @param interlaced interlaced flag (frame isn't right)
|
||||||
|
/// @param frame frame to display
|
||||||
|
///
|
||||||
|
/// @note frame->interlaced_frame can't be used for interlace detection
|
||||||
|
///
|
||||||
|
static void VideoSetPts(int64_t * pts_p, int interlaced, const AVFrame * frame)
|
||||||
|
{
|
||||||
|
int64_t pts;
|
||||||
|
|
||||||
|
// update video clock
|
||||||
|
if ((uint64_t) * pts_p != AV_NOPTS_VALUE) {
|
||||||
|
*pts_p += interlaced ? 40 * 90 : 20 * 90;
|
||||||
|
}
|
||||||
|
//pts = frame->best_effort_timestamp;
|
||||||
|
pts = frame->pkt_pts;
|
||||||
|
if ((uint64_t) pts == AV_NOPTS_VALUE || !pts) {
|
||||||
|
// libav: 0.8pre didn't set pts
|
||||||
|
pts = frame->pkt_dts;
|
||||||
|
}
|
||||||
|
// libav: sets only pkt_dts which can be 0
|
||||||
|
if (pts && (uint64_t) pts != AV_NOPTS_VALUE) {
|
||||||
|
// build a monotonic pts
|
||||||
|
if ((uint64_t) * pts_p != AV_NOPTS_VALUE) {
|
||||||
|
int64_t delta;
|
||||||
|
|
||||||
|
delta = pts - *pts_p;
|
||||||
|
// ignore negative jumps
|
||||||
|
if (delta > -600 * 90 && delta <= -40 * 90) {
|
||||||
|
if (-delta > VideoDeltaPTS) {
|
||||||
|
VideoDeltaPTS = -delta;
|
||||||
|
Debug(4,
|
||||||
|
"video: %#012" PRIx64 "->%#012" PRIx64 " delta+%4"
|
||||||
|
PRId64 " pts\n", *pts_p, pts, pts - *pts_p);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*pts_p != pts) {
|
||||||
|
Debug(4,
|
||||||
|
"video: %#012" PRIx64 "->%#012" PRIx64 " delta=%4" PRId64
|
||||||
|
" pts\n", *pts_p, pts, pts - *pts_p);
|
||||||
|
*pts_p = pts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Update output for new size or aspect ratio.
|
||||||
|
///
|
||||||
|
/// @param input_aspect_ratio video stream aspect
|
||||||
|
///
|
||||||
|
static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width,
|
||||||
|
int input_height, int *output_x, int *output_y, int *output_width,
|
||||||
|
int *output_height, int *crop_x, int *crop_y, int *crop_width,
|
||||||
|
int *crop_height)
|
||||||
|
{
|
||||||
|
AVRational display_aspect_ratio;
|
||||||
|
|
||||||
|
if (!input_aspect_ratio.num || !input_aspect_ratio.den) {
|
||||||
|
input_aspect_ratio.num = 1;
|
||||||
|
input_aspect_ratio.den = 1;
|
||||||
|
Debug(3, "video: aspect defaults to %d:%d\n", input_aspect_ratio.num,
|
||||||
|
input_aspect_ratio.den);
|
||||||
|
}
|
||||||
|
|
||||||
|
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
|
||||||
|
input_width * input_aspect_ratio.num,
|
||||||
|
input_height * input_aspect_ratio.den, 1024 * 1024);
|
||||||
|
|
||||||
|
// InputWidth/Height can be zero = uninitialized
|
||||||
|
if (!display_aspect_ratio.num || !display_aspect_ratio.den) {
|
||||||
|
display_aspect_ratio.num = 1;
|
||||||
|
display_aspect_ratio.den = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(3, "video: aspect %d:%d\n", display_aspect_ratio.num,
|
||||||
|
display_aspect_ratio.den);
|
||||||
|
|
||||||
|
*crop_x = 0;
|
||||||
|
*crop_y = VideoSkipLines;
|
||||||
|
*crop_width = input_width;
|
||||||
|
*crop_height = input_height - VideoSkipLines * 2;
|
||||||
|
|
||||||
|
// FIXME: store different positions for the ratios
|
||||||
|
if (display_aspect_ratio.num == 4 && display_aspect_ratio.den == 3) {
|
||||||
|
switch (Video4to3ZoomMode) {
|
||||||
|
case VideoNormal:
|
||||||
|
goto normal;
|
||||||
|
case VideoStretch:
|
||||||
|
goto stretch;
|
||||||
|
case VideoCenterCutOut:
|
||||||
|
goto center_cut_out;
|
||||||
|
case VideoAnamorphic:
|
||||||
|
// FIXME: rest should be done by hardware
|
||||||
|
goto stretch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FIXME: this overwrites user choosen output position
|
||||||
|
|
||||||
|
normal:
|
||||||
|
*output_x = 0;
|
||||||
|
*output_y = 0;
|
||||||
|
*output_width = (VideoWindowHeight * display_aspect_ratio.num)
|
||||||
|
/ display_aspect_ratio.den;
|
||||||
|
*output_height = (VideoWindowWidth * display_aspect_ratio.den)
|
||||||
|
/ display_aspect_ratio.num;
|
||||||
|
if ((unsigned)*output_width > VideoWindowWidth) {
|
||||||
|
*output_width = VideoWindowWidth;
|
||||||
|
*output_y = (VideoWindowHeight - *output_height) / 2;
|
||||||
|
} else if ((unsigned)*output_height > VideoWindowHeight) {
|
||||||
|
*output_height = VideoWindowHeight;
|
||||||
|
*output_x = (VideoWindowWidth - *output_width) / 2;
|
||||||
|
}
|
||||||
|
Debug(3, "video: aspect output %dx%d+%d+%d\n", *output_width,
|
||||||
|
*output_height, *output_x, *output_y);
|
||||||
|
return;
|
||||||
|
|
||||||
|
stretch:
|
||||||
|
*output_x = 0;
|
||||||
|
*output_y = 0;
|
||||||
|
*output_width = VideoWindowWidth;
|
||||||
|
*output_height = VideoWindowHeight;
|
||||||
|
return;
|
||||||
|
|
||||||
|
center_cut_out:
|
||||||
|
*output_x = 0;
|
||||||
|
*output_y = 0;
|
||||||
|
*output_height = VideoWindowHeight;
|
||||||
|
*output_width = VideoWindowWidth;
|
||||||
|
|
||||||
|
*crop_width = (VideoWindowHeight * display_aspect_ratio.num)
|
||||||
|
/ display_aspect_ratio.den;
|
||||||
|
*crop_height = (VideoWindowWidth * display_aspect_ratio.den)
|
||||||
|
/ display_aspect_ratio.num;
|
||||||
|
|
||||||
|
// look which side must be cut
|
||||||
|
if ((unsigned)*crop_width > VideoWindowWidth) {
|
||||||
|
*crop_height = input_height;
|
||||||
|
|
||||||
|
// adjust scaiing
|
||||||
|
*crop_x = ((*crop_width - (signed)VideoWindowWidth) * input_width)
|
||||||
|
/ (2 * VideoWindowWidth);
|
||||||
|
*crop_width = input_width - *crop_x * 2;
|
||||||
|
} else if ((unsigned)*crop_height > VideoWindowHeight) {
|
||||||
|
*crop_width = input_width;
|
||||||
|
|
||||||
|
// adjust scaiing
|
||||||
|
*crop_y = ((*crop_height - (signed)VideoWindowHeight) * input_height)
|
||||||
|
/ (2 * VideoWindowHeight);
|
||||||
|
*crop_height = input_height - *crop_y * 2;
|
||||||
|
} else {
|
||||||
|
*crop_width = input_width;
|
||||||
|
*crop_height = input_height;
|
||||||
|
}
|
||||||
|
Debug(3, "video: aspect crop %dx%d+%d+%d\n", *crop_width, *crop_height,
|
||||||
|
*crop_x, *crop_y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// GLX
|
// GLX
|
||||||
@ -972,7 +1132,7 @@ static void AutoCropDetect(AutoCropCtx * autocrop, int width, int height,
|
|||||||
//
|
//
|
||||||
for (y = SKIP_Y; y < y1; ++y) {
|
for (y = SKIP_Y; y < y1; ++y) {
|
||||||
if (!AutoCropIsBlackLineY(data_y + logo_skip + y * length_y,
|
if (!AutoCropIsBlackLineY(data_y + logo_skip + y * length_y,
|
||||||
(length_y - 2 * logo_skip) / 8, 8)) {
|
(width - 2 * logo_skip) / 8, 8)) {
|
||||||
if (y == SKIP_Y) {
|
if (y == SKIP_Y) {
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
@ -985,7 +1145,7 @@ static void AutoCropDetect(AutoCropCtx * autocrop, int width, int height,
|
|||||||
//
|
//
|
||||||
for (y = height - SKIP_Y - 1; y > y2; --y) {
|
for (y = height - SKIP_Y - 1; y > y2; --y) {
|
||||||
if (!AutoCropIsBlackLineY(data_y + logo_skip + y * length_y,
|
if (!AutoCropIsBlackLineY(data_y + logo_skip + y * length_y,
|
||||||
(length_y - 2 * logo_skip) / 8, 8)) {
|
(width - 2 * logo_skip) / 8, 8)) {
|
||||||
if (y == height - SKIP_Y - 1) {
|
if (y == height - SKIP_Y - 1) {
|
||||||
y = height - 1;
|
y = height - 1;
|
||||||
}
|
}
|
||||||
@ -1006,7 +1166,6 @@ static void AutoCropDetect(AutoCropCtx * autocrop, int width, int height,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// search right
|
// search right
|
||||||
//
|
//
|
||||||
@ -1084,7 +1243,7 @@ struct _vaapi_decoder_
|
|||||||
|
|
||||||
VAImage DeintImages[5]; ///< deinterlace image buffers
|
VAImage DeintImages[5]; ///< deinterlace image buffers
|
||||||
|
|
||||||
int PutImage; ///< flag put image can be used
|
int GetPutImage; ///< flag get/put image can be used
|
||||||
VAImage Image[1]; ///< image buffer to update surface
|
VAImage Image[1]; ///< image buffer to update surface
|
||||||
|
|
||||||
struct vaapi_context VaapiContext[1]; ///< ffmpeg VA-API context
|
struct vaapi_context VaapiContext[1]; ///< ffmpeg VA-API context
|
||||||
@ -1301,6 +1460,9 @@ static void VaapiDestroySurfaces(VaapiDecoder * decoder)
|
|||||||
// FIXME surfaces used for output
|
// FIXME surfaces used for output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// forward definition release surface
|
||||||
|
static void VaapiReleaseSurface(VaapiDecoder *, VASurfaceID);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Get a free surface.
|
/// Get a free surface.
|
||||||
///
|
///
|
||||||
@ -1311,25 +1473,41 @@ static void VaapiDestroySurfaces(VaapiDecoder * decoder)
|
|||||||
static VASurfaceID VaapiGetSurface(VaapiDecoder * decoder)
|
static VASurfaceID VaapiGetSurface(VaapiDecoder * decoder)
|
||||||
{
|
{
|
||||||
VASurfaceID surface;
|
VASurfaceID surface;
|
||||||
|
VASurfaceStatus status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!decoder->SurfaceFreeN) {
|
// try to use oldest surface
|
||||||
Error(_("video/vaapi: out of surfaces\n"));
|
|
||||||
return VA_INVALID_ID;
|
|
||||||
}
|
|
||||||
// use oldest surface
|
|
||||||
surface = decoder->SurfacesFree[0];
|
|
||||||
|
|
||||||
decoder->SurfaceFreeN--;
|
|
||||||
for (i = 0; i < decoder->SurfaceFreeN; ++i) {
|
for (i = 0; i < decoder->SurfaceFreeN; ++i) {
|
||||||
decoder->SurfacesFree[i] = decoder->SurfacesFree[i + 1];
|
surface = decoder->SurfacesFree[i];
|
||||||
|
if (vaQuerySurfaceStatus(decoder->VaDisplay, surface, &status)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: vaQuerySurface failed\n"));
|
||||||
|
status = VASurfaceReady;
|
||||||
|
}
|
||||||
|
// surface still in use, try next
|
||||||
|
if (status != VASurfaceReady) {
|
||||||
|
Debug("video/vaapi: surface %#010x not ready: %d\n", surface,
|
||||||
|
status);
|
||||||
|
if (!VaapiBuggyVdpau || i < 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
usleep(1 * 1000);
|
||||||
|
}
|
||||||
|
// copy remaining surfaces down
|
||||||
|
decoder->SurfaceFreeN--;
|
||||||
|
for (; i < decoder->SurfaceFreeN; ++i) {
|
||||||
|
decoder->SurfacesFree[i] = decoder->SurfacesFree[i + 1];
|
||||||
|
}
|
||||||
|
decoder->SurfacesFree[i] = VA_INVALID_ID;
|
||||||
|
|
||||||
|
// save as used
|
||||||
|
decoder->SurfacesUsed[decoder->SurfaceUsedN++] = surface;
|
||||||
|
|
||||||
|
return surface;
|
||||||
}
|
}
|
||||||
decoder->SurfacesFree[i] = VA_INVALID_ID;
|
|
||||||
|
|
||||||
// save as used
|
Error(_("video/vaapi: out of surfaces\n"));
|
||||||
decoder->SurfacesUsed[decoder->SurfaceUsedN++] = surface;
|
return VA_INVALID_ID;
|
||||||
|
|
||||||
return surface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -1351,7 +1529,7 @@ static void VaapiReleaseSurface(VaapiDecoder * decoder, VASurfaceID surface)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Error(_("video/vaapi: release surface %#x, which is not in use\n"),
|
Error(_("video/vaapi: release surface %#010x, which is not in use\n"),
|
||||||
surface);
|
surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1495,7 +1673,7 @@ static VaapiDecoder *VaapiNewDecoder(void)
|
|||||||
decoder->OutputWidth = VideoWindowWidth;
|
decoder->OutputWidth = VideoWindowWidth;
|
||||||
decoder->OutputHeight = VideoWindowHeight;
|
decoder->OutputHeight = VideoWindowHeight;
|
||||||
|
|
||||||
decoder->PutImage = !VaapiBuggyIntel;
|
decoder->GetPutImage = !VaapiBuggyIntel;
|
||||||
|
|
||||||
VaapiDecoders[VaapiDecoderN++] = decoder;
|
VaapiDecoders[VaapiDecoderN++] = decoder;
|
||||||
|
|
||||||
@ -1746,64 +1924,15 @@ static void VaapiExit(void)
|
|||||||
///
|
///
|
||||||
/// @param decoder VA-API decoder
|
/// @param decoder VA-API decoder
|
||||||
///
|
///
|
||||||
/// @todo combine VaapiUpdateOutput and VdpauUpdateOutput
|
|
||||||
///
|
|
||||||
static void VaapiUpdateOutput(VaapiDecoder * decoder)
|
static void VaapiUpdateOutput(VaapiDecoder * decoder)
|
||||||
{
|
{
|
||||||
AVRational input_aspect_ratio;
|
VideoUpdateOutput(decoder->InputAspect, decoder->InputWidth,
|
||||||
AVRational display_aspect_ratio;
|
decoder->InputHeight, &decoder->OutputX, &decoder->OutputY,
|
||||||
|
&decoder->OutputWidth, &decoder->OutputHeight, &decoder->CropX,
|
||||||
input_aspect_ratio = decoder->InputAspect;
|
&decoder->CropY, &decoder->CropWidth, &decoder->CropHeight);
|
||||||
if (!input_aspect_ratio.num || !input_aspect_ratio.den) {
|
|
||||||
input_aspect_ratio.num = 1;
|
|
||||||
input_aspect_ratio.den = 1;
|
|
||||||
Debug(3, "video: aspect defaults to %d:%d\n", input_aspect_ratio.num,
|
|
||||||
input_aspect_ratio.den);
|
|
||||||
}
|
|
||||||
|
|
||||||
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
|
|
||||||
decoder->InputWidth * input_aspect_ratio.num,
|
|
||||||
decoder->InputHeight * input_aspect_ratio.den, 1024 * 1024);
|
|
||||||
|
|
||||||
// InputWidth/Height can be zero = uninitialized
|
|
||||||
if (!display_aspect_ratio.num || !display_aspect_ratio.den) {
|
|
||||||
display_aspect_ratio.num = 1;
|
|
||||||
display_aspect_ratio.den = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug(3, "video: aspect %d:%d\n", display_aspect_ratio.num,
|
|
||||||
display_aspect_ratio.den);
|
|
||||||
|
|
||||||
// FIXME: store different positions for the ratios
|
|
||||||
if (display_aspect_ratio.num == 4 && display_aspect_ratio.den == 3) {
|
|
||||||
switch (Video4to3ZoomMode) {
|
|
||||||
case VideoNormal:
|
|
||||||
case VideoStretch:
|
|
||||||
case VideoZoom:
|
|
||||||
case VideoAnamorphic:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// FIXME: this overwrites user choosen output position
|
|
||||||
decoder->OutputX = 0;
|
|
||||||
decoder->OutputY = 0;
|
|
||||||
decoder->OutputWidth = (VideoWindowHeight * display_aspect_ratio.num)
|
|
||||||
/ display_aspect_ratio.den;
|
|
||||||
decoder->OutputHeight = (VideoWindowWidth * display_aspect_ratio.den)
|
|
||||||
/ display_aspect_ratio.num;
|
|
||||||
if ((unsigned)decoder->OutputWidth > VideoWindowWidth) {
|
|
||||||
decoder->OutputWidth = VideoWindowWidth;
|
|
||||||
decoder->OutputY = (VideoWindowHeight - decoder->OutputHeight) / 2;
|
|
||||||
} else if ((unsigned)decoder->OutputHeight > VideoWindowHeight) {
|
|
||||||
decoder->OutputHeight = VideoWindowHeight;
|
|
||||||
decoder->OutputX = (VideoWindowWidth - decoder->OutputWidth) / 2;
|
|
||||||
}
|
|
||||||
Debug(3, "video: aspect output %dx%d+%d+%d\n", decoder->OutputWidth,
|
|
||||||
decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
|
|
||||||
|
|
||||||
#ifdef USE_AUTOCROP
|
#ifdef USE_AUTOCROP
|
||||||
decoder->AutoCrop->State = 0;
|
decoder->AutoCrop->State = 0;
|
||||||
decoder->AutoCrop->Count = 0;
|
decoder->AutoCrop->Count = AutoCropDelay;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2027,12 +2156,7 @@ static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
|
|||||||
goto slow_path;
|
goto slow_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder->CropX = 0;
|
decoder->PixFmt = *fmt_idx;
|
||||||
decoder->CropY = VideoSkipLines;
|
|
||||||
decoder->CropWidth = video_ctx->width;
|
|
||||||
decoder->CropHeight = video_ctx->height - VideoSkipLines * 2;
|
|
||||||
|
|
||||||
decoder->PixFmt = video_ctx->pix_fmt;
|
|
||||||
decoder->InputWidth = video_ctx->width;
|
decoder->InputWidth = video_ctx->width;
|
||||||
decoder->InputHeight = video_ctx->height;
|
decoder->InputHeight = video_ctx->height;
|
||||||
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
||||||
@ -2146,7 +2270,7 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
|
|||||||
}
|
}
|
||||||
if (status != VASurfaceReady) {
|
if (status != VASurfaceReady) {
|
||||||
Warning(_
|
Warning(_
|
||||||
("video/vaapi: surface %#x not ready: still displayed %d\n"),
|
("video/vaapi: surface %#010x not ready: still displayed %d\n"),
|
||||||
surface, status);
|
surface, status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2359,7 +2483,8 @@ static void VaapiSetup(VaapiDecoder * decoder,
|
|||||||
VaapiFindImageFormat(decoder, video_ctx->pix_fmt, format);
|
VaapiFindImageFormat(decoder, video_ctx->pix_fmt, format);
|
||||||
|
|
||||||
// FIXME: this image is only needed for software decoder and auto-crop
|
// FIXME: this image is only needed for software decoder and auto-crop
|
||||||
if (vaCreateImage(VaDisplay, format, width, height,
|
if (decoder->GetPutImage
|
||||||
|
&& vaCreateImage(VaDisplay, format, width, height,
|
||||||
decoder->Image) != VA_STATUS_SUCCESS) {
|
decoder->Image) != VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't create image!\n"));
|
Error(_("video/vaapi: can't create image!\n"));
|
||||||
}
|
}
|
||||||
@ -2417,7 +2542,8 @@ static void VaapiAutoCrop(VaapiDecoder * decoder)
|
|||||||
width = decoder->InputWidth;
|
width = decoder->InputWidth;
|
||||||
height = decoder->InputHeight;
|
height = decoder->InputHeight;
|
||||||
|
|
||||||
if (decoder->Image->image_id == VA_INVALID_ID) {
|
again:
|
||||||
|
if (decoder->GetPutImage && decoder->Image->image_id == VA_INVALID_ID) {
|
||||||
VAImageFormat format[1];
|
VAImageFormat format[1];
|
||||||
|
|
||||||
Debug(3, "video/vaapi: download image not available\n");
|
Debug(3, "video/vaapi: download image not available\n");
|
||||||
@ -2439,7 +2565,16 @@ static void VaapiAutoCrop(VaapiDecoder * decoder)
|
|||||||
1) % VIDEO_SURFACES_MAX];
|
1) % VIDEO_SURFACES_MAX];
|
||||||
|
|
||||||
// Copy data from frame to image
|
// Copy data from frame to image
|
||||||
if ((i = vaGetImage(decoder->VaDisplay, surface, 0, 0, decoder->InputWidth,
|
if (!decoder->GetPutImage
|
||||||
|
&& vaDeriveImage(decoder->VaDisplay, surface,
|
||||||
|
decoder->Image) != VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: vaDeriveImage failed\n"));
|
||||||
|
decoder->GetPutImage = 1;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
if (decoder->GetPutImage
|
||||||
|
&& (i =
|
||||||
|
vaGetImage(decoder->VaDisplay, surface, 0, 0, decoder->InputWidth,
|
||||||
decoder->InputHeight,
|
decoder->InputHeight,
|
||||||
decoder->Image->image_id)) != VA_STATUS_SUCCESS) {
|
decoder->Image->image_id)) != VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't get auto-crop image %d\n"), i);
|
Error(_("video/vaapi: can't get auto-crop image %d\n"), i);
|
||||||
@ -2462,6 +2597,13 @@ static void VaapiAutoCrop(VaapiDecoder * decoder)
|
|||||||
if (vaUnmapBuffer(VaDisplay, decoder->Image->buf) != VA_STATUS_SUCCESS) {
|
if (vaUnmapBuffer(VaDisplay, decoder->Image->buf) != VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't unmap auto-crop image!\n"));
|
Error(_("video/vaapi: can't unmap auto-crop image!\n"));
|
||||||
}
|
}
|
||||||
|
if (!decoder->GetPutImage) {
|
||||||
|
if (vaDestroyImage(VaDisplay, decoder->Image->image_id)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't destroy image!\n"));
|
||||||
|
}
|
||||||
|
decoder->Image->image_id = VA_INVALID_ID;
|
||||||
|
}
|
||||||
// FIXME: this a copy of vdpau, combine the two same things
|
// FIXME: this a copy of vdpau, combine the two same things
|
||||||
|
|
||||||
// ignore black frames
|
// ignore black frames
|
||||||
@ -2515,9 +2657,7 @@ static void VaapiAutoCrop(VaapiDecoder * decoder)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder->AutoCrop->Count = 0;
|
|
||||||
decoder->AutoCrop->State = next_state;
|
decoder->AutoCrop->State = next_state;
|
||||||
|
|
||||||
if (next_state) {
|
if (next_state) {
|
||||||
decoder->CropX = 0;
|
decoder->CropX = 0;
|
||||||
decoder->CropY = (next_state == 16 ? crop16 : crop14) + VideoSkipLines;
|
decoder->CropY = (next_state == 16 ? crop16 : crop14) + VideoSkipLines;
|
||||||
@ -2526,6 +2666,7 @@ static void VaapiAutoCrop(VaapiDecoder * decoder)
|
|||||||
|
|
||||||
// FIXME: this overwrites user choosen output position
|
// FIXME: this overwrites user choosen output position
|
||||||
// FIXME: resize kills the auto crop values
|
// FIXME: resize kills the auto crop values
|
||||||
|
// FIXME: support other 4:3 zoom modes
|
||||||
decoder->OutputX = 0;
|
decoder->OutputX = 0;
|
||||||
decoder->OutputY = 0;
|
decoder->OutputY = 0;
|
||||||
decoder->OutputWidth = (VideoWindowHeight * next_state) / 9;
|
decoder->OutputWidth = (VideoWindowHeight * next_state) / 9;
|
||||||
@ -2541,13 +2682,10 @@ static void VaapiAutoCrop(VaapiDecoder * decoder)
|
|||||||
decoder->InputWidth, decoder->InputHeight, decoder->OutputWidth,
|
decoder->InputWidth, decoder->InputHeight, decoder->OutputWidth,
|
||||||
decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
|
decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
|
||||||
} else {
|
} else {
|
||||||
decoder->CropX = 0;
|
// sets AutoCrop->Count
|
||||||
decoder->CropY = VideoSkipLines;
|
|
||||||
decoder->CropWidth = decoder->InputWidth;
|
|
||||||
decoder->CropHeight = decoder->InputHeight - VideoSkipLines * 2;
|
|
||||||
|
|
||||||
VaapiUpdateOutput(decoder);
|
VaapiUpdateOutput(decoder);
|
||||||
}
|
}
|
||||||
|
decoder->AutoCrop->Count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -2648,7 +2786,7 @@ static void VaapiQueueSurface(VaapiDecoder * decoder, VASurfaceID surface,
|
|||||||
}
|
}
|
||||||
if (status != VASurfaceReady) {
|
if (status != VASurfaceReady) {
|
||||||
Warning(_
|
Warning(_
|
||||||
("video/vaapi: surface %#x not ready: still displayed %d\n"),
|
("video/vaapi: surface %#010x not ready: still displayed %d\n"),
|
||||||
old, status);
|
old, status);
|
||||||
if (0
|
if (0
|
||||||
&& vaSyncSurface(decoder->VaDisplay,
|
&& vaSyncSurface(decoder->VaDisplay,
|
||||||
@ -3344,7 +3482,7 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
surface = (unsigned)(size_t) frame->data[3];
|
surface = (unsigned)(size_t) frame->data[3];
|
||||||
Debug(4, "video/vaapi: hw render hw surface %#x\n", surface);
|
Debug(4, "video/vaapi: hw render hw surface %#010x\n", surface);
|
||||||
|
|
||||||
if (interlaced
|
if (interlaced
|
||||||
&& VideoDeinterlace[decoder->Resolution] ==
|
&& VideoDeinterlace[decoder->Resolution] ==
|
||||||
@ -3379,11 +3517,6 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
|
|||||||
Debug(3,
|
Debug(3,
|
||||||
"video/vaapi: stream <-> surface size/interlace mismatch\n");
|
"video/vaapi: stream <-> surface size/interlace mismatch\n");
|
||||||
|
|
||||||
decoder->CropX = 0;
|
|
||||||
decoder->CropY = VideoSkipLines;
|
|
||||||
decoder->CropWidth = width;
|
|
||||||
decoder->CropHeight = height - VideoSkipLines * 2;
|
|
||||||
|
|
||||||
decoder->PixFmt = video_ctx->pix_fmt;
|
decoder->PixFmt = video_ctx->pix_fmt;
|
||||||
// FIXME: aspect done above!
|
// FIXME: aspect done above!
|
||||||
decoder->InputWidth = width;
|
decoder->InputWidth = width;
|
||||||
@ -3393,17 +3526,25 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
|
|||||||
VaapiUpdateOutput(decoder);
|
VaapiUpdateOutput(decoder);
|
||||||
}
|
}
|
||||||
// FIXME: Need to insert software deinterlace here
|
// FIXME: Need to insert software deinterlace here
|
||||||
// FIXME: can/must insert auto-crop here
|
// FIXME: can/must insert auto-crop here (is done after upload)
|
||||||
|
|
||||||
// get a free surface and upload the image
|
// get a free surface and upload the image
|
||||||
surface = VaapiGetSurface(decoder);
|
surface = VaapiGetSurface(decoder);
|
||||||
Debug(4, "video/vaapi: video surface %#010x displayed\n", surface);
|
Debug(4, "video/vaapi: video surface %#010x displayed\n", surface);
|
||||||
|
|
||||||
if (!decoder->PutImage
|
if (!decoder->GetPutImage
|
||||||
&& vaDeriveImage(decoder->VaDisplay, surface,
|
&& vaDeriveImage(decoder->VaDisplay, surface,
|
||||||
decoder->Image) != VA_STATUS_SUCCESS) {
|
decoder->Image) != VA_STATUS_SUCCESS) {
|
||||||
|
VAImageFormat format[1];
|
||||||
|
|
||||||
Error(_("video/vaapi: vaDeriveImage failed\n"));
|
Error(_("video/vaapi: vaDeriveImage failed\n"));
|
||||||
decoder->PutImage = 1;
|
|
||||||
|
decoder->GetPutImage = 1;
|
||||||
|
VaapiFindImageFormat(decoder, video_ctx->pix_fmt, format);
|
||||||
|
if (vaCreateImage(VaDisplay, format, width, height,
|
||||||
|
decoder->Image) != VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't create image!\n"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Copy data from frame to image
|
// Copy data from frame to image
|
||||||
@ -3468,7 +3609,7 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
|
|||||||
Debug(4, "video/vaapi: buffer %dx%d <- %dx%d\n", decoder->Image->width,
|
Debug(4, "video/vaapi: buffer %dx%d <- %dx%d\n", decoder->Image->width,
|
||||||
decoder->Image->height, width, height);
|
decoder->Image->height, width, height);
|
||||||
|
|
||||||
if (decoder->PutImage
|
if (decoder->GetPutImage
|
||||||
&& (i =
|
&& (i =
|
||||||
vaPutImage(VaDisplay, surface, decoder->Image->image_id, 0, 0,
|
vaPutImage(VaDisplay, surface, decoder->Image->image_id, 0, 0,
|
||||||
width, height, 0, 0, width,
|
width, height, 0, 0, width,
|
||||||
@ -3476,10 +3617,12 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
|
|||||||
Error(_("video/vaapi: can't put image err:%d!\n"), i);
|
Error(_("video/vaapi: can't put image err:%d!\n"), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!decoder->PutImage
|
if (!decoder->GetPutImage) {
|
||||||
&& vaDestroyImage(VaDisplay,
|
if (vaDestroyImage(VaDisplay, decoder->Image->image_id)
|
||||||
decoder->Image->image_id) != VA_STATUS_SUCCESS) {
|
!= VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't destroy image!\n"));
|
Error(_("video/vaapi: can't destroy image!\n"));
|
||||||
|
}
|
||||||
|
decoder->Image->image_id = VA_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
VaapiQueueSurface(decoder, surface, 1);
|
VaapiQueueSurface(decoder, surface, 1);
|
||||||
@ -4427,7 +4570,7 @@ static void VdpauReleaseSurface(VdpauDecoder * decoder, unsigned surface)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Error(_("video/vdpau: release surface %#x, which is not in use\n"),
|
Error(_("video/vdpau: release surface %#08x, which is not in use\n"),
|
||||||
surface);
|
surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5371,67 +5514,15 @@ static void VdpauExit(void)
|
|||||||
///
|
///
|
||||||
/// @param decoder VDPAU hw decoder
|
/// @param decoder VDPAU hw decoder
|
||||||
///
|
///
|
||||||
/// @todo combine VaapiUpdateOutput and VdpauUpdateOutput
|
|
||||||
///
|
|
||||||
static void VdpauUpdateOutput(VdpauDecoder * decoder)
|
static void VdpauUpdateOutput(VdpauDecoder * decoder)
|
||||||
{
|
{
|
||||||
AVRational input_aspect_ratio;
|
VideoUpdateOutput(decoder->InputAspect, decoder->InputWidth,
|
||||||
AVRational display_aspect_ratio;
|
decoder->InputHeight, &decoder->OutputX, &decoder->OutputY,
|
||||||
|
&decoder->OutputWidth, &decoder->OutputHeight, &decoder->CropX,
|
||||||
input_aspect_ratio = decoder->InputAspect;
|
&decoder->CropY, &decoder->CropWidth, &decoder->CropHeight);
|
||||||
Debug(3, "video: input aspect %d:%d\n", input_aspect_ratio.num,
|
|
||||||
input_aspect_ratio.den);
|
|
||||||
if (!input_aspect_ratio.num || !input_aspect_ratio.den) {
|
|
||||||
input_aspect_ratio.num = 1;
|
|
||||||
input_aspect_ratio.den = 1;
|
|
||||||
Debug(3, "video: aspect defaults to %d:%d\n", input_aspect_ratio.num,
|
|
||||||
input_aspect_ratio.den);
|
|
||||||
}
|
|
||||||
|
|
||||||
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
|
|
||||||
decoder->InputWidth * input_aspect_ratio.num,
|
|
||||||
decoder->InputHeight * input_aspect_ratio.den, 1024 * 1024);
|
|
||||||
|
|
||||||
// InputWidth/Height can be zero = uninitialized
|
|
||||||
if (!display_aspect_ratio.num || !display_aspect_ratio.den) {
|
|
||||||
display_aspect_ratio.num = 1;
|
|
||||||
display_aspect_ratio.den = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug(3, "video: aspect %d:%d\n", display_aspect_ratio.num,
|
|
||||||
display_aspect_ratio.den);
|
|
||||||
|
|
||||||
// FIXME: store different positions for the ratios
|
|
||||||
if (display_aspect_ratio.num == 4 && display_aspect_ratio.den == 3) {
|
|
||||||
switch (Video4to3ZoomMode) {
|
|
||||||
case VideoNormal:
|
|
||||||
case VideoStretch:
|
|
||||||
case VideoZoom:
|
|
||||||
case VideoAnamorphic:
|
|
||||||
// AutoCrop
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// FIXME: this overwrites user choosen output position
|
|
||||||
decoder->OutputX = 0;
|
|
||||||
decoder->OutputY = 0;
|
|
||||||
decoder->OutputWidth = (VideoWindowHeight * display_aspect_ratio.num)
|
|
||||||
/ display_aspect_ratio.den;
|
|
||||||
decoder->OutputHeight = (VideoWindowWidth * display_aspect_ratio.den)
|
|
||||||
/ display_aspect_ratio.num;
|
|
||||||
if ((unsigned)decoder->OutputWidth > VideoWindowWidth) {
|
|
||||||
decoder->OutputWidth = VideoWindowWidth;
|
|
||||||
decoder->OutputY = (VideoWindowHeight - decoder->OutputHeight) / 2;
|
|
||||||
} else if ((unsigned)decoder->OutputHeight > VideoWindowHeight) {
|
|
||||||
decoder->OutputHeight = VideoWindowHeight;
|
|
||||||
decoder->OutputX = (VideoWindowWidth - decoder->OutputWidth) / 2;
|
|
||||||
}
|
|
||||||
Debug(3, "video: aspect output %dx%d+%d+%d\n", decoder->OutputWidth,
|
|
||||||
decoder->OutputHeight, decoder->OutputX, decoder->OutputY);
|
|
||||||
|
|
||||||
#ifdef USE_AUTOCROP
|
#ifdef USE_AUTOCROP
|
||||||
decoder->AutoCrop->State = 0;
|
decoder->AutoCrop->State = 0;
|
||||||
decoder->AutoCrop->Count = 0;
|
decoder->AutoCrop->Count = AutoCropDelay;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5645,7 +5736,7 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder,
|
|||||||
decoder->CropWidth = video_ctx->width;
|
decoder->CropWidth = video_ctx->width;
|
||||||
decoder->CropHeight = video_ctx->height - VideoSkipLines * 2;
|
decoder->CropHeight = video_ctx->height - VideoSkipLines * 2;
|
||||||
|
|
||||||
decoder->PixFmt = video_ctx->pix_fmt;
|
decoder->PixFmt = *fmt_idx;
|
||||||
decoder->InputWidth = video_ctx->width;
|
decoder->InputWidth = video_ctx->width;
|
||||||
decoder->InputHeight = video_ctx->height;
|
decoder->InputHeight = video_ctx->height;
|
||||||
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
||||||
@ -5937,9 +6028,7 @@ static void VdpauAutoCrop(VdpauDecoder * decoder)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder->AutoCrop->Count = 0;
|
|
||||||
decoder->AutoCrop->State = next_state;
|
decoder->AutoCrop->State = next_state;
|
||||||
|
|
||||||
if (next_state) {
|
if (next_state) {
|
||||||
decoder->CropX = 0;
|
decoder->CropX = 0;
|
||||||
decoder->CropY = (next_state == 16 ? crop16 : crop14) + VideoSkipLines;
|
decoder->CropY = (next_state == 16 ? crop16 : crop14) + VideoSkipLines;
|
||||||
@ -5948,6 +6037,7 @@ static void VdpauAutoCrop(VdpauDecoder * decoder)
|
|||||||
|
|
||||||
// FIXME: this overwrites user choosen output position
|
// FIXME: this overwrites user choosen output position
|
||||||
// FIXME: resize kills the auto crop values
|
// FIXME: resize kills the auto crop values
|
||||||
|
// FIXME: support other 4:3 zoom modes
|
||||||
decoder->OutputX = 0;
|
decoder->OutputX = 0;
|
||||||
decoder->OutputY = 0;
|
decoder->OutputY = 0;
|
||||||
decoder->OutputWidth = (VideoWindowHeight * next_state) / 9;
|
decoder->OutputWidth = (VideoWindowHeight * next_state) / 9;
|
||||||
@ -5968,8 +6058,10 @@ static void VdpauAutoCrop(VdpauDecoder * decoder)
|
|||||||
decoder->CropWidth = decoder->InputWidth;
|
decoder->CropWidth = decoder->InputWidth;
|
||||||
decoder->CropHeight = decoder->InputHeight - VideoSkipLines * 2;
|
decoder->CropHeight = decoder->InputHeight - VideoSkipLines * 2;
|
||||||
|
|
||||||
|
// sets AutoCrop->Count
|
||||||
VdpauUpdateOutput(decoder);
|
VdpauUpdateOutput(decoder);
|
||||||
}
|
}
|
||||||
|
decoder->AutoCrop->Count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -6064,7 +6156,7 @@ static void VdpauQueueSurface(VdpauDecoder * decoder, VdpVideoSurface surface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug(4, "video/vdpau: yy video surface %#x@%d ready\n", surface,
|
Debug(4, "video/vdpau: yy video surface %#08x@%d ready\n", surface,
|
||||||
decoder->SurfaceWrite);
|
decoder->SurfaceWrite);
|
||||||
|
|
||||||
decoder->SurfacesRb[decoder->SurfaceWrite] = surface;
|
decoder->SurfacesRb[decoder->SurfaceWrite] = surface;
|
||||||
@ -6145,7 +6237,7 @@ static void VdpauRenderFrame(VdpauDecoder * decoder,
|
|||||||
|
|
||||||
vrs = (struct vdpau_render_state *)frame->data[0];
|
vrs = (struct vdpau_render_state *)frame->data[0];
|
||||||
surface = vrs->surface;
|
surface = vrs->surface;
|
||||||
Debug(4, "video/vdpau: hw render hw surface %#x\n", surface);
|
Debug(4, "video/vdpau: hw render hw surface %#08x\n", surface);
|
||||||
|
|
||||||
if (VideoDeinterlace[decoder->Resolution] == VideoDeinterlaceSoftware
|
if (VideoDeinterlace[decoder->Resolution] == VideoDeinterlaceSoftware
|
||||||
&& interlaced) {
|
&& interlaced) {
|
||||||
@ -6454,7 +6546,7 @@ static void VdpauMixVideo(VdpauDecoder * decoder)
|
|||||||
VdpauGetErrorString(status));
|
VdpauGetErrorString(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug(4, "video/vdpau: yy video surface %#x@%d displayed\n", current,
|
Debug(4, "video/vdpau: yy video surface %#08x@%d displayed\n", current,
|
||||||
decoder->SurfaceRead);
|
decoder->SurfaceRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7822,56 +7914,6 @@ enum PixelFormat Video_get_format(VideoHwDecoder * decoder,
|
|||||||
return fmt[0];
|
return fmt[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// Update video pts.
|
|
||||||
///
|
|
||||||
/// @param pts_p pointer to pts
|
|
||||||
/// @param interlaced interlaced flag (frame isn't right)
|
|
||||||
/// @param frame frame to display
|
|
||||||
///
|
|
||||||
/// @note frame->interlaced_frame can't be used for interlace detection
|
|
||||||
///
|
|
||||||
static void VideoSetPts(int64_t * pts_p, int interlaced, const AVFrame * frame)
|
|
||||||
{
|
|
||||||
int64_t pts;
|
|
||||||
|
|
||||||
// update video clock
|
|
||||||
if ((uint64_t) * pts_p != AV_NOPTS_VALUE) {
|
|
||||||
*pts_p += interlaced ? 40 * 90 : 20 * 90;
|
|
||||||
}
|
|
||||||
//pts = frame->best_effort_timestamp;
|
|
||||||
pts = frame->pkt_pts;
|
|
||||||
if ((uint64_t) pts == AV_NOPTS_VALUE || !pts) {
|
|
||||||
// libav: 0.8pre didn't set pts
|
|
||||||
pts = frame->pkt_dts;
|
|
||||||
}
|
|
||||||
// libav: sets only pkt_dts which can be 0
|
|
||||||
if (pts && (uint64_t) pts != AV_NOPTS_VALUE) {
|
|
||||||
// build a monotonic pts
|
|
||||||
if ((uint64_t) * pts_p != AV_NOPTS_VALUE) {
|
|
||||||
int64_t delta;
|
|
||||||
|
|
||||||
delta = pts - *pts_p;
|
|
||||||
// ignore negative jumps
|
|
||||||
if (delta > -600 * 90 && delta <= -40 * 90) {
|
|
||||||
if (-delta > VideoDeltaPTS) {
|
|
||||||
VideoDeltaPTS = -delta;
|
|
||||||
Debug(4,
|
|
||||||
"video: %#012" PRIx64 "->%#012" PRIx64 " delta+%4"
|
|
||||||
PRId64 " pts\n", *pts_p, pts, pts - *pts_p);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (*pts_p != pts) {
|
|
||||||
Debug(4,
|
|
||||||
"video: %#012" PRIx64 "->%#012" PRIx64 " delta=%4" PRId64
|
|
||||||
" pts\n", *pts_p, pts, pts - *pts_p);
|
|
||||||
*pts_p = pts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Display a ffmpeg frame
|
/// Display a ffmpeg frame
|
||||||
///
|
///
|
||||||
@ -8337,6 +8379,39 @@ void VideoSetVideoMode( __attribute__ ((unused))
|
|||||||
VideoOsdInit();
|
VideoOsdInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Set video display format.
|
||||||
|
///
|
||||||
|
void VideoSetDisplayFormat(int format)
|
||||||
|
{
|
||||||
|
VideoOsdExit();
|
||||||
|
// FIXME: must tell VDR that the OsdSize has been changed!
|
||||||
|
|
||||||
|
if (VideoThread) {
|
||||||
|
VideoThreadLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case 0: // pan&scan (we have no pan&scan)
|
||||||
|
Video4to3ZoomMode = VideoStretch;
|
||||||
|
break;
|
||||||
|
case 1: // letter box
|
||||||
|
Video4to3ZoomMode = VideoNormal;
|
||||||
|
break;
|
||||||
|
case 2: // center cut-out
|
||||||
|
Video4to3ZoomMode = VideoCenterCutOut;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VideoUsedModule) {
|
||||||
|
VideoUsedModule->SetVideoMode();
|
||||||
|
}
|
||||||
|
if (VideoThread) {
|
||||||
|
VideoThreadUnlock();
|
||||||
|
}
|
||||||
|
VideoOsdInit();
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Send fullscreen message to window.
|
/// Send fullscreen message to window.
|
||||||
///
|
///
|
||||||
|
3
video.h
3
video.h
@ -80,6 +80,9 @@ extern void VideoSetOutputPosition(int, int, int, int);
|
|||||||
/// Set video mode.
|
/// Set video mode.
|
||||||
extern void VideoSetVideoMode(int, int, int, int);
|
extern void VideoSetVideoMode(int, int, int, int);
|
||||||
|
|
||||||
|
/// Set display format.
|
||||||
|
extern void VideoSetDisplayFormat(int);
|
||||||
|
|
||||||
/// Set video fullscreen mode.
|
/// Set video fullscreen mode.
|
||||||
extern void VideoSetFullscreen(int);
|
extern void VideoSetFullscreen(int);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user