Buffer less video and audio.

This commit is contained in:
Johns 2012-04-05 15:47:59 +02:00
parent 8612044b9b
commit c986d285ea
3 changed files with 53 additions and 16 deletions

View File

@ -2,6 +2,8 @@ User johns
Date: Date:
Release Version 0.5.0 Release Version 0.5.0
Buffer less video and audio.
Fix 100% cpu use, with mp3 plugin.
Audio/Video sync rewrite, trick-speed support moved to video. Audio/Video sync rewrite, trick-speed support moved to video.
Faster VdpauBlackSurface version. Faster VdpauBlackSurface version.
Fix bug: VideoSetPts wrong position for multi frame packets. Fix bug: VideoSetPts wrong position for multi frame packets.

View File

@ -878,13 +878,12 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
// channel switch: SetAudioChannelDevice: SetDigitalAudioDevice: // channel switch: SetAudioChannelDevice: SetDigitalAudioDevice:
if (StreamFreezed) { // stream freezed
return 0;
}
if (SkipAudio || !MyAudioDecoder) { // skip audio if (SkipAudio || !MyAudioDecoder) { // skip audio
return size; return size;
} }
if (StreamFreezed) { // stream freezed
return 0;
}
if (NewAudioStream) { if (NewAudioStream) {
// this clears the audio ringbuffer indirect, open and setup does it // this clears the audio ringbuffer indirect, open and setup does it
CodecAudioClose(MyAudioDecoder); CodecAudioClose(MyAudioDecoder);
@ -893,10 +892,14 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
AudioChannelID = -1; AudioChannelID = -1;
NewAudioStream = 0; NewAudioStream = 0;
} }
// Don't overrun audio buffers on replay // hard limit buffer full: don't overrun audio buffers on replay
if (AudioFreeBytes() < AUDIO_MIN_BUFFER_FREE) { if (AudioFreeBytes() < AUDIO_MIN_BUFFER_FREE) {
return 0; return 0;
} }
// soft limit buffer full
if (AudioUsedBytes() > AUDIO_MIN_BUFFER_FREE && VideoGetBuffers() > 3) {
return 0;
}
// PES header 0x00 0x00 0x01 ID // PES header 0x00 0x00 0x01 ID
// ID 0xBD 0xC0-0xCF // ID 0xBD 0xC0-0xCF
@ -1088,17 +1091,12 @@ int PlayTsAudio(const uint8_t * data, int size)
{ {
static TsDemux tsdx[1]; static TsDemux tsdx[1];
if (StreamFreezed) { // stream freezed
return 0;
}
if (SkipAudio || !MyAudioDecoder) { // skip audio if (SkipAudio || !MyAudioDecoder) { // skip audio
return size; return size;
} }
// Don't overrun audio buffers on replay if (StreamFreezed) { // stream freezed
if (AudioFreeBytes() < AUDIO_MIN_BUFFER_FREE) {
return 0; return 0;
} }
if (NewAudioStream) { if (NewAudioStream) {
// this clears the audio ringbuffer indirect, open and setup does it // this clears the audio ringbuffer indirect, open and setup does it
CodecAudioClose(MyAudioDecoder); CodecAudioClose(MyAudioDecoder);
@ -1109,6 +1107,15 @@ int PlayTsAudio(const uint8_t * data, int size)
NewAudioStream = 0; NewAudioStream = 0;
PesReset(PesDemuxAudio); PesReset(PesDemuxAudio);
} }
// hard limit buffer full: don't overrun audio buffers on replay
if (AudioFreeBytes() < AUDIO_MIN_BUFFER_FREE) {
return 0;
}
// soft limit buffer full
if (AudioUsedBytes() > AUDIO_MIN_BUFFER_FREE && VideoGetBuffers() > 3) {
return 0;
}
return TsDemuxer(tsdx, data, size); return TsDemuxer(tsdx, data, size);
} }
@ -1612,10 +1619,6 @@ int PlayVideo(const uint8_t * data, int size)
int z; int z;
int l; int l;
if (Usr1Signal) { // x11 server ready
Usr1Signal = 0;
StartVideo();
}
if (!MyVideoDecoder) { // no x11 video started if (!MyVideoDecoder) { // no x11 video started
return size; return size;
} }
@ -1660,10 +1663,15 @@ int PlayVideo(const uint8_t * data, int size)
} }
return size; return size;
} }
// buffer full: needed for replay // hard limit buffer full: needed for replay
if (atomic_read(&VideoPacketsFilled) >= VIDEO_PACKET_MAX - 3) { if (atomic_read(&VideoPacketsFilled) >= VIDEO_PACKET_MAX - 3) {
return 0; return 0;
} }
// soft limit buffer full
if (atomic_read(&VideoPacketsFilled) > 3
&& AudioUsedBytes() > AUDIO_MIN_BUFFER_FREE) {
return 0;
}
// get pts/dts // get pts/dts
pts = AV_NOPTS_VALUE; pts = AV_NOPTS_VALUE;
if (data[7] & 0x80) { if (data[7] & 0x80) {
@ -2069,6 +2077,7 @@ int Poll(int timeout)
// poll is only called during replay, flush buffers after replay // poll is only called during replay, flush buffers after replay
VideoClearClose = 1; VideoClearClose = 1;
for (;;) { for (;;) {
#if 0
int empty; int empty;
int t; int t;
@ -2078,6 +2087,18 @@ int Poll(int timeout)
if (empty || !timeout) { if (empty || !timeout) {
return empty; return empty;
} }
#else
int full;
int t;
// one buffer is full
full = AudioFreeBytes() >= AUDIO_MIN_BUFFER_FREE
|| atomic_read(&VideoPacketsFilled) < VIDEO_PACKET_MAX - 3;
if (!full || !timeout) {
return !full;
}
#endif
t = 15; t = 15;
if (timeout < t) { if (timeout < t) {
t = timeout; t = timeout;
@ -2461,11 +2482,23 @@ void Stop(void)
#endif #endif
} }
/**
** Perform any cleanup or other regular tasks.
*/
void Housekeeping(void)
{
}
/** /**
** Main thread hook, periodic called from main thread. ** Main thread hook, periodic called from main thread.
*/ */
void MainThreadHook(void) void MainThreadHook(void)
{ {
if (Usr1Signal) { // x11 server ready
Usr1Signal = 0;
StartVideo();
VideoDisplayWakeup();
}
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@ -81,6 +81,8 @@ extern "C"
extern int Start(void); extern int Start(void);
/// C plugin stop code /// C plugin stop code
extern void Stop(void); extern void Stop(void);
/// C plugin house keeping
extern void Housekeeping(void);
/// C plugin main thread hook /// C plugin main thread hook
extern void MainThreadHook(void); extern void MainThreadHook(void);