mirror of
				https://github.com/jojo61/vdr-plugin-softhdcuvid.git
				synced 2025-03-01 10:39:28 +00:00 
			
		
		
		
	Compare commits
	
		
			61 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | f27e4fb35f | ||
|  | e14ea73a00 | ||
|  | 72cb77f771 | ||
|  | c679d812d1 | ||
|  | 47b461ab46 | ||
|  | 8629946041 | ||
|  | a222f6a1d5 | ||
|  | b51589aaa9 | ||
|  | c3af54aae0 | ||
|  | 7e387fa3f1 | ||
|  | f3e5a14fdf | ||
|  | aa0c2f80e4 | ||
|  | 215f251572 | ||
|  | a425ec94e0 | ||
|  | 91961bdffe | ||
|  | f741dff042 | ||
|  | 7a31761c89 | ||
|  | d5ca73c22f | ||
|  | 6704b2ca5a | ||
|  | e0bbaceec0 | ||
|  | 45043b9ffc | ||
|  | a56b3737c7 | ||
|  | e59eeba0d2 | ||
|  | 838dfab45b | ||
|  | ddd44e6f62 | ||
|  | 1390139cbd | ||
|  | f72653c3c1 | ||
|  | 4b9cd22405 | ||
|  | 38bda0c834 | ||
|  | 45c86f12dd | ||
|  | e2e9ae94d7 | ||
|  | 4837f7fa35 | ||
|  | 7f054f8320 | ||
|  | ad7acde1f4 | ||
|  | e5c48a4bb7 | ||
|  | fb67617d63 | ||
|  | 8aa807eec6 | ||
|  | 0621ed064d | ||
|  | 9219f06c5a | ||
|  | 4e96489e35 | ||
|  | 65017da5ac | ||
|  | 7b41b9b45a | ||
|  | 58c39d51f4 | ||
|  | d78e905411 | ||
|  | 7b10c2d0a3 | ||
|  | 9714824a5a | ||
|  | 3e9b909685 | ||
|  | 464f7de014 | ||
|  | da33b90f94 | ||
|  | 90194d4b6c | ||
|  | 45a83eaa3f | ||
|  | 37f87e2511 | ||
|  | bd9184db01 | ||
|  | 101bffd01f | ||
|  | 43085a3608 | ||
|  | 3de7a17105 | ||
|  | c229e77151 | ||
|  | af370721d4 | ||
|  | 79fa8efc6a | ||
|  | d5dec38d62 | ||
|  | 74847c9bed | 
							
								
								
									
										20
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								Makefile
									
									
									
									
									
								
							| @@ -24,18 +24,17 @@ DRM ?= 0 | ||||
|  | ||||
| # use libplacebo - | ||||
| # available for all decoders but for DRM you need LIBPLACEBO_GL | ||||
| LIBPLACEBO ?= 1 | ||||
| LIBPLACEBO ?= 0 | ||||
| LIBPLACEBO_GL ?= 0 | ||||
|  | ||||
| # use YADIF deint - only available with cuvid | ||||
| #YADIF = 1 | ||||
| YADIF = 1 | ||||
|  | ||||
| # use gamma correction | ||||
| #GAMMA ?= 0 | ||||
|  | ||||
| CONFIG := -DDEBUG 		# remove '#' to enable debug output | ||||
|  | ||||
|  | ||||
| #--------------------- no more config needed past this point-------------------------------- | ||||
|  | ||||
| # sanitize selections -------- | ||||
| @@ -159,29 +158,29 @@ endif | ||||
|  | ||||
| ifeq ($(LIBPLACEBO_GL),1) | ||||
| CONFIG += -DPLACEBO_GL -DPLACEBO | ||||
| LIBS += -lepoxy | ||||
| LIBS += -lplacebo | ||||
| _CFLAGS += $(shell pkg-config --cflags libplacebo) | ||||
| LIBS += $(shell pkg-config --libs epoxy libplacebo) | ||||
| else | ||||
| LIBS += -lEGL | ||||
| LIBS += $(shell pkg-config --libs egl) | ||||
| endif | ||||
|  | ||||
| ifeq ($(LIBPLACEBO),1) | ||||
| CONFIG += -DPLACEBO | ||||
| LIBS += -lEGL | ||||
| LIBS += -lplacebo | ||||
| _CFLAGS += $(shell pkg-config --cflags libplacebo) | ||||
| LIBS += $(shell pkg-config --libs egl libplacebo) | ||||
| endif | ||||
|  | ||||
| ifeq ($(DRM),1) | ||||
| PLUGIN = softhddrm | ||||
| CONFIG += -DUSE_DRM -DVAAPI | ||||
| _CFLAGS += $(shell pkg-config --cflags libdrm) | ||||
| LIBS += -lgbm -ldrm -lEGL | ||||
| LIBS += $(shell pkg-config --libs egl gbm libdrm) | ||||
| endif | ||||
|  | ||||
| ifeq ($(CUVID),1) | ||||
| #CONFIG += -DUSE_PIP			# PIP support | ||||
| CONFIG += -DCUVID			# enable CUVID decoder | ||||
| LIBS += -lEGL -lGL | ||||
| LIBS += $(shell pkg-config --libs egl gl) | ||||
| ifeq ($(YADIF),1) | ||||
| CONFIG += -DYADIF			# Yadif only with CUVID | ||||
| endif | ||||
| @@ -274,6 +273,7 @@ LIBS += -lcuda -lnvcuvid | ||||
| endif | ||||
|  | ||||
| LIBS += -lGLEW -lGLU  -ldl -lglut | ||||
| #LIBS += -ldl $(shell pkg-config --libs glew glu glut) | ||||
|  | ||||
| ### Includes and Defines (add further entries here): | ||||
|  | ||||
|   | ||||
| @@ -37,7 +37,6 @@ A software and GPU emulated UHD output device plugin for VDR. | ||||
|     o PIP (Picture-in-Picture) (only for CUVID) | ||||
|  | ||||
|  | ||||
| To compile you must have the 'requires' installed. | ||||
|  | ||||
|  | ||||
| This is a fork of johns original softhddevice work and I reworked it to support HEVC with CUDA and opengl output. | ||||
| @@ -83,7 +82,6 @@ You have to adapt the Makefile. There are 3 possible Version that you can build: | ||||
|     runs without X Server. There are several commandline options to select the resolution and refresh rate. | ||||
|     I recommend to use libplacebo and set LIBPLACEBO_GL=1 in the Makefile. | ||||
|  | ||||
|     Libplacebo API Version >= 113 is needed. | ||||
|  | ||||
|  | ||||
| Install: | ||||
| @@ -122,6 +120,9 @@ Beginners Guide for libplacebo: | ||||
|  | ||||
|     All other settings can be in their default state. | ||||
|  | ||||
| 	Note for NUC11/12 Users: | ||||
| 	Provide paramete -w alsa-no-test to get Audio working. | ||||
|  | ||||
|     Beginning with libplacebo API 58 user shaders from mpv are supported. Use -S parameter to set the shader. | ||||
|     The plugins searches the shaders in $ConfigDir/plugins/shaders for the shaders. One example shader is | ||||
|     provided in the shader subdirectory. Copy it to e.g.: /etc/vdr/plugins/shaders and then start | ||||
|   | ||||
							
								
								
									
										63
									
								
								audio.c
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								audio.c
									
									
									
									
									
								
							| @@ -93,6 +93,7 @@ static const AudioModule NoopModule; ///< forward definition of noop module | ||||
| //  Variables | ||||
| //---------------------------------------------------------------------------- | ||||
|  | ||||
| char AudioAlsaNotest;          ///< disable Audio capbility test | ||||
| char AudioAlsaDriverBroken;   ///< disable broken driver message | ||||
| char AudioAlsaNoCloseOpen;    ///< disable alsa close/open fix | ||||
| char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix | ||||
| @@ -927,6 +928,7 @@ static snd_pcm_t *AlsaOpenPCM(int passthrough) { | ||||
|     const char *device; | ||||
|     snd_pcm_t *handle; | ||||
|     int err; | ||||
|     char tmp[80]; | ||||
|  | ||||
|     // &&|| hell | ||||
|     if (!(passthrough && ((device = AudioPassthroughDevice) || (device = getenv("ALSA_PASSTHROUGH_DEVICE")))) && | ||||
| @@ -936,31 +938,43 @@ static snd_pcm_t *AlsaOpenPCM(int passthrough) { | ||||
|     if (!AudioDoingInit) { // reduce blabla during init | ||||
|         Info(_("audio/alsa: using %sdevice '%s'\n"), passthrough ? "pass-through " : "", device); | ||||
|     } | ||||
|     //printf("audio/alsa: using %sdevice '%s'\n", passthrough ? "pass-through " : "", device); | ||||
|      | ||||
|     // | ||||
|     // for AC3 pass-through try to set the non-audio bit, use AES0=6 | ||||
|     // | ||||
|     if (passthrough && AudioAppendAES) { | ||||
| #if 0 | ||||
| 	// FIXME: not yet finished | ||||
| 	char *buf; | ||||
| 	const char *s; | ||||
| 	int n; | ||||
|         if (!(strchr(device, ':'))) { | ||||
|             sprintf(tmp, | ||||
|                         //"AES0=%d,AES1=%d,AES2=0,AES3=%d", | ||||
|                         "%s:AES0=%d,AES1=%d,AES2=0", | ||||
|                         device, | ||||
|                         IEC958_AES0_NONAUDIO | IEC958_AES0_PRO_EMPHASIS_NONE, | ||||
|                         IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER); | ||||
|                         //map_iec958_srate(ao->samplerate)); | ||||
|         }  | ||||
|         else { | ||||
|             sprintf(tmp, | ||||
|                         //"AES0=%d,AES1=%d,AES2=0,AES3=%d", | ||||
|                         "%s,AES0=%d,AES1=%d,AES2=0", | ||||
|                         device, | ||||
|                         IEC958_AES0_NONAUDIO | IEC958_AES0_PRO_EMPHASIS_NONE, | ||||
|                         IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER); | ||||
|                         //map_iec958_srate(ao->samplerate)); | ||||
|         } | ||||
|          | ||||
| 	n = strlen(device); | ||||
| 	buf = alloca(n + sizeof(":AES0=6") + 1); | ||||
| 	strcpy(buf, device); | ||||
| 	if (!(s = strchr(buf, ':'))) { | ||||
| 	    // no alsa parameters | ||||
| 	    strcpy(buf + n, ":AES=6"); | ||||
| 	} | ||||
| 	Debug(3, "audio/alsa: try '%s'\n", buf); | ||||
| #endif | ||||
|         printf( "opening device '%s' => '%s'\n", device, tmp); | ||||
|         if ((err = snd_pcm_open(&handle, tmp, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0 ) { | ||||
|             Error(_("audio/alsa: playback open '%s' error: %s\n"), device, snd_strerror(err)); | ||||
|             return NULL; | ||||
|         }  | ||||
|     } else { | ||||
|         // open none blocking; if device is already used, we don't want wait | ||||
|         if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { | ||||
|             Error(_("audio/alsa: playback open '%s' error: %s\n"), device, snd_strerror(err)); | ||||
|             return NULL; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if ((err = snd_pcm_nonblock(handle, 0)) < 0) { | ||||
|         Error(_("audio/alsa: can't set block mode: %s\n"), snd_strerror(err)); | ||||
| @@ -2173,6 +2187,24 @@ found: | ||||
|     AudioDoingInit = 1; | ||||
|     AudioRingInit(); | ||||
|     AudioUsedModule->Init(); | ||||
|  | ||||
|     if (AudioAlsaNotest) { | ||||
|         for (u = 0; u < AudioRatesMax; ++u) { | ||||
|          | ||||
|             AudioChannelMatrix[u][1]=AudioChannelMatrix[u][2]=2; | ||||
|             AudioChannelMatrix[u][3]=AudioChannelMatrix[u][4]=4; | ||||
|             AudioChannelMatrix[u][5]=AudioChannelMatrix[u][6]=6; | ||||
|             AudioChannelMatrix[u][7]=AudioChannelMatrix[u][8]=8; | ||||
|             printf("audio: %6dHz supports %d %d %d %d %d %d %d %d channels\n", AudioRatesTable[u], | ||||
|                 AudioChannelMatrix[u][1], AudioChannelMatrix[u][2], AudioChannelMatrix[u][3], AudioChannelMatrix[u][4], | ||||
|                 AudioChannelMatrix[u][5], AudioChannelMatrix[u][6], AudioChannelMatrix[u][7], AudioChannelMatrix[u][8]); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         AudioChannelsInHw[1]=AudioChannelsInHw[3]=AudioChannelsInHw[4]=AudioChannelsInHw[5]=AudioChannelsInHw[6]=AudioChannelsInHw[7]=AudioChannelsInHw[8]=0; | ||||
|         AudioChannelsInHw[2]=2; | ||||
|     } | ||||
|     else { | ||||
|         // | ||||
|         //	Check which channels/rates/formats are supported | ||||
|         //	FIXME: we force 44.1Khz and 48Khz must be supported equal | ||||
| @@ -2290,10 +2322,11 @@ found: | ||||
|             } | ||||
|         } | ||||
|         for (u = 0; u < AudioRatesMax; ++u) { | ||||
|         Info(_("audio: %6dHz supports %d %d %d %d %d %d %d %d channels\n"), AudioRatesTable[u], | ||||
|             Debug(3,"audio: %6dHz supports %d %d %d %d %d %d %d %d channels\n", AudioRatesTable[u], | ||||
|                 AudioChannelMatrix[u][1], AudioChannelMatrix[u][2], AudioChannelMatrix[u][3], AudioChannelMatrix[u][4], | ||||
|                 AudioChannelMatrix[u][5], AudioChannelMatrix[u][6], AudioChannelMatrix[u][7], AudioChannelMatrix[u][8]); | ||||
|         } | ||||
|     } | ||||
| #ifdef USE_AUDIO_THREAD | ||||
|     if (AudioUsedModule->Thread) { // supports threads | ||||
|         AudioInitThread(); | ||||
|   | ||||
							
								
								
									
										1
									
								
								audio.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								audio.h
									
									
									
									
									
								
							| @@ -60,6 +60,7 @@ extern void AudioExit(void);               ///< cleanup and exit audio module | ||||
| //  Variables | ||||
| //---------------------------------------------------------------------------- | ||||
|  | ||||
| extern char AudioAlsaNotest;         ///< disable Alsa capability test | ||||
| extern char AudioAlsaDriverBroken;   ///< disable broken driver message | ||||
| extern char AudioAlsaNoCloseOpen;    ///< disable alsa close/open fix | ||||
| extern char AudioAlsaCloseOpenDelay; ///< enable alsa close/open delay fix | ||||
|   | ||||
							
								
								
									
										98
									
								
								codec.c
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								codec.c
									
									
									
									
									
								
							| @@ -234,20 +234,6 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) { | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
| #ifdef RASPI | ||||
|     switch (codec_id) { | ||||
|         case AV_CODEC_ID_MPEG2VIDEO: | ||||
|             name = "mpeg2_v4l2m2m"; | ||||
|             break; | ||||
|         case AV_CODEC_ID_H264: | ||||
|             name = "h264_v4l2m2m"; | ||||
|             //	name = "h264_mmal"; | ||||
|             break; | ||||
|         case AV_CODEC_ID_HEVC: | ||||
|             name = "hevc_v4l2m2m"; | ||||
|             break; | ||||
|     } | ||||
| #endif | ||||
|     if (name && (video_codec = avcodec_find_decoder_by_name(name))) { | ||||
|         Debug(3, "codec: decoder found\n"); | ||||
| @@ -264,31 +250,27 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) { | ||||
|         Fatal(_("codec: can't allocate video codec context\n")); | ||||
|     } | ||||
|  | ||||
| #ifndef RASPI | ||||
|     if (!HwDeviceContext) { | ||||
|         Fatal("codec: no hw device context to be used"); | ||||
|     } | ||||
|     decoder->VideoCtx->hw_device_ctx = av_buffer_ref(HwDeviceContext); | ||||
| #else | ||||
|     decoder->VideoCtx->pix_fmt = AV_PIX_FMT_DRM_PRIME; /* request a DRM frame */ | ||||
|     //	decoder->VideoCtx->pix_fmt = AV_PIX_FMT_MMAL;	/* request a DRM frame | ||||
|     //*/ | ||||
| #endif | ||||
|  | ||||
|     // FIXME: for software decoder use all cpus, otherwise 1 | ||||
|     decoder->VideoCtx->thread_count = 1; | ||||
|  | ||||
|     decoder->VideoCtx->pkt_timebase.num = 1; | ||||
|     decoder->VideoCtx->pkt_timebase.den = 90000; | ||||
|     decoder->VideoCtx->framerate.num = 50; | ||||
|     decoder->VideoCtx->framerate.den = 1; | ||||
|     //decoder->VideoCtx->framerate.num = 50; | ||||
|     //decoder->VideoCtx->framerate.den = 1; | ||||
|  | ||||
|     pthread_mutex_lock(&CodecLockMutex); | ||||
|     // open codec | ||||
| #ifdef YADIF | ||||
|     deint = 2; | ||||
| #endif | ||||
| #if defined VAAPI && !defined RASPI | ||||
|  | ||||
| #if defined VAAPI | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,8,100) | ||||
|     // decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1 | ||||
|     if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) { | ||||
|         Debug(3, "codec: auto threads enabled"); | ||||
| @@ -299,6 +281,7 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) { | ||||
|         Debug(3, "codec: supports truncated packets"); | ||||
|         // decoder->VideoCtx->flags |= CODEC_FLAG_TRUNCATED; | ||||
|     } | ||||
| #endif | ||||
|     // FIXME: own memory management for video frames. | ||||
|     if (video_codec->capabilities & AV_CODEC_CAP_DR1) { | ||||
|         Debug(3, "codec: can use own buffer management"); | ||||
| @@ -315,22 +298,10 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) { | ||||
|     } | ||||
|     //    if (av_opt_set_int(decoder->VideoCtx, "refcounted_frames", 1, 0) < 0) | ||||
|     //	  Fatal(_("VAAPI Refcounts invalid\n")); | ||||
| #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,8,100) | ||||
|     decoder->VideoCtx->thread_safe_callbacks = 0; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #ifdef RASPI | ||||
|     decoder->VideoCtx->codec_id = codec_id; | ||||
|     decoder->VideoCtx->flags |= AV_CODEC_FLAG_BITEXACT; | ||||
|     if (video_codec->capabilities & AV_CODEC_CAP_FRAME_THREADS || AV_CODEC_CAP_SLICE_THREADS) { | ||||
|         Debug(3, "codec: supports frame threads"); | ||||
|         decoder->VideoCtx->thread_count = 4; | ||||
|         //   decoder->VideoCtx->thread_type |= FF_THREAD_FRAME; | ||||
|     } | ||||
|     if (video_codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) { | ||||
|         Debug(3, "codec: supports slice threads"); | ||||
|         decoder->VideoCtx->thread_type |= FF_THREAD_SLICE; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| #ifdef CUVID | ||||
| @@ -340,12 +311,12 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) { | ||||
|             pthread_mutex_unlock(&CodecLockMutex); | ||||
|             Fatal(_("codec: can't set option deint to video codec!\n")); | ||||
|         } | ||||
| #if 1 | ||||
|         if (av_opt_set_int(decoder->VideoCtx->priv_data, "surfaces", 9, 0) < 0) { | ||||
|  | ||||
|         if (av_opt_set_int(decoder->VideoCtx->priv_data, "surfaces", 10, 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) { | ||||
|             pthread_mutex_unlock(&CodecLockMutex); | ||||
|             Fatal(_("codec: can't set option drop 2.field to video codec!\n")); | ||||
| @@ -355,12 +326,10 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) { | ||||
|             pthread_mutex_unlock(&CodecLockMutex); | ||||
|             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) { | ||||
|             pthread_mutex_unlock(&CodecLockMutex); | ||||
|             Fatal(_("codec: can't set option drop 2.field  to video codec!\n")); | ||||
| @@ -401,7 +370,7 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) { | ||||
|  | ||||
|     // reset buggy ffmpeg/libav flag | ||||
|     decoder->GetFormatDone = 0; | ||||
| #if defined(YADIF) || defined(RASPI) | ||||
| #if defined(YADIF) | ||||
|     decoder->filter = 0; | ||||
| #endif | ||||
| } | ||||
| @@ -521,8 +490,7 @@ void CodecVideoDecode(VideoDecoder *decoder, const AVPacket *avpkt) { | ||||
|                             decoder->filter = 2; | ||||
|                         } | ||||
|                     } | ||||
|                     if (frame->interlaced_frame && decoder->filter == 2 && | ||||
|                         (frame->height != 720)) { // broken ZDF sends Interlaced flag | ||||
|                     if (decoder->filter == 2) {  | ||||
|                         push_filters(video_ctx, decoder->HwDecoder, frame); | ||||
|                         continue; | ||||
|                     } | ||||
| @@ -554,7 +522,6 @@ next_part: | ||||
|     pkt = avpkt; // use copy | ||||
|     got_frame = 0; | ||||
|  | ||||
|     // printf("decode packet  %d\n",(GetusTicks()-first_time)/1000000); | ||||
|     ret1 = avcodec_send_packet(video_ctx, pkt); | ||||
|  | ||||
|     // first_time = GetusTicks(); | ||||
| @@ -574,12 +541,12 @@ next_part: | ||||
|             frame = av_frame_alloc(); | ||||
|             ret = avcodec_receive_frame(video_ctx, frame); // get new frame | ||||
|             if (ret >= 0) {                                // one is avail. | ||||
|             first_time = frame->pts; | ||||
|                 got_frame = 1; | ||||
|             } else { | ||||
|                 got_frame = 0; | ||||
|             } | ||||
|             //		  printf("got %s packet from | ||||
|             // decoder\n",got_frame?"1":"no"); | ||||
|             //printf("got %s packet from decoder\n",got_frame?"1":"no"); | ||||
|             if (got_frame) { // frame completed | ||||
| //		printf("video frame pts %#012" PRIx64 " | ||||
| //%dms\n",frame->pts,(int)(apts - frame->pts) / 90); | ||||
| @@ -587,15 +554,14 @@ next_part: | ||||
|                 if (decoder->filter) { | ||||
|                     if (decoder->filter == 1) { | ||||
|                         if (init_filters(video_ctx, decoder->HwDecoder, frame) < 0) { | ||||
|                             Fatal(_("video: Init of YADIF Filter failed\n")); | ||||
|                             Debug(3,"video: Init of YADIF Filter failed\n"); | ||||
|                             decoder->filter = 0; | ||||
|                         } 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 | ||||
|                     if (decoder->filter == 2) {  | ||||
|                         ret = push_filters(video_ctx, decoder->HwDecoder, frame); | ||||
|                         // av_frame_unref(frame); | ||||
|                         continue; | ||||
| @@ -750,9 +716,6 @@ void CodecAudioOpen(AudioDecoder *audio_decoder, int codec_id) { | ||||
|         Fatal(_("codec: can't allocate audio codec context\n")); | ||||
|     } | ||||
|  | ||||
|     if (CodecDownmix) { | ||||
|         audio_decoder->AudioCtx->request_channel_layout = AV_CH_LAYOUT_STEREO; | ||||
|     } | ||||
|     pthread_mutex_lock(&CodecLockMutex); | ||||
|     // open codec | ||||
|     if (1) { | ||||
| @@ -905,7 +868,7 @@ static int CodecAudioUpdateHelper(AudioDecoder *audio_decoder, int *passthrough) | ||||
|     int err; | ||||
|  | ||||
|     audio_ctx = audio_decoder->AudioCtx; | ||||
|     Debug(3, "codec/audio: format change %s %dHz *%d channels%s%s%s%s%s\n", | ||||
|     Debug(3, "codec/audio: Chanlayout %lx format change %s %dHz *%d channels%s%s%s%s%s\n",audio_ctx->channel_layout, | ||||
|           av_get_sample_fmt_name(audio_ctx->sample_fmt), audio_ctx->sample_rate, audio_ctx->channels, | ||||
|           CodecPassthrough & CodecPCM ? " PCM" : "", CodecPassthrough & CodecMPA ? " MPA" : "", | ||||
|           CodecPassthrough & CodecAC3 ? " AC-3" : "", CodecPassthrough & CodecEAC3 ? " E-AC-3" : "", | ||||
| @@ -915,7 +878,7 @@ static int CodecAudioUpdateHelper(AudioDecoder *audio_decoder, int *passthrough) | ||||
|     audio_decoder->SampleRate = audio_ctx->sample_rate; | ||||
|     audio_decoder->HwSampleRate = audio_ctx->sample_rate; | ||||
|     audio_decoder->Channels = audio_ctx->channels; | ||||
|     audio_decoder->HwChannels = audio_ctx->channels; | ||||
|     audio_decoder->HwChannels = CodecDownmix ? 2 : audio_ctx->channels; | ||||
|     audio_decoder->Passthrough = CodecPassthrough; | ||||
|  | ||||
|     // SPDIF/HDMI pass-through | ||||
| @@ -923,7 +886,7 @@ static int CodecAudioUpdateHelper(AudioDecoder *audio_decoder, int *passthrough) | ||||
|         (CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == AV_CODEC_ID_EAC3)) { | ||||
|         if (audio_ctx->codec_id == AV_CODEC_ID_EAC3) { | ||||
|             // E-AC-3 over HDMI some receivers need HBR | ||||
|             audio_decoder->HwSampleRate *= 4; | ||||
|             //audio_decoder->HwSampleRate *= 4; | ||||
|         } | ||||
|         audio_decoder->HwChannels = 2; | ||||
|         audio_decoder->SpdifIndex = 0; // reset buffer | ||||
| @@ -1195,14 +1158,29 @@ static void CodecAudioUpdateFormat(AudioDecoder *audio_decoder) { | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     audio_decoder->Resample = swr_alloc_set_opts(audio_decoder->Resample, audio_ctx->channel_layout, AV_SAMPLE_FMT_S16, | ||||
|                                                  audio_decoder->HwSampleRate, audio_ctx->channel_layout, | ||||
|                                                  audio_ctx->sample_fmt, audio_ctx->sample_rate, 0, NULL); | ||||
| #if LIBSWRESAMPLE_VERSION_INT < AV_VERSION_INT(4,5,100) | ||||
|         audio_decoder->Resample = swr_alloc_set_opts(audio_decoder->Resample,  | ||||
|                                     CodecDownmix ? AV_CH_LAYOUT_STEREO : audio_ctx->channel_layout, | ||||
|                                     AV_SAMPLE_FMT_S16, audio_decoder->HwSampleRate, | ||||
| 	                                audio_ctx->channel_layout, audio_ctx->sample_fmt,audio_ctx->sample_rate, | ||||
|                                     0, NULL); | ||||
| #else | ||||
|     //printf("last ressort downmix Layout in %lx Lyout out: %llx \n",audio_ctx->channel_layout,AV_CH_LAYOUT_STEREO); | ||||
|         audio_decoder->Resample = swr_alloc(); | ||||
|         av_opt_set_channel_layout(audio_decoder->Resample, "in_channel_layout",audio_ctx->channel_layout, 0); | ||||
|         av_opt_set_channel_layout(audio_decoder->Resample, "out_channel_layout", CodecDownmix ? AV_CH_LAYOUT_STEREO : audio_ctx->channel_layout ,  0); | ||||
|         av_opt_set_int(audio_decoder->Resample, "in_sample_rate",     audio_ctx->sample_rate,                0); | ||||
|         av_opt_set_int(audio_decoder->Resample, "out_sample_rate",    audio_ctx->sample_rate,                0); | ||||
|         av_opt_set_sample_fmt(audio_decoder->Resample, "in_sample_fmt",  audio_ctx->sample_fmt, 0); | ||||
|         av_opt_set_sample_fmt(audio_decoder->Resample, "out_sample_fmt", AV_SAMPLE_FMT_S16,  0); | ||||
| #endif | ||||
|     if (audio_decoder->Resample) { | ||||
| 	    swr_init(audio_decoder->Resample); | ||||
|     } else { | ||||
| 	    Error(_("codec/audio: can't setup resample\n")); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1254,6 +1232,7 @@ void CodecAudioDecode(AudioDecoder *audio_decoder, const AVPacket *avpkt) { | ||||
|             if (CodecAudioPassthroughHelper(audio_decoder, avpkt)) { | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             if (audio_decoder->Resample) { | ||||
|                 uint8_t outbuf[8192  * 2 * 8]; | ||||
|                 uint8_t *out[1]; | ||||
| @@ -1261,6 +1240,7 @@ void CodecAudioDecode(AudioDecoder *audio_decoder, const AVPacket *avpkt) { | ||||
|                 out[0] = outbuf; | ||||
|                 ret = swr_convert(audio_decoder->Resample, out, sizeof(outbuf) / (2 * audio_decoder->HwChannels), | ||||
|                                   (const uint8_t **)frame->extended_data, frame->nb_samples); | ||||
|                                    | ||||
|                 if (ret > 0) { | ||||
|                     if (!(audio_decoder->Passthrough & CodecPCM)) { | ||||
|                         CodecReorderAudioFrame((int16_t *)outbuf, ret * 2 * audio_decoder->HwChannels, | ||||
|   | ||||
							
								
								
									
										54
									
								
								drm.c
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								drm.c
									
									
									
									
									
								
							| @@ -168,6 +168,7 @@ void set_video_mode(int width, int height) { | ||||
|     drmModeConnector *connector; | ||||
|     drmModeModeInfo *mode; | ||||
|     int ii; | ||||
|     printf("Set video mode %d &%d\n",width,height); | ||||
|     if (height != 1080 && height != 2160) | ||||
|         return; | ||||
|     connector = drmModeGetConnector(render->fd_drm, render->connector_id); | ||||
| @@ -206,11 +207,7 @@ static int FindDevice(VideoRender *render) { | ||||
|     int i, ii = 0; | ||||
|     char connectorstr[10]; | ||||
|     int found = 0; | ||||
| #ifdef RASPI | ||||
|     render->fd_drm = open("/dev/dri/card1", O_RDWR); | ||||
| #else | ||||
|     render->fd_drm = open("/dev/dri/card0", O_RDWR); | ||||
| #endif | ||||
|     if (render->fd_drm < 0) { | ||||
|         fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n"); | ||||
|         return -errno; | ||||
| @@ -278,10 +275,12 @@ static int FindDevice(VideoRender *render) { | ||||
|                 connector->connector_type_id); | ||||
|         printf("Connector >%s< is %sconnected\n", connectorstr, | ||||
|                connector->connection == DRM_MODE_CONNECTED ? "" : "not "); | ||||
|         Debug(3,"Connector >%s< is %sconnected\n", connectorstr, | ||||
|                connector->connection == DRM_MODE_CONNECTED ? "" : "not "); | ||||
|         if (DRMConnector && strcmp(DRMConnector, connectorstr)) | ||||
|             continue; | ||||
|  | ||||
|         if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) { | ||||
|         if (/*connector->connection == DRM_MODE_CONNECTED && */ connector->count_modes > 0) { | ||||
|             float aspect = (float)connector->mmWidth / (float)connector->mmHeight; | ||||
|             if ((aspect > 1.70) && (aspect < 1.85)) { | ||||
|                 render->mmHeight = 90; | ||||
| @@ -309,7 +308,7 @@ static int FindDevice(VideoRender *render) { | ||||
|                 mode = &connector->modes[ii]; | ||||
|  | ||||
|                 printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh); | ||||
|  | ||||
|                 Debug(3,"Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh); | ||||
|                 if (VideoWindowWidth && VideoWindowHeight) { // preset by command line | ||||
|                     if (VideoWindowWidth == mode->hdisplay && VideoWindowHeight == mode->vdisplay && | ||||
|                         mode->vrefresh == DRMRefresh && !(mode->flags & DRM_MODE_FLAG_INTERLACE)) { | ||||
| @@ -328,11 +327,16 @@ static int FindDevice(VideoRender *render) { | ||||
|             found = 1; | ||||
|             i = resources->count_connectors; // uuuuhh | ||||
|         } | ||||
|  | ||||
|         if (found) { | ||||
|             VideoWindowWidth = render->mode.hdisplay; | ||||
|             VideoWindowHeight = render->mode.vdisplay; | ||||
|         if (found) | ||||
|          | ||||
|             printf("Use Mode %d %dx%d Rate %d\n", ii, render->mode.hdisplay, render->mode.vdisplay, | ||||
|                    render->mode.vrefresh); | ||||
|             Debug(3,"Use Mode %d %dx%d Rate %d\n", ii, render->mode.hdisplay, render->mode.vdisplay, | ||||
|                    render->mode.vrefresh); | ||||
|         } | ||||
|         drmModeFreeConnector(connector); | ||||
|     } | ||||
|     if (!found) { | ||||
| @@ -372,11 +376,7 @@ static int FindDevice(VideoRender *render) { | ||||
|         for (k = 0; k < plane->count_formats; k++) { | ||||
|             if (encoder->possible_crtcs & plane->possible_crtcs) { | ||||
|                 switch (plane->formats[k]) { | ||||
| #ifdef RASPI | ||||
|                     case DRM_FORMAT_ARGB8888: | ||||
| #else | ||||
|                     case DRM_FORMAT_XRGB2101010: | ||||
| #endif | ||||
|                         if (!render->video_plane) { | ||||
|                             render->video_plane = plane->plane_id; | ||||
|                         } | ||||
| @@ -492,6 +492,7 @@ static void drm_swap_buffers() { | ||||
|     uint32_t fb; | ||||
|  | ||||
|     eglSwapBuffers(eglDisplay, eglSurface); | ||||
|     usleep(1000); | ||||
|     struct gbm_bo *bo = gbm_surface_lock_front_buffer(gbm.surface); | ||||
| #if 1 | ||||
|     if (bo == NULL) | ||||
| @@ -544,6 +545,7 @@ static void drm_swap_buffers() { | ||||
|         m_need_modeset = 0; | ||||
|         has_modeset = 1; | ||||
|     } | ||||
|      | ||||
|     drmModeSetCrtc(render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode); | ||||
|  | ||||
|     if (previous_bo) { | ||||
| @@ -561,15 +563,16 @@ static void drm_clean_up() { | ||||
|         return; | ||||
|     Debug(3, "drm clean up\n"); | ||||
|  | ||||
|     if (previous_bo) { | ||||
|         drmModeRmFB(render->fd_drm, previous_fb); | ||||
|         gbm_surface_release_buffer(gbm.surface, previous_bo); | ||||
|     } | ||||
|      | ||||
|     drmModeSetCrtc(render->fd_drm, render->saved_crtc->crtc_id, render->saved_crtc->buffer_id, render->saved_crtc->x, | ||||
|                    render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode); | ||||
|     drmModeFreeCrtc(render->saved_crtc); | ||||
|  | ||||
|     if (previous_bo) { | ||||
|         drmModeRmFB(render->fd_drm, previous_fb); | ||||
|         gbm_surface_release_buffer(gbm.surface, previous_bo); | ||||
|     } | ||||
|  | ||||
|     if (has_modeset) { | ||||
|         drmModeAtomicReqPtr ModeReq; | ||||
|         const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; | ||||
| @@ -612,22 +615,29 @@ static void drm_clean_up() { | ||||
|     if (render->hdr_blob_id) | ||||
|         drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id); | ||||
|     render->hdr_blob_id = 0; | ||||
|  | ||||
| #if 0 | ||||
|     eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | ||||
|     eglDestroySurface(eglDisplay, eglSurface); | ||||
|     EglCheck(); | ||||
|     gbm_surface_destroy(gbm.surface); | ||||
|     eglDestroyContext(eglDisplay, eglContext); | ||||
|     EglCheck(); | ||||
|     eglDestroyContext(eglDisplay, eglSharedContext); | ||||
|     EglCheck(); | ||||
|     eglDestroyContext(eglDisplay, eglContext); | ||||
|     EglCheck(); | ||||
|     eglSharedContext = NULL; | ||||
|  | ||||
|     eglContext = NULL; | ||||
|     eglTerminate(eglDisplay); | ||||
|     EglCheck(); | ||||
|  | ||||
|     eglDisplay = NULL; | ||||
| #endif | ||||
|     eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | ||||
|     eglDestroySurface(eglDisplay, eglSurface); | ||||
|     EglCheck(); | ||||
|     eglSurface = NULL; | ||||
|     gbm_surface_destroy(gbm.surface); | ||||
|     gbm_device_destroy(gbm.dev); | ||||
|     drmDropMaster(render->fd_drm); | ||||
|     close(render->fd_drm); | ||||
|     eglDisplay = NULL; | ||||
|     free(render); | ||||
|     render = NULL; | ||||
|     Debug(3, "nach drm clean up\n"); | ||||
| } | ||||
| @@ -20,12 +20,8 @@ void ConvertColor(const GLint &colARGB, glm::vec4 &col) { | ||||
| #ifdef CUVID | ||||
| const char *glversion = "#version 330 core "; | ||||
| #else | ||||
| #ifdef RASPI | ||||
| const char *glversion = "#version 300 es"; | ||||
| #else | ||||
| const char *glversion = "#version 300 es  "; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| const char *rectVertexShader = "%s\n \ | ||||
| \ | ||||
| @@ -730,14 +726,15 @@ bool cOglCmdDeleteFb::Execute(void) { | ||||
|  | ||||
| //------------------ cOglCmdRenderFbToBufferFb -------------------- | ||||
| cOglCmdRenderFbToBufferFb::cOglCmdRenderFbToBufferFb(cOglFb *fb, cOglFb *buffer, GLint x, GLint y, GLint transparency, | ||||
|                                                      GLint drawPortX, GLint drawPortY) | ||||
|                                                      GLint drawPortX, GLint drawPortY, bool alphablending) | ||||
|     : cOglCmd(fb) { | ||||
|     this->buffer = buffer; | ||||
|     this->x = (GLfloat)x; | ||||
|     this->y = (GLfloat)y; | ||||
|     this->drawPortX = (GLfloat)drawPortX; | ||||
|     this->drawPortY = (GLfloat)drawPortY; | ||||
|     this->transparency = transparency; | ||||
|      this->transparency = (alphablending ? transparency : ALPHA_OPAQUE); | ||||
|     this->alphablending = alphablending; | ||||
| } | ||||
|  | ||||
| bool cOglCmdRenderFbToBufferFb::Execute(void) { | ||||
| @@ -777,11 +774,14 @@ bool cOglCmdRenderFbToBufferFb::Execute(void) { | ||||
|  | ||||
|     if (!fb->BindTexture()) | ||||
|         return false; | ||||
|  | ||||
|     if (!alphablending) | ||||
|         VertexBuffers[vbTexture]->DisableBlending(); | ||||
|     VertexBuffers[vbTexture]->Bind(); | ||||
|     VertexBuffers[vbTexture]->SetVertexData(quadVertices); | ||||
|     VertexBuffers[vbTexture]->DrawArrays(); | ||||
|     VertexBuffers[vbTexture]->Unbind(); | ||||
|     if (!alphablending) | ||||
|         VertexBuffers[vbTexture]->EnableBlending(); | ||||
|     buffer->Unbind(); | ||||
|  | ||||
|     return true; | ||||
| @@ -837,6 +837,8 @@ cOglCmdDrawRectangle::cOglCmdDrawRectangle(cOglFb *fb, GLint x, GLint y, GLint w | ||||
| } | ||||
|  | ||||
| bool cOglCmdDrawRectangle::Execute(void) { | ||||
|     if (width <= 0 || height <= 0) | ||||
|         return false; | ||||
|     GLfloat x1 = x; | ||||
|     GLfloat y1 = y; | ||||
|     GLfloat x2 = x + width; | ||||
| @@ -883,6 +885,8 @@ cOglCmdDrawEllipse::cOglCmdDrawEllipse(cOglFb *fb, GLint x, GLint y, GLint width | ||||
| } | ||||
|  | ||||
| bool cOglCmdDrawEllipse::Execute(void) { | ||||
|     if (width <= 0 || height <= 0) | ||||
|         return false; | ||||
|     int numVertices = 0; | ||||
|     GLfloat *vertices = NULL; | ||||
|  | ||||
| @@ -1090,6 +1094,8 @@ cOglCmdDrawSlope::cOglCmdDrawSlope(cOglFb *fb, GLint x, GLint y, GLint width, GL | ||||
| } | ||||
|  | ||||
| bool cOglCmdDrawSlope::Execute(void) { | ||||
|     if (width <= 0 || height <= 0) | ||||
|         return false; | ||||
|     bool falling = type & 0x02; | ||||
|     bool vertical = type & 0x04; | ||||
|  | ||||
| @@ -1177,7 +1183,7 @@ cOglCmdDrawText::~cOglCmdDrawText(void) { free(symbols); } | ||||
| bool cOglCmdDrawText::Execute(void) { | ||||
|     cOglFont *f = cOglFont::Get(*fontName, fontSize); | ||||
|  | ||||
|     if (!f) | ||||
|     if (!f || !symbols[0]) | ||||
|         return false; | ||||
|  | ||||
|     VertexBuffers[vbText]->ActivateShader(); | ||||
| @@ -1256,10 +1262,13 @@ cOglCmdDrawImage::cOglCmdDrawImage(cOglFb *fb, tColor *argb, GLint width, GLint | ||||
| cOglCmdDrawImage::~cOglCmdDrawImage(void) { free(argb); } | ||||
|  | ||||
| bool cOglCmdDrawImage::Execute(void) { | ||||
|     if (width <= 0 || height <= 0) | ||||
|         return false; | ||||
|     GLuint texture; | ||||
|  | ||||
| #ifdef USE_DRM | ||||
|     //  pthread_mutex_lock(&OSDMutex); | ||||
|     //esyslog("upload Image\n"); | ||||
|     pthread_mutex_lock(&OSDMutex); | ||||
|     GlxDrawopengl(); // here we need the Shared Context for upload | ||||
|     GlxCheck(); | ||||
| #endif | ||||
| @@ -1275,13 +1284,13 @@ bool cOglCmdDrawImage::Execute(void) { | ||||
| #ifdef USE_DRM   | ||||
|     GlxInitopengl(); // Reset Context | ||||
|     GlxCheck(); | ||||
| //  pthread_mutex_unlock(&OSDMutex); | ||||
|     pthread_mutex_unlock(&OSDMutex); | ||||
| #endif | ||||
|  | ||||
|     GLfloat x1 = x;                   // left | ||||
|     GLfloat y1 = y;                   // top | ||||
|     GLfloat x2 = x + width;  // right | ||||
|     GLfloat y2 = y + height; // bottom | ||||
|     GLfloat x2 = x + width * scaleX;  // right | ||||
|     GLfloat y2 = y + height * scaleY; // bottom | ||||
|  | ||||
|     GLfloat quadVertices[] = { | ||||
|         x1, y2, 0.0, 1.0, // left bottom | ||||
| @@ -1315,17 +1324,21 @@ bool cOglCmdDrawImage::Execute(void) { | ||||
| } | ||||
|  | ||||
| //------------------ cOglCmdDrawTexture -------------------- | ||||
| cOglCmdDrawTexture::cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y) : cOglCmd(fb) { | ||||
| cOglCmdDrawTexture::cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y, double scaleX, double scaleY) : cOglCmd(fb) { | ||||
|     this->imageRef = imageRef; | ||||
|     this->x = x; | ||||
|     this->y = y; | ||||
|     this->scaleX = scaleX; | ||||
|     this->scaleY = scaleY; | ||||
| } | ||||
|  | ||||
| bool cOglCmdDrawTexture::Execute(void) { | ||||
|     if (imageRef->width <= 0 || imageRef->height <= 0) | ||||
|         return false; | ||||
|     GLfloat x1 = x;                             // top | ||||
|     GLfloat y1 = y;                             // left | ||||
|     GLfloat x2 = x + imageRef->width;  // right | ||||
|     GLfloat y2 = y + imageRef->height; // bottom | ||||
|     GLfloat x2 = x + imageRef->width * scaleX;  // right | ||||
|     GLfloat y2 = y + imageRef->height * scaleY; // bottom | ||||
|  | ||||
|     GLfloat quadVertices[] = { | ||||
|         // Pos	  // TexCoords | ||||
| @@ -1363,7 +1376,8 @@ cOglCmdStoreImage::~cOglCmdStoreImage(void) { free(data); } | ||||
|  | ||||
| bool cOglCmdStoreImage::Execute(void) { | ||||
| #ifdef USE_DRM | ||||
|     //  pthread_mutex_lock(&OSDMutex); | ||||
|     return false; | ||||
|     pthread_mutex_lock(&OSDMutex); | ||||
|     GlxDrawopengl(); // here we need the Shared Context for upload | ||||
|     GlxCheck(); | ||||
| #endif | ||||
| @@ -1380,7 +1394,7 @@ bool cOglCmdStoreImage::Execute(void) { | ||||
| #ifdef USE_DRM | ||||
|     GlxInitopengl(); // Reset Context | ||||
|     GlxCheck(); | ||||
| //  pthread_mutex_lock(&OSDMutex); | ||||
|     pthread_mutex_lock(&OSDMutex); | ||||
| #endif | ||||
|     return true; | ||||
| } | ||||
| @@ -1460,7 +1474,9 @@ int cOglThread::StoreImage(const cImage &image) { | ||||
|     if (!maxCacheSize) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
| #ifdef USE_DRM | ||||
|     return 0; | ||||
| #endif | ||||
|     if (image.Width() > maxTextureSize || image.Height() > maxTextureSize) { | ||||
|         esyslog("[softhddev] cannot store image of %dpx x %dpx " | ||||
|                 "(maximum size is %dpx x %dpx) - falling back to " | ||||
| @@ -1640,6 +1656,7 @@ void cOglThread::Action(void) { | ||||
|  | ||||
| bool cOglThread::InitOpenGL(void) { | ||||
| #ifdef USE_DRM | ||||
|     esyslog("InitOpenGL\n"); | ||||
|     GlxInitopengl(); | ||||
| #else | ||||
|     const char *displayName = X11DisplayName; | ||||
| @@ -1651,7 +1668,7 @@ bool cOglThread::InitOpenGL(void) { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     dsyslog("[softhddev]OpenGL using display %s", displayName); | ||||
|     esyslog("[softhddev]OpenGL using display %s", displayName); | ||||
|  | ||||
|     int argc = 3; | ||||
|     char *buffer[3]; | ||||
| @@ -1815,6 +1832,10 @@ void cOglPixmap::Fill(tColor Color) { | ||||
| } | ||||
|  | ||||
| void cOglPixmap::DrawImage(const cPoint &Point, const cImage &Image) { | ||||
|     DrawScaledImage(Point, Image); | ||||
| } | ||||
|  | ||||
| void cOglPixmap::DrawScaledImage(const cPoint &Point, const cImage &Image, double FactorX, double FactorY, bool AntiAlias) { | ||||
|     if (!oglThread->Active()) | ||||
|         return; | ||||
|     tColor *argb = MALLOC(tColor, Image.Width() * Image.Height()); | ||||
| @@ -1823,19 +1844,25 @@ void cOglPixmap::DrawImage(const cPoint &Point, const cImage &Image) { | ||||
|         return; | ||||
|     memcpy(argb, Image.Data(), sizeof(tColor) * Image.Width() * Image.Height()); | ||||
|  | ||||
|     oglThread->DoCmd(new cOglCmdDrawImage(fb, argb, Image.Width(), Image.Height(), Point.X(), Point.Y())); | ||||
|     oglThread->DoCmd(new cOglCmdDrawImage(fb, argb, Image.Width(), Image.Height(), Point.X(), Point.Y(), true, FactorX, FactorY)); | ||||
|     SetDirty(); | ||||
|     MarkDrawPortDirty(cRect(Point, cSize(Image.Width(), Image.Height())).Intersected(DrawPort().Size())); | ||||
|     MarkDrawPortDirty(cRect(Point, cSize(Image.Width() * FactorX, Image.Height() * FactorY)).Intersected(DrawPort().Size())); | ||||
| } | ||||
|  | ||||
| void cOglPixmap::DrawImage(const cPoint &Point, int ImageHandle) { | ||||
|     DrawScaledImage(Point, ImageHandle); | ||||
| } | ||||
|  | ||||
| void cOglPixmap::DrawScaledImage(const cPoint &Point, int ImageHandle, double FactorX, double FactorY, bool AntiAlias) { | ||||
|     if (!oglThread->Active()) | ||||
|         return; | ||||
|  | ||||
|     if (ImageHandle < 0 && oglThread->GetImageRef(ImageHandle)) { | ||||
|         sOglImage *img = oglThread->GetImageRef(ImageHandle); | ||||
|  | ||||
|         oglThread->DoCmd(new cOglCmdDrawTexture(fb, img, Point.X(), Point.Y())); | ||||
|         oglThread->DoCmd(new cOglCmdDrawTexture(fb, img, Point.X(), Point.Y(), FactorX, FactorY)); | ||||
|         SetDirty(); | ||||
|         MarkDrawPortDirty(cRect(Point, cSize(img->width * FactorX, img->height * FactorY)).Intersected(DrawPort().Size())); | ||||
|     } | ||||
|     /* | ||||
|        Fallback to VDR implementation, needs to separate cSoftOsdProvider from | ||||
| @@ -1843,8 +1870,6 @@ void cOglPixmap::DrawImage(const cPoint &Point, int ImageHandle) { | ||||
|        DrawImage(Point, *cSoftOsdProvider::GetImageData(ImageHandle)); | ||||
|        } | ||||
|      */ | ||||
|     SetDirty(); | ||||
|     MarkDrawPortDirty(DrawPort()); | ||||
| } | ||||
|  | ||||
| void cOglPixmap::DrawPixel(const cPoint &Point, tColor Color) { | ||||
| @@ -2085,6 +2110,14 @@ cPixmap *cOglOsd::CreatePixmap(int Layer, const cRect &ViewPort, const cRect &Dr | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| extern "C" {void VideoSetOsdSize(int, int ) ;} | ||||
|  | ||||
| void SetOsdPosition(int Left, int Top, int Width, int Height) { | ||||
|     printf("Set OSD Position %d %d\n",Width,Height); | ||||
|   VideoSetOsdSize( Width, Height) ;  | ||||
| } | ||||
|  | ||||
| void cOglOsd::DestroyPixmap(cPixmap *Pixmap) { | ||||
|     if (!oglThread->Active()) | ||||
|         return; | ||||
| @@ -2130,10 +2163,16 @@ void cOglOsd::Flush(void) { | ||||
|         for (int i = 0; i < oglPixmaps.Size(); i++) { | ||||
|             if (oglPixmaps[i]) { | ||||
|                 if (oglPixmaps[i]->Layer() == layer) { | ||||
|                     oglThread->DoCmd(new cOglCmdRenderFbToBufferFb( | ||||
|                         oglPixmaps[i]->Fb(), bFb, oglPixmaps[i]->ViewPort().X(), | ||||
|                         (!isSubtitleOsd) ? oglPixmaps[i]->ViewPort().Y() : 0, oglPixmaps[i]->Alpha(), | ||||
|                         oglPixmaps[i]->DrawPort().X(), oglPixmaps[i]->DrawPort().Y())); | ||||
|                     bool alphablending = layer == 0 ? false : true; // Decide wether to render (with alpha) or copy a pixmap | ||||
|                     oglThread->DoCmd(new cOglCmdRenderFbToBufferFb( oglPixmaps[i]->Fb(),  | ||||
|                                                                     bFb, | ||||
|                                                                     oglPixmaps[i]->ViewPort().X(),  | ||||
|                                                                     (!isSubtitleOsd) ? oglPixmaps[i]->ViewPort().Y() : 0, | ||||
|                                                                     oglPixmaps[i]->Alpha(),  | ||||
|                                                                     oglPixmaps[i]->DrawPort().X(),  | ||||
|                                                                     oglPixmaps[i]->DrawPort().Y(), | ||||
|                                                                     alphablending | ||||
|                                                                     )); | ||||
|                     oglPixmaps[i]->SetDirty(false); | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -290,10 +290,11 @@ class cOglCmdRenderFbToBufferFb : public cOglCmd { | ||||
|     GLfloat x, y; | ||||
|     GLfloat drawPortX, drawPortY; | ||||
|     GLint transparency; | ||||
|     GLint alphablending; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdRenderFbToBufferFb(cOglFb *fb, cOglFb *buffer, GLint x, GLint y, GLint transparency, GLint drawPortX, | ||||
|                               GLint drawPortY); | ||||
|                               GLint drawPortY, bool alphablending); | ||||
|     virtual ~cOglCmdRenderFbToBufferFb(void){}; | ||||
|     virtual const char *Description(void) { return "Render Framebuffer to Buffer"; } | ||||
|     virtual bool Execute(void); | ||||
| @@ -402,9 +403,10 @@ class cOglCmdDrawTexture : public cOglCmd { | ||||
|   private: | ||||
|     sOglImage *imageRef; | ||||
|     GLint x, y; | ||||
|     GLfloat scaleX, scaleY; | ||||
|  | ||||
|   public: | ||||
|     cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y); | ||||
|     cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y, double scaleX = 1.0f, double scaleY = 1.0f); | ||||
|     virtual ~cOglCmdDrawTexture(void){}; | ||||
|     virtual const char *Description(void) { return "Draw Texture"; } | ||||
|     virtual bool Execute(void); | ||||
| @@ -500,6 +502,8 @@ class cOglPixmap : public cPixmap { | ||||
|     virtual void Fill(tColor Color); | ||||
|     virtual void DrawImage(const cPoint &Point, const cImage &Image); | ||||
|     virtual void DrawImage(const cPoint &Point, int ImageHandle); | ||||
|     virtual void DrawScaledImage(const cPoint &Point, const cImage &Image, double FactorX = 1.0f, double FactorY = 1.0f, bool AntiAlias = false); | ||||
|     virtual void DrawScaledImage(const cPoint &Point, int ImageHandle, double FactorX = 1.0f, double FactorY = 1.0f, bool AntiAlias = false); | ||||
|     virtual void DrawPixel(const cPoint &Point, tColor Color); | ||||
|     virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, | ||||
|                             bool Overlay = false); | ||||
| @@ -528,6 +532,7 @@ class cOglOsd : public cOsd { | ||||
|   public: | ||||
|     cOglOsd(int Left, int Top, uint Level, std::shared_ptr<cOglThread> oglThread); | ||||
|     virtual ~cOglOsd(); | ||||
|     static void SetOsdPosition(int Left, int Top, int Width, int Height); | ||||
|     virtual eOsdError SetAreas(const tArea *Areas, int NumAreas); | ||||
|     virtual cPixmap *CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null); | ||||
|     virtual void DestroyPixmap(cPixmap *Pixmap); | ||||
|   | ||||
| @@ -4,12 +4,8 @@ | ||||
| #ifdef CUVID | ||||
| const char *gl_version = "#version 330"; | ||||
| #else | ||||
| #ifdef RASPI | ||||
| const char *gl_version = "#version 300 es"; | ||||
| #else | ||||
| const char *gl_version = "#version 300 es "; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| /* Color conversion matrix: RGB = m * YUV + c | ||||
|  * m is in row-major matrix, with m[row][col], e.g.: | ||||
|   | ||||
							
								
								
									
										113
									
								
								softhdcuvid.cpp
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								softhdcuvid.cpp
									
									
									
									
									
								
							| @@ -61,7 +61,7 @@ extern void ToggleLUT(); | ||||
| /// vdr-plugin version number. | ||||
| /// Makefile extracts the version number for generating the file name | ||||
| /// for the distribution archive. | ||||
| static const char *const VERSION = "3.6" | ||||
| static const char *const VERSION = "3.20" | ||||
| #ifdef GIT_REV | ||||
|                                    "-GIT" GIT_REV | ||||
| #endif | ||||
| @@ -642,36 +642,107 @@ void cSoftOsd::Flush(void) { | ||||
|  | ||||
| #ifdef USE_OPENGLOSD | ||||
|  | ||||
| //Dummy Pixmap for skins | ||||
| // Dummy Pixmap for skins | ||||
| class cDummyPixmap : public cPixmap { | ||||
| public: | ||||
|     cDummyPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null) : cPixmap(Layer, ViewPort, DrawPort) {} | ||||
|   public: | ||||
|     cDummyPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null) | ||||
|         : cPixmap(Layer, ViewPort, DrawPort) {} | ||||
|     virtual ~cDummyPixmap(void) {} | ||||
|     virtual void Clear(void) {} | ||||
|     virtual void Fill(tColor Color) { (void)Color; } | ||||
|     virtual void DrawImage(const cPoint &Point, const cImage &Image) { (void)Point; (void)Image; } | ||||
|     virtual void DrawImage(const cPoint &Point, int ImageHandle) { (void)Point; (void)ImageHandle; } | ||||
|     virtual void DrawPixel(const cPoint &Point, tColor Color) { (void)Point; (void)Color; } | ||||
|     virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false) { | ||||
|         (void) Point; (void)Bitmap; (void)ColorFg; (void)ColorBg; (void)Overlay; } | ||||
|     virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault) { | ||||
|         (void)Point; (void)s; (void)ColorFg; (void) ColorBg; (void) Font; (void)Width; (void)Height; (void)Alignment; } | ||||
|     virtual void DrawRectangle(const cRect &Rect, tColor Color) { (void)Rect; (void)Color; } | ||||
|     virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants = 0) { (void)Rect; (void)Color; (void)Quadrants; } | ||||
|     virtual void DrawSlope(const cRect &Rect, tColor Color, int Type) { (void)Rect; (void)Color; (void)Type; } | ||||
|     virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) { (void)Pixmap; (void)Source; (void)Dest; } | ||||
|     virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) { (void)Pixmap; (void)Source; (void)Dest; } | ||||
|     virtual void Scroll(const cPoint &Dest, const cRect &Source = cRect::Null) { (void)Dest; (void)Source; } | ||||
|     virtual void Pan(const cPoint &Dest, const cRect &Source = cRect::Null) { (void)Dest; (void)Source; } | ||||
|     virtual void DrawImage(const cPoint &Point, const cImage &Image) { | ||||
|         (void)Point; | ||||
|         (void)Image; | ||||
|     } | ||||
|     virtual void DrawImage(const cPoint &Point, int ImageHandle) { | ||||
|         (void)Point; | ||||
|         (void)ImageHandle; | ||||
|     } | ||||
|     virtual void DrawScaledImage(const cPoint &Point, const cImage &Image, double FactorX, double FactorY, bool AntiAlias) { | ||||
|         (void)Point; | ||||
|         (void)Image; | ||||
|         (void)FactorX; | ||||
|         (void)FactorY; | ||||
|         (void)AntiAlias; | ||||
|     } | ||||
|     virtual void DrawScaledImage(const cPoint &Point, int ImageHandle, double FactorX, double FactorY, bool AntiAlias) { | ||||
|         (void)Point; | ||||
|         (void)ImageHandle; | ||||
|         (void)FactorX; | ||||
|         (void)FactorY; | ||||
|         (void)AntiAlias; | ||||
|     } | ||||
|     virtual void DrawPixel(const cPoint &Point, tColor Color) { | ||||
|         (void)Point; | ||||
|         (void)Color; | ||||
|     } | ||||
|     virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, | ||||
|                             bool Overlay = false) { | ||||
|         (void)Point; | ||||
|         (void)Bitmap; | ||||
|         (void)ColorFg; | ||||
|         (void)ColorBg; | ||||
|         (void)Overlay; | ||||
|     } | ||||
|     virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, | ||||
|                           int Width = 0, int Height = 0, int Alignment = taDefault) { | ||||
|         (void)Point; | ||||
|         (void)s; | ||||
|         (void)ColorFg; | ||||
|         (void)ColorBg; | ||||
|         (void)Font; | ||||
|         (void)Width; | ||||
|         (void)Height; | ||||
|         (void)Alignment; | ||||
|     } | ||||
|     virtual void DrawRectangle(const cRect &Rect, tColor Color) { | ||||
|         (void)Rect; | ||||
|         (void)Color; | ||||
|     } | ||||
|     virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants = 0) { | ||||
|         (void)Rect; | ||||
|         (void)Color; | ||||
|         (void)Quadrants; | ||||
|     } | ||||
|     virtual void DrawSlope(const cRect &Rect, tColor Color, int Type) { | ||||
|         (void)Rect; | ||||
|         (void)Color; | ||||
|         (void)Type; | ||||
|     } | ||||
|     virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) { | ||||
|         (void)Pixmap; | ||||
|         (void)Source; | ||||
|         (void)Dest; | ||||
|     } | ||||
|     virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) { | ||||
|         (void)Pixmap; | ||||
|         (void)Source; | ||||
|         (void)Dest; | ||||
|     } | ||||
|     virtual void Scroll(const cPoint &Dest, const cRect &Source = cRect::Null) { | ||||
|         (void)Dest; | ||||
|         (void)Source; | ||||
|     } | ||||
|     virtual void Pan(const cPoint &Dest, const cRect &Source = cRect::Null) { | ||||
|         (void)Dest; | ||||
|         (void)Source; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| // Dummy OSD for OpenGL OSD if no X Server is available | ||||
| class cDummyOsd : public cOsd { | ||||
|   private: | ||||
|     cDummyPixmap *p; | ||||
|  | ||||
|   public: | ||||
|     cDummyOsd(int Left, int Top, uint Level) : cOsd(Left, Top, Level) {} | ||||
|     virtual ~cDummyOsd() {} | ||||
|     static void SetOsdPosition(int Left, int Top, int Width, int Height) { | ||||
|         (void) Left; | ||||
|         (void) Top; | ||||
|         (void) Width; | ||||
|         (void) Height; | ||||
|     } | ||||
|     virtual cPixmap *CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null) { | ||||
|         p = new cDummyPixmap(Layer, ViewPort, DrawPort); | ||||
|         return p; | ||||
| @@ -1096,9 +1167,9 @@ void cMenuSetupSoft::Create(void) { | ||||
|  | ||||
|     if (scalers == 0) { | ||||
|         scalingtest[0] = (char *)"Off"; | ||||
|         for (scalers = 0; pl_named_filters[scalers].name != NULL; scalers++) { | ||||
|             scaling[scalers] = (char *)pl_named_filters[scalers].name; | ||||
|             scalingtest[scalers + 1] = (char *)pl_named_filters[scalers].name; | ||||
|         for (scalers = 0; pl_filter_presets[scalers].name != NULL; scalers++) { | ||||
|             scaling[scalers] = (char *)pl_filter_presets[scalers].name; | ||||
|             scalingtest[scalers + 1] = (char *)pl_filter_presets[scalers].name; | ||||
|             // printf("Scaler %s\n",pl_named_filters[scalers].name); | ||||
|         } | ||||
|         // scalers -= 2; | ||||
|   | ||||
							
								
								
									
										10
									
								
								softhddev.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								softhddev.c
									
									
									
									
									
								
							| @@ -364,7 +364,7 @@ static int Ac3Check(const uint8_t *data, int size) { | ||||
|         if ((data[4] & 0xF0) == 0xF0) { // invalid fscod fscod2 | ||||
|             return 0; | ||||
|         } | ||||
|         frame_size = ((data[2] & 0x03) << 8) + data[3] + 1; | ||||
|         frame_size = ((data[2] & 0x07) << 8) + data[3] + 1; | ||||
|         frame_size *= 2; | ||||
|     } else { // AC-3 | ||||
|         int fscod; | ||||
| @@ -2142,7 +2142,7 @@ int PlayVideo3(VideoStream *stream, const uint8_t *data, int size) { | ||||
|     } | ||||
|     // hard limit buffer full: needed for replay | ||||
|     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; | ||||
|     } | ||||
| #ifdef USE_SOFTLIMIT | ||||
| @@ -2817,8 +2817,8 @@ const char *CommandLineHelp(void) { | ||||
|            "\tstill-h264-hw-decoder\tenable h264 hw decoder for still-pictures\n" | ||||
|            "\talsa-driver-broken\tdisable broken alsa driver message\n" | ||||
|            "\talsa-no-close-open\tdisable close open to fix alsa no sound bug\n" | ||||
|            "\talsa-close-open-delay\tenable close open delay to fix no sound " | ||||
|            "bug\n" | ||||
|            "\talsa-no-test\tdisable Alsa Capability test on start for NUC11/12\n" | ||||
|            "\talsa-close-open-delay\tenable close open delay to fix no sound bug\n" | ||||
|            "\tignore-repeat-pict\tdisable repeat pict message\n" | ||||
|            "\tuse-possible-defect-frames prefer faster channel switch\n" | ||||
|            "	 -D\t\tstart in detached mode\n"; | ||||
| @@ -2908,6 +2908,8 @@ int ProcessArgs(int argc, char *const argv[]) { | ||||
|                     AudioAlsaDriverBroken = 1; | ||||
|                 } else if (!strcasecmp("alsa-no-close-open", optarg)) { | ||||
|                     AudioAlsaNoCloseOpen = 1; | ||||
|                 } else if (!strcasecmp("alsa-no-test", optarg)) { | ||||
|                     AudioAlsaNotest = 1; | ||||
|                 } else if (!strcasecmp("alsa-close-open-delay", optarg)) { | ||||
|                     AudioAlsaCloseOpenDelay = 1; | ||||
|                 } else if (!strcasecmp("ignore-repeat-pict", optarg)) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user