From eeb4be0c7f793acc78eeb035a52900abc7ee9d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 30 Jul 2009 20:47:05 +0000 Subject: [PATCH] Hack for interlaced video. We cannot know if video is interlaced from the current libavformat API. FFmpeg is a little inconsistent in this regard. For interlaced video, it will report a frame rate which is the field rate, but still decode both fields into a single frame. For the time being, we reduce the frame rate from 50.0 to 25.0 and handle interlaced video transparently for the clients. This needs to be fixed later on... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31995 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/plugins/ffmpeg/AVFormatReader.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp index a33618ec22..b4fcba6b6d 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp @@ -502,10 +502,13 @@ AVFormatReader::StreamCookie::Init(int32 virtualIndex) // format->u.encoded_video.forward_history = 0; // format->u.encoded_video.backward_history = 0; + // TODO: Fix up for interlaced video format->u.encoded_video.output.field_rate = av_q2d(stream->r_frame_rate); +if (format->u.encoded_video.output.field_rate == 50.0f) + format->u.encoded_video.output.field_rate = 25.0f; format->u.encoded_video.output.interlace = 1; - // TODO: Fix up for interlaced video + format->u.encoded_video.output.first_active = 0; format->u.encoded_video.output.last_active = codecContext->height - 1; @@ -724,7 +727,7 @@ AVFormatReader::StreamCookie::Seek(uint32 flags, int64* frame, *frame, *time); if ((flags & B_MEDIA_SEEK_TO_FRAME) != 0) - *time = *frame * 1000000LL / FrameRate(); + *time = (bigtime_t)(*frame * 1000000LL / FrameRate()); double timeBase = av_q2d(fStream->time_base); int64_t timeStamp; @@ -768,7 +771,7 @@ AVFormatReader::StreamCookie::FindKeyFrame(uint32 flags, int64* frame, double frameRate = FrameRate(); if ((flags & B_MEDIA_SEEK_TO_FRAME) != 0) - *time = *frame * 1000000LL / frameRate; + *time = (bigtime_t)(*frame * 1000000LL / frameRate); double timeBase = av_q2d(fStream->time_base); int64_t timeStamp; @@ -823,6 +826,12 @@ AVFormatReader::StreamCookie::GetNextChunk(const void** chunkBuffer, return ret; } + // NOTE: AVPacket has a field called "convergence_duration", for which + // the documentation is quite interesting. It sounds like it could be + // used to know the time until the next I-Frame in streams that don't + // let you know the position of keyframes in another way (like through + // the index). + // According to libavformat documentation, fPacket is valid until the // next call to av_read_frame(). This is what we want and we can share // the memory with the least overhead.