summaryrefslogtreecommitdiffstats
path: root/player/video.c
diff options
context:
space:
mode:
Diffstat (limited to 'player/video.c')
-rw-r--r--player/video.c80
1 files changed, 42 insertions, 38 deletions
diff --git a/player/video.c b/player/video.c
index dc46140859..faa8a652bb 100644
--- a/player/video.c
+++ b/player/video.c
@@ -193,16 +193,15 @@ static void filter_reconfig(struct vo_chain *vo_c)
static void recreate_video_filters(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
- struct dec_video *d_video = mpctx->d_video;
struct vo_chain *vo_c = mpctx->vo_chain;
- assert(d_video && vo_c);
+ assert(vo_c);
vf_destroy(vo_c->vf);
vo_c->vf = vf_new(mpctx->global);
- vo_c->vf->hwdec = d_video->hwdec_info;
+ vo_c->vf->hwdec = vo_c->hwdec_info;
vo_c->vf->wakeup_callback = wakeup_playloop;
vo_c->vf->wakeup_callback_ctx = mpctx;
- vo_c->vf->container_fps = d_video->fps;
+ vo_c->vf->container_fps = vo_c->container_fps;
vo_control(vo_c->vo, VOCTRL_GET_DISPLAY_FPS, &vo_c->vf->display_fps);
vf_append_filter_list(vo_c->vf, opts->vf_settings);
@@ -216,10 +215,9 @@ static void recreate_video_filters(struct MPContext *mpctx)
int reinit_video_filters(struct MPContext *mpctx)
{
- struct dec_video *d_video = mpctx->d_video;
struct vo_chain *vo_c = mpctx->vo_chain;
- if (!d_video)
+ if (!vo_c)
return 0;
bool need_reconfig = vo_c->vf->initialized != 0;
@@ -243,10 +241,10 @@ static void vo_chain_reset_state(struct vo_chain *vo_c)
void reset_video_state(struct MPContext *mpctx)
{
- if (mpctx->d_video)
- video_reset(mpctx->d_video);
- if (mpctx->vo_chain)
+ if (mpctx->vo_chain) {
+ video_reset(mpctx->vo_chain->video_src);
vo_chain_reset_state(mpctx->vo_chain);
+ }
for (int n = 0; n < mpctx->num_next_frames; n++)
mp_image_unrefp(&mpctx->next_frames[n]);
@@ -266,7 +264,7 @@ void reset_video_state(struct MPContext *mpctx)
mpctx->display_sync_drift_dir = 0;
mpctx->display_sync_broken = false;
- mpctx->video_status = mpctx->d_video ? STATUS_SYNCING : STATUS_EOF;
+ mpctx->video_status = mpctx->vo_chain ? STATUS_SYNCING : STATUS_EOF;
}
void uninit_video_out(struct MPContext *mpctx)
@@ -282,20 +280,21 @@ void uninit_video_out(struct MPContext *mpctx)
static void vo_chain_uninit(struct vo_chain *vo_c)
{
mp_image_unrefp(&vo_c->input_mpi);
- if (vo_c)
+ if (vo_c) {
vf_destroy(vo_c->vf);
+ if (vo_c->video_src)
+ video_uninit(vo_c->video_src);
+ }
talloc_free(vo_c);
// this does not free the VO
}
void uninit_video_chain(struct MPContext *mpctx)
{
- if (mpctx->d_video) {
+ if (mpctx->vo_chain) {
reset_video_state(mpctx);
vo_chain_uninit(mpctx->vo_chain);
mpctx->vo_chain = NULL;
- video_uninit(mpctx->d_video);
- mpctx->d_video = NULL;
mpctx->video_status = STATUS_EOF;
mpctx->sync_audio_to_video = false;
reselect_demux_streams(mpctx);
@@ -307,7 +306,6 @@ void uninit_video_chain(struct MPContext *mpctx)
int reinit_video_chain(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
- assert(!mpctx->d_video);
assert(!mpctx->vo_chain);
struct track *track = mpctx->current_track[0][STREAM_VIDEO];
struct sh_stream *sh = track ? track->stream : NULL;
@@ -333,17 +331,21 @@ int reinit_video_chain(struct MPContext *mpctx)
update_window_title(mpctx, true);
- struct dec_video *d_video = talloc_zero(NULL, struct dec_video);
- mpctx->d_video = d_video;
+ struct vo_chain *vo_c = talloc_zero(NULL, struct vo_chain);
+ mpctx->vo_chain = vo_c;
+ vo_c->log = mpctx->log;
+ vo_c->vo = mpctx->video_out;
+
+ vo_control(vo_c->vo, VOCTRL_GET_HWDEC_INFO, &vo_c->hwdec_info);
+
+ track->d_video = talloc_zero(NULL, struct dec_video);
+ struct dec_video *d_video = track->d_video;
d_video->global = mpctx->global;
d_video->log = mp_log_new(d_video, mpctx->log, "!vd");
d_video->opts = mpctx->opts;
d_video->header = sh;
d_video->fps = sh->codec->fps;
-
- mpctx->vo_chain = talloc_zero(NULL, struct vo_chain);
- mpctx->vo_chain->log = d_video->log;
- mpctx->vo_chain->vo = mpctx->video_out;
+ d_video->hwdec_info = vo_c->hwdec_info;
MP_VERBOSE(d_video, "Container reported FPS: %f\n", sh->codec->fps);
@@ -353,23 +355,24 @@ int reinit_video_chain(struct MPContext *mpctx)
MP_INFO(mpctx, "Use --no-correct-pts to force FPS based timing.\n");
}
+ vo_c->container_fps = d_video->fps;
+ vo_c->video_src = d_video;
+
#if HAVE_ENCODING
if (mpctx->encode_lavc_ctx)
encode_lavc_set_video_fps(mpctx->encode_lavc_ctx, d_video->fps);
#endif
- vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, &d_video->hwdec_info);
-
recreate_video_filters(mpctx);
if (!video_init_best_codec(d_video, opts->video_decoders))
goto err_out;
bool saver_state = opts->pause || !opts->stop_screensaver;
- vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER
- : VOCTRL_KILL_SCREENSAVER, NULL);
+ vo_control(vo_c->vo, saver_state ? VOCTRL_RESTORE_SCREENSAVER
+ : VOCTRL_KILL_SCREENSAVER, NULL);
- vo_set_paused(mpctx->video_out, mpctx->paused);
+ vo_set_paused(vo_c->vo, mpctx->paused);
mpctx->sync_audio_to_video = !sh->attached_picture;
@@ -410,19 +413,19 @@ void mp_force_video_refresh(struct MPContext *mpctx)
}
}
-static bool check_framedrop(struct MPContext *mpctx)
+static bool check_framedrop(struct MPContext *mpctx, struct vo_chain *vo_c)
{
struct MPOpts *opts = mpctx->opts;
// check for frame-drop:
if (mpctx->video_status == STATUS_PLAYING && !mpctx->paused &&
mpctx->audio_status == STATUS_PLAYING && !ao_untimed(mpctx->ao))
{
- float fps = mpctx->d_video->fps;
+ float fps = vo_c->container_fps;
double frame_time = fps > 0 ? 1.0 / fps : 0;
// we should avoid dropping too many frames in sequence unless we
// are too late. and we allow 100ms A-V delay here:
int dropped_frames =
- mpctx->d_video->dropped_frames - mpctx->dropped_frames_start;
+ vo_c->video_src->dropped_frames - mpctx->dropped_frames_start;
if (mpctx->last_av_difference - 0.100 > dropped_frames * frame_time)
return !!(opts->frame_dropping & 2);
}
@@ -433,14 +436,14 @@ static bool check_framedrop(struct MPContext *mpctx)
// returns VD_* code
static int decode_image(struct MPContext *mpctx)
{
- struct dec_video *d_video = mpctx->d_video;
struct vo_chain *vo_c = mpctx->vo_chain;
+ struct dec_video *d_video = vo_c->video_src;
bool hrseek = mpctx->hrseek_active && mpctx->video_status == STATUS_SYNCING &&
mpctx->hrseek_framedrop;
video_set_start(d_video, hrseek ? mpctx->hrseek_pts : MP_NOPTS_VALUE);
- video_set_framedrop(d_video, check_framedrop(mpctx));
+ video_set_framedrop(d_video, check_framedrop(mpctx, vo_c));
video_work(d_video);
@@ -504,7 +507,7 @@ static int video_filter(struct MPContext *mpctx, bool eof)
// Most video filters don't work with hardware decoding, so this
// might be the reason why filter reconfig failed.
if (vf->initialized < 0 &&
- video_vd_control(mpctx->d_video, VDCTRL_FORCE_HWDEC_FALLBACK, NULL)
+ video_vd_control(vo_c->video_src, VDCTRL_FORCE_HWDEC_FALLBACK, NULL)
== CONTROL_OK)
{
// Fallback active; decoder will return software format next
@@ -630,7 +633,7 @@ static void handle_new_frame(struct MPContext *mpctx)
mpctx->time_frame += frame_time / mpctx->video_speed;
adjust_sync(mpctx, pts, frame_time);
}
- mpctx->dropped_frames_start = mpctx->d_video->dropped_frames;
+ mpctx->dropped_frames_start = mpctx->vo_chain->video_src->dropped_frames;
MP_TRACE(mpctx, "frametime=%5.3f\n", frame_time);
}
@@ -689,7 +692,8 @@ static int video_output_image(struct MPContext *mpctx, double endpts)
{
bool hrseek = mpctx->hrseek_active && mpctx->video_status == STATUS_SYNCING;
- if (mpctx->d_video->header->attached_picture) {
+ struct track *track = mpctx->current_track[0][STREAM_VIDEO];
+ if (track && track->stream && track->stream->attached_picture) {
if (vo_has_frame(mpctx->video_out))
return VD_EOF;
hrseek = false;
@@ -1123,8 +1127,8 @@ static void calculate_frame_duration(struct MPContext *mpctx)
{
assert(mpctx->num_past_frames >= 1 && mpctx->num_next_frames >= 1);
- double demux_duration =
- mpctx->d_video->fps > 0 ? 1.0 / mpctx->d_video->fps : -1;
+ double demux_duration = mpctx->vo_chain->container_fps > 0
+ ? 1.0 / mpctx->vo_chain->container_fps : -1;
double duration = -1;
if (mpctx->num_next_frames >= 2) {
@@ -1175,10 +1179,10 @@ static void calculate_frame_duration(struct MPContext *mpctx)
void write_video(struct MPContext *mpctx, double endpts)
{
struct MPOpts *opts = mpctx->opts;
- struct vo *vo = mpctx->video_out;
- if (!mpctx->d_video)
+ if (!mpctx->vo_chain)
return;
+ struct vo *vo = mpctx->vo_chain->vo;
// Actual playback starts when both audio and video are ready.
if (mpctx->video_status == STATUS_READY)