From 30952face42de011d6805586b817184c4e90e7a6 Mon Sep 17 00:00:00 2001 From: Johns Date: Wed, 24 Oct 2012 15:38:09 +0200 Subject: [PATCH] Fix bug #1089: vdpau wrong number of mpeg refs. --- ChangeLog | 1 + codec.c | 24 ++++++++++++++++++++++-- softhddev.c | 4 ++-- video.c | 6 +++--- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index eec4301..abc76b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ User johns Date: + Fix bug #1089: Vdpau decoder used wrong number of mpeg reference frames. Fix bug: with some streams endless loop in pes audio parser. Report correct video size in cSoftHdDevice::GetVideoSize. Add picture adjustment support for vdpau. diff --git a/codec.c b/codec.c index 38702b3..7ba9676 100644 --- a/codec.c +++ b/codec.c @@ -385,6 +385,17 @@ void CodecVideoOpen(VideoDecoder * decoder, const char *name, int codec_id) Fatal(_("codec: can't open video codec!\n")); } #else + if (video_codec->capabilities & (CODEC_CAP_HWACCEL_VDPAU | + CODEC_CAP_HWACCEL)) { + Debug(3, "codec: video mpeg hack active\n"); + // HACK around badly placed checks in mpeg_mc_decode_init + // taken from mplayer vd_ffmpeg.c + decoder->VideoCtx->slice_flags = + SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; + decoder->VideoCtx->thread_count = 1; + decoder->VideoCtx->active_thread_type = 0; + } + if (avcodec_open2(decoder->VideoCtx, video_codec, NULL) < 0) { pthread_mutex_unlock(&CodecLockMutex); Fatal(_("codec: can't open video codec!\n")); @@ -402,7 +413,7 @@ void CodecVideoOpen(VideoDecoder * decoder, const char *name, int codec_id) } if (video_codec->capabilities & CODEC_CAP_TRUNCATED) { Debug(3, "codec: video can use truncated packets\n"); - // we do not send complete frames + // we send incomplete frames, for old PES recordings decoder->VideoCtx->flags |= CODEC_FLAG_TRUNCATED; } // FIXME: own memory management for video frames. @@ -538,6 +549,11 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) Debug(4, "%s: %p %d -> %d %d\n", __FUNCTION__, pkt->data, pkt->size, used, got_frame); + if (used < 0) { + Debug(3, "codec: bad video frame\n"); + return; + } + if (got_frame) { // frame completed //DisplayPts(video_ctx, frame); VideoRenderFrame(decoder->HwDecoder, video_ctx, frame); @@ -548,6 +564,9 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) Debug(4, "codec: %8d incomplete interlaced frame %d bytes used\n", video_ctx->frame_number, used); } + +#if 1 + // old code to support truncated or multi frame packets if (used != pkt->size) { // ffmpeg 0.8.7 dislikes our seq_end_h264 and enters endless loop here if (used == 0 && pkt->size == 5 && pkt->data[4] == 0x0A) { @@ -561,10 +580,11 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) used, pkt->size); pkt->size -= used; pkt->data += used; + // FIXME: align problem? goto next_part; } - Debug(3, "codec: bad frame %d\n", used); } +#endif } /** diff --git a/softhddev.c b/softhddev.c index 5b48fa8..09e9f51 100644 --- a/softhddev.c +++ b/softhddev.c @@ -1236,7 +1236,7 @@ void SetVolumeDevice(int volume) #ifdef DEBUG uint32_t VideoSwitch; ///< debug video switch ticks #endif -//#define STILL_DEBUG 1 +//#define STILL_DEBUG 2 #ifdef STILL_DEBUG static char InStillPicture; ///< flag still picture #endif @@ -1406,7 +1406,7 @@ static void VideoNextPacket(int codec_id) /** ** Fix packet for FFMpeg. ** -** Some tv-stations sends mulitple pictures in a singe PES packet. +** Some tv-stations sends mulitple pictures in a single PES packet. ** Current ffmpeg 0.10 and libav-0.8 has problems with this. ** Split the packet into single picture packets. */ diff --git a/video.c b/video.c index 6635daa..55808af 100644 --- a/video.c +++ b/video.c @@ -261,7 +261,7 @@ typedef struct _video_module_ #define CODEC_SURFACES_MAX 31 ///< maximal of surfaces -#define CODEC_SURFACES_DEFAULT (21+4) ///< default of surfaces +#define CODEC_SURFACES_DEFAULT 21 ///< default of surfaces // FIXME: video-xvba only supports 14 #define xCODEC_SURFACES_DEFAULT 14 ///< default of surfaces @@ -6677,11 +6677,11 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder, // check profile switch (video_ctx->codec_id) { case CODEC_ID_MPEG1VIDEO: - max_refs = 2; + max_refs = CODEC_SURFACES_MPEG2; profile = VdpauCheckProfile(decoder, VDP_DECODER_PROFILE_MPEG1); break; case CODEC_ID_MPEG2VIDEO: - max_refs = 2; + max_refs = CODEC_SURFACES_MPEG2; profile = VdpauCheckProfile(decoder, VDP_DECODER_PROFILE_MPEG2_MAIN); break;