mirror of
https://github.com/jojo61/vdr-plugin-softhdcuvid.git
synced 2023-10-10 13:37:41 +02:00
YADIF Deinterlacer
This commit is contained in:
parent
8682ab01c4
commit
7e5c6f349d
1
Makefile
1
Makefile
@ -36,6 +36,7 @@ endif
|
|||||||
|
|
||||||
CONFIG := #-DDEBUG #-DOSD_DEBUG # enable debug output+functions
|
CONFIG := #-DDEBUG #-DOSD_DEBUG # enable debug output+functions
|
||||||
CONFIG += -DCUVID # enable CUVID decoder
|
CONFIG += -DCUVID # enable CUVID decoder
|
||||||
|
#CONFIG += -DYADIF # enable yadif_cuda deinterlacer
|
||||||
CONFIG += -DHAVE_GL # needed for mpv libs
|
CONFIG += -DHAVE_GL # needed for mpv libs
|
||||||
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
|
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
|
||||||
|
|
||||||
|
42
codec.c
42
codec.c
@ -61,6 +61,7 @@
|
|||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#include <libavutil/mem.h>
|
#include <libavutil/mem.h>
|
||||||
|
|
||||||
// support old ffmpeg versions <1.0
|
// support old ffmpeg versions <1.0
|
||||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,18,102)
|
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,18,102)
|
||||||
#define AVCodecID CodecID
|
#define AVCodecID CodecID
|
||||||
@ -267,7 +268,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
{
|
{
|
||||||
AVCodec *video_codec;
|
AVCodec *video_codec;
|
||||||
const char *name;
|
const char *name;
|
||||||
int ret;
|
int ret,deint=2;
|
||||||
|
|
||||||
Debug(3, "***************codec: Video Open using video codec ID %#06x (%s)\n", codec_id,
|
Debug(3, "***************codec: Video Open using video codec ID %#06x (%s)\n", codec_id,
|
||||||
avcodec_get_name(codec_id));
|
avcodec_get_name(codec_id));
|
||||||
@ -321,9 +322,12 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
|
|
||||||
pthread_mutex_lock(&CodecLockMutex);
|
pthread_mutex_lock(&CodecLockMutex);
|
||||||
// open codec
|
// open codec
|
||||||
|
#ifdef YADIF
|
||||||
|
deint = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (strcmp(decoder->VideoCodec->long_name,"Nvidia CUVID MPEG2VIDEO decoder") == 0) { // deinterlace for mpeg2 is somehow broken
|
if (strcmp(decoder->VideoCodec->long_name,"Nvidia CUVID MPEG2VIDEO decoder") == 0) { // deinterlace for mpeg2 is somehow broken
|
||||||
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", 2 ,0) < 0) { // adaptive
|
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", deint ,0) < 0) { // adaptive
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option deint to video codec!\n"));
|
Fatal(_("codec: can't set option deint to video codec!\n"));
|
||||||
}
|
}
|
||||||
@ -339,10 +343,16 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strstr(decoder->VideoCodec->long_name,"Nvidia CUVID") != NULL) {
|
else if (strstr(decoder->VideoCodec->long_name,"Nvidia CUVID") != NULL) {
|
||||||
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", 2 ,0) < 0) { // adaptive
|
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", deint ,0) < 0) { // adaptive
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option deint to video codec!\n"));
|
Fatal(_("codec: can't set option deint to video codec!\n"));
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
if (av_opt_set_int(decoder->VideoCtx->priv_data, "surfaces", 13 ,0) < 0) {
|
||||||
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
|
Fatal(_("codec: can't set option surfces to video codec!\n"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (av_opt_set(decoder->VideoCtx->priv_data, "drop_second_field", "false" ,0) < 0) {
|
if (av_opt_set(decoder->VideoCtx->priv_data, "drop_second_field", "false" ,0) < 0) {
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
Fatal(_("codec: can't set option drop 2.field to video codec!\n"));
|
Fatal(_("codec: can't set option drop 2.field to video codec!\n"));
|
||||||
@ -383,6 +393,9 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
|
|
||||||
// reset buggy ffmpeg/libav flag
|
// reset buggy ffmpeg/libav flag
|
||||||
decoder->GetFormatDone = 0;
|
decoder->GetFormatDone = 0;
|
||||||
|
#ifdef YADIF
|
||||||
|
decoder->filter = 0;
|
||||||
|
#endif
|
||||||
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
|
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
|
||||||
decoder->FirstKeyFrame = 1;
|
decoder->FirstKeyFrame = 1;
|
||||||
#endif
|
#endif
|
||||||
@ -458,7 +471,10 @@ void DisplayPts(AVCodecContext * video_ctx, AVFrame * frame)
|
|||||||
** @param avpkt video packet
|
** @param avpkt video packet
|
||||||
*/
|
*/
|
||||||
extern int CuvidTestSurfaces();
|
extern int CuvidTestSurfaces();
|
||||||
|
#ifdef YADIF
|
||||||
|
extern int init_filters(AVCodecContext * dec_ctx,void * decoder,AVFrame *frame);
|
||||||
|
extern int push_filters(AVCodecContext * dec_ctx,void * decoder,AVFrame *frame);
|
||||||
|
#endif
|
||||||
void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
||||||
{
|
{
|
||||||
AVCodecContext *video_ctx;
|
AVCodecContext *video_ctx;
|
||||||
@ -491,6 +507,24 @@ next_part:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (got_frame) { // frame completed
|
if (got_frame) { // frame completed
|
||||||
|
#ifdef YADIF
|
||||||
|
if (decoder->filter ) {
|
||||||
|
if (decoder->filter == 1) {
|
||||||
|
if (init_filters(video_ctx,decoder->HwDecoder,frame) < 0) {
|
||||||
|
Error(_("video: Init of YADIF Filter failed\n"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Debug(3,"Init YADIF ok\n");
|
||||||
|
}
|
||||||
|
decoder->filter = 2;
|
||||||
|
}
|
||||||
|
if (frame->interlaced_frame && decoder->filter == 2 && (frame->height != 720)) { // broken ZDF sends Interlaced flag
|
||||||
|
ret = push_filters(video_ctx,decoder->HwDecoder,frame);
|
||||||
|
av_frame_unref(frame);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
|
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
|
||||||
if (!CodecUsePossibleDefectFrames && decoder->FirstKeyFrame) {
|
if (!CodecUsePossibleDefectFrames && decoder->FirstKeyFrame) {
|
||||||
decoder->FirstKeyFrame++;
|
decoder->FirstKeyFrame++;
|
||||||
|
4
codec.h
4
codec.h
@ -62,7 +62,9 @@ struct _video_decoder_
|
|||||||
int FirstKeyFrame; ///< flag first frame
|
int FirstKeyFrame; ///< flag first frame
|
||||||
//#endif
|
//#endif
|
||||||
AVFrame *Frame; ///< decoded video frame
|
AVFrame *Frame; ///< decoded video frame
|
||||||
|
#ifdef YADIF
|
||||||
|
int filter; // flag for yadif filter
|
||||||
|
#endif
|
||||||
/* hwaccel options */
|
/* hwaccel options */
|
||||||
enum HWAccelID hwaccel_id;
|
enum HWAccelID hwaccel_id;
|
||||||
char *hwaccel_device;
|
char *hwaccel_device;
|
||||||
|
2
misc.h
2
misc.h
@ -160,7 +160,7 @@ static inline uint64_t GetusTicks(void)
|
|||||||
struct timespec tspec;
|
struct timespec tspec;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tspec);
|
clock_gettime(CLOCK_MONOTONIC, &tspec);
|
||||||
return (tspec.tv_sec * 1000000) + (tspec.tv_nsec) ;
|
return (uint64_t) (tspec.tv_sec * 1000000) + (tspec.tv_nsec) ;
|
||||||
#else
|
#else
|
||||||
struct timeval tval;
|
struct timeval tval;
|
||||||
|
|
||||||
|
@ -992,13 +992,12 @@ void cMenuSetupSoft::Create(void)
|
|||||||
static const char *const video_display_formats_16_9[] = {
|
static const char *const video_display_formats_16_9[] = {
|
||||||
"pan&scan", "pillarbox", "center cut-out",
|
"pan&scan", "pillarbox", "center cut-out",
|
||||||
};
|
};
|
||||||
#if 0
|
#ifdef YADIF
|
||||||
static const char *const deinterlace[] = {
|
static const char *const deinterlace[] = {
|
||||||
"Bob", "Weave/None", "Temporal", "TemporalSpatial", "Software Bob",
|
"Cuda", "Yadif",
|
||||||
"Software Spatial",
|
|
||||||
};
|
};
|
||||||
static const char *const deinterlace_short[] = {
|
static const char *const deinterlace_short[] = {
|
||||||
"B", "W", "T", "T+S", "S+B", "S+S",
|
"C", "Y",
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1006,7 +1005,7 @@ void cMenuSetupSoft::Create(void)
|
|||||||
"None", "PCM", "AC-3", "PCM + AC-3"
|
"None", "PCM", "AC-3", "PCM + AC-3"
|
||||||
};
|
};
|
||||||
static const char *const resolution[RESOLUTIONS] = {
|
static const char *const resolution[RESOLUTIONS] = {
|
||||||
"576", "720", "fake 1080", "1080" ,"UHD"
|
"576i", "720p", "fake 1080", "1080" ,"2160p"
|
||||||
};
|
};
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
static const char *const target_colorspace[] = {
|
static const char *const target_colorspace[] = {
|
||||||
@ -1126,12 +1125,15 @@ void cMenuSetupSoft::Create(void)
|
|||||||
Add(CollapsedItem(resolution[i], ResolutionShown[i], msg));
|
Add(CollapsedItem(resolution[i], ResolutionShown[i], msg));
|
||||||
|
|
||||||
if (ResolutionShown[i]) {
|
if (ResolutionShown[i]) {
|
||||||
#if PLACEBO
|
#ifdef PLACEBO
|
||||||
Add(new cMenuEditStraItem(tr("Scaling"), &Scaling[i], scalers, scaling));
|
Add(new cMenuEditStraItem(tr("Scaling"), &Scaling[i], scalers, scaling));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef YADIF
|
||||||
|
if ( i == 0 || i == 2 || i == 3) {
|
||||||
|
Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace[i],2, deinterlace));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
Add(new cMenuEditStraItem(tr("Deinterlace"), &Deinterlace[i],
|
|
||||||
6, deinterlace));
|
|
||||||
Add(new cMenuEditBoolItem(tr("SkipChromaDeinterlace (vdpau)"),
|
Add(new cMenuEditBoolItem(tr("SkipChromaDeinterlace (vdpau)"),
|
||||||
&SkipChromaDeinterlace[i], trVDR("no"), trVDR("yes")));
|
&SkipChromaDeinterlace[i], trVDR("no"), trVDR("yes")));
|
||||||
Add(new cMenuEditBoolItem(tr("Inverse Telecine (vdpau)"),
|
Add(new cMenuEditBoolItem(tr("Inverse Telecine (vdpau)"),
|
||||||
|
@ -2219,7 +2219,7 @@ int PlayVideo3(VideoStream * stream, const uint8_t * data, int size)
|
|||||||
}
|
}
|
||||||
// hard limit buffer full: needed for replay
|
// hard limit buffer full: needed for replay
|
||||||
if (atomic_read(&stream->PacketsFilled) >= VIDEO_PACKET_MAX - 10) {
|
if (atomic_read(&stream->PacketsFilled) >= VIDEO_PACKET_MAX - 10) {
|
||||||
Debug(3, "video: video buffer full\n");
|
// Debug(3, "video: video buffer full\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef USE_SOFTLIMIT
|
#ifdef USE_SOFTLIMIT
|
||||||
@ -2907,7 +2907,7 @@ const char *CommandLineHelp(void)
|
|||||||
" -d display\tdisplay of x11 server (fe. :0.0)\n"
|
" -d display\tdisplay of x11 server (fe. :0.0)\n"
|
||||||
" -f\t\tstart with fullscreen window (only with window manager)\n"
|
" -f\t\tstart with fullscreen window (only with window manager)\n"
|
||||||
" -g geometry\tx11 window geometry wxh+x+y\n"
|
" -g geometry\tx11 window geometry wxh+x+y\n"
|
||||||
" -v device\tvideo driver device (va-api, vdpau, noop)\n"
|
" -v device\tvideo driver device (cuvid)\n"
|
||||||
" -s\t\tstart in suspended mode\n"
|
" -s\t\tstart in suspended mode\n"
|
||||||
" -x\t\tstart x11 server, with -xx try to connect, if this fails\n"
|
" -x\t\tstart x11 server, with -xx try to connect, if this fails\n"
|
||||||
" -X args\tX11 server arguments (f.e. -nocursor)\n"
|
" -X args\tX11 server arguments (f.e. -nocursor)\n"
|
||||||
|
426
video.c
426
video.c
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
//#define PLACEBO
|
//#define PLACEBO
|
||||||
|
|
||||||
|
|
||||||
#define USE_XLIB_XCB ///< use xlib/xcb backend
|
#define USE_XLIB_XCB ///< use xlib/xcb backend
|
||||||
#define noUSE_SCREENSAVER ///< support disable screensaver
|
#define noUSE_SCREENSAVER ///< support disable screensaver
|
||||||
//#define USE_AUTOCROP ///< compile auto-crop support
|
//#define USE_AUTOCROP ///< compile auto-crop support
|
||||||
@ -55,12 +56,23 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define USE_VIDEO_THREAD ///< run decoder in an own thread
|
#define USE_VIDEO_THREAD ///< run decoder in an own thread
|
||||||
//#define USE_VIDEO_THREAD2 ///< run decoder+display in own threads
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <fcntl.h> /* File Control Definitions */
|
||||||
|
#include <termios.h> /* POSIX Terminal Control Definitions */
|
||||||
|
#include <unistd.h> /* UNIX Standard Definitions */
|
||||||
|
#include <errno.h> /* ERROR Number Definitions */
|
||||||
|
#include <sys/ioctl.h> /* ioctl() */
|
||||||
|
//#include <sys/stat.h>
|
||||||
|
//#include <fcntl.h>
|
||||||
|
//#include <stropts.h>
|
||||||
|
//#inclde <asm-generic/ioctls.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -171,7 +183,7 @@ typedef enum
|
|||||||
#include <libswscale/swscale.h>
|
#include <libswscale/swscale.h>
|
||||||
|
|
||||||
// support old ffmpeg versions <1.0
|
// support old ffmpeg versions <1.0
|
||||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,18,102)
|
#if 0 //LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,18,102)
|
||||||
#define AVCodecID CodecID
|
#define AVCodecID CodecID
|
||||||
#define AV_CODEC_ID_H263 CODEC_ID_H263
|
#define AV_CODEC_ID_H263 CODEC_ID_H263
|
||||||
#define AV_CODEC_ID_H264 CODEC_ID_H264
|
#define AV_CODEC_ID_H264 CODEC_ID_H264
|
||||||
@ -185,6 +197,12 @@ typedef enum
|
|||||||
#include <libavutil/pixdesc.h>
|
#include <libavutil/pixdesc.h>
|
||||||
#include <libavutil/hwcontext.h>
|
#include <libavutil/hwcontext.h>
|
||||||
|
|
||||||
|
#ifdef YADIF
|
||||||
|
#include <libavfilter/buffersink.h>
|
||||||
|
#include <libavfilter/buffersrc.h>
|
||||||
|
#include <libavutil/opt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,86,100)
|
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,86,100)
|
||||||
///
|
///
|
||||||
/// ffmpeg version 1.1.1 calls get_format with zero width and height
|
/// ffmpeg version 1.1.1 calls get_format with zero width and height
|
||||||
@ -225,12 +243,8 @@ typedef enum _video_resolutions_
|
|||||||
///
|
///
|
||||||
typedef enum _video_deinterlace_modes_
|
typedef enum _video_deinterlace_modes_
|
||||||
{
|
{
|
||||||
VideoDeinterlaceBob, ///< bob deinterlace
|
VideoDeinterlaceCuda, ///< Cuda build in deinterlace
|
||||||
VideoDeinterlaceWeave, ///< weave deinterlace
|
VideoDeinterlaceYadif, ///< Yadif deinterlace
|
||||||
VideoDeinterlaceTemporal, ///< temporal deinterlace
|
|
||||||
VideoDeinterlaceTemporalSpatial, ///< temporal spatial deinterlace
|
|
||||||
VideoDeinterlaceSoftBob, ///< software bob deinterlace
|
|
||||||
VideoDeinterlaceSoftSpatial, ///< software spatial deinterlace
|
|
||||||
} VideoDeinterlaceModes;
|
} VideoDeinterlaceModes;
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -327,7 +341,7 @@ typedef struct {
|
|||||||
#define CODEC_SURFACES_MAX 16 ///< maximal of surfaces
|
#define CODEC_SURFACES_MAX 16 ///< maximal of surfaces
|
||||||
|
|
||||||
#define VIDEO_SURFACES_MAX 8 ///< video output surfaces for queue
|
#define VIDEO_SURFACES_MAX 8 ///< video output surfaces for queue
|
||||||
#define OUTPUT_SURFACES_MAX 4 ///< output surfaces for flip page
|
//#define OUTPUT_SURFACES_MAX 4 ///< output surfaces for flip page
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Variables
|
// Variables
|
||||||
@ -439,14 +453,14 @@ static pthread_mutex_t VideoLockMutex; ///< video lock mutex
|
|||||||
pthread_mutex_t OSDMutex; ///< OSD update mutex
|
pthread_mutex_t OSDMutex; ///< OSD update mutex
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_VIDEO_THREAD2
|
|
||||||
|
|
||||||
static pthread_t VideoDisplayThread; ///< video decode thread
|
|
||||||
static pthread_cond_t VideoWakeupCond; ///< wakeup condition variable
|
|
||||||
static pthread_mutex_t VideoDisplayMutex; ///< video condition mutex
|
|
||||||
static pthread_mutex_t VideoDisplayLockMutex; ///< video lock mutex
|
|
||||||
|
|
||||||
#endif
|
static pthread_t VideoDisplayThread; ///< video display thread
|
||||||
|
//static pthread_cond_t VideoDisplayWakeupCond; ///< wakeup condition variable
|
||||||
|
//static pthread_mutex_t VideoDisplayMutex; ///< video condition mutex
|
||||||
|
//static pthread_mutex_t VideoDisplayLockMutex; ///< video lock mutex
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int OsdConfigWidth; ///< osd configured width
|
static int OsdConfigWidth; ///< osd configured width
|
||||||
static int OsdConfigHeight; ///< osd configured height
|
static int OsdConfigHeight; ///< osd configured height
|
||||||
@ -554,9 +568,7 @@ static void VideoSetPts(int64_t * pts_p, int interlaced,
|
|||||||
if (delta > -600 * 90 && delta <= -40 * 90) {
|
if (delta > -600 * 90 && delta <= -40 * 90) {
|
||||||
if (-delta > VideoDeltaPTS) {
|
if (-delta > VideoDeltaPTS) {
|
||||||
VideoDeltaPTS = -delta;
|
VideoDeltaPTS = -delta;
|
||||||
Debug(4,
|
Debug(4,"video: %#012" PRIx64 "->%#012" PRIx64 " delta%+4" PRId64 " pts\n", *pts_p, pts, pts - *pts_p);
|
||||||
"video: %#012" PRIx64 "->%#012" PRIx64 " delta%+4"
|
|
||||||
PRId64 " pts\n", *pts_p, pts, pts - *pts_p);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -564,9 +576,7 @@ static void VideoSetPts(int64_t * pts_p, int interlaced,
|
|||||||
AudioVideoReady(pts);
|
AudioVideoReady(pts);
|
||||||
}
|
}
|
||||||
if (*pts_p != pts) {
|
if (*pts_p != pts) {
|
||||||
Debug(4,
|
Debug(4,"video: %#012" PRIx64 "->%#012" PRIx64 " delta=%4" PRId64" pts\n", *pts_p, pts, pts - *pts_p);
|
||||||
"video: %#012" PRIx64 "->%#012" PRIx64 " delta=%4" PRId64
|
|
||||||
" pts\n", *pts_p, pts, pts - *pts_p);
|
|
||||||
*pts_p = pts;
|
*pts_p = pts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1043,7 +1053,7 @@ static void GlxSetupWindow(xcb_window_t window, int width, int height, GLXContex
|
|||||||
unsigned count;
|
unsigned count;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO_
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1658,7 +1668,7 @@ typedef struct _cuvid_decoder_
|
|||||||
CUcontext cuda_ctx;
|
CUcontext cuda_ctx;
|
||||||
|
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
struct pl_image pl_images[CODEC_SURFACES_MAX+1]; // images f<EFBFBD>r Placebo chain
|
struct pl_image pl_images[CODEC_SURFACES_MAX+1]; // images for Placebo chain
|
||||||
const struct pl_tex *pl_tex_in[CODEC_SURFACES_MAX+1][2]; // Textures in image
|
const struct pl_tex *pl_tex_in[CODEC_SURFACES_MAX+1][2]; // Textures in image
|
||||||
const struct pl_buf *pl_buf_Y,*pl_buf_UV; // buffer for Texture upload
|
const struct pl_buf *pl_buf_Y,*pl_buf_UV; // buffer for Texture upload
|
||||||
struct ext_buf ebuf[2]; // for managing vk buffer
|
struct ext_buf ebuf[2]; // for managing vk buffer
|
||||||
@ -1674,6 +1684,12 @@ typedef struct _cuvid_decoder_
|
|||||||
int SyncOnAudio; ///< flag sync to audio
|
int SyncOnAudio; ///< flag sync to audio
|
||||||
int64_t PTS; ///< video PTS clock
|
int64_t PTS; ///< video PTS clock
|
||||||
|
|
||||||
|
#ifdef YADIF
|
||||||
|
AVFilterContext *buffersink_ctx;
|
||||||
|
AVFilterContext *buffersrc_ctx;
|
||||||
|
AVFilterGraph *filter_graph;
|
||||||
|
#endif
|
||||||
|
|
||||||
int LastAVDiff; ///< last audio - video difference
|
int LastAVDiff; ///< last audio - video difference
|
||||||
int SyncCounter; ///< counter to sync frames
|
int SyncCounter; ///< counter to sync frames
|
||||||
int StartCounter; ///< counter for video start
|
int StartCounter; ///< counter for video start
|
||||||
@ -1703,10 +1719,14 @@ typedef struct priv {
|
|||||||
struct pl_render_params r_params;
|
struct pl_render_params r_params;
|
||||||
struct pl_tex final_fbo;
|
struct pl_tex final_fbo;
|
||||||
VkSurfaceKHR pSurface;
|
VkSurfaceKHR pSurface;
|
||||||
|
VkSemaphore sig_in;
|
||||||
}priv;
|
}priv;
|
||||||
static priv *p;
|
static priv *p;
|
||||||
static struct pl_overlay osdoverlay;
|
static struct pl_overlay osdoverlay;
|
||||||
|
|
||||||
|
static int semid;
|
||||||
|
struct itimerval itimer;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -1985,7 +2005,7 @@ static CuvidDecoder *CuvidNewHwDecoder(VideoStream * stream)
|
|||||||
CuvidDecoder *decoder;
|
CuvidDecoder *decoder;
|
||||||
int i=0;
|
int i=0;
|
||||||
|
|
||||||
setenv ("DISPLAY", ":0", 0);
|
// setenv ("DISPLAY", ":0", 0);
|
||||||
|
|
||||||
Debug(3,"Cuvid New HW Decoder\n");
|
Debug(3,"Cuvid New HW Decoder\n");
|
||||||
if ((unsigned)CuvidDecoderN >= sizeof(CuvidDecoders) / sizeof(*CuvidDecoders)) {
|
if ((unsigned)CuvidDecoderN >= sizeof(CuvidDecoders) / sizeof(*CuvidDecoders)) {
|
||||||
@ -2256,7 +2276,7 @@ createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned i
|
|||||||
img->num_overlays = 0;
|
img->num_overlays = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder->pl_buf_Y = pl_buf_create(p->gpu, &(struct pl_buf_params) { // buffer f<EFBFBD>r Y texture upload
|
decoder->pl_buf_Y = pl_buf_create(p->gpu, &(struct pl_buf_params) { // buffer for Y texture upload
|
||||||
.type = PL_BUF_TEX_TRANSFER,
|
.type = PL_BUF_TEX_TRANSFER,
|
||||||
.size = size_x * size_y * size,
|
.size = size_x * size_y * size,
|
||||||
.host_mapped = false,
|
.host_mapped = false,
|
||||||
@ -2265,9 +2285,8 @@ createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned i
|
|||||||
.handle_type = PL_HANDLE_FD,
|
.handle_type = PL_HANDLE_FD,
|
||||||
});
|
});
|
||||||
decoder->ebuf[0].fd = dup(decoder->pl_buf_Y->shared_mem.handle.fd); // dup fd
|
decoder->ebuf[0].fd = dup(decoder->pl_buf_Y->shared_mem.handle.fd); // dup fd
|
||||||
// printf("Y Offset %d Size %d FD %d\n",decoder->pl_buf_Y->handle_offset,decoder->pl_buf_Y->handles.size,decoder->pl_buf_Y->handles.fd);
|
|
||||||
|
|
||||||
decoder->pl_buf_UV = pl_buf_create(p->gpu, &(struct pl_buf_params) { // buffer f<EFBFBD>r UV texture upload
|
decoder->pl_buf_UV = pl_buf_create(p->gpu, &(struct pl_buf_params) { // buffer for UV texture upload
|
||||||
.type = PL_BUF_TEX_TRANSFER,
|
.type = PL_BUF_TEX_TRANSFER,
|
||||||
.size = size_x * size_y * size / 2,
|
.size = size_x * size_y * size / 2,
|
||||||
.host_mapped = false,
|
.host_mapped = false,
|
||||||
@ -2277,8 +2296,6 @@ createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned i
|
|||||||
});
|
});
|
||||||
decoder->ebuf[1].fd = dup(decoder->pl_buf_UV->shared_mem.handle.fd); // dup fd
|
decoder->ebuf[1].fd = dup(decoder->pl_buf_UV->shared_mem.handle.fd); // dup fd
|
||||||
|
|
||||||
// printf("UV Offset %d Size %d FD %d\n",decoder->pl_buf_UV->handle_offset,decoder->pl_buf_UV->handles.size,decoder->pl_buf_UV->handles.fd);
|
|
||||||
|
|
||||||
CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
|
CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = {
|
||||||
.type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
|
.type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD,
|
||||||
.handle.fd = decoder->ebuf[0].fd,
|
.handle.fd = decoder->ebuf[0].fd,
|
||||||
@ -2309,7 +2326,6 @@ createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned i
|
|||||||
};
|
};
|
||||||
checkCudaErrors(cuExternalMemoryGetMappedBuffer(&decoder->ebuf[1].buf, decoder->ebuf[1].mem, &buf_desc1)); // get pointer
|
checkCudaErrors(cuExternalMemoryGetMappedBuffer(&decoder->ebuf[1].buf, decoder->ebuf[1].mem, &buf_desc1)); // get pointer
|
||||||
|
|
||||||
//printf("generate textures %d %d\n",size_x,size_y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2468,6 +2484,145 @@ static unsigned CuvidGetVideoSurface(CuvidDecoder * decoder,
|
|||||||
return CuvidGetVideoSurface0(decoder);
|
return CuvidGetVideoSurface0(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef YADIF
|
||||||
|
static void CuvidSyncRenderFrame(CuvidDecoder * decoder,
|
||||||
|
const AVCodecContext * video_ctx, const AVFrame * frame);
|
||||||
|
|
||||||
|
int push_filters(AVCodecContext * dec_ctx,CuvidDecoder * decoder,AVFrame *frame) {
|
||||||
|
int ret;
|
||||||
|
AVFrame *filt_frame = av_frame_alloc();
|
||||||
|
|
||||||
|
// frame->pts = frame->best_effort_timestamp;
|
||||||
|
|
||||||
|
/* push the decoded frame into the filtergraph */
|
||||||
|
if (av_buffersrc_add_frame_flags(decoder->buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("Interlaced %d tff %d\n",frame->interlaced_frame,frame->top_field_first);
|
||||||
|
/* pull filtered frames from the filtergraph */
|
||||||
|
while ((ret = av_buffersink_get_frame(decoder->buffersink_ctx, filt_frame)) >= 0) {
|
||||||
|
// filt_frame->pts = frame->pts; // Restore orginal pts
|
||||||
|
// frame->pts += 20 * 90; // prepare for next frame
|
||||||
|
filt_frame->pts /= 2;
|
||||||
|
// Debug(3,"video:new %#012" PRIx64 " old %#012" PRIx64 "\n",filt_frame->pts,frame->pts);
|
||||||
|
CuvidSyncRenderFrame(decoder, dec_ctx, filt_frame);
|
||||||
|
av_frame_unref(filt_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
av_frame_free(&filt_frame);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int init_filters(AVCodecContext * dec_ctx,CuvidDecoder * decoder,AVFrame *frame)
|
||||||
|
{
|
||||||
|
const char *filters_descr = "yadif_cuda=1:0:1"; // mode=send_field,parity=tff,deint=interlaced";
|
||||||
|
char args[512];
|
||||||
|
int ret = 0;
|
||||||
|
const AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||||
|
const AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
||||||
|
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||||
|
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||||
|
AVBufferSrcParameters *src_params;
|
||||||
|
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE };
|
||||||
|
|
||||||
|
if (decoder->filter_graph)
|
||||||
|
avfilter_graph_free(&decoder->filter_graph);
|
||||||
|
|
||||||
|
decoder->filter_graph = avfilter_graph_alloc();
|
||||||
|
if (!outputs || !inputs || !decoder->filter_graph) {
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buffer video source: the decoded frames from the decoder will be inserted here. */
|
||||||
|
snprintf(args, sizeof(args),
|
||||||
|
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
|
||||||
|
dec_ctx->width, dec_ctx->height, AV_PIX_FMT_CUDA,
|
||||||
|
1, 90000,
|
||||||
|
dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
|
||||||
|
|
||||||
|
ret = avfilter_graph_create_filter(&decoder->buffersrc_ctx, buffersrc, "in",
|
||||||
|
args, NULL, decoder->filter_graph);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
src_params = av_buffersrc_parameters_alloc();
|
||||||
|
src_params->hw_frames_ctx = frame->hw_frames_ctx;
|
||||||
|
src_params->format = AV_PIX_FMT_CUDA;
|
||||||
|
src_params->time_base.num = 1;
|
||||||
|
src_params->time_base.den = 90000;
|
||||||
|
src_params->width = dec_ctx->width;
|
||||||
|
src_params->height = dec_ctx->height;
|
||||||
|
src_params->frame_rate.num = 50;
|
||||||
|
src_params->frame_rate.den = 1;
|
||||||
|
src_params->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
|
||||||
|
|
||||||
|
//printf("width %d height %d hw_frames_ctx %p\n",dec_ctx->width,dec_ctx->height ,frame->hw_frames_ctx);
|
||||||
|
ret = av_buffersrc_parameters_set(decoder->buffersrc_ctx, src_params);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Cannot set hw_frames_ctx to src\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
/* buffer video sink: to terminate the filter chain. */
|
||||||
|
ret = avfilter_graph_create_filter(&decoder->buffersink_ctx, buffersink, "out",
|
||||||
|
NULL, NULL, decoder->filter_graph);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = av_opt_set_int_list(decoder->buffersink_ctx, "pix_fmts", pix_fmts,
|
||||||
|
AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the endpoints for the filter graph. The filter_graph will
|
||||||
|
* be linked to the graph described by filters_descr.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The buffer source output must be connected to the input pad of
|
||||||
|
* the first filter described by filters_descr; since the first
|
||||||
|
* filter input label is not specified, it is set to "in" by
|
||||||
|
* default.
|
||||||
|
*/
|
||||||
|
outputs->name = av_strdup("in");
|
||||||
|
outputs->filter_ctx = decoder->buffersrc_ctx;
|
||||||
|
outputs->pad_idx = 0;
|
||||||
|
outputs->next = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The buffer sink input must be connected to the output pad of
|
||||||
|
* the last filter described by filters_descr; since the last
|
||||||
|
* filter output label is not specified, it is set to "out" by
|
||||||
|
* default.
|
||||||
|
*/
|
||||||
|
inputs->name = av_strdup("out");
|
||||||
|
inputs->filter_ctx = decoder->buffersink_ctx;
|
||||||
|
inputs->pad_idx = 0;
|
||||||
|
inputs->next = NULL;
|
||||||
|
|
||||||
|
if ((ret = avfilter_graph_parse_ptr(decoder->filter_graph, filters_descr,
|
||||||
|
&inputs, &outputs, NULL)) < 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
if ((ret = avfilter_graph_config(decoder->filter_graph, NULL)) < 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
end:
|
||||||
|
avfilter_inout_free(&inputs);
|
||||||
|
avfilter_inout_free(&outputs);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct CUVIDContext {
|
typedef struct CUVIDContext {
|
||||||
@ -2487,7 +2642,7 @@ static enum AVPixelFormat Cuvid_get_format(CuvidDecoder * decoder,
|
|||||||
AVCodecContext * video_ctx, const enum AVPixelFormat *fmt)
|
AVCodecContext * video_ctx, const enum AVPixelFormat *fmt)
|
||||||
{
|
{
|
||||||
const enum AVPixelFormat *fmt_idx;
|
const enum AVPixelFormat *fmt_idx;
|
||||||
int bitformat16 = 0;
|
int bitformat16 = 0,deint=0;
|
||||||
|
|
||||||
VideoDecoder *ist = video_ctx->opaque;
|
VideoDecoder *ist = video_ctx->opaque;
|
||||||
|
|
||||||
@ -2537,9 +2692,10 @@ static enum AVPixelFormat Cuvid_get_format(CuvidDecoder * decoder,
|
|||||||
decoder->PixFmt = AV_PIX_FMT_NV12; // 8 Bit Planar
|
decoder->PixFmt = AV_PIX_FMT_NV12; // 8 Bit Planar
|
||||||
ist->hwaccel_output_format = AV_PIX_FMT_NV12;
|
ist->hwaccel_output_format = AV_PIX_FMT_NV12;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
if ( video_ctx->width != decoder->InputWidth
|
if (1 || video_ctx->width != decoder->InputWidth
|
||||||
|| video_ctx->height != decoder->InputHeight) {
|
|| video_ctx->height != decoder->InputHeight) {
|
||||||
|
|
||||||
CuvidCleanup(decoder);
|
CuvidCleanup(decoder);
|
||||||
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
decoder->InputAspect = video_ctx->sample_aspect_ratio;
|
||||||
decoder->InputWidth = video_ctx->width;
|
decoder->InputWidth = video_ctx->width;
|
||||||
@ -2550,9 +2706,24 @@ static enum AVPixelFormat Cuvid_get_format(CuvidDecoder * decoder,
|
|||||||
CuvidSetupOutput(decoder);
|
CuvidSetupOutput(decoder);
|
||||||
#ifdef PLACEBO // dont show first frame
|
#ifdef PLACEBO // dont show first frame
|
||||||
decoder->newchannel = 1;
|
decoder->newchannel = 1;
|
||||||
|
#endif
|
||||||
|
#ifdef YADIF
|
||||||
|
if (VideoDeinterlace[decoder->Resolution] == VideoDeinterlaceYadif) {
|
||||||
|
deint = 0;
|
||||||
|
ist->filter = 1; // init yadif_cuda
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deint = 2;
|
||||||
|
ist->filter = 0;
|
||||||
|
}
|
||||||
|
CuvidMessage(2,"deint = %s\n",deint==0?"Yadif":"Cuda");
|
||||||
|
if (av_opt_set_int(video_ctx->priv_data, "deint", deint ,0) < 0) { // adaptive
|
||||||
|
Fatal(_("codec: can't set option deint to video codec!\n"));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
CuvidMessage(2,"CUVID Init ok %dx%d\n",video_ctx->width,video_ctx->height);
|
CuvidMessage(2,"CUVID Init ok %dx%d\n",video_ctx->width,video_ctx->height);
|
||||||
ist->active_hwaccel_id = HWACCEL_CUVID;
|
ist->active_hwaccel_id = HWACCEL_CUVID;
|
||||||
ist->hwaccel_pix_fmt = AV_PIX_FMT_CUDA;
|
ist->hwaccel_pix_fmt = AV_PIX_FMT_CUDA;
|
||||||
@ -3161,7 +3332,7 @@ static void CuvidRenderFrame(CuvidDecoder * decoder,
|
|||||||
video_ctx->width != decoder->InputWidth
|
video_ctx->width != decoder->InputWidth
|
||||||
// || decoder->ColorSpace != color
|
// || decoder->ColorSpace != color
|
||||||
|| video_ctx->height != decoder->InputHeight) {
|
|| video_ctx->height != decoder->InputHeight) {
|
||||||
Debug(3,"fmt %02d:%02d width %d:%d hight %d:%d\n",decoder->ColorSpace,frame->colorspace ,video_ctx->width, decoder->InputWidth,video_ctx->height, decoder->InputHeight);
|
//Debug(3,"fmt %02d:%02d width %d:%d hight %d:%d\n",decoder->ColorSpace,frame->colorspace ,video_ctx->width, decoder->InputWidth,video_ctx->height, decoder->InputHeight);
|
||||||
|
|
||||||
decoder->InputWidth = video_ctx->width;
|
decoder->InputWidth = video_ctx->width;
|
||||||
decoder->InputHeight = video_ctx->height;
|
decoder->InputHeight = video_ctx->height;
|
||||||
@ -3190,7 +3361,6 @@ Debug(3,"fmt %02d:%02d width %d:%d hight %d:%d\n",decoder->ColorSpace,frame->co
|
|||||||
if (surface == -1) // no free surfaces
|
if (surface == -1) // no free surfaces
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
#if 0 // old copy via host ram
|
#if 0 // old copy via host ram
|
||||||
{
|
{
|
||||||
AVFrame *output;
|
AVFrame *output;
|
||||||
@ -3526,10 +3696,10 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))int lev
|
|||||||
decoder->newchannel = 0;
|
decoder->newchannel = 0;
|
||||||
|
|
||||||
if (!pl_render_image(p->renderer, &decoder->pl_images[current], target, &render_params)) {
|
if (!pl_render_image(p->renderer, &decoder->pl_images[current], target, &render_params)) {
|
||||||
Fatal(_("Failed rendering frame!\n"));
|
Debug(3,"Failed rendering frame!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VideoScalerTest) { // left side internal scaler (bicubic)
|
if (VideoScalerTest) { // left side test scaler
|
||||||
// Source crop
|
// Source crop
|
||||||
img->src_rect.x0 = video_src_rect.x0;
|
img->src_rect.x0 = video_src_rect.x0;
|
||||||
img->src_rect.y0 = video_src_rect.y0;
|
img->src_rect.y0 = video_src_rect.y0;
|
||||||
@ -3548,7 +3718,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))int lev
|
|||||||
p->renderertest = pl_renderer_create(p->ctx, p->gpu);
|
p->renderertest = pl_renderer_create(p->ctx, p->gpu);
|
||||||
|
|
||||||
if (!pl_render_image(p->renderertest, &decoder->pl_images[current], target, &render_params)) {
|
if (!pl_render_image(p->renderertest, &decoder->pl_images[current], target, &render_params)) {
|
||||||
Fatal(_("Failed rendering frame!\n"));
|
Debug(3,"Failed rendering frame!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (p->renderertest) {
|
else if (p->renderertest) {
|
||||||
@ -3557,6 +3727,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))int lev
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Debug(4, "video/vdpau: yy video surface %p displayed\n", current, decoder->SurfaceRead);
|
Debug(4, "video/vdpau: yy video surface %p displayed\n", current, decoder->SurfaceRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3624,13 +3795,17 @@ static void CuvidDisplayFrame(void)
|
|||||||
static unsigned int Count;
|
static unsigned int Count;
|
||||||
int filled;
|
int filled;
|
||||||
CuvidDecoder *decoder;
|
CuvidDecoder *decoder;
|
||||||
|
int RTS_flag;
|
||||||
|
|
||||||
|
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
uint64_t diff;
|
uint64_t diff;
|
||||||
struct pl_swapchain_frame frame;
|
struct pl_swapchain_frame frame;
|
||||||
struct pl_render_target target;
|
struct pl_render_target target;
|
||||||
bool ok;
|
bool ok;
|
||||||
|
VkImage Image;
|
||||||
|
const struct pl_fmt *fmt;
|
||||||
const float black[4] = { 0.0f,0.0f,0.0f,1.0f};
|
const float black[4] = { 0.0f,0.0f,0.0f,1.0f};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PLACEBO
|
#ifndef PLACEBO
|
||||||
@ -3645,27 +3820,45 @@ static void CuvidDisplayFrame(void)
|
|||||||
glXWaitVideoSyncSGI (2, (Count + 1) % 2, &Count); // wait for previous frame to swap
|
glXWaitVideoSyncSGI (2, (Count + 1) % 2, &Count); // wait for previous frame to swap
|
||||||
last_time = GetusTicks();
|
last_time = GetusTicks();
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
#else
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
if (CuvidDecoderN)
|
||||||
|
CuvidDecoders[0]->Frameproc = (float)(GetusTicks()-last_time)/1000000.0;
|
||||||
|
#if 0
|
||||||
diff = (GetusTicks()-last_time)/1000000;
|
diff = (GetusTicks()-last_time)/1000000;
|
||||||
// printf("Time wait %2.2f \n",(float)(diff));
|
// printf("Time wait %2.2f \n",(float)(diff));
|
||||||
last_time = GetusTicks();
|
last_time = GetusTicks();
|
||||||
|
if (diff < 19) {
|
||||||
|
// printf("Sleep %d\n",19-diff);
|
||||||
|
// usleep((18 - diff) * 1000);
|
||||||
|
}
|
||||||
|
// usleep(15000);
|
||||||
|
// printf("sleept %d\n",(GetusTicks()-last_time)/1000000);
|
||||||
|
|
||||||
|
// last_time = GetusTicks();
|
||||||
|
#endif
|
||||||
pl_swapchain_swap_buffers(p->swapchain); // swap buffers
|
|
||||||
|
|
||||||
// printf(" Latency %d Time wait %2.2f\n",pl_swapchain_latency(p->swapchain),(float)(GetusTicks()-last_time)/1000000.0);
|
|
||||||
last_time = GetusTicks();
|
|
||||||
if (!p->swapchain)
|
if (!p->swapchain)
|
||||||
return;
|
return;
|
||||||
usleep(1000);
|
|
||||||
if (!pl_swapchain_start_frame(p->swapchain, &frame)) { // get new frame
|
|
||||||
usleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// pl_swapchain_swap_buffers(p->swapchain); // swap buffers
|
||||||
|
|
||||||
|
// printf(" Latency %d \n",pl_swapchain_latency(p->swapchain));
|
||||||
|
// last_time = GetusTicks();
|
||||||
|
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&VideoLockMutex);
|
||||||
|
|
||||||
|
while (!pl_swapchain_start_frame(p->swapchain, &frame)) { // get new frame wait for previous to swap
|
||||||
|
usleep(5);
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&VideoLockMutex);
|
||||||
|
|
||||||
|
last_time = GetusTicks();
|
||||||
|
if (!frame.fbo)
|
||||||
|
return;
|
||||||
pl_render_target_from_swapchain(&target, &frame); // make target frame
|
pl_render_target_from_swapchain(&target, &frame); // make target frame
|
||||||
|
|
||||||
|
|
||||||
if (VideoSurfaceModesChanged){
|
if (VideoSurfaceModesChanged){
|
||||||
pl_renderer_destroy(&p->renderer);
|
pl_renderer_destroy(&p->renderer);
|
||||||
p->renderer = pl_renderer_create(p->ctx, p->gpu);
|
p->renderer = pl_renderer_create(p->ctx, p->gpu);
|
||||||
@ -3685,8 +3878,8 @@ static void CuvidDisplayFrame(void)
|
|||||||
// target.repr.bits.sample_depth = 16;
|
// target.repr.bits.sample_depth = 16;
|
||||||
// target.repr.bits.color_depth = 16;
|
// target.repr.bits.color_depth = 16;
|
||||||
// target.repr.bits.bit_shift =0;
|
// target.repr.bits.bit_shift =0;
|
||||||
|
// pl_tex_clear(p->gpu,target.fbo,(float[4]){0});
|
||||||
|
|
||||||
pl_tex_clear(p->gpu,target.fbo,(float[4]){0});
|
|
||||||
switch (VulkanTargetColorSpace) {
|
switch (VulkanTargetColorSpace) {
|
||||||
case 0:
|
case 0:
|
||||||
memcpy(&target.color,&pl_color_space_monitor,sizeof(struct pl_color_space));
|
memcpy(&target.color,&pl_color_space_monitor,sizeof(struct pl_color_space));
|
||||||
@ -3726,15 +3919,19 @@ static void CuvidDisplayFrame(void)
|
|||||||
// need 1 frame for progressive, 3 frames for interlaced
|
// need 1 frame for progressive, 3 frames for interlaced
|
||||||
if (filled < 1 + 2 * decoder->Interlaced) {
|
if (filled < 1 + 2 * decoder->Interlaced) {
|
||||||
// FIXME: rewrite MixVideo to support less surfaces
|
// FIXME: rewrite MixVideo to support less surfaces
|
||||||
if ((VideoShowBlackPicture && !decoder->TrickSpeed) || (VideoShowBlackPicture && decoder->Closing < -300)) {
|
if ((VideoShowBlackPicture && !decoder->TrickSpeed) ||
|
||||||
|
(VideoShowBlackPicture && decoder->Closing < -300)) { // ||
|
||||||
|
// (!decoder->TrickSpeed && decoder->newchannel)) {
|
||||||
CuvidBlackSurface(decoder);
|
CuvidBlackSurface(decoder);
|
||||||
|
#ifdef PLACEBO
|
||||||
|
pl_tex_clear(p->gpu,target.fbo,(float[4]){0});
|
||||||
|
#endif
|
||||||
CuvidMessage(3, "video/cuvid: black surface displayed\n");
|
CuvidMessage(3, "video/cuvid: black surface displayed\n");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
if (OsdShown == 1) { // New OSD opened
|
if (OsdShown == 1) { // New OSD opened
|
||||||
// VideoSetAbove();
|
|
||||||
pthread_mutex_lock(&OSDMutex);
|
pthread_mutex_lock(&OSDMutex);
|
||||||
make_osd_overlay(OSDx,OSDy,OSDxsize,OSDysize);
|
make_osd_overlay(OSDx,OSDy,OSDxsize,OSDysize);
|
||||||
if (posd) {
|
if (posd) {
|
||||||
@ -3748,12 +3945,11 @@ static void CuvidDisplayFrame(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
if (OsdShown == 2) {
|
if (OsdShown == 2) {
|
||||||
// VideoSetAbove();
|
|
||||||
CuvidMixVideo(decoder, i, &target, &osdoverlay);
|
CuvidMixVideo(decoder, i, &target, &osdoverlay);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
CuvidMixVideo(decoder, i, &target, NULL);
|
CuvidMixVideo(decoder, i, &target, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
CuvidMixVideo(decoder, i);
|
CuvidMixVideo(decoder, i);
|
||||||
#endif
|
#endif
|
||||||
@ -3795,13 +3991,9 @@ static void CuvidDisplayFrame(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
|
|
||||||
if (!pl_swapchain_submit_frame(p->swapchain))
|
if (!pl_swapchain_submit_frame(p->swapchain))
|
||||||
Fatal(_("Failed to submit swapchain buffer\n"));
|
Fatal(_("Failed to submit swapchain buffer\n"));
|
||||||
|
pl_swapchain_swap_buffers(p->swapchain); // swap buffers
|
||||||
if (CuvidDecoderN)
|
|
||||||
CuvidDecoders[0]->Frameproc = (float)(GetusTicks()-last_time)/1000000.0;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
glXGetVideoSyncSGI (&Count); // get current frame
|
glXGetVideoSyncSGI (&Count); // get current frame
|
||||||
glXSwapBuffers(XlibDisplay, VideoWindow);
|
glXSwapBuffers(XlibDisplay, VideoWindow);
|
||||||
@ -3815,7 +4007,7 @@ static void CuvidDisplayFrame(void)
|
|||||||
// remember time of last shown surface
|
// remember time of last shown surface
|
||||||
CuvidDecoders[i]->FrameTime = CuvidFrameTime;
|
CuvidDecoders[i]->FrameTime = CuvidFrameTime;
|
||||||
}
|
}
|
||||||
// xcb_flush(Connection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -3976,6 +4168,9 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder)
|
|||||||
goto skip_sync;
|
goto skip_sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if (video_clock == (int64_t) AV_NOPTS_VALUE)
|
||||||
|
// printf("no video pts\n");
|
||||||
|
|
||||||
if (audio_clock != (int64_t) AV_NOPTS_VALUE
|
if (audio_clock != (int64_t) AV_NOPTS_VALUE
|
||||||
&& video_clock != (int64_t) AV_NOPTS_VALUE) {
|
&& video_clock != (int64_t) AV_NOPTS_VALUE) {
|
||||||
// both clocks are known
|
// both clocks are known
|
||||||
@ -3984,10 +4179,12 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder)
|
|||||||
diff = video_clock - audio_clock - VideoAudioDelay;
|
diff = video_clock - audio_clock - VideoAudioDelay;
|
||||||
diff = (decoder->LastAVDiff + diff) / 2;
|
diff = (decoder->LastAVDiff + diff) / 2;
|
||||||
decoder->LastAVDiff = diff;
|
decoder->LastAVDiff = diff;
|
||||||
//if (abs(diff/90) > 30)
|
//if (abs(diff/90) > 100)
|
||||||
// printf("Diff %d\n",diff/90);
|
// printf("Diff %d\n",diff/90);
|
||||||
if (abs(diff) > 5000 * 90) { // more than 5s
|
if (abs(diff) > 5000 * 90) { // more than 5s
|
||||||
err = CuvidMessage(2, "video: audio/video difference too big\n");
|
err = CuvidMessage(2, "video: audio/video difference too big\n");
|
||||||
|
decoder->SyncCounter = 1;
|
||||||
|
goto out;
|
||||||
} else if (diff > 100 * 90) {
|
} else if (diff > 100 * 90) {
|
||||||
// FIXME: this quicker sync step, did not work with new code!
|
// FIXME: this quicker sync step, did not work with new code!
|
||||||
err = CuvidMessage(4, "video: slow down video, duping frame\n");
|
err = CuvidMessage(4, "video: slow down video, duping frame\n");
|
||||||
@ -4153,6 +4350,7 @@ Debug(3,"Set video mode %dx%d\n",VideoWindowWidth,VideoWindowHeight);
|
|||||||
|
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
|
|
||||||
|
#if 0
|
||||||
// delete swapchain
|
// delete swapchain
|
||||||
if(p->swapchain)
|
if(p->swapchain)
|
||||||
pl_swapchain_destroy(&p->swapchain);;
|
pl_swapchain_destroy(&p->swapchain);;
|
||||||
@ -4167,6 +4365,7 @@ Debug(3,"Set video mode %dx%d\n",VideoWindowWidth,VideoWindowHeight);
|
|||||||
if (!p->swapchain) {
|
if (!p->swapchain) {
|
||||||
Fatal(_("Failed creating vulkan swapchain!"));
|
Fatal(_("Failed creating vulkan swapchain!"));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -4181,11 +4380,9 @@ Debug(3,"Set video mode %dx%d\n",VideoWindowWidth,VideoWindowHeight);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_VIDEO_THREAD2
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef USE_VIDEO_THREAD
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Handle a CUVID display.
|
/// Handle a CUVID display.
|
||||||
@ -4231,7 +4428,7 @@ static void CuvidDisplayHandlerThread(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
usleep(100);
|
// usleep(1000);
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -4239,11 +4436,12 @@ static void CuvidDisplayHandlerThread(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&VideoLockMutex);
|
pthread_mutex_unlock(&VideoLockMutex);
|
||||||
|
#if 1
|
||||||
if (!decoded) { // nothing decoded, sleep
|
if (!decoded) { // nothing decoded, sleep
|
||||||
// FIXME: sleep on wakeup
|
// FIXME: sleep on wakeup
|
||||||
usleep(1 * 100);
|
usleep(1 * 100);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
usleep(100);
|
usleep(100);
|
||||||
#endif
|
#endif
|
||||||
@ -4259,19 +4457,14 @@ static void CuvidDisplayHandlerThread(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef PLACEBO
|
||||||
pthread_mutex_lock(&VideoLockMutex);
|
pthread_mutex_lock(&VideoLockMutex);
|
||||||
CuvidSyncDisplayFrame();
|
CuvidSyncDisplayFrame();
|
||||||
pthread_mutex_unlock(&VideoLockMutex);
|
pthread_mutex_unlock(&VideoLockMutex);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define CuvidDisplayHandlerThread NULL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set video output position.
|
/// Set video output position.
|
||||||
@ -4853,6 +5046,7 @@ void VideoSetVideoEventCallback(void (*videoEventCallback)(void))
|
|||||||
///
|
///
|
||||||
static void VideoThreadLock(void)
|
static void VideoThreadLock(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (VideoThread) {
|
if (VideoThread) {
|
||||||
if (pthread_mutex_lock(&VideoLockMutex)) {
|
if (pthread_mutex_lock(&VideoLockMutex)) {
|
||||||
Error(_("video: can't lock thread\n"));
|
Error(_("video: can't lock thread\n"));
|
||||||
@ -4887,19 +5081,22 @@ void pl_log_intern(void *stream, enum pl_log_level level, const char *msg)
|
|||||||
printf("%5s: %s\n", prefix[level], msg);
|
printf("%5s: %s\n", prefix[level], msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void InitPlacebo(){
|
void InitPlacebo(){
|
||||||
|
|
||||||
struct pl_vulkan_params params;
|
struct pl_vulkan_params params;
|
||||||
struct pl_vk_inst_params iparams = pl_vk_inst_default_params;
|
struct pl_vk_inst_params iparams = pl_vk_inst_default_params;
|
||||||
VkXcbSurfaceCreateInfoKHR xcbinfo;
|
VkXcbSurfaceCreateInfoKHR xcbinfo;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char xcbext[] = {"VK_KHR_xcb_surface"};
|
char xcbext[] = {"VK_KHR_xcb_surface"};
|
||||||
char surfext[] = {"VK_KHR_surface"};
|
char surfext[] = {"VK_KHR_surface"};
|
||||||
|
|
||||||
Debug(3,"Init Placebo\n");
|
Debug(3,"Init Placebo\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
p = calloc(1,sizeof(struct priv));
|
p = calloc(1,sizeof(struct priv));
|
||||||
if (!p)
|
if (!p)
|
||||||
Fatal(_("Cant get memory for PLACEBO struct"));
|
Fatal(_("Cant get memory for PLACEBO struct"));
|
||||||
@ -4919,9 +5116,9 @@ void InitPlacebo(){
|
|||||||
// iparams.debug = true;
|
// iparams.debug = true;
|
||||||
iparams.num_extensions = 2;
|
iparams.num_extensions = 2;
|
||||||
iparams.extensions = malloc(2 * sizeof(const char *));
|
iparams.extensions = malloc(2 * sizeof(const char *));
|
||||||
*iparams.extensions = xcbext;
|
*iparams.extensions = surfext;
|
||||||
iparams.debug = false;
|
iparams.debug = false;
|
||||||
*(iparams.extensions+1) = surfext;
|
*(iparams.extensions+1) = xcbext;
|
||||||
|
|
||||||
p->vk_inst = pl_vk_inst_create(p->ctx, &iparams);
|
p->vk_inst = pl_vk_inst_create(p->ctx, &iparams);
|
||||||
|
|
||||||
@ -4943,9 +5140,9 @@ void InitPlacebo(){
|
|||||||
params.instance = p->vk_inst->instance;
|
params.instance = p->vk_inst->instance;
|
||||||
params.async_transfer = true;
|
params.async_transfer = true;
|
||||||
params.async_compute = true;
|
params.async_compute = true;
|
||||||
// params.queue_count = 8;
|
params.queue_count = 1;
|
||||||
params.surface = p->pSurface;
|
params.surface = p->pSurface;
|
||||||
params.allow_software = true;
|
params.allow_software = false;
|
||||||
|
|
||||||
p->vk = pl_vulkan_create(p->ctx, ¶ms);
|
p->vk = pl_vulkan_create(p->ctx, ¶ms);
|
||||||
if (!p->vk)
|
if (!p->vk)
|
||||||
@ -4984,7 +5181,7 @@ static void *VideoDisplayHandlerThread(void *dummy)
|
|||||||
CUcontext cuda_ctx;
|
CUcontext cuda_ctx;
|
||||||
|
|
||||||
#ifdef PLACEBO_
|
#ifdef PLACEBO_
|
||||||
InitPlacebo();
|
// InitPlacebo();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
prctl(PR_SET_NAME,"cuvid video",0,0,0);
|
prctl(PR_SET_NAME,"cuvid video",0,0,0);
|
||||||
@ -5001,14 +5198,14 @@ static void *VideoDisplayHandlerThread(void *dummy)
|
|||||||
GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight, GlxThreadContext);
|
GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight, GlxThreadContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// fix dead-lock with CuvidExit
|
// fix dead-lock with CuvidExit
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
|
#ifndef PLACEBO
|
||||||
VideoPollEvent();
|
VideoPollEvent();
|
||||||
|
#endif
|
||||||
VideoUsedModule->DisplayHandlerThread();
|
VideoUsedModule->DisplayHandlerThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5029,6 +5226,32 @@ static void *VideoDisplayHandlerThread(void *dummy)
|
|||||||
return dummy;
|
return dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PLACEBO
|
||||||
|
static void *VideoHandlerThread(void *dummy) {
|
||||||
|
CuvidDecoder *decoder;
|
||||||
|
int filled;
|
||||||
|
|
||||||
|
decoder = CuvidDecoders[0];
|
||||||
|
|
||||||
|
prctl(PR_SET_NAME,"cuvid video display",0,0,0);
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||||
|
pthread_testcancel();
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
|
|
||||||
|
VideoPollEvent();
|
||||||
|
usleep(2000);
|
||||||
|
filled = atomic_read(&decoder->SurfacesFilled);
|
||||||
|
// if (filled >= 0) {
|
||||||
|
pthread_mutex_lock(&VideoLockMutex);
|
||||||
|
CuvidSyncDisplayFrame();
|
||||||
|
pthread_mutex_unlock(&VideoLockMutex);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
///
|
///
|
||||||
/// Initialize video threads.
|
/// Initialize video threads.
|
||||||
///
|
///
|
||||||
@ -5043,6 +5266,11 @@ static void VideoThreadInit(void)
|
|||||||
pthread_mutex_init(&OSDMutex, NULL);
|
pthread_mutex_init(&OSDMutex, NULL);
|
||||||
pthread_cond_init(&VideoWakeupCond, NULL);
|
pthread_cond_init(&VideoWakeupCond, NULL);
|
||||||
pthread_create(&VideoThread, NULL, VideoDisplayHandlerThread, NULL);
|
pthread_create(&VideoThread, NULL, VideoDisplayHandlerThread, NULL);
|
||||||
|
#ifdef PLACEBO
|
||||||
|
pthread_create(&VideoDisplayThread, NULL, VideoHandlerThread, NULL);
|
||||||
|
#else
|
||||||
|
VideoDisplayThread = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -5054,15 +5282,25 @@ static void VideoThreadExit(void)
|
|||||||
void *retval;
|
void *retval;
|
||||||
|
|
||||||
Debug(3, "video: video thread canceled\n");
|
Debug(3, "video: video thread canceled\n");
|
||||||
//VideoThreadLock();
|
|
||||||
// FIXME: can't cancel locked
|
// FIXME: can't cancel locked
|
||||||
if (pthread_cancel(VideoThread)) {
|
if (pthread_cancel(VideoThread)) {
|
||||||
Error(_("video: can't queue cancel video display thread\n"));
|
Error(_("video: can't queue cancel video display thread\n"));
|
||||||
}
|
}
|
||||||
//VideoThreadUnlock();
|
|
||||||
if (pthread_join(VideoThread, &retval) || retval != PTHREAD_CANCELED) {
|
if (pthread_join(VideoThread, &retval) || retval != PTHREAD_CANCELED) {
|
||||||
Error(_("video: can't cancel video display thread\n"));
|
Error(_("video: can't cancel video display thread\n"));
|
||||||
}
|
}
|
||||||
|
if (VideoDisplayThread) {
|
||||||
|
if (pthread_cancel(VideoDisplayThread)) {
|
||||||
|
Error(_("video: can't queue cancel video display thread\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_join(VideoDisplayThread, &retval) || retval != PTHREAD_CANCELED) {
|
||||||
|
Error(_("video: can't cancel video display thread\n"));
|
||||||
|
}
|
||||||
|
VideoDisplayThread = 0;
|
||||||
|
}
|
||||||
VideoThread = 0;
|
VideoThread = 0;
|
||||||
pthread_cond_destroy(&VideoWakeupCond);
|
pthread_cond_destroy(&VideoWakeupCond);
|
||||||
pthread_mutex_destroy(&VideoLockMutex);
|
pthread_mutex_destroy(&VideoLockMutex);
|
||||||
@ -6098,11 +6336,11 @@ void VideoSetAbove()
|
|||||||
///
|
///
|
||||||
void VideoSetDeinterlace(int mode[VideoResolutionMax])
|
void VideoSetDeinterlace(int mode[VideoResolutionMax])
|
||||||
{
|
{
|
||||||
VideoDeinterlace[0] = mode[0];
|
VideoDeinterlace[0] = mode[0]; // 576i
|
||||||
VideoDeinterlace[1] = mode[1];
|
VideoDeinterlace[1] = 1; //mode[1]; // 720p
|
||||||
VideoDeinterlace[2] = mode[2];
|
VideoDeinterlace[2] = mode[2]; // fake 1080
|
||||||
VideoDeinterlace[3] = mode[3];
|
VideoDeinterlace[3] = mode[3]; // 1080
|
||||||
VideoDeinterlace[4] = mode[4];
|
VideoDeinterlace[4] = 1, //mode[4]; 2160p
|
||||||
VideoSurfaceModesChanged = 1;
|
VideoSurfaceModesChanged = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6500,11 +6738,11 @@ void VideoExit(void)
|
|||||||
pl_swapchain_destroy(&p->swapchain);
|
pl_swapchain_destroy(&p->swapchain);
|
||||||
vkDestroySurfaceKHR(p->vk_inst->instance, p->pSurface, NULL);
|
vkDestroySurfaceKHR(p->vk_inst->instance, p->pSurface, NULL);
|
||||||
pl_vk_inst_destroy(&p->vk_inst);
|
pl_vk_inst_destroy(&p->vk_inst);
|
||||||
printf("1\n");
|
|
||||||
// pl_vulkan_destroy(&p->vk);
|
// pl_vulkan_destroy(&p->vk);
|
||||||
printf("1\n");
|
|
||||||
pl_context_destroy(&p->ctx);
|
pl_context_destroy(&p->ctx);
|
||||||
printf("1\n");
|
|
||||||
free(p);
|
free(p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user