summaryrefslogtreecommitdiffstats
path: root/libmpcodecs/vd_ffmpeg.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2009-11-21 20:53:10 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2009-11-21 20:53:10 +0200
commit74b7dcc5f4d9be7293b78fced5ce888bb94c08dc (patch)
treee7b3c4da431f6e73ca858a4731f2883651bce697 /libmpcodecs/vd_ffmpeg.c
parent4aff125b35984e7777d06edccdceeb28e531b907 (diff)
downloadmpv-74b7dcc5f4d9be7293b78fced5ce888bb94c08dc.tar.bz2
mpv-74b7dcc5f4d9be7293b78fced5ce888bb94c08dc.tar.xz
core: Add support for decoder reordering of pts values
Add a mode where libavcodec's reordered_opaque feature is used to associate container packet timestamps with decoded frames. This should improve behavior at least for MPEG files with interlaced h264; the previous code does not cope well with the libavformat demuxer producing two field packets with separate timestamps but the libavcodec h264 decoder only producing a single output frame for those two packets (so half the timestamps have no associated output frame). The current libavformat mpeg demuxer seems to finally work with interlaced h264 files and produce valid timestamps which are useful with a mode like this. By default MPlayer now selects between this new mode and the old one automatically based on the number of timestamp problems they cause; by default the new mode is used if both seem to work. The new option -pts-association-mode can be used to force a particular mode. If correct-pts mode is disabled this has no effect on timing. Also remove the "EXPERIMENTAL" marker from the manpage description of -correct-pts.
Diffstat (limited to 'libmpcodecs/vd_ffmpeg.c')
-rw-r--r--libmpcodecs/vd_ffmpeg.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c
index 5e22bc6c81..eb53c6e830 100644
--- a/libmpcodecs/vd_ffmpeg.c
+++ b/libmpcodecs/vd_ffmpeg.c
@@ -14,7 +14,10 @@
#include "mpbswap.h"
#include "fmt-conversion.h"
-#include "vd_internal.h"
+#include "vd.h"
+#include "img_format.h"
+#include "libmpdemux/stheader.h"
+#include "codec-cfg.h"
static const vd_info_t info = {
"FFmpeg's libavcodec codec family",
@@ -24,8 +27,6 @@ static const vd_info_t info = {
"native codecs"
};
-LIBVD_EXTERN(ffmpeg)
-
#include "libavcodec/avcodec.h"
#if CONFIG_XVMC
@@ -62,6 +63,7 @@ static void draw_slice(struct AVCodecContext *s, const AVFrame *src,
static enum PixelFormat get_format(struct AVCodecContext *avctx,
const enum PixelFormat *pix_fmt);
+static void uninit(struct sh_video *sh);
const m_option_t lavc_decode_opts_conf[]={
OPT_INTRANGE("bug", lavc_param.workaround_bugs, 0, -1, 999999),
@@ -627,6 +629,13 @@ else
ctx->b_age=1;
}
pic->type= FF_BUFFER_TYPE_USER;
+
+ /* The libavcodec reordered_opaque functionality is implemented by
+ * a similar copy in avcodec_default_get_buffer() and without a
+ * workaround like this it'd stop working when a custom buffer
+ * callback is used.
+ */
+ pic->reordered_opaque = avctx->reordered_opaque;
return 0;
}
@@ -691,7 +700,9 @@ static void swap_palette(void *pal) {
}
// decode a frame
-static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){
+static struct mp_image *decode(struct sh_video *sh, void *data, int len,
+ int flags, double *reordered_pts)
+{
int got_picture=0;
int ret;
vd_ffmpeg_ctx *ctx = sh->context;
@@ -726,7 +737,10 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){
pkt.size = len;
// HACK: make PNGs decode normally instead of as CorePNG delta frames
pkt.flags = PKT_FLAG_KEY;
+ // The avcodec opaque field stupidly supports only int64_t type
+ *(double *)&avctx->reordered_opaque = *reordered_pts;
ret = avcodec_decode_video2(avctx, pic, &got_picture, &pkt);
+ *reordered_pts = *(double *)&pic->reordered_opaque;
dr1= ctx->do_dr1;
if(ret<0) mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Error while decoding frame!\n");
@@ -877,3 +891,11 @@ static enum PixelFormat get_format(struct AVCodecContext *avctx,
return selected_format;
}
#endif /* CONFIG_XVMC || CONFIG_VDPAU */
+
+const struct vd_functions mpcodecs_vd_ffmpeg = {
+ .info = &info,
+ .init = init,
+ .uninit = uninit,
+ .control = control,
+ .decode2 = decode
+};