summaryrefslogtreecommitdiffstats
path: root/mpvcore
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-27 20:54:56 +0100
committerwm4 <wm4@nowhere>2013-11-27 21:14:39 +0100
commitf5219720f8917145cb2e0d9258b3233de1a6fb19 (patch)
tree418d0b147b51844c7982d58134ac9bceb751f1c8 /mpvcore
parent1e96f5bcd98f41fa11d87f1a5236468f985327a9 (diff)
downloadmpv-f5219720f8917145cb2e0d9258b3233de1a6fb19.tar.bz2
mpv-f5219720f8917145cb2e0d9258b3233de1a6fb19.tar.xz
video: refactor PTS code, add fall back heuristic to DTS
Refactor the PTS handling code to make it cleaner, and to separate the bits that use PTS sorting. Add a heuristic to fall back to DTS if the PTS us non-monotonic. This code is based on what FFmpeg/Libav use for ffplay/avplay and also best_effort_timestamp (which is only in FFmpeg). Basically, this 1. just uses the DTS if PTS is unset, and 2. ignores PTS entirely if PTS is non- monotonic, but DTS is sorted. The code is pretty much the same as in Libav [1]. I'm not sure if all of it is really needed, or if it does more than what the paragraph above mentions. But maybe it's fine to cargo-cult this. This heuristic fixes playback of mpeg4 in ogm, which returns packets with PTS==DTS, even though the PTS timestamps should follow codec reordering. This is probably a libavformat demuxer bug, but good luck trying to fix it. The way vd_lavc.c returns the frame PTS and DTS to dec_video.c is a bit inelegant, but maybe better than trying to mess the PTS back into the decoder callback again. [1] https://git.libav.org/?p=libav.git;a=blob;f=cmdutils.c;h=3f1c667075724c5cde69d840ed5ed7d992898334;hb=fa515c2088e1d082d45741bbd5c05e13b0500804#l1431
Diffstat (limited to 'mpvcore')
-rw-r--r--mpvcore/av_common.c8
-rw-r--r--mpvcore/av_common.h2
2 files changed, 4 insertions, 6 deletions
diff --git a/mpvcore/av_common.c b/mpvcore/av_common.c
index 3e3caa8f0d..d233071c23 100644
--- a/mpvcore/av_common.c
+++ b/mpvcore/av_common.c
@@ -91,12 +91,10 @@ void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt)
// Return the pts/dts from a frame returned by libavcodec. Note that this
// assumes libavcodec was fed a packet setup with mp_set_av_packet()! If not,
// the timestamps might contain garbage.
-// Normally, this returns the pts. If the pts is unknown, return dts instead.
-double mp_get_av_frame_pkt_pdts(AVFrame *frame)
+void mp_get_av_frame_pkt_ts(AVFrame *frame, double *out_pts, double *out_dts)
{
- double pts = (union pts){.i = frame->pkt_pts}.d;
- double dts = (union pts){.i = frame->pkt_dts}.d;
- return pts == MP_NOPTS_VALUE ? dts : pts;
+ *out_pts = (union pts){.i = frame->pkt_pts}.d;
+ *out_dts = (union pts){.i = frame->pkt_dts}.d;
}
void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type)
diff --git a/mpvcore/av_common.h b/mpvcore/av_common.h
index 683570971d..103185329c 100644
--- a/mpvcore/av_common.h
+++ b/mpvcore/av_common.h
@@ -26,7 +26,7 @@ struct demux_packet;
void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st);
void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt);
-double mp_get_av_frame_pkt_pdts(AVFrame *frame);
+void mp_get_av_frame_pkt_ts(AVFrame *frame, double *out_pts, double *out_dts);
void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type);
int mp_codec_to_av_codec_id(const char *codec);
const char *mp_codec_from_av_codec_id(int codec_id);