You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current QVideoDecoder code assumes that packet.dts values are equivalent to
frame numbers (i.e. start from 0 and are incremented by one with each
successfully read packet). However, this does not hold for all video codecs
(such as H.264), according to my experience. The effect is that such videos are
unable to be played back or at least seeked correctly. See
http://www.auby.no/files/video_tests/h264_720p_mp_3.1_3mbps_aac_shrinkage.mp4
for a sample behaviour.
The proposed fix is based on the implementation in Blender
(https://svn.blender.org/svnroot/bf-blender/trunk/blender/source/gameengine/Vide
oTexture/VideoFFmpeg.cpp):
*** In bool QVideoDecoder::decodeSeekFrame(int after) ***
REPLACE
int f = packet.dts;
WITH
double m_baseFrameRate = av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate);
double timeBase = av_q2d(pFormatCtx->streams[videoStream]->time_base);
int64_t startTs = pFormatCtx->streams[videoStream]->start_time;
if (startTs == AV_NOPTS_VALUE) startTs = 0;
int f = (long)((packet.dts-startTs) * (m_baseFrameRate*timeBase) + 0.5);
*** In bool QVideoDecoder::seekFrame(int64_t frame) ***
REPLACE
//printf("\t avformat_seek_file\n");
if(ffmpeg::avformat_seek_file(pFormatCtx,videoStream,0,frame,frame,AVSEEK_FLAG_F
RAME)<0)
WITH
double m_baseFrameRate = av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate);
double timeBase = av_q2d(pFormatCtx->streams[videoStream]->time_base);
int64_t startTs = pFormatCtx->streams[videoStream]->start_time;
if (startTs == AV_NOPTS_VALUE) startTs = 0;
double preSeek = 1*getFPS(); //ffmpeg bug?: with H.264 avformat_seek_file often
seeks not in a keyframe, thus the following avcodec_decode_video2 iterations
may go past desiredDts
int desiredDts = (frame-0.5-preSeek) / (m_baseFrameRate*timeBase) + startTs;
if (desiredDts<startTs) desiredDts = startTs;
//printf("\t avformat_seek_file to %d (pts %d)\n", frame, desiredDts);
if(ffmpeg::avformat_seek_file(pFormatCtx,videoStream,-0x7ffffffffffffff,desiredD
ts,desiredDts,AVSEEK_FLAG_BACKWARD)<0)
Original issue reported on code.google.com by [email protected] on 21 Oct 2013 at 3:28
The text was updated successfully, but these errors were encountered:
Original issue reported on code.google.com by
[email protected]
on 21 Oct 2013 at 3:28The text was updated successfully, but these errors were encountered: