From 7b570c507cf0634e1249f60e7d008ff43f0d264a Mon Sep 17 00:00:00 2001 From: Johns Date: Mon, 12 Mar 2012 17:58:19 +0100 Subject: [PATCH] Cleanups. --- README.txt | 4 +++- audio.c | 19 ++++++++------- codec.c | 23 +++++++++++-------- softhddev.c | 59 ++++++++++++++++++++++++++++------------------- video.c | 66 +++++++++++++++++++++++++++++++---------------------- 5 files changed, 101 insertions(+), 70 deletions(-) diff --git a/README.txt b/README.txt index 83c9683..3b9859f 100644 --- a/README.txt +++ b/README.txt @@ -166,7 +166,9 @@ Setup: /etc/vdr/setup.conf 32bit RGBA background color (Red * 16777216 + Green * 65536 + Blue * 256 + Alpha) or hex RRGGBBAA - grey = 2155905279 + grey 127 * 16777216 + 127 * 65536 + 127 * 256 => 2139062016 + in the setup menu this is entered as (24bit RGB and 8bit Alpha) + (Red * 65536 + Green * 256 + Blue) softhddevice.SkipLines = 0 skip 'n' lines at top and bottom of the video picture. diff --git a/audio.c b/audio.c index cd1f9cf..21ec179 100644 --- a/audio.c +++ b/audio.c @@ -435,8 +435,7 @@ static void AlsaFlushBuffers(void) RingBufferReadAdvance(AlsaRingBuffer, RingBufferUsedBytes(AlsaRingBuffer)); state = snd_pcm_state(AlsaPCMHandle); - Debug(3, "audio/alsa: flush state %d - %s\n", state, - snd_pcm_state_name(state)); + Debug(3, "audio/alsa: flush state %s\n", snd_pcm_state_name(state)); if (state != SND_PCM_STATE_OPEN) { if ((err = snd_pcm_drop(AlsaPCMHandle)) < 0) { Error(_("audio: snd_pcm_drop(): %s\n"), snd_strerror(err)); @@ -943,7 +942,7 @@ static int64_t AlsaGetDelay(void) pts = ((int64_t) delay * 90 * 1000) / AudioSampleRate; pts += ((int64_t) RingBufferUsedBytes(AlsaRingBuffer) * 90 * 1000) / (AudioSampleRate * AudioChannels * AudioBytesProSample); - Debug(4, "audio/alsa: hw+sw delay %zd %" PRId64 " ms\n", + Debug(4, "audio/alsa: hw+sw delay %zd %" PRId64 "ms\n", RingBufferUsedBytes(AlsaRingBuffer), pts / 90); return pts; @@ -1147,7 +1146,7 @@ static int AlsaSetup(int *freq, int *channels, int use_ac3) // update buffer snd_pcm_get_params(AlsaPCMHandle, &buffer_size, &period_size); - Info(_("audio/alsa: buffer size %lu %zdms, period size %lu %zdms\n"), + Debug(3, "audio/alsa: buffer size %lu %zdms, period size %lu %zdms\n", buffer_size, snd_pcm_frames_to_bytes(AlsaPCMHandle, buffer_size) * 1000 / (AudioSampleRate * AudioChannels * AudioBytesProSample), period_size, @@ -1172,7 +1171,7 @@ static int AlsaSetup(int *freq, int *channels, int use_ac3) if (AlsaStartThreshold > RingBufferFreeBytes(AlsaRingBuffer)) { AlsaStartThreshold = RingBufferFreeBytes(AlsaRingBuffer); } - Info(_("audio/alsa: delay %u ms\n"), (AlsaStartThreshold * 1000) + Info(_("audio/alsa: delay %ums\n"), (AlsaStartThreshold * 1000) / (AudioSampleRate * AudioChannels * AudioBytesProSample)); return ret; @@ -1450,7 +1449,7 @@ static void OssEnqueue(const void *samples, int count) uint32_t tick; tick = GetMsTicks(); - Debug(4, "audio/oss: %4d %d ms\n", count, tick - last_tick); + Debug(4, "audio/oss: %4d %dms\n", count, tick - last_tick); last_tick = tick; #endif @@ -1756,7 +1755,7 @@ static int64_t OssGetDelay(void) pts = ((int64_t) (delay + RingBufferUsedBytes(OssRingBuffer)) * 90 * 1000) / (AudioSampleRate * AudioChannels * AudioBytesProSample); - Debug(4, "audio/oss: hw+sw delay %zd %" PRId64 " ms\n", + Debug(4, "audio/oss: hw+sw delay %zd %" PRId64 "ms\n", RingBufferUsedBytes(OssRingBuffer), pts / 90); return pts; @@ -1865,7 +1864,7 @@ static int OssSetup(int *freq, int *channels, int use_ac3) OssFragmentTime = (bi.fragsize * 1000) / (AudioSampleRate * AudioChannels * AudioBytesProSample); - Info(_("audio/oss: buffer size %d %dms, fragment size %d %dms\n"), + Debug(3, "audio/oss: buffer size %d %dms, fragment size %d %dms\n", bi.fragsize * bi.fragstotal, (bi.fragsize * bi.fragstotal * 1000) / (AudioSampleRate * AudioChannels * AudioBytesProSample), bi.fragsize, OssFragmentTime); @@ -1890,7 +1889,7 @@ static int OssSetup(int *freq, int *channels, int use_ac3) OssStartThreshold = RingBufferFreeBytes(OssRingBuffer); } - Info(_("audio/oss: delay %u ms\n"), (OssStartThreshold * 1000) + Info(_("audio/oss: delay %ums\n"), (OssStartThreshold * 1000) / (AudioSampleRate * AudioChannels * AudioBytesProSample)); return ret; @@ -2080,7 +2079,7 @@ static void *AudioPlayHandlerThread(void *dummy) // cond_wait can return, without signal! } while (!AudioRunning); - Debug(3, "audio: ----> %d ms start\n", (AudioUsedBytes() * 1000) + Debug(3, "audio: ----> %dms start\n", (AudioUsedBytes() * 1000) / (!AudioSampleRate + !AudioChannels + AudioSampleRate * AudioChannels * AudioBytesProSample)); diff --git a/codec.c b/codec.c index 0630874..122f8ab 100644 --- a/codec.c +++ b/codec.c @@ -728,8 +728,8 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, const char *name, if (audio_codec->capabilities & CODEC_CAP_TRUNCATED) { Debug(3, "codec: audio can use truncated packets\n"); - // we do not send complete frames - audio_decoder->AudioCtx->flags |= CODEC_FLAG_TRUNCATED; + // we send only complete frames + // audio_decoder->AudioCtx->flags |= CODEC_FLAG_TRUNCATED; } audio_decoder->SampleRate = 0; audio_decoder->Channels = 0; @@ -800,6 +800,10 @@ void CodecSetAudioDownmix(int onoff) ** ffmpeg L R C Ls Rs -> alsa L R Ls Rs C ** ffmpeg L R C LFE Ls Rs -> alsa L R Ls Rs C LFE ** ffmpeg L R C LFE Ls Rs Rl Rr -> alsa L R Ls Rs C LFE Rl Rr +** +** @param buf[IN,OUT] sample buffer +** @param size size of sample buffer in bytes +** @param channels number of channels interleaved in sample buffer */ static void CodecReorderAudioFrame(int16_t * buf, int size, int channels) { @@ -960,10 +964,6 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder) int err; int isAC3; - audio_ctx = audio_decoder->AudioCtx; - - audio_decoder->PassthroughAC3 = CodecPassthroughAC3; - // FIXME: use swr_convert from swresample (only in ffmpeg!) if (audio_decoder->ReSample) { audio_resample_close(audio_decoder->ReSample); @@ -975,9 +975,16 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder) audio_decoder->RemainCount = 0; } + audio_ctx = audio_decoder->AudioCtx; + Debug(3, "codec/audio: format change %dHz %d channels %s\n", + audio_ctx->sample_rate, audio_ctx->channels, + CodecPassthroughAC3 ? "pass-through" : ""); + audio_decoder->SampleRate = audio_ctx->sample_rate; audio_decoder->HwSampleRate = audio_ctx->sample_rate; audio_decoder->Channels = audio_ctx->channels; + audio_decoder->PassthroughAC3 = CodecPassthroughAC3; + // SPDIF/HDMI passthrough if (CodecPassthroughAC3 && audio_ctx->codec_id == CODEC_ID_AC3) { audio_decoder->HwChannels = 2; @@ -1044,8 +1051,7 @@ static void CodecAudioUpdateFormat(AudioDecoder * audio_decoder) ** ** @param audio_decoder audio decoder data ** @param data samples data -** @param count number of samples -** +** @param count number of bytes in sample data */ void CodecAudioEnqueue(AudioDecoder * audio_decoder, int16_t * data, int count) { @@ -1162,7 +1168,6 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt) // update audio clock if (avpkt->pts != (int64_t) AV_NOPTS_VALUE) { CodecAudioSetClock(audio_decoder, avpkt->pts); - } // FIXME: must first play remainings bytes, than change and play new. if (audio_decoder->PassthroughAC3 != CodecPassthroughAC3 diff --git a/softhddev.c b/softhddev.c index c99334a..a6dca5f 100644 --- a/softhddev.c +++ b/softhddev.c @@ -315,6 +315,12 @@ static inline int FastAc3Check(const uint8_t * p) if (p[1] != 0x77) { return 0; } + if ((p[4] & 0xC0) == 0xC0) { // invalid sample rate + return 0; + } + if ((p[4] & 0x3F) > 37) { // invalid frame size + return 0; + } return 1; } @@ -338,7 +344,7 @@ static int Ac3Check(const uint8_t * data, int size) // crc1 crc1 fscod|frmsizcod fscod = data[4] >> 6; - frmsizcod = data[4] & 0x3F; + frmsizcod = data[4] & 0x3F; // invalid is checked by fast frame_size = Ac3FrameSizeTable[frmsizcod][fscod] * 2; if (frame_size + 2 > size) { @@ -425,12 +431,25 @@ typedef struct _pes_demux_ int64_t DTS; ///< decode time stamp } PesDemux; +/// +/// Reset packetized elementary stream demuxer. +/// +static void PesReset(PesDemux * pesdx) +{ + pesdx->State = PES_INIT; + pesdx->Index = 0; + pesdx->Skip = 0; + pesdx->StartCode = -1; + pesdx->PTS = AV_NOPTS_VALUE; + pesdx->DTS = AV_NOPTS_VALUE; +} + /// /// Initialize a packetized elementary stream demuxer. /// /// @param pesdx packetized elementary stream demuxer /// -void PesInit(PesDemux * pesdx) +static void PesInit(PesDemux * pesdx) { memset(pesdx, 0, sizeof(*pesdx)); pesdx->Size = PES_MAX_PAYLOAD; @@ -438,20 +457,7 @@ void PesInit(PesDemux * pesdx) if (!pesdx->Buffer) { Fatal(_("pesdemux: out of memory\n")); } - pesdx->PTS = AV_NOPTS_VALUE; // reset - pesdx->DTS = AV_NOPTS_VALUE; -} - -/// -/// Reset packetized elementary stream demuxer. -/// -void PesReset(PesDemux * pesdx) -{ - pesdx->State = PES_INIT; - pesdx->Index = 0; - pesdx->Skip = 0; - pesdx->PTS = AV_NOPTS_VALUE; - pesdx->DTS = AV_NOPTS_VALUE; + PesReset(pesdx); } /// @@ -462,7 +468,8 @@ void PesReset(PesDemux * pesdx) /// @param size number of payload data bytes /// @param is_start flag, start of pes packet /// -void PesParse(PesDemux * pesdx, const uint8_t * data, int size, int is_start) +static void PesParse(PesDemux * pesdx, const uint8_t * data, int size, + int is_start) { const uint8_t *p; const uint8_t *q; @@ -609,6 +616,8 @@ void PesParse(PesDemux * pesdx, const uint8_t * data, int size, int is_start) Debug(3, "pesdemux: pes start code id %#02x\n", code); // FIXME: need to save start code id? pesdx->StartCode = code; + // we could have already detect a valid stream type + // don't switch to codec 'none' } pesdx->State = PES_HEADER; @@ -668,11 +677,11 @@ void PesParse(PesDemux * pesdx, const uint8_t * data, int size, int is_start) // only private stream 1, has sub streams pesdx->State = PES_START; } - //pesdx->HeaderIndex = 0; - //pesdx->Index = 0; } break; +#if 0 + // Played with PlayAudio case PES_LPCM_HEADER: // lpcm header n = pesdx->HeaderSize - pesdx->HeaderIndex; if (n > size) { @@ -749,6 +758,7 @@ void PesParse(PesDemux * pesdx, const uint8_t * data, int size, int is_start) AudioEnqueue(pesdx->Buffer, pesdx->Index); pesdx->Index = 0; break; +#endif } } while (size > 0); } @@ -786,7 +796,7 @@ static PesDemux PesDemuxAudio[1]; ///< audio demuxer /// /// @returns number of bytes consumed from buffer. /// -int TsDemuxer(TsDemux * tsdx, const uint8_t * data, int size) +static int TsDemuxer(TsDemux * tsdx, const uint8_t * data, int size) { const uint8_t *p; @@ -876,7 +886,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id) } if (NewAudioStream) { - // FIXME: does this clear the audio ringbuffer? + // this clears the audio ringbuffer indirect, open and setup does it CodecAudioClose(MyAudioDecoder); AudioSetBufferTime(0); AudioCodecID = CODEC_ID_NONE; @@ -928,7 +938,7 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id) AudioAvPkt->stream_index = 0; } - if (AudioChannelID != id) { + if (AudioChannelID != id) { // id changed audio track changed AudioChannelID = id; AudioCodecID = CODEC_ID_NONE; } @@ -1067,6 +1077,8 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id) /** ** Play transport stream audio packet. ** +** VDR can have buffered data belonging to previous channel! +** ** @param data data of exactly one complete TS packet ** @param size size of TS packet (always TS_PACKET_SIZE) ** @@ -1088,11 +1100,12 @@ int PlayTsAudio(const uint8_t * data, int size) } if (NewAudioStream) { - // FIXME: does this clear the audio ringbuffer? + // this clears the audio ringbuffer indirect, open and setup does it CodecAudioClose(MyAudioDecoder); // max time between audio packets 200ms + 24ms hw buffer AudioSetBufferTime(264); AudioCodecID = CODEC_ID_NONE; + AudioChannelID = -1; NewAudioStream = 0; PesReset(PesDemuxAudio); } diff --git a/video.c b/video.c index a0afa58..175230f 100644 --- a/video.c +++ b/video.c @@ -538,15 +538,6 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, return; } -/// -/// Output video messages. -/// -/// Reduce output. -/// -//static void VideoMessage(const char *message) -//{ -//} - //---------------------------------------------------------------------------- // GLX //---------------------------------------------------------------------------- @@ -776,7 +767,7 @@ static void GlxSetupWindow(xcb_window_t window, int width, int height) end = GetMsTicks(); GlxGetVideoSyncSGI(&count); - Debug(3, "video/glx: %5d frame rate %d ms\n", count, end - start); + Debug(3, "video/glx: %5d frame rate %dms\n", count, end - start); // nvidia can queue 5 swaps if (i > 5 && (end - start) < 15) { Warning(_("video/glx: no v-sync\n")); @@ -1983,7 +1974,7 @@ static void Vaapi1080i(void) } tick = GetMsTicks(); if (!(n % 10)) { - fprintf(stderr, "%d ms / frame\n", (tick - start_tick) / n); + fprintf(stderr, "%dms / frame\n", (tick - start_tick) / n); } } @@ -2445,9 +2436,9 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface, } e = GetMsTicks(); if (e - s > 2000) { - Error(_("video/vaapi: gpu hung %d ms %d\n"), e - s, + Error(_("video/vaapi: gpu hung %dms %d\n"), e - s, decoder->FrameCounter); - fprintf(stderr, _("video/vaapi: gpu hung %d ms %d\n"), e - s, + fprintf(stderr, _("video/vaapi: gpu hung %dms %d\n"), e - s, decoder->FrameCounter); } @@ -3154,9 +3145,9 @@ static void VaapiBlackSurface(VaapiDecoder * decoder) put1 = GetMsTicks(); if (put1 - sync > 2000) { - Error(_("video/vaapi: gpu hung %d ms %d\n"), put1 - sync, + Error(_("video/vaapi: gpu hung %dms %d\n"), put1 - sync, decoder->FrameCounter); - fprintf(stderr, _("video/vaapi: gpu hung %d ms %d\n"), put1 - sync, + fprintf(stderr, _("video/vaapi: gpu hung %dms %d\n"), put1 - sync, decoder->FrameCounter); } Debug(4, "video/vaapi: sync %2u put1 %2u\n", sync - start, put1 - sync); @@ -4317,7 +4308,7 @@ static void VaapiDisplayFrame(void) if ((nowtime.tv_sec - decoder->FrameTime.tv_sec) * 1000 * 1000 * 1000 + (nowtime.tv_nsec - decoder->FrameTime.tv_nsec) > 30 * 1000 * 1000) { - Debug(3, "video/vaapi: time/frame too long %ld ms\n", + Debug(3, "video/vaapi: time/frame too long %ldms\n", ((nowtime.tv_sec - decoder->FrameTime.tv_sec) * 1000 * 1000 * 1000 + (nowtime.tv_nsec - decoder->FrameTime.tv_nsec)) / (1000 * 1000)); @@ -4325,12 +4316,12 @@ static void VaapiDisplayFrame(void) put2 - put1); } #ifdef noDEBUG - Debug(3, "video/vaapi: time/frame %ld ms\n", + Debug(3, "video/vaapi: time/frame %ldms\n", ((nowtime.tv_sec - decoder->FrameTime.tv_sec) * 1000 * 1000 * 1000 + (nowtime.tv_nsec - decoder->FrameTime.tv_nsec)) / (1000 * 1000)); if (put2 > start + 20) { - Debug(3, "video/vaapi: putsurface too long %u ms\n", put2 - start); + Debug(3, "video/vaapi: putsurface too long %ums\n", put2 - start); } Debug(4, "video/vaapi: put1 %2u put2 %2u\n", put1 - start, put2 - put1); @@ -4410,7 +4401,7 @@ static void VaapiSyncDisplayFrame(VaapiDecoder * decoder) Info("video: %s%+5" PRId64 " %4" PRId64 " %3d/\\ms %3d v-buf\n", Timestamp2String(video_clock), abs((video_clock - audio_clock) / 90) < - 9999 ? ((video_clock - audio_clock) / 90) : 88888, + 8888 ? ((video_clock - audio_clock) / 90) : 8888, AudioGetDelay() / 90, (int)VideoDeltaPTS / 90, VideoGetBuffers()); } #endif @@ -4667,8 +4658,8 @@ static void VaapiOsdDrawARGB(int x, int y, int width, int height, } end = GetMsTicks(); - Debug(3, "video/vaapi: osd upload %dx%d+%d+%d %d ms %d\n", width, height, - x, y, end - start, width * height * 4); + Debug(3, "video/vaapi: osd upload %dx%d+%d+%d %dms %d\n", width, height, x, + y, end - start, width * height * 4); } /// @@ -5017,6 +5008,24 @@ static void VdpauOsdInit(int, int); ///< forward definition //---------------------------------------------------------------------------- +/// +/// Output video messages. +/// +/// Reduce output. +/// +static void VdpauMessage(int level, const char *format, ...) +{ + if (SysLogLevel > level || DebugLevel > level) { + va_list ap; + + va_start(ap, format); + vsyslog(LOG_ERR, format, ap); + va_end(ap); + } +} + +//---------------------------------------------------------------------------- + /// /// Create surfaces for VDPAU decoder. /// @@ -5520,6 +5529,8 @@ static VdpauDecoder *VdpauNewHwDecoder(void) decoder->Procamp.saturation = 1.0; decoder->Procamp.hue = 0.0; // default values + decoder->PTS = AV_NOPTS_VALUE; + // FIXME: hack VdpauDecoderN = 1; VdpauDecoders[0] = decoder; @@ -7082,7 +7093,7 @@ static void VdpauMixOsd(void) #endif //end = GetMsTicks(); /* - Debug(4, "video:/vdpau: osd render %d %d ms\n", VdpauOsdSurfaceIndex, + Debug(4, "video:/vdpau: osd render %d %dms\n", VdpauOsdSurfaceIndex, end - start); */ @@ -7349,6 +7360,7 @@ static void VdpauDisplayFrame(void) VdpauGetErrorString(status)); } // check if surface was displayed for more than 1 frame + // FIXME: 21 only correct for 50Hz if (last_time && first_time > last_time + 21 * 1000 * 1000) { Debug(3, "video/vdpau: %ld display time %ld\n", first_time / 1000, (first_time - last_time) / 1000); @@ -7482,7 +7494,7 @@ static void VdpauSyncDisplayFrame(VdpauDecoder * decoder) Info("video: %s%+5" PRId64 " %4" PRId64 " %3d/\\ms %3d v-buf\n", Timestamp2String(video_clock), abs((video_clock - audio_clock) / 90) < - 9999 ? ((video_clock - audio_clock) / 90) : 88888, + 8888 ? ((video_clock - audio_clock) / 90) : 8888, AudioGetDelay() / 90, (int)VideoDeltaPTS / 90, VideoGetBuffers()); } #endif @@ -7876,8 +7888,8 @@ static void VdpauOsdDrawARGB(int x, int y, int width, int height, #endif end = GetMsTicks(); - Debug(3, "video/vdpau: osd upload %dx%d+%d+%d %d ms %d\n", width, height, - x, y, end - start, width * height * 4); + Debug(3, "video/vdpau: osd upload %dx%d+%d+%d %dms %d\n", width, height, x, + y, end - start, width * height * 4); } /// @@ -8806,7 +8818,7 @@ void VideoDrawRenderState(VideoHwDecoder * hw_decoder, } if (end - start > 35) { // report this - Info(_("video/vdpau: decoder render too slow %u ms\n"), + Info(_("video/vdpau: decoder render too slow %ums\n"), end - start); } return; @@ -9860,7 +9872,7 @@ int main(int argc, char *const argv[]) tick = GetMsTicks(); n++; if (!(n % 100)) { - printf("%d ms / frame\n", (tick - start_tick) / n); + printf("%dms / frame\n", (tick - start_tick) / n); } usleep(2 * 1000); }