summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-25 23:08:29 +0100
committerwm4 <wm4@nowhere>2013-11-25 23:08:29 +0100
commit4205bbf243227bf151f2439ecb7772c41ecbfd12 (patch)
tree141fa5f769a6bd5eb5a3b5095ba9c36e85666cd9 /video
parent51bce52d57467cffba040cf926708befb3d6633b (diff)
downloadmpv-4205bbf243227bf151f2439ecb7772c41ecbfd12.tar.bz2
mpv-4205bbf243227bf151f2439ecb7772c41ecbfd12.tar.xz
video: pass PTS as part of demux_packet/AVPacket and mp_image/AVFrame
Instead of passing the PTS as separate field, pass it as part of the usual data structures. Basically, this removes strange artifacts from the API. (It's not finished, though: the final decoded PTS goes through strange paths, and filter_video() finally overwrites the decoded mp_image's pts field with it.) We also stop using libavcodec's reordered_opaque fields, and use AVPacket.pts and AVFrame.pkt_pts. This is slightly unorthodox, because these pts fields are not "really" opaque anymore, yet we treat them as such. But the end result should be the same, and reordered_opaque is marked as partially deprecated (it's not clear whether it's really deprecated).
Diffstat (limited to 'video')
-rw-r--r--video/decode/dec_video.c7
-rw-r--r--video/decode/dec_video.h8
-rw-r--r--video/decode/vd.h2
-rw-r--r--video/decode/vd_lavc.c22
4 files changed, 22 insertions, 17 deletions
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index 34dc9bd073..e9a59da255 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -206,10 +206,11 @@ bool video_init_best_codec(struct dec_video *d_video, char* video_decoders)
}
void *video_decode(struct dec_video *d_video, struct demux_packet *packet,
- int drop_frame, double pts)
+ int drop_frame)
{
mp_image_t *mpi = NULL;
struct MPOpts *opts = d_video->opts;
+ double pts = packet ? packet->pts : MP_NOPTS_VALUE;
if (opts->correct_pts && pts != MP_NOPTS_VALUE) {
int delay = -1;
@@ -242,7 +243,7 @@ void *video_decode(struct dec_video *d_video, struct demux_packet *packet,
}
}
- mpi = d_video->vd_driver->decode(d_video, packet, drop_frame, &pts);
+ mpi = d_video->vd_driver->decode(d_video, packet, drop_frame);
//------------------------ frame decoded. --------------------
@@ -256,6 +257,8 @@ void *video_decode(struct dec_video *d_video, struct demux_packet *packet,
else if (opts->field_dominance == 1)
mpi->fields &= ~MP_IMGFIELD_TOP_FIRST;
+ pts = mpi->pts;
+
double prevpts = d_video->codec_reordered_pts;
d_video->prev_codec_reordered_pts = prevpts;
d_video->codec_reordered_pts = pts;
diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h
index 9f01d32947..7d8928eb58 100644
--- a/video/decode/dec_video.h
+++ b/video/decode/dec_video.h
@@ -42,8 +42,6 @@ struct dec_video {
void *priv;
- float next_frame_time;
- double last_pts;
double buffered_pts[32];
int num_buffered_pts;
double codec_reordered_pts;
@@ -59,6 +57,10 @@ struct dec_video {
int i_bps; // == bitrate (compressed bytes/sec)
float fps; // FPS from demuxer or from user override
float initial_decoder_aspect;
+
+ // State used only by player/video.c
+ float next_frame_time;
+ double last_pts;
};
struct mp_decoder_list *video_decoder_list(void);
@@ -68,7 +70,7 @@ void video_uninit(struct dec_video *d_video);
struct demux_packet;
void *video_decode(struct dec_video *d_video, struct demux_packet *packet,
- int drop_frame, double pts);
+ int drop_frame);
int video_get_colors(struct dec_video *d_video, const char *item, int *value);
int video_set_colors(struct dec_video *d_video, const char *item, int value);
diff --git a/video/decode/vd.h b/video/decode/vd.h
index dd2536ab2a..045914f502 100644
--- a/video/decode/vd.h
+++ b/video/decode/vd.h
@@ -35,7 +35,7 @@ typedef struct vd_functions
void (*uninit)(struct dec_video *vd);
int (*control)(struct dec_video *vd, int cmd, void *arg);
struct mp_image *(*decode)(struct dec_video *vd, struct demux_packet *pkt,
- int flags, double *reordered_pts);
+ int flags);
} vd_functions_t;
// NULL terminated array of all drivers
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 864da74741..03d77e1c2b 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -729,12 +729,11 @@ static struct mp_image *image_from_decoder(struct dec_video *vd)
#endif /* HAVE_AVUTIL_REFCOUNTING */
static int decode(struct dec_video *vd, struct demux_packet *packet,
- int flags, double *reordered_pts, struct mp_image **out_image)
+ int flags, struct mp_image **out_image)
{
int got_picture = 0;
int ret;
vd_ffmpeg_ctx *ctx = vd->priv;
- AVFrame *pic = ctx->pic;
AVCodecContext *avctx = ctx->avctx;
AVPacket pkt;
@@ -747,22 +746,23 @@ static int decode(struct dec_video *vd, struct demux_packet *packet,
mp_set_av_packet(&pkt, packet);
- // The avcodec opaque field stupidly supports only int64_t type
+ // We merely pass-through our PTS as an int64_t; libavcodec won't use it.
union pts { int64_t i; double d; };
- avctx->reordered_opaque = (union pts){.d = *reordered_pts}.i;
- ret = avcodec_decode_video2(avctx, pic, &got_picture, &pkt);
+ pkt.pts = (union pts){.d = packet ? packet->pts : MP_NOPTS_VALUE}.i;
+ ret = avcodec_decode_video2(avctx, ctx->pic, &got_picture, &pkt);
if (ret < 0) {
mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Error while decoding frame!\n");
return -1;
}
- *reordered_pts = (union pts){.i = pic->reordered_opaque}.d;
// Skipped frame, or delayed output due to multithreaded decoding.
if (!got_picture)
return 0;
- update_image_params(vd, pic);
+ update_image_params(vd, ctx->pic);
+ double out_pts = (union pts){.i = ctx->pic->pkt_pts}.d;
+ // Note: potentially resets ctx->pic as it is transferred to mpi
struct mp_image *mpi = image_from_decoder(vd);
assert(mpi->planes[0]);
mp_image_set_params(mpi, &ctx->image_params);
@@ -772,6 +772,7 @@ static int decode(struct dec_video *vd, struct demux_packet *packet,
struct mp_image_params vo_params;
mp_image_params_from_image(&vo_params, mpi);
+ mpi->pts = out_pts;
if (!mp_image_params_equals(&vo_params, &ctx->vo_image_params)) {
mp_image_pool_clear(ctx->non_dr1_pool);
@@ -787,15 +788,14 @@ static int decode(struct dec_video *vd, struct demux_packet *packet,
}
static struct mp_image *decode_with_fallback(struct dec_video *vd,
- struct demux_packet *packet,
- int flags, double *reordered_pts)
+ struct demux_packet *packet, int flags)
{
vd_ffmpeg_ctx *ctx = vd->priv;
if (!ctx->avctx)
return NULL;
struct mp_image *mpi = NULL;
- int res = decode(vd, packet, flags, reordered_pts, &mpi);
+ int res = decode(vd, packet, flags, &mpi);
if (res >= 0)
return mpi;
@@ -811,7 +811,7 @@ static struct mp_image *decode_with_fallback(struct dec_video *vd,
mpi = NULL;
if (vd->vf_initialized < 0)
vd->vf_initialized = 0;
- decode(vd, packet, flags, reordered_pts, &mpi);
+ decode(vd, packet, flags, &mpi);
return mpi;
}
}