mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
				synced 2023-10-10 17:16:51 +00:00 
			
		
		
		
	Improved replay of recordings.
This commit is contained in:
		
							
								
								
									
										2
									
								
								Todo
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Todo
									
									
									
									
									
								
							| @@ -83,8 +83,8 @@ HDMI/SPDIF Passthrough: | ||||
|     Channels are wrong setup, if changing setting during operation. | ||||
|  | ||||
| playback of recording | ||||
|     play back is too fast | ||||
|     pause is not reset, when replay exit | ||||
|     replay/pause need 100% cpu | ||||
|  | ||||
| setup: | ||||
|     Setup of decoder type. | ||||
|   | ||||
							
								
								
									
										99
									
								
								audio.c
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								audio.c
									
									
									
									
									
								
							| @@ -342,6 +342,11 @@ static int AlsaPlayRingbuffer(void) | ||||
| 		if (err == -EAGAIN) { | ||||
| 		    goto again; | ||||
| 		} | ||||
| 		/* | ||||
| 		   if (err == -EBADFD) { | ||||
| 		   goto again; | ||||
| 		   } | ||||
| 		 */ | ||||
| 		Error(_("audio/alsa: underrun error?\n")); | ||||
| 		err = snd_pcm_recover(AlsaPCMHandle, err, 0); | ||||
| 		if (err >= 0) { | ||||
| @@ -370,9 +375,13 @@ static void AlsaFlushBuffers(void) | ||||
|     int err; | ||||
|  | ||||
|     RingBufferReadAdvance(AlsaRingBuffer, RingBufferUsedBytes(AlsaRingBuffer)); | ||||
|     if ((err = snd_pcm_drop(AlsaPCMHandle))) { | ||||
|     if ((err = snd_pcm_drop(AlsaPCMHandle)) < 0) { | ||||
| 	Error(_("audio: snd_pcm_drop(): %s\n"), snd_strerror(err)); | ||||
|     } | ||||
|     if ((err = snd_pcm_prepare(AlsaPCMHandle)) < 0) { | ||||
| 	Error(_("audio: snd_pcm_prepare(): %s\n"), snd_strerror(err)); | ||||
|     } | ||||
|     AudioPTS = INT64_C(0x8000000000000000); | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| @@ -567,8 +576,20 @@ static void AlsaThread(void) | ||||
|     for (;;) { | ||||
| 	int err; | ||||
|  | ||||
| 	Debug(4, "audio: play loop\n"); | ||||
| 	pthread_testcancel(); | ||||
| 	if (AlsaFlushBuffer) { | ||||
| 	    // we can flush too many, but wo cares | ||||
| 	    Debug(3, "audio/alsa: flushing buffers\n"); | ||||
| 	    AlsaFlushBuffers(); | ||||
| 	    /* | ||||
| 	       if ((err = snd_pcm_prepare(AlsaPCMHandle))) { | ||||
| 	       Error(_("audio: snd_pcm_prepare(): %s\n"), snd_strerror(err)); | ||||
| 	       } | ||||
| 	     */ | ||||
| 	    AlsaFlushBuffer = 0; | ||||
| 	    break; | ||||
| 	} | ||||
| 	// wait for space in kernel buffers | ||||
| 	if ((err = snd_pcm_wait(AlsaPCMHandle, 100)) < 0) { | ||||
| 	    Error(_("audio/alsa: wait underrun error?\n")); | ||||
| 	    err = snd_pcm_recover(AlsaPCMHandle, err, 0); | ||||
| @@ -580,14 +601,7 @@ static void AlsaThread(void) | ||||
| 	    continue; | ||||
| 	} | ||||
| 	if (AlsaFlushBuffer) { | ||||
| 	    // we can flush too many, but wo cares | ||||
| 	    Debug(3, "audio/alsa: flushing buffers\n"); | ||||
| 	    AlsaFlushBuffers(); | ||||
| 	    if ((err = snd_pcm_prepare(AlsaPCMHandle))) { | ||||
| 		Error(_("audio: snd_pcm_prepare(): %s\n"), snd_strerror(err)); | ||||
| 	    } | ||||
| 	    AlsaFlushBuffer = 0; | ||||
| 	    break; | ||||
| 	    continue; | ||||
| 	} | ||||
| 	if ((err = AlsaPlayRingbuffer())) {	// empty / error | ||||
| 	    snd_pcm_state_t state; | ||||
| @@ -600,7 +614,8 @@ static void AlsaThread(void) | ||||
| 		Debug(3, "audio/alsa: stopping play\n"); | ||||
| 		break; | ||||
| 	    } | ||||
| 	    usleep(20 * 1000); | ||||
| 	    pthread_yield(); | ||||
| 	    usleep(20 * 1000);		// let fill the buffers | ||||
| 	} | ||||
|     } | ||||
| } | ||||
| @@ -1195,6 +1210,21 @@ static int OssPlayRingbuffer(void) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Flush oss buffers. | ||||
| */ | ||||
| static void OssFlushBuffers(void) | ||||
| { | ||||
|     RingBufferReadAdvance(OssRingBuffer, RingBufferUsedBytes(OssRingBuffer)); | ||||
|     // flush kernel buffers | ||||
|     if (ioctl(OssPcmFildes, SNDCTL_DSP_HALT_OUTPUT, NULL) < 0) { | ||||
| 	Error(_("audio/oss: ioctl(SNDCTL_DSP_HALT_OUTPUT): %s\n"), | ||||
| 	    strerror(errno)); | ||||
| 	return; | ||||
|     } | ||||
|     AudioPTS = INT64_C(0x8000000000000000); | ||||
| } | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| //	OSS pcm polled | ||||
| //---------------------------------------------------------------------------- | ||||
| @@ -1410,14 +1440,7 @@ static int OssSetup(int *freq, int *channels) | ||||
|     // flush any buffered data | ||||
|     { | ||||
| 	AudioRunning = 0; | ||||
| 	RingBufferReadAdvance(OssRingBuffer, | ||||
| 	    RingBufferUsedBytes(OssRingBuffer)); | ||||
| 	// flush kernel buffers | ||||
| 	if (ioctl(OssPcmFildes, SNDCTL_DSP_HALT_OUTPUT, NULL) == -1) { | ||||
| 	    Error(_("audio/oss: ioctl(SNDCTL_DSP_HALT_OUTPUT): %s\n"), | ||||
| 		strerror(errno)); | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	OssFlushBuffers(); | ||||
|     } | ||||
|     AudioPTS = INT64_C(0x8000000000000000); | ||||
|  | ||||
| @@ -1672,6 +1695,30 @@ void AudioEnqueue(const void *samples, int count) | ||||
|     (void)count; | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Flush audio buffers. | ||||
| */ | ||||
| void AudioFlushBuffers(void) | ||||
| { | ||||
| #ifdef USE_ALSA | ||||
| #ifdef USE_AUDIO_THREAD | ||||
|     if (AudioRunning) { | ||||
| 	while (AudioRunning) { | ||||
| 	    AlsaFlushBuffer = 1; | ||||
| 	    usleep(1 * 1000); | ||||
| 	} | ||||
| 	AlsaFlushBuffer = 0; | ||||
|     } else | ||||
| #endif | ||||
|     { | ||||
| 	AlsaFlushBuffers(); | ||||
|     } | ||||
| #endif | ||||
| #ifdef USE_OSS | ||||
|     OssFlushBuffers(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Call back to play audio polled. | ||||
| */ | ||||
| @@ -1687,6 +1734,20 @@ void AudioPoller(void) | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Get free bytes in audio output. | ||||
| */ | ||||
| int AudioFreeBytes(void) | ||||
| { | ||||
| #ifdef USE_ALSA | ||||
|     return RingBufferFreeBytes(AlsaRingBuffer); | ||||
| #endif | ||||
| #ifdef USE_OSS | ||||
|     return RingBufferFreeBytes(OssRingBuffer); | ||||
| #endif | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Set audio clock base. | ||||
| ** | ||||
|   | ||||
							
								
								
									
										8
									
								
								audio.h
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								audio.h
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| /// | ||||
| ///	@file audio.h		@brief Audio module headerfile | ||||
| /// | ||||
| ///	Copyright (c) 2009 - 2011 by Johns.  All Rights Reserved. | ||||
| ///	Copyright (c) 2009 - 2012 by Johns.  All Rights Reserved. | ||||
| /// | ||||
| ///	Contributor(s): | ||||
| /// | ||||
| @@ -28,12 +28,14 @@ | ||||
| //---------------------------------------------------------------------------- | ||||
|  | ||||
| extern void AudioEnqueue(const void *, int);	///< buffer audio samples | ||||
| extern void AudioFlushBuffers(void);	///< flush audio buffers | ||||
| extern void AudioPoller(void);		///< poll audio events/handling | ||||
|  | ||||
| extern int AudioFreeBytes(void);	///< free bytes in audio output | ||||
|  | ||||
| //extern int AudioFreeBytes(void);	///< free bytes in audio output | ||||
| //extern int AudioUsedBytes(void);	///< used bytes in audio output | ||||
| extern void AudioSetClock(int64_t);	///< set audio clock base | ||||
| extern int64_t AudioGetClock();		///< get current audio clock | ||||
|  | ||||
| extern uint64_t AudioGetDelay(void);	///< get current audio delay | ||||
|  | ||||
| extern int AudioSetup(int *, int *);	///< setup audio output | ||||
|   | ||||
							
								
								
									
										23
									
								
								codec.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								codec.c
									
									
									
									
									
								
							| @@ -561,6 +561,16 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Flush the video decoder. | ||||
| ** | ||||
| **	@param decoder	video decoder data | ||||
| */ | ||||
| void CodecVideoFlushBuffers(VideoDecoder * decoder) | ||||
| { | ||||
|     avcodec_flush_buffers(decoder->VideoCtx); | ||||
| } | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| //	Audio | ||||
| //---------------------------------------------------------------------------- | ||||
| @@ -738,9 +748,11 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt) | ||||
|     spkt->pts = avpkt->pts; | ||||
|     spkt->dts = avpkt->dts; | ||||
| #endif | ||||
| #ifdef DEBUG | ||||
|     if (!audio_decoder->AudioParser) { | ||||
| 	Fatal(_("codec: internal error parser freeded while running\n")); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     audio_ctx = audio_decoder->AudioCtx; | ||||
|     index = 0; | ||||
| @@ -1026,6 +1038,17 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt) | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /** | ||||
| **	Flush the audio decoder. | ||||
| ** | ||||
| **	@param decoder	audio decoder data | ||||
| */ | ||||
| void CodecAudioFlushBuffers(AudioDecoder * decoder) | ||||
| { | ||||
|     // FIXME: reset audio parser | ||||
|     avcodec_flush_buffers(decoder->AudioCtx); | ||||
| } | ||||
|  | ||||
| //---------------------------------------------------------------------------- | ||||
| //	Codec | ||||
| //---------------------------------------------------------------------------- | ||||
|   | ||||
							
								
								
									
										24
									
								
								codec.h
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								codec.h
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| /// | ||||
| ///	@file codec.h	@brief Codec module headerfile | ||||
| /// | ||||
| ///	Copyright (c) 2009 - 2011 by Johns.  All Rights Reserved. | ||||
| ///	Copyright (c) 2009 - 2012 by Johns.  All Rights Reserved. | ||||
| /// | ||||
| ///	Contributor(s): | ||||
| /// | ||||
| @@ -40,26 +40,32 @@ typedef struct _audio_decoder_ AudioDecoder; | ||||
|     /// Allocate a new video decoder context. | ||||
| extern VideoDecoder *CodecVideoNewDecoder(VideoHwDecoder *); | ||||
|  | ||||
|     /// Open video codec | ||||
|     /// Open video codec. | ||||
| extern void CodecVideoOpen(VideoDecoder *, const char *, int); | ||||
|  | ||||
|     /// Close video codec | ||||
|     /// Close video codec. | ||||
| extern void CodecVideoClose(VideoDecoder *); | ||||
|  | ||||
|     /// Decode a video packet | ||||
| extern void CodecVideoDecode(VideoDecoder *, const AVPacket * pkt); | ||||
|     /// Decode a video packet. | ||||
| extern void CodecVideoDecode(VideoDecoder *, const AVPacket *); | ||||
|  | ||||
|     /// Flush video buffers. | ||||
| extern void CodecVideoFlushBuffers(VideoDecoder *); | ||||
|  | ||||
|     /// Allocate a new audio decoder context. | ||||
| extern AudioDecoder *CodecAudioNewDecoder(void); | ||||
|  | ||||
|     /// Open audio codec | ||||
|     /// Open audio codec. | ||||
| extern void CodecAudioOpen(AudioDecoder *, const char *, int); | ||||
|  | ||||
|     /// Close audio codec | ||||
|     /// Close audio codec. | ||||
| extern void CodecAudioClose(AudioDecoder *); | ||||
|  | ||||
|     /// Decode an audio packet | ||||
| extern void CodecAudioDecode(AudioDecoder *, const AVPacket * pkt); | ||||
|     /// Decode an audio packet. | ||||
| extern void CodecAudioDecode(AudioDecoder *, const AVPacket *); | ||||
|  | ||||
|     /// Flush audio buffers. | ||||
| extern void CodecAudioFlushBuffers(AudioDecoder *); | ||||
|  | ||||
|     /// Setup and initialize codec module. | ||||
| extern void CodecInit(void); | ||||
|   | ||||
							
								
								
									
										78
									
								
								softhddev.c
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								softhddev.c
									
									
									
									
									
								
							| @@ -59,6 +59,7 @@ static const char DeviceStopped = 1;	///< flag device stopped | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| static volatile char NewAudioStream;	///< new audio stream | ||||
| static volatile char SkipAudio;		///< skip audio stream | ||||
| static AudioDecoder *MyAudioDecoder;	///< audio decoder | ||||
| static enum CodecID AudioCodecID;	///< current codec id | ||||
|  | ||||
| @@ -185,10 +186,11 @@ static int FindAudioSync(const AVPacket * avpkt) | ||||
| **	@param size	size of PES packet | ||||
| **	@param id	PES packet type | ||||
| */ | ||||
| void PlayAudio(const uint8_t * data, int size, | ||||
| int PlayAudio(const uint8_t * data, int size, | ||||
|     __attribute__ ((unused)) uint8_t id) | ||||
| { | ||||
|     int n; | ||||
|     int osize; | ||||
|     AVPacket avpkt[1]; | ||||
|  | ||||
|     // channel switch: SetAudioChannelDevice: SetDigitalAudioDevice: | ||||
| @@ -199,12 +201,19 @@ void PlayAudio(const uint8_t * data, int size, | ||||
| 	AudioCodecID = CODEC_ID_NONE; | ||||
| 	NewAudioStream = 0; | ||||
|     } | ||||
|     if (SkipAudio) { | ||||
| 	return size; | ||||
|     } | ||||
|     // PES header 0x00 0x00 0x01 ID | ||||
|     // ID 0xBD 0xC0-0xCF | ||||
|  | ||||
|     if (size < 9) { | ||||
| 	Error(_("[softhddev] invalid audio packet\n")); | ||||
| 	return; | ||||
| 	return size; | ||||
|     } | ||||
|     // Don't overrun audio buffers on replay | ||||
|     if (AudioFreeBytes() < 3072 * 8 * 8) {	// 8 channels 8 packets | ||||
| 	return 0; | ||||
|     } | ||||
|  | ||||
|     n = data[8];			// header size | ||||
| @@ -225,11 +234,12 @@ void PlayAudio(const uint8_t * data, int size, | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|     osize = size; | ||||
|     data += 9 + n; | ||||
|     size -= 9 + n;			// skip pes header | ||||
|     if (size <= 0) { | ||||
| 	Error(_("[softhddev] invalid audio packet\n")); | ||||
| 	return; | ||||
| 	return osize; | ||||
|     } | ||||
|     // Detect audio code | ||||
|     // MPEG-PS mp2 MPEG1, MPEG2, AC3 | ||||
| @@ -271,7 +281,7 @@ void PlayAudio(const uint8_t * data, int size, | ||||
| 	    avpkt->size = size; | ||||
| 	    n = FindAudioSync(avpkt); | ||||
| 	    if (n < 0) { | ||||
| 		return; | ||||
| 		return osize; | ||||
| 	    } | ||||
| 	    if (!MyAudioDecoder) { | ||||
| 		MyAudioDecoder = CodecAudioNewDecoder(); | ||||
| @@ -286,13 +296,15 @@ void PlayAudio(const uint8_t * data, int size, | ||||
|  | ||||
|     // no decoder or codec known | ||||
|     if (!MyAudioDecoder || AudioCodecID == CODEC_ID_NONE) { | ||||
| 	return; | ||||
| 	return osize; | ||||
|     } | ||||
|  | ||||
|     avpkt->data = (void *)data; | ||||
|     avpkt->size = size; | ||||
|     //memset(avpkt->data + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); | ||||
|     CodecAudioDecode(MyAudioDecoder, avpkt); | ||||
|  | ||||
|     return osize; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -300,6 +312,7 @@ void PlayAudio(const uint8_t * data, int size, | ||||
| */ | ||||
| void Mute(void) | ||||
| { | ||||
|     SkipAudio = 1; | ||||
|     AudioSetVolume(0); | ||||
| } | ||||
|  | ||||
| @@ -480,6 +493,10 @@ int VideoDecode(void) | ||||
|     } | ||||
|     if (VideoClearBuffers) { | ||||
| 	atomic_set(&VideoPacketsFilled, 0); | ||||
| 	VideoPacketRead = VideoPacketWrite; | ||||
| 	if (MyVideoDecoder) { | ||||
| 	    CodecVideoFlushBuffers(MyVideoDecoder); | ||||
| 	} | ||||
| 	VideoClearBuffers = 0; | ||||
| 	return 1; | ||||
|     } | ||||
| @@ -751,8 +768,12 @@ void SetPlayMode(void) | ||||
| 	} | ||||
|     } | ||||
|     if (MyAudioDecoder) { | ||||
| 	NewAudioStream = 1; | ||||
| 	if (AudioCodecID != CODEC_ID_NONE) { | ||||
| 	    NewAudioStream = 1; | ||||
| 	} | ||||
|     } | ||||
|     VideoFreezed = 0; | ||||
|     SkipAudio = 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -760,9 +781,16 @@ void SetPlayMode(void) | ||||
| */ | ||||
| void Clear(void) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     VideoNextPacket(VideoCodecID);	// terminate work | ||||
|     VideoClearBuffers = 1; | ||||
|     // FIXME: avcodec_flush_buffers | ||||
|     // FIXME: flush audio buffers | ||||
|     AudioFlushBuffers(); | ||||
|  | ||||
|     for (i = 0; VideoClearBuffers && i < 20; ++i) { | ||||
| 	usleep(1 * 1000); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -771,6 +799,7 @@ void Clear(void) | ||||
| void Play(void) | ||||
| { | ||||
|     VideoFreezed = 0; | ||||
|     SkipAudio = 0; | ||||
|     // FIXME: restart audio | ||||
| } | ||||
|  | ||||
| @@ -781,16 +810,33 @@ void Freeze(void) | ||||
| { | ||||
|     VideoFreezed = 1; | ||||
|     // FIXME: freeze audio | ||||
|     AudioFlushBuffers(); | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Display the given I-frame as a still picture. | ||||
| */ | ||||
| void StillPicture(const uint8_t * data, int size) | ||||
| { | ||||
|     // must be a PES start code | ||||
|     if (size < 9 || !data || data[0] || data[1] || data[2] != 0x01) { | ||||
| 	Error(_("[softhddev] invalid PES video packet\n")); | ||||
| 	return; | ||||
|     } | ||||
|     PlayVideo(data, size); | ||||
|     PlayVideo(data, size); | ||||
|     VideoNextPacket(VideoCodecID);	// terminate work | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Poll if device is ready.  Called by replay. | ||||
| ** | ||||
| **	@param timeout	timeout to become ready in ms | ||||
| */ | ||||
| int Poll(int timeout) | ||||
| { | ||||
|     // buffers are too full | ||||
|     if (atomic_read(&VideoPacketsFilled) >= VIDEO_PACKET_MAX / 2) { | ||||
| 	Debug(3, "replay: poll %d\n", timeout); | ||||
| 	if (timeout) { | ||||
| 	    // let display thread work | ||||
| 	    usleep(timeout * 1000); | ||||
| @@ -800,6 +846,22 @@ int Poll(int timeout) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Flush the device output buffers. | ||||
| ** | ||||
| **	@param timeout	timeout to flush in ms | ||||
| */ | ||||
| int Flush(int timeout) | ||||
| { | ||||
|     if (atomic_read(&VideoPacketsFilled)) { | ||||
| 	if (timeout) {			// let display thread work | ||||
| 	    usleep(timeout * 1000); | ||||
| 	} | ||||
| 	return !atomic_read(&VideoPacketsFilled); | ||||
|     } | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| //	OSD | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| /// | ||||
| ///	@file softhddev.h	@brief software HD device plugin header file. | ||||
| /// | ||||
| ///	Copyright (c) 2011 by Johns.  All Rights Reserved. | ||||
| ///	Copyright (c) 2011 - 2012 by Johns.  All Rights Reserved. | ||||
| /// | ||||
| ///	Contributor(s): | ||||
| /// | ||||
| @@ -36,7 +36,7 @@ extern "C" | ||||
|     extern void OsdDrawARGB(int, int, int, int, const uint8_t *); | ||||
|  | ||||
|     /// C plugin play audio packet | ||||
|     extern void PlayAudio(const uint8_t *, int, uint8_t); | ||||
|     extern int PlayAudio(const uint8_t *, int, uint8_t); | ||||
|     /// C plugin mute audio | ||||
|     extern void Mute(void); | ||||
|     /// C plugin set audio volume | ||||
| @@ -55,8 +55,12 @@ extern "C" | ||||
|     extern void Play(void); | ||||
|     /// C plugin sets the device into "freeze frame" mode | ||||
|     extern void Freeze(void); | ||||
|     /// C plugin display I-frame as a still picture. | ||||
|     extern void StillPicture(const uint8_t *, int); | ||||
|     /// C plugin poll if ready | ||||
|     extern int Poll(int); | ||||
|     /// C plugin flush output buffers | ||||
|     extern int Flush(int); | ||||
|  | ||||
|     /// C plugin command line help | ||||
|     extern const char *CommandLineHelp(void); | ||||
|   | ||||
| @@ -499,9 +499,14 @@ int64_t cSoftHdDevice::GetSTC(void) | ||||
|     return::VideoGetClock(); | ||||
| } | ||||
|  | ||||
| void cSoftHdDevice::TrickSpeed(int Speed) | ||||
| /** | ||||
| **	Set trick play speed. | ||||
| ** | ||||
| **	@param speed	trick speed | ||||
| */ | ||||
| void cSoftHdDevice::TrickSpeed(int speed) | ||||
| { | ||||
|     dsyslog("[softhddev]%s: %d\n", __FUNCTION__, Speed); | ||||
|     dsyslog("[softhddev]%s: %d\n", __FUNCTION__, speed); | ||||
| } | ||||
|  | ||||
| void cSoftHdDevice::Clear(void) | ||||
| @@ -533,24 +538,37 @@ void cSoftHdDevice::Mute(void) | ||||
|     dsyslog("[softhddev]%s:\n", __FUNCTION__); | ||||
|  | ||||
|     cDevice::Mute(); | ||||
|  | ||||
|     ::Mute(); | ||||
| } | ||||
|  | ||||
| void cSoftHdDevice::SetVolumeDevice(int volume) | ||||
| { | ||||
|     //dsyslog("[softhddev]%s: %d\n", __FUNCTION__, volume); | ||||
|     dsyslog("[softhddev]%s: %d\n", __FUNCTION__, volume); | ||||
|  | ||||
|     ::SetVolumeDevice(volume); | ||||
| } | ||||
|  | ||||
| void cSoftHdDevice::StillPicture( | ||||
|     __attribute__ ((unused)) const uchar * data, __attribute__ ((unused)) | ||||
|     int length) | ||||
| /** | ||||
| **	Display the given I-frame as a still picture. | ||||
| */ | ||||
| void cSoftHdDevice::StillPicture(const uchar * data, int length) | ||||
| { | ||||
|     dsyslog("[softhddev]%s:\n", __FUNCTION__); | ||||
|  | ||||
|     if ( data[0] == 0x47 ) {		// ts sync | ||||
| 	cDevice::StillPicture(data, length); | ||||
| 	return; | ||||
|     } | ||||
|  | ||||
|     ::StillPicture(data, length); | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Check if the device is ready for further action. | ||||
| ** | ||||
| **	@param poller		file handles (unused) | ||||
| **	@param timeout_ms	timeout in ms to become ready | ||||
| */ | ||||
| bool cSoftHdDevice::Poll( | ||||
|     __attribute__ ((unused)) cPoller & poller, int timeout_ms) | ||||
| { | ||||
| @@ -559,11 +577,16 @@ bool cSoftHdDevice::Poll( | ||||
|     return::Poll(timeout_ms); | ||||
| } | ||||
|  | ||||
| /** | ||||
| **	Flush the device output buffers. | ||||
| ** | ||||
| **	@param timeout_ms	timeout in ms to become ready | ||||
| */ | ||||
| bool cSoftHdDevice::Flush(int timeout_ms) | ||||
| { | ||||
|     dsyslog("[softhddev]%s: %d ms\n", __FUNCTION__, timeout_ms); | ||||
|  | ||||
|     return true; | ||||
|     return::Flush(timeout_ms); | ||||
| } | ||||
|  | ||||
| // ---------------------------------------------------------------------------- | ||||
| @@ -580,13 +603,14 @@ void cSoftHdDevice::GetOsdSize(int &width, int &height, double &pixel_aspect) | ||||
|  | ||||
| // ---------------------------------------------------------------------------- | ||||
|  | ||||
| /** | ||||
| **	Play a audio packet. | ||||
| */ | ||||
| int cSoftHdDevice::PlayAudio(const uchar * data, int length, uchar id) | ||||
| { | ||||
|     //dsyslog("[softhddev]%s: %p %p %d %d\n", __FUNCTION__, this, data, length, id); | ||||
|  | ||||
|     ::PlayAudio(data, length, id); | ||||
|  | ||||
|     return length; | ||||
|     return::PlayAudio(data, length, id); | ||||
| } | ||||
|  | ||||
| void cSoftHdDevice::SetAudioTrackDevice( | ||||
|   | ||||
							
								
								
									
										15
									
								
								video.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								video.c
									
									
									
									
									
								
							| @@ -6245,6 +6245,7 @@ enum PixelFormat Video_get_format(VideoHwDecoder * decoder, | ||||
| static void VideoSetPts(int64_t * pts_p, int interlaced, const AVFrame * frame) | ||||
| { | ||||
|     int64_t pts; | ||||
|     int64_t delta; | ||||
|  | ||||
|     // update video clock | ||||
|     if ((uint64_t) * pts_p != AV_NOPTS_VALUE) { | ||||
| @@ -6259,14 +6260,16 @@ static void VideoSetPts(int64_t * pts_p, int interlaced, const AVFrame * frame) | ||||
|     if (!pts) { | ||||
| 	pts = AV_NOPTS_VALUE; | ||||
|     } | ||||
|     // build a monotonic pts | ||||
|     if ((uint64_t) * pts_p != AV_NOPTS_VALUE) { | ||||
| 	if (pts - *pts_p < -10 * 90) { | ||||
| 	    pts = AV_NOPTS_VALUE; | ||||
| 	} | ||||
|     } | ||||
|     // libav: sets only pkt_dts which can be 0 | ||||
|     if ((uint64_t) pts != AV_NOPTS_VALUE) { | ||||
| 	// build a monotonic pts | ||||
| 	if ((uint64_t) * pts_p != AV_NOPTS_VALUE) { | ||||
| 	    delta = pts - *pts_p; | ||||
| 	    // ignore negative jumps | ||||
| 	    if (delta > -300 * 90 && delta < -15 * 90) { | ||||
| 		return; | ||||
| 	    } | ||||
| 	} | ||||
| 	if (*pts_p != pts) { | ||||
| 	    Debug(3, | ||||
| 		"video: %#012" PRIx64 "->%#012" PRIx64 " %4" PRId64 " pts\n", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user