diff --git a/demux/demux.c b/demux/demux.c index 095c23fd0c..592ad1608a 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -241,7 +241,6 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type) .demuxer = demuxer, .index = demuxer->num_streams, .demuxer_id = demuxer_id, // may be overwritten by demuxer - .opts = demuxer->opts, .ds = talloc_zero(sh, struct demux_stream), }; MP_TARRAY_APPEND(demuxer, demuxer->streams, demuxer->num_streams, sh); @@ -249,21 +248,18 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type) case STREAM_VIDEO: { struct sh_video *sht = talloc_zero(demuxer, struct sh_video); sht->gsh = sh; - sht->opts = sh->opts; sh->video = sht; break; } case STREAM_AUDIO: { struct sh_audio *sht = talloc_zero(demuxer, struct sh_audio); sht->gsh = sh; - sht->opts = sh->opts; sh->audio = sht; break; } case STREAM_SUB: { struct sh_sub *sht = talloc_zero(demuxer, struct sh_sub); sht->gsh = sh; - sht->opts = sh->opts; sh->sub = sht; break; } diff --git a/demux/stheader.h b/demux/stheader.h index eb7c3d132b..1c151cda3d 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -63,30 +63,14 @@ struct sh_stream { // stream is a picture (such as album art) struct demux_packet *attached_picture; - // Human readable description of the running decoder, or NULL - char *decoder_desc; - - // shouldn't exist type of stuff - struct MPOpts *opts; - // Internal to demux.c struct demux_stream *ds; }; -#define SH_COMMON \ - struct sh_stream *gsh; \ - struct MPOpts *opts; \ - /* usually a FourCC, exact meaning depends on gsh->format */ \ - unsigned int format; \ - int initialized; \ - /* audio: last known pts value in output from decoder \ - * video: predicted/interpolated PTS of the current frame */ \ - double pts; \ - /* decoder context */ \ - void *context; \ - typedef struct sh_audio { - SH_COMMON + struct sh_stream *gsh; + /* usually a FourCC, exact meaning depends on gsh->codec */ + unsigned int format; int samplerate; struct mp_chmap channels; int i_bps; // == bitrate (compressed bytes/sec) @@ -98,37 +82,18 @@ typedef struct sh_audio { } sh_audio_t; typedef struct sh_video { - SH_COMMON - float next_frame_time; - double last_pts; - double buffered_pts[32]; - int num_buffered_pts; - double codec_reordered_pts; - double prev_codec_reordered_pts; - int num_reordered_pts_problems; - double sorted_pts; - double prev_sorted_pts; - int num_sorted_pts_problems; - int pts_assoc_mode; - // output format: (set by demuxer) + struct sh_stream *gsh; + /* usually a FourCC, exact meaning depends on gsh->codec */ + unsigned int format; float fps; // frames per second (set only if constant fps) float aspect; // aspect ratio stored in the file (for prescaling) - float stream_aspect; // aspect ratio in media headers (DVD IFO files) int i_bps; // == bitrate (compressed bytes/sec) - int disp_w, disp_h; // display size (filled by demuxer or decoder) - // output driver/filters: (set by libmpcodecs core) - struct vf_instance *vfilter; // video filter chain - const struct vd_functions *vd_driver; - int vf_initialized; // -1 failed, 0 not done, 1 done - long vf_reconfig_count; // incremented each mpcodecs_reconfig_vo() call - struct mp_image_params *vf_input; // video filter input params - struct mp_hwdec_info *hwdec_info; // video output hwdec handles - // win32-compatible codec parameters: + int disp_w, disp_h; // display size MP_BITMAPINFOHEADER *bih; } sh_video_t; typedef struct sh_sub { - SH_COMMON + struct sh_stream *gsh; unsigned char *extradata; // extra header data passed from demuxer int extradata_len; int frame_based; // timestamps are frame-based diff --git a/mpvcore/player/audio.c b/mpvcore/player/audio.c index ce161a58d5..377b393dfd 100644 --- a/mpvcore/player/audio.c +++ b/mpvcore/player/audio.c @@ -36,6 +36,7 @@ #include "audio/filter/af.h" #include "audio/out/ao.h" #include "demux/demux.h" +#include "video/decode/dec_video.h" #include "mp_core.h" @@ -302,7 +303,7 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize) if (hrseek) ptsdiff = written_pts - mpctx->hrseek_pts; else - ptsdiff = written_pts - mpctx->sh_video->pts - mpctx->delay + ptsdiff = written_pts - mpctx->d_video->pts - mpctx->delay - mpctx->audio_delay; samples = ptsdiff * real_samplerate; @@ -376,7 +377,7 @@ int fill_audio_out_buffers(struct MPContext *mpctx, double endpts) playsize = ao_get_space(ao); // Coming here with hrseek_active still set means audio-only - if (!mpctx->sh_video || !mpctx->sync_audio_to_video) + if (!mpctx->d_video || !mpctx->sync_audio_to_video) mpctx->syncing_audio = false; if (!opts->initial_audio_sync || !modifiable_audio_format) { mpctx->syncing_audio = false; diff --git a/mpvcore/player/command.c b/mpvcore/player/command.c index cdeb11c713..c09a046cd2 100644 --- a/mpvcore/player/command.c +++ b/mpvcore/player/command.c @@ -316,7 +316,7 @@ static int mp_property_length(m_option_t *prop, int action, void *arg, static int mp_property_avsync(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - if (!mpctx->d_audio || !mpctx->sh_video) + if (!mpctx->d_audio || !mpctx->d_video) return M_PROPERTY_UNAVAILABLE; if (mpctx->last_av_difference == MP_NOPTS_VALUE) return M_PROPERTY_UNAVAILABLE; @@ -623,8 +623,8 @@ static int mp_property_angle(m_option_t *prop, int action, void *arg, case M_PROPERTY_SET: angle = demuxer_set_angle(demuxer, *(int *)arg); if (angle >= 0) { - if (mpctx->sh_video) - resync_video_stream(mpctx->sh_video); + if (mpctx->d_video) + video_resync_stream(mpctx->d_video); if (mpctx->d_audio) audio_resync_stream(mpctx->d_audio); @@ -817,7 +817,7 @@ static int mp_property_volrestore(m_option_t *prop, int action, static int mp_property_audio_delay(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - if (!(mpctx->d_audio && mpctx->sh_video)) + if (!(mpctx->d_audio && mpctx->d_video)) return M_PROPERTY_UNAVAILABLE; float delay = mpctx->opts->audio_delay; switch (action) { @@ -1168,7 +1168,7 @@ static int probe_deint_filters(struct MPContext *mpctx, const char *cmd) static int get_deinterlacing(struct MPContext *mpctx) { - vf_instance_t *vf = mpctx->sh_video->vfilter; + vf_instance_t *vf = mpctx->d_video->vfilter; int enabled = 0; if (vf->control(vf, VFCTRL_GET_DEINTERLACE, &enabled) != CONTROL_OK) enabled = -1; @@ -1182,7 +1182,7 @@ static int get_deinterlacing(struct MPContext *mpctx) static void set_deinterlacing(struct MPContext *mpctx, bool enable) { - vf_instance_t *vf = mpctx->sh_video->vfilter; + vf_instance_t *vf = mpctx->d_video->vfilter; if (vf_find_by_label(vf, VF_DEINTERLACE_LABEL)) { if (!enable) edit_filters(mpctx, STREAM_VIDEO, "del", "@" VF_DEINTERLACE_LABEL); @@ -1199,7 +1199,7 @@ static void set_deinterlacing(struct MPContext *mpctx, bool enable) static int mp_property_deinterlace(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - if (!mpctx->sh_video || !mpctx->sh_video->vfilter) + if (!mpctx->d_video || !mpctx->d_video->vfilter) return M_PROPERTY_UNAVAILABLE; switch (action) { case M_PROPERTY_GET: @@ -1218,7 +1218,7 @@ static int video_refresh_property_helper(m_option_t *prop, int action, { int r = mp_property_generic_option(prop, action, arg, mpctx); if (action == M_PROPERTY_SET) { - if (mpctx->sh_video) { + if (mpctx->d_video) { reinit_video_filters(mpctx); mp_force_video_refresh(mpctx); } @@ -1239,8 +1239,8 @@ static int mp_property_colormatrix(m_option_t *prop, int action, void *arg, vo_control(mpctx->video_out, VOCTRL_GET_YUV_COLORSPACE, &vo_csp); struct mp_image_params vd_csp = {0}; - if (mpctx->sh_video) - vd_control(mpctx->sh_video, VDCTRL_GET_PARAMS, &vd_csp); + if (mpctx->d_video) + video_vd_control(mpctx->d_video, VDCTRL_GET_PARAMS, &vd_csp); char *res = talloc_asprintf(NULL, "%s", mp_csp_names[opts->requested_colorspace]); @@ -1273,8 +1273,8 @@ static int mp_property_colormatrix_input_range(m_option_t *prop, int action, vo_control(mpctx->video_out, VOCTRL_GET_YUV_COLORSPACE, &vo_csp ); struct mp_image_params vd_csp = {0}; - if (mpctx->sh_video) - vd_control(mpctx->sh_video, VDCTRL_GET_PARAMS, &vd_csp); + if (mpctx->d_video) + video_vd_control(mpctx->d_video, VDCTRL_GET_PARAMS, &vd_csp); char *res = talloc_asprintf(NULL, "%s", mp_csp_levels_names[opts->requested_input_range]); @@ -1372,7 +1372,7 @@ static int mp_property_border(m_option_t *prop, int action, void *arg, static int mp_property_framedrop(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - if (!mpctx->sh_video) + if (!mpctx->d_video) return M_PROPERTY_UNAVAILABLE; return mp_property_generic_option(prop, action, arg, mpctx); @@ -1381,17 +1381,17 @@ static int mp_property_framedrop(m_option_t *prop, int action, static int mp_property_video_color(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - if (!mpctx->sh_video) + if (!mpctx->d_video) return M_PROPERTY_UNAVAILABLE; switch (action) { case M_PROPERTY_SET: { - if (set_video_colors(mpctx->sh_video, prop->name, *(int *) arg) <= 0) + if (video_set_colors(mpctx->d_video, prop->name, *(int *) arg) <= 0) return M_PROPERTY_UNAVAILABLE; break; } case M_PROPERTY_GET: - if (get_video_colors(mpctx->sh_video, prop->name, (int *)arg) <= 0) + if (video_get_colors(mpctx->d_video, prop->name, (int *)arg) <= 0) return M_PROPERTY_UNAVAILABLE; // Write new value to option variable mp_property_generic_option(prop, M_PROPERTY_SET, arg, mpctx); @@ -1404,7 +1404,7 @@ static int mp_property_video_color(m_option_t *prop, int action, void *arg, static int mp_property_video_format(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - const char *c = mpctx->sh_video ? mpctx->sh_video->gsh->codec : NULL; + const char *c = mpctx->d_video ? mpctx->d_video->header->codec : NULL; return m_property_strdup_ro(prop, action, arg, c); } @@ -1412,7 +1412,7 @@ static int mp_property_video_format(m_option_t *prop, int action, static int mp_property_video_codec(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - const char *c = mpctx->sh_video ? mpctx->sh_video->gsh->decoder_desc : NULL; + const char *c = mpctx->d_video ? mpctx->d_video->decoder_desc : NULL; return m_property_strdup_ro(prop, action, arg, c); } @@ -1421,42 +1421,44 @@ static int mp_property_video_codec(m_option_t *prop, int action, static int mp_property_video_bitrate(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - if (!mpctx->sh_video) + if (!mpctx->d_video) return M_PROPERTY_UNAVAILABLE; if (action == M_PROPERTY_PRINT) { - *(char **)arg = format_bitrate(mpctx->sh_video->i_bps); + *(char **)arg = format_bitrate(mpctx->d_video->i_bps); return M_PROPERTY_OK; } - return m_property_int_ro(prop, action, arg, mpctx->sh_video->i_bps); + return m_property_int_ro(prop, action, arg, mpctx->d_video->i_bps); } /// Video display width (RO) static int mp_property_width(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - struct sh_video *sh = mpctx->sh_video; - if (!sh) + struct dec_video *vd = mpctx->d_video; + if (!vd) return M_PROPERTY_UNAVAILABLE; + struct sh_video *sh = vd->header->video; return m_property_int_ro(prop, action, arg, - sh->vf_input ? sh->vf_input->w : sh->disp_w); + vd->vf_input ? vd->vf_input->w : sh->disp_w); } /// Video display height (RO) static int mp_property_height(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - struct sh_video *sh = mpctx->sh_video; - if (!sh) + struct dec_video *vd = mpctx->d_video; + if (!vd) return M_PROPERTY_UNAVAILABLE; + struct sh_video *sh = vd->header->video; return m_property_int_ro(prop, action, arg, - sh->vf_input ? sh->vf_input->h : sh->disp_h); + vd->vf_input ? vd->vf_input->h : sh->disp_h); } static int property_vo_wh(m_option_t *prop, int action, void *arg, MPContext *mpctx, bool get_w) { struct vo *vo = mpctx->video_out; - if (!mpctx->sh_video && !vo || !vo->hasframe) + if (!mpctx->d_video || !vo || !vo->hasframe) return M_PROPERTY_UNAVAILABLE; return m_property_int_ro(prop, action, arg, get_w ? vo->aspdat.prew : vo->aspdat.preh); @@ -1530,18 +1532,19 @@ static int mp_property_osd_par(m_option_t *prop, int action, void *arg, static int mp_property_fps(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - if (!mpctx->sh_video) + if (!mpctx->d_video) return M_PROPERTY_UNAVAILABLE; - return m_property_float_ro(prop, action, arg, mpctx->sh_video->fps); + return m_property_float_ro(prop, action, arg, mpctx->d_video->header->video->fps); } /// Video aspect (RO) static int mp_property_aspect(m_option_t *prop, int action, void *arg, MPContext *mpctx) { - struct sh_video *sh_video = mpctx->sh_video; - if (!mpctx->sh_video) + if (!mpctx->d_video) return M_PROPERTY_UNAVAILABLE; + struct dec_video *d_video = mpctx->d_video; + struct sh_video *sh_video = d_video->header->video; switch (action) { case M_PROPERTY_SET: { mpctx->opts->movie_aspect = *(float *)arg; @@ -1551,7 +1554,7 @@ static int mp_property_aspect(m_option_t *prop, int action, void *arg, } case M_PROPERTY_GET: { float aspect = -1; - struct mp_image_params *params = sh_video->vf_input; + struct mp_image_params *params = d_video->vf_input; if (params && params->d_w && params->d_h) { aspect = (float)params->d_w / params->d_h; } else if (sh_video->disp_w && sh_video->disp_h) { diff --git a/mpvcore/player/loadfile.c b/mpvcore/player/loadfile.c index 856f5469c0..51d3f2ec7e 100644 --- a/mpvcore/player/loadfile.c +++ b/mpvcore/player/loadfile.c @@ -99,8 +99,9 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) if (mask & INITIALIZED_VCODEC) { mpctx->initialized_flags &= ~INITIALIZED_VCODEC; - if (mpctx->sh_video) - uninit_video(mpctx->sh_video); + if (mpctx->d_video) + video_uninit(mpctx->d_video); + mpctx->d_video = NULL; cleanup_demux_stream(mpctx, STREAM_VIDEO); mpctx->sync_audio_to_video = false; } @@ -113,7 +114,7 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask) mpctx->num_tracks = 0; for (int t = 0; t < STREAM_TYPE_COUNT; t++) mpctx->current_track[t] = NULL; - assert(!mpctx->sh_video && !mpctx->d_audio && !mpctx->sh_sub); + assert(!mpctx->d_video && !mpctx->d_audio && !mpctx->sh_sub); mpctx->master_demuxer = NULL; for (int i = 0; i < mpctx->num_sources; i++) { uninit_subs(mpctx->sources[i]); @@ -269,7 +270,6 @@ static void set_demux_field(struct MPContext *mpctx, enum stream_type type, mpctx->sh[type] = s; // redundant fields for convenience access switch(type) { - case STREAM_VIDEO: mpctx->sh_video = s ? s->video : NULL; break; case STREAM_SUB: mpctx->sh_sub = s ? s->sub : NULL; break; } } @@ -348,7 +348,7 @@ bool timeline_set_part(struct MPContext *mpctx, int i, bool force) if (n->source == p->source && !force) return false; enum stop_play_reason orig_stop_play = mpctx->stop_play; - if (!mpctx->sh_video && mpctx->stop_play == KEEP_PLAYING) + if (!mpctx->d_video && mpctx->stop_play == KEEP_PLAYING) mpctx->stop_play = AT_END_OF_FILE; // let audio uninit drain data uninit_player(mpctx, INITIALIZED_VCODEC | (mpctx->opts->fixed_vo ? 0 : INITIALIZED_VO) | (mpctx->opts->gapless_audio ? 0 : INITIALIZED_AO) | INITIALIZED_ACODEC | INITIALIZED_SUB); mpctx->stop_play = orig_stop_play; @@ -1050,7 +1050,7 @@ static void play_current_file(struct MPContext *mpctx) assert(mpctx->stream == NULL); assert(mpctx->demuxer == NULL); assert(mpctx->d_audio == NULL); - assert(mpctx->sh_video == NULL); + assert(mpctx->d_video == NULL); assert(mpctx->sh_sub == NULL); char *stream_filename = mpctx->filename; @@ -1189,14 +1189,14 @@ goto_reopen_demuxer: ; //================ SETUP STREAMS ========================== - if (opts->force_fps && mpctx->sh_video) { - mpctx->sh_video->fps = opts->force_fps; - MP_INFO(mpctx, "FPS forced to be %5.3f.\n", mpctx->sh_video->fps); + if (opts->force_fps && mpctx->d_video) { + mpctx->d_video->header->video->fps = opts->force_fps; + MP_INFO(mpctx, "FPS forced to be %5.3f.\n", mpctx->d_video->header->video->fps); } //==================== START PLAYING ======================= - if (!mpctx->sh_video && !mpctx->d_audio) { + if (!mpctx->d_video && !mpctx->d_audio) { MP_FATAL(mpctx, "No video or audio streams selected.\n"); #if HAVE_DVBIN if (mpctx->stream->type == STREAMTYPE_DVB) { diff --git a/mpvcore/player/main.c b/mpvcore/player/main.c index 528076bc57..84b5aa2651 100644 --- a/mpvcore/player/main.c +++ b/mpvcore/player/main.c @@ -200,7 +200,7 @@ static bool handle_help_options(struct MPContext *mpctx) opt_exit = 1; } if (opts->video_decoders && strcmp(opts->video_decoders, "help") == 0) { - struct mp_decoder_list *list = mp_video_decoder_list(); + struct mp_decoder_list *list = video_decoder_list(); mp_print_decoders(MSGT_CPLAYER, MSGL_INFO, "Video decoders:", list); talloc_free(list); opt_exit = 1; diff --git a/mpvcore/player/mp_core.h b/mpvcore/player/mp_core.h index aa0728d10f..f372c4e137 100644 --- a/mpvcore/player/mp_core.h +++ b/mpvcore/player/mp_core.h @@ -199,9 +199,9 @@ typedef struct MPContext { struct track *current_track[STREAM_TYPE_COUNT]; struct sh_stream *sh[STREAM_TYPE_COUNT]; - struct sh_video *sh_video; // same as sh[STREAM_VIDEO]->video struct sh_sub *sh_sub; // same as sh[STREAM_SUB]->sub + struct dec_video *d_video; struct dec_audio *d_audio; // Uses: accessing metadata (consider ordered chapters case, where the main diff --git a/mpvcore/player/osd.c b/mpvcore/player/osd.c index 04052c359e..6f81deae2e 100644 --- a/mpvcore/player/osd.c +++ b/mpvcore/player/osd.c @@ -85,7 +85,6 @@ void write_status_line(struct MPContext *mpctx, const char *line) void print_status(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; - sh_video_t * const sh_video = mpctx->sh_video; update_window_title(mpctx, false); @@ -110,7 +109,7 @@ void print_status(struct MPContext *mpctx) if (mpctx->d_audio) saddf(&line, "A"); - if (mpctx->sh_video) + if (mpctx->d_video) saddf(&line, "V"); saddf(&line, ": "); @@ -131,7 +130,7 @@ void print_status(struct MPContext *mpctx) saddf(&line, " x%4.2f", opts->playback_speed); // A-V sync - if (mpctx->d_audio && sh_video && mpctx->sync_audio_to_video) { + if (mpctx->d_audio && mpctx->d_video && mpctx->sync_audio_to_video) { if (mpctx->last_av_difference != MP_NOPTS_VALUE) saddf(&line, " A-V:%7.3f", mpctx->last_av_difference); else @@ -152,7 +151,7 @@ void print_status(struct MPContext *mpctx) #endif { // VO stats - if (sh_video && mpctx->drop_frame_cnt) + if (mpctx->d_video && mpctx->drop_frame_cnt) saddf(&line, " Late: %d", mpctx->drop_frame_cnt); } diff --git a/mpvcore/player/playloop.c b/mpvcore/player/playloop.c index 51daf03bb1..591d31fbca 100644 --- a/mpvcore/player/playloop.c +++ b/mpvcore/player/playloop.c @@ -93,7 +93,7 @@ void pause_player(struct MPContext *mpctx) mpctx->osd_function = 0; mpctx->paused_for_cache = false; - if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok) + if (mpctx->video_out && mpctx->d_video && mpctx->video_out->config_ok) vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL); if (mpctx->ao && mpctx->d_audio) @@ -126,7 +126,7 @@ void unpause_player(struct MPContext *mpctx) if (mpctx->ao && mpctx->d_audio) ao_resume(mpctx->ao); - if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok) + if (mpctx->video_out && mpctx->d_video && mpctx->video_out->config_ok) vo_control(mpctx->video_out, VOCTRL_RESUME, NULL); // resume video (void)get_relative_time(mpctx); // ignore time that passed during pause } @@ -153,7 +153,7 @@ static bool redraw_osd(struct MPContext *mpctx) void add_step_frame(struct MPContext *mpctx, int dir) { - if (!mpctx->sh_video) + if (!mpctx->d_video) return; if (dir > 0) { mpctx->step_frames += 1; @@ -169,14 +169,14 @@ void add_step_frame(struct MPContext *mpctx, int dir) static void seek_reset(struct MPContext *mpctx, bool reset_ao) { - if (mpctx->sh_video) { - resync_video_stream(mpctx->sh_video); + if (mpctx->d_video) { + video_resync_stream(mpctx->d_video); vo_seek_reset(mpctx->video_out); - if (mpctx->sh_video->vf_initialized == 1) - vf_chain_seek_reset(mpctx->sh_video->vfilter); - mpctx->sh_video->num_buffered_pts = 0; - mpctx->sh_video->last_pts = MP_NOPTS_VALUE; - mpctx->sh_video->pts = MP_NOPTS_VALUE; + if (mpctx->d_video->vf_initialized == 1) + vf_chain_seek_reset(mpctx->d_video->vfilter); + mpctx->d_video->num_buffered_pts = 0; + mpctx->d_video->last_pts = MP_NOPTS_VALUE; + mpctx->d_video->pts = MP_NOPTS_VALUE; mpctx->video_pts = MP_NOPTS_VALUE; mpctx->delay = 0; mpctx->time_frame = 0; @@ -589,7 +589,7 @@ do_seek: static void update_avsync(struct MPContext *mpctx) { - if (!mpctx->d_audio || !mpctx->sh_video) + if (!mpctx->d_audio || !mpctx->d_video) return; double a_pos = playing_audio_pts(mpctx); @@ -624,7 +624,7 @@ static void adjust_sync(struct MPContext *mpctx, double frame_time) return; double a_pts = written_audio_pts(mpctx) - mpctx->delay; - double v_pts = mpctx->sh_video->pts; + double v_pts = mpctx->d_video->pts; double av_delay = a_pts - v_pts; // Try to sync vo_flip() so it will *finish* at given time av_delay += mpctx->last_vo_flip_duration; @@ -797,7 +797,7 @@ static void handle_backstep(struct MPContext *mpctx) double current_pts = mpctx->last_vo_pts; mpctx->backstep_active = false; bool demuxer_ok = mpctx->demuxer && mpctx->demuxer->accurate_seek; - if (demuxer_ok && mpctx->sh_video && current_pts != MP_NOPTS_VALUE) { + if (demuxer_ok && mpctx->d_video && current_pts != MP_NOPTS_VALUE) { double seek_pts = find_previous_pts(mpctx, current_pts); if (seek_pts != MP_NOPTS_VALUE) { queue_seek(mpctx, MPSEEK_ABSOLUTE, seek_pts, 1); @@ -863,7 +863,7 @@ static void handle_keep_open(struct MPContext *mpctx) void handle_force_window(struct MPContext *mpctx, bool reconfig) { // Don't interfere with real video playback - if (mpctx->sh_video) + if (mpctx->d_video) return; struct vo *vo = mpctx->video_out; @@ -982,7 +982,7 @@ void run_playloop(struct MPContext *mpctx) } double buffered_audio = -1; - while (mpctx->sh_video) { // never loops, for "break;" only + while (mpctx->d_video) { // never loops, for "break;" only struct vo *vo = mpctx->video_out; update_fps(mpctx); @@ -990,7 +990,7 @@ void run_playloop(struct MPContext *mpctx) if (!vo->frame_loaded && (!mpctx->paused || mpctx->restart_playback)) { double frame_time = update_video(mpctx, endpts); mp_dbg(MSGT_AVSYNC, MSGL_DBG2, "*** ftime=%5.3f ***\n", frame_time); - if (mpctx->sh_video->vf_initialized < 0) { + if (mpctx->d_video->vf_initialized < 0) { MP_FATAL(mpctx, "\nFATAL: Could not initialize video filters " "(-vf) or video output (-vo).\n"); int uninit = INITIALIZED_VCODEC; @@ -1016,7 +1016,7 @@ void run_playloop(struct MPContext *mpctx) } if (endpts != MP_NOPTS_VALUE) - video_left &= mpctx->sh_video->pts < endpts; + video_left &= mpctx->d_video->pts < endpts; handle_heartbeat_cmd(mpctx); @@ -1070,8 +1070,7 @@ void run_playloop(struct MPContext *mpctx) //=================== FLIP PAGE (VIDEO BLT): ====================== vo_new_frame_imminent(vo); - struct sh_video *sh_video = mpctx->sh_video; - mpctx->video_pts = sh_video->pts; + mpctx->video_pts = mpctx->d_video->pts; mpctx->last_vo_pts = mpctx->video_pts; mpctx->playback_pts = mpctx->video_pts; update_subtitles(mpctx); @@ -1182,7 +1181,7 @@ void run_playloop(struct MPContext *mpctx) * should trigger after seek only, when we know there's no audio * buffered. */ - if ((mpctx->d_audio || mpctx->sh_video) && !audio_left && !video_left + if ((mpctx->d_audio || mpctx->d_video) && !audio_left && !video_left && (opts->gapless_audio || buffered_audio < 0.05) && (!mpctx->paused || was_restart)) { if (end_is_chapter) { diff --git a/mpvcore/player/screenshot.c b/mpvcore/player/screenshot.c index aeb15c0fd7..f564b5e9d7 100644 --- a/mpvcore/player/screenshot.c +++ b/mpvcore/player/screenshot.c @@ -315,8 +315,8 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode) struct voctrl_screenshot_args args = { .full_window = (mode == MODE_FULL_WINDOW) }; - if (mpctx->sh_video && mpctx->sh_video->vfilter) { - struct vf_instance *vfilter = mpctx->sh_video->vfilter; + if (mpctx->d_video && mpctx->d_video->vfilter) { + struct vf_instance *vfilter = mpctx->d_video->vfilter; vfilter->control(vfilter, VFCTRL_SCREENSHOT, &args); } diff --git a/mpvcore/player/sub.c b/mpvcore/player/sub.c index 94368435d1..d659e74851 100644 --- a/mpvcore/player/sub.c +++ b/mpvcore/player/sub.c @@ -33,6 +33,7 @@ #include "sub/dec_sub.h" #include "demux/demux.h" #include "video/mp_image.h" +#include "video/decode/dec_video.h" #include "mp_core.h" @@ -83,8 +84,8 @@ void update_subtitles(struct MPContext *mpctx) assert(track && sh_sub); struct dec_sub *dec_sub = sh_sub->dec_sub; - if (mpctx->sh_video && mpctx->sh_video->vf_input) { - struct mp_image_params params = *mpctx->sh_video->vf_input; + if (mpctx->d_video && mpctx->d_video->vf_input) { + struct mp_image_params params = *mpctx->d_video->vf_input; sub_control(dec_sub, SD_CTRL_SET_VIDEO_PARAMS, ¶ms); } @@ -194,9 +195,11 @@ void reinit_subs(struct MPContext *mpctx) assert(dec_sub); if (!sub_is_initialized(dec_sub)) { - int w = mpctx->sh_video ? mpctx->sh_video->disp_w : 0; - int h = mpctx->sh_video ? mpctx->sh_video->disp_h : 0; - float fps = mpctx->sh_video ? mpctx->sh_video->fps : 25; + struct sh_video *sh_video = + mpctx->d_video ? mpctx->d_video->header->video : NULL; + int w = sh_video ? sh_video->disp_w : 0; + int h = sh_video ? sh_video->disp_h : 0; + float fps = sh_video ? sh_video->fps : 25; set_dvdsub_fake_extradata(dec_sub, track->demuxer->stream, w, h); sub_set_video_res(dec_sub, w, h); diff --git a/mpvcore/player/video.c b/mpvcore/player/video.c index ac6406968f..333b694f9c 100644 --- a/mpvcore/player/video.c +++ b/mpvcore/player/video.c @@ -46,63 +46,64 @@ void update_fps(struct MPContext *mpctx) { #if HAVE_ENCODING - struct sh_video *sh_video = mpctx->sh_video; - if (mpctx->encode_lavc_ctx && sh_video) - encode_lavc_set_video_fps(mpctx->encode_lavc_ctx, sh_video->fps); + struct dec_video *d_video = mpctx->d_video; + if (mpctx->encode_lavc_ctx && d_video) + encode_lavc_set_video_fps(mpctx->encode_lavc_ctx, d_video->header->video->fps); #endif } static void recreate_video_filters(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; - struct sh_video *sh_video = mpctx->sh_video; - assert(sh_video); + struct dec_video *d_video = mpctx->d_video; + assert(d_video); - vf_uninit_filter_chain(sh_video->vfilter); + vf_uninit_filter_chain(d_video->vfilter); char *vf_arg[] = { "_oldargs_", (char *)mpctx->video_out, NULL }; - sh_video->vfilter = vf_open_filter(opts, NULL, "vo", vf_arg); + d_video->vfilter = vf_open_filter(opts, NULL, "vo", vf_arg); - sh_video->vfilter = append_filters(sh_video->vfilter, opts->vf_settings); + d_video->vfilter = append_filters(d_video->vfilter, opts->vf_settings); - struct vf_instance *vf = sh_video->vfilter; + struct vf_instance *vf = d_video->vfilter; mpctx->osd->render_subs_in_filter = vf->control(vf, VFCTRL_INIT_OSD, NULL) == VO_TRUE; } int reinit_video_filters(struct MPContext *mpctx) { - struct sh_video *sh_video = mpctx->sh_video; + struct dec_video *d_video = mpctx->d_video; - if (!sh_video) + if (!d_video) return -2; recreate_video_filters(mpctx); - video_reinit_vo(sh_video); + video_reinit_vo(d_video); - return sh_video->vf_initialized > 0 ? 0 : -1; + return d_video->vf_initialized > 0 ? 0 : -1; } int reinit_video_chain(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; assert(!(mpctx->initialized_flags & INITIALIZED_VCODEC)); + assert(!mpctx->d_video); init_demux_stream(mpctx, STREAM_VIDEO); - sh_video_t *sh_video = mpctx->sh_video; - if (!sh_video) + struct sh_stream *sh = mpctx->sh[STREAM_VIDEO]; + if (!sh) goto no_video; MP_VERBOSE(mpctx, "[V] fourcc:0x%X size:%dx%d fps:%5.3f\n", - mpctx->sh_video->format, - mpctx->sh_video->disp_w, mpctx->sh_video->disp_h, - mpctx->sh_video->fps); + sh->video->format, + sh->video->disp_w, sh->video->disp_h, + sh->video->fps); if (opts->force_fps) - mpctx->sh_video->fps = opts->force_fps; + sh->video->fps = opts->force_fps; update_fps(mpctx); - if (!mpctx->sh_video->fps && !opts->force_fps && !opts->correct_pts) { + if (!sh->video->fps && !opts->force_fps && !opts->correct_pts) { MP_ERR(mpctx, "FPS not specified in the " "header or invalid, use the -fps option.\n"); } @@ -121,26 +122,31 @@ int reinit_video_chain(struct MPContext *mpctx) mpctx->initialized_flags |= INITIALIZED_VO; } - // dynamic allocation only to make stheader.h lighter - talloc_free(sh_video->hwdec_info); - sh_video->hwdec_info = talloc_zero(sh_video, struct mp_hwdec_info); - vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, sh_video->hwdec_info); - update_window_title(mpctx, true); - if (stream_control(mpctx->sh_video->gsh->demuxer->stream, - STREAM_CTRL_GET_ASPECT_RATIO, &ar) != STREAM_UNSUPPORTED) - mpctx->sh_video->stream_aspect = ar; + struct dec_video *d_video = talloc_zero(NULL, struct dec_video); + mpctx->d_video = d_video; + d_video->last_pts = MP_NOPTS_VALUE; + d_video->opts = mpctx->opts; + d_video->header = sh; + mpctx->initialized_flags |= INITIALIZED_VCODEC; + + // dynamic allocation only to make stheader.h lighter + talloc_free(d_video->hwdec_info); + d_video->hwdec_info = talloc_zero(d_video, struct mp_hwdec_info); + vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, d_video->hwdec_info); + + if (stream_control(sh->demuxer->stream, STREAM_CTRL_GET_ASPECT_RATIO, &ar) + != STREAM_UNSUPPORTED) + d_video->stream_aspect = ar; recreate_video_filters(mpctx); - init_best_video_codec(sh_video, opts->video_decoders); + video_init_best_codec(d_video, opts->video_decoders); - if (!sh_video->initialized) + if (!d_video->initialized) goto err_out; - mpctx->initialized_flags |= INITIALIZED_VCODEC; - bool saver_state = opts->pause || !opts->stop_screensaver; vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER : VOCTRL_KILL_SCREENSAVER, NULL); @@ -148,12 +154,9 @@ int reinit_video_chain(struct MPContext *mpctx) vo_control(mpctx->video_out, mpctx->paused ? VOCTRL_PAUSE : VOCTRL_RESUME, NULL); - sh_video->last_pts = MP_NOPTS_VALUE; - sh_video->num_buffered_pts = 0; - sh_video->next_frame_time = 0; mpctx->last_vf_reconfig_count = 0; mpctx->restart_playback = true; - mpctx->sync_audio_to_video = !sh_video->gsh->attached_picture; + mpctx->sync_audio_to_video = !sh->attached_picture; mpctx->delay = 0; mpctx->vo_pts_history_seek_ts++; @@ -185,10 +188,10 @@ void mp_force_video_refresh(struct MPContext *mpctx) static bool filter_output_queued_frame(struct MPContext *mpctx) { - struct sh_video *sh_video = mpctx->sh_video; + struct dec_video *d_video = mpctx->d_video; struct vo *video_out = mpctx->video_out; - struct mp_image *img = vf_chain_output_queued_frame(sh_video->vfilter); + struct mp_image *img = vf_chain_output_queued_frame(d_video->vfilter); if (img) vo_queue_image(video_out, img); talloc_free(img); @@ -208,16 +211,16 @@ static bool load_next_vo_frame(struct MPContext *mpctx, bool eof) static void init_filter_params(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; - struct sh_video *sh_video = mpctx->sh_video; + struct dec_video *d_video = mpctx->d_video; // Note that the video decoder already initializes the filter chain. This // might recreate the chain a second time, which is not very elegant, but // allows us to test whether enabling deinterlacing works with the current // video format and other filters. - if (sh_video->vf_initialized != 1) + if (d_video->vf_initialized != 1) return; - if (sh_video->vf_reconfig_count <= mpctx->last_vf_reconfig_count) { + if (d_video->vf_reconfig_count <= mpctx->last_vf_reconfig_count) { if (opts->deinterlace >= 0) { mp_property_do("deinterlace", M_PROPERTY_SET, &opts->deinterlace, mpctx); @@ -225,18 +228,18 @@ static void init_filter_params(struct MPContext *mpctx) } // Setting filter params has to be "stable" (no change if params already // set) - checking the reconfig count is just an optimization. - mpctx->last_vf_reconfig_count = sh_video->vf_reconfig_count; + mpctx->last_vf_reconfig_count = d_video->vf_reconfig_count; } static void filter_video(struct MPContext *mpctx, struct mp_image *frame) { - struct sh_video *sh_video = mpctx->sh_video; + struct dec_video *d_video = mpctx->d_video; init_filter_params(mpctx); - frame->pts = sh_video->pts; - mp_image_set_params(frame, sh_video->vf_input); - vf_filter_frame(sh_video->vfilter, frame); + frame->pts = d_video->pts; + mp_image_set_params(frame, d_video->vf_input); + vf_filter_frame(d_video->vfilter, frame); filter_output_queued_frame(mpctx); } @@ -249,8 +252,9 @@ static int check_framedrop(struct MPContext *mpctx, double frame_time) { float delay = opts->playback_speed * ao_get_delay(mpctx->ao); float d = delay - mpctx->delay; + float fps = mpctx->d_video->header->video->fps; if (frame_time < 0) - frame_time = mpctx->sh_video->fps > 0 ? 1.0 / mpctx->sh_video->fps : 0; + 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: if (d < -mpctx->dropped_frames * frame_time - 0.100 && !mpctx->paused @@ -266,24 +270,25 @@ static int check_framedrop(struct MPContext *mpctx, double frame_time) static struct demux_packet *video_read_frame(struct MPContext *mpctx) { - sh_video_t *sh_video = mpctx->sh_video; - demuxer_t *demuxer = sh_video->gsh->demuxer; - float pts1 = sh_video->last_pts; + struct dec_video *d_video = mpctx->d_video; + sh_video_t *sh_video = d_video->header->video; + demuxer_t *demuxer = d_video->header->demuxer; + float pts1 = d_video->last_pts; - struct demux_packet *pkt = demux_read_packet(sh_video->gsh); + struct demux_packet *pkt = demux_read_packet(d_video->header); if (!pkt) return NULL; // EOF if (pkt->pts != MP_NOPTS_VALUE) - sh_video->last_pts = pkt->pts; + d_video->last_pts = pkt->pts; float frame_time = sh_video->fps > 0 ? 1.0f / sh_video->fps : 0; // override frame_time for variable/unknown FPS formats: if (!mpctx->opts->force_fps) { - double next_pts = demux_get_next_pts(sh_video->gsh); - double d = next_pts == MP_NOPTS_VALUE ? sh_video->last_pts - pts1 - : next_pts - sh_video->last_pts; + double next_pts = demux_get_next_pts(d_video->header); + double d = next_pts == MP_NOPTS_VALUE ? d_video->last_pts - pts1 + : next_pts - d_video->last_pts; if (d >= 0) { if (demuxer->type == DEMUXER_TYPE_TV) { if (d > 0) @@ -296,20 +301,20 @@ static struct demux_packet *video_read_frame(struct MPContext *mpctx) } } - sh_video->pts = sh_video->last_pts; - sh_video->next_frame_time = frame_time; + d_video->pts = d_video->last_pts; + d_video->next_frame_time = frame_time; return pkt; } static double update_video_nocorrect_pts(struct MPContext *mpctx) { - struct sh_video *sh_video = mpctx->sh_video; + struct dec_video *d_video = mpctx->d_video; double frame_time = 0; while (1) { // In nocorrect-pts mode there is no way to properly time these frames if (load_next_vo_frame(mpctx, false)) break; - frame_time = sh_video->next_frame_time; + frame_time = d_video->next_frame_time; if (mpctx->restart_playback) frame_time = 0; struct demux_packet *pkt = video_read_frame(mpctx); @@ -321,8 +326,8 @@ static double update_video_nocorrect_pts(struct MPContext *mpctx) update_fps(mpctx); int framedrop_type = check_framedrop(mpctx, frame_time); - void *decoded_frame = decode_video(sh_video, pkt, framedrop_type, - sh_video->pts); + void *decoded_frame = video_decode(d_video, pkt, framedrop_type, + d_video->pts); talloc_free(pkt); if (decoded_frame) { filter_video(mpctx, decoded_frame); @@ -334,62 +339,61 @@ static double update_video_nocorrect_pts(struct MPContext *mpctx) static double update_video_attached_pic(struct MPContext *mpctx) { - struct sh_video *sh_video = mpctx->sh_video; + struct dec_video *d_video = mpctx->d_video; // Try to decode the picture multiple times, until it is displayed. if (mpctx->video_out->hasframe) return -1; struct mp_image *decoded_frame = - decode_video(sh_video, sh_video->gsh->attached_picture, 0, 0); + video_decode(d_video, d_video->header->attached_picture, 0, 0); if (decoded_frame) filter_video(mpctx, decoded_frame); load_next_vo_frame(mpctx, true); - mpctx->sh_video->pts = MP_NOPTS_VALUE; + d_video->pts = MP_NOPTS_VALUE; return 0; } static void determine_frame_pts(struct MPContext *mpctx) { - struct sh_video *sh_video = mpctx->sh_video; + struct dec_video *d_video = mpctx->d_video; struct MPOpts *opts = mpctx->opts; if (opts->user_pts_assoc_mode) - sh_video->pts_assoc_mode = opts->user_pts_assoc_mode; - else if (sh_video->pts_assoc_mode == 0) { - if (mpctx->sh_video->gsh->demuxer->timestamp_type == TIMESTAMP_TYPE_PTS - && sh_video->codec_reordered_pts != MP_NOPTS_VALUE) - sh_video->pts_assoc_mode = 1; + d_video->pts_assoc_mode = opts->user_pts_assoc_mode; + else if (d_video->pts_assoc_mode == 0) { + if (d_video->header->demuxer->timestamp_type == TIMESTAMP_TYPE_PTS + && d_video->codec_reordered_pts != MP_NOPTS_VALUE) + d_video->pts_assoc_mode = 1; else - sh_video->pts_assoc_mode = 2; + d_video->pts_assoc_mode = 2; } else { - int probcount1 = sh_video->num_reordered_pts_problems; - int probcount2 = sh_video->num_sorted_pts_problems; - if (sh_video->pts_assoc_mode == 2) { + int probcount1 = d_video->num_reordered_pts_problems; + int probcount2 = d_video->num_sorted_pts_problems; + if (d_video->pts_assoc_mode == 2) { int tmp = probcount1; probcount1 = probcount2; probcount2 = tmp; } if (probcount1 >= probcount2 * 1.5 + 2) { - sh_video->pts_assoc_mode = 3 - sh_video->pts_assoc_mode; + d_video->pts_assoc_mode = 3 - d_video->pts_assoc_mode; MP_VERBOSE(mpctx, "Switching to pts association mode " - "%d.\n", sh_video->pts_assoc_mode); + "%d.\n", d_video->pts_assoc_mode); } } - sh_video->pts = sh_video->pts_assoc_mode == 1 ? - sh_video->codec_reordered_pts : sh_video->sorted_pts; + d_video->pts = d_video->pts_assoc_mode == 1 ? + d_video->codec_reordered_pts : d_video->sorted_pts; } double update_video(struct MPContext *mpctx, double endpts) { - struct sh_video *sh_video = mpctx->sh_video; + struct dec_video *d_video = mpctx->d_video; struct vo *video_out = mpctx->video_out; - sh_video->vfilter->control(sh_video->vfilter, VFCTRL_SET_OSD_OBJ, - mpctx->osd); // for vf_sub + vf_control(d_video->vfilter, VFCTRL_SET_OSD_OBJ, mpctx->osd); // for vf_sub if (!mpctx->opts->correct_pts) return update_video_nocorrect_pts(mpctx); - if (sh_video->gsh->attached_picture) + if (d_video->header->attached_picture) return update_video_attached_pic(mpctx); double pts; @@ -400,7 +404,7 @@ double update_video(struct MPContext *mpctx, double endpts) pts = MP_NOPTS_VALUE; struct demux_packet *pkt = NULL; while (1) { - pkt = demux_read_packet(mpctx->sh_video->gsh); + pkt = demux_read_packet(d_video->header); if (!pkt || pkt->len) break; /* Packets with size 0 are assumed to not correspond to frames, @@ -417,7 +421,7 @@ double update_video(struct MPContext *mpctx, double endpts) int framedrop_type = mpctx->hrseek_active && mpctx->hrseek_framedrop ? 1 : check_framedrop(mpctx, -1); struct mp_image *decoded_frame = - decode_video(sh_video, pkt, framedrop_type, pts); + video_decode(d_video, pkt, framedrop_type, pts); talloc_free(pkt); if (decoded_frame) { determine_frame_pts(mpctx); @@ -436,9 +440,9 @@ double update_video(struct MPContext *mpctx, double endpts) if (pts == MP_NOPTS_VALUE) { MP_ERR(mpctx, "Video pts after filters MISSING\n"); // Try to use decoder pts from before filters - pts = sh_video->pts; + pts = d_video->pts; if (pts == MP_NOPTS_VALUE) - pts = sh_video->last_pts; + pts = d_video->last_pts; } if (endpts == MP_NOPTS_VALUE || pts < endpts) add_frame_pts(mpctx, pts); @@ -447,29 +451,29 @@ double update_video(struct MPContext *mpctx, double endpts) return 0; } mpctx->hrseek_active = false; - sh_video->pts = pts; - if (sh_video->last_pts == MP_NOPTS_VALUE) - sh_video->last_pts = sh_video->pts; - else if (sh_video->last_pts > sh_video->pts) { + d_video->pts = pts; + if (d_video->last_pts == MP_NOPTS_VALUE) { + d_video->last_pts = d_video->pts; + } else if (d_video->last_pts > d_video->pts) { MP_WARN(mpctx, "Decreasing video pts: %f < %f\n", - sh_video->pts, sh_video->last_pts); + d_video->pts, d_video->last_pts); /* If the difference in pts is small treat it as jitter around the * right value (possibly caused by incorrect timestamp ordering) and * just show this frame immediately after the last one. * Treat bigger differences as timestamp resets and start counting * timing of later frames from the position of this one. */ - if (sh_video->last_pts - sh_video->pts > 0.5) - sh_video->last_pts = sh_video->pts; + if (d_video->last_pts - d_video->pts > 0.5) + d_video->last_pts = d_video->pts; else - sh_video->pts = sh_video->last_pts; - } else if (sh_video->pts >= sh_video->last_pts + 60) { + d_video->pts = d_video->last_pts; + } else if (d_video->pts >= d_video->last_pts + 60) { // Assume a PTS difference >= 60 seconds is a discontinuity. MP_WARN(mpctx, "Jump in video pts: %f -> %f\n", - sh_video->last_pts, sh_video->pts); - sh_video->last_pts = sh_video->pts; + d_video->last_pts, d_video->pts); + d_video->last_pts = d_video->pts; } - double frame_time = sh_video->pts - sh_video->last_pts; - sh_video->last_pts = sh_video->pts; + double frame_time = d_video->pts - d_video->last_pts; + d_video->last_pts = d_video->pts; if (mpctx->d_audio) mpctx->delay -= frame_time; return frame_time; diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c index e6f56a3d57..cdfbd816a9 100644 --- a/video/decode/dec_video.c +++ b/video/decode/dec_video.c @@ -56,17 +56,17 @@ const vd_functions_t * const mpcodecs_vd_drivers[] = { NULL }; -int vd_control(struct sh_video *sh_video, int cmd, void *arg) +int video_vd_control(struct dec_video *d_video, int cmd, void *arg) { - const struct vd_functions *vd = sh_video->vd_driver; + const struct vd_functions *vd = d_video->vd_driver; if (vd) - return vd->control(sh_video, cmd, arg); + return vd->control(d_video, cmd, arg); return CONTROL_UNKNOWN; } -int set_video_colors(sh_video_t *sh_video, const char *item, int value) +int video_set_colors(struct dec_video *d_video, const char *item, int value) { - vf_instance_t *vf = sh_video->vfilter; + vf_instance_t *vf = d_video->vfilter; vf_equalizer_t data; data.item = item; @@ -83,9 +83,9 @@ int set_video_colors(sh_video_t *sh_video, const char *item, int value) return 0; } -int get_video_colors(sh_video_t *sh_video, const char *item, int *value) +int video_get_colors(struct dec_video *d_video, const char *item, int *value) { - vf_instance_t *vf = sh_video->vfilter; + vf_instance_t *vf = d_video->vfilter; vf_equalizer_t data; data.item = item; @@ -101,55 +101,48 @@ int get_video_colors(sh_video_t *sh_video, const char *item, int *value) return 0; } -void resync_video_stream(sh_video_t *sh_video) +void video_resync_stream(struct dec_video *d_video) { - vd_control(sh_video, VDCTRL_RESYNC_STREAM, NULL); - sh_video->prev_codec_reordered_pts = MP_NOPTS_VALUE; - sh_video->prev_sorted_pts = MP_NOPTS_VALUE; + video_vd_control(d_video, VDCTRL_RESYNC_STREAM, NULL); + d_video->prev_codec_reordered_pts = MP_NOPTS_VALUE; + d_video->prev_sorted_pts = MP_NOPTS_VALUE; } -void video_reinit_vo(struct sh_video *sh_video) +void video_reinit_vo(struct dec_video *d_video) { - vd_control(sh_video, VDCTRL_REINIT_VO, NULL); + video_vd_control(d_video, VDCTRL_REINIT_VO, NULL); } -int get_current_video_decoder_lag(sh_video_t *sh_video) +void video_uninit(struct dec_video *d_video) { - int ret = -1; - vd_control(sh_video, VDCTRL_QUERY_UNSEEN_FRAMES, &ret); - return ret; + if (d_video->initialized) { + mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Uninit video.\n"); + d_video->vd_driver->uninit(d_video); + } + talloc_free(d_video->priv); + d_video->priv = NULL; + vf_uninit_filter_chain(d_video->vfilter); + d_video->vfilter = NULL; + talloc_free(d_video); } -void uninit_video(sh_video_t *sh_video) +static int init_video_codec(struct dec_video *d_video, const char *decoder) { - if (!sh_video->initialized) - return; - mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Uninit video.\n"); - sh_video->vd_driver->uninit(sh_video); - vf_uninit_filter_chain(sh_video->vfilter); - sh_video->vfilter = NULL; - talloc_free(sh_video->gsh->decoder_desc); - sh_video->gsh->decoder_desc = NULL; - sh_video->initialized = 0; -} + assert(!d_video->initialized); -static int init_video_codec(sh_video_t *sh_video, const char *decoder) -{ - assert(!sh_video->initialized); - - if (!sh_video->vd_driver->init(sh_video, decoder)) { + if (!d_video->vd_driver->init(d_video, decoder)) { mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Video decoder init failed.\n"); - //uninit_video(sh_video); + //uninit_video(d_video); return 0; } - sh_video->initialized = 1; - sh_video->prev_codec_reordered_pts = MP_NOPTS_VALUE; - sh_video->prev_sorted_pts = MP_NOPTS_VALUE; + d_video->initialized = 1; + d_video->prev_codec_reordered_pts = MP_NOPTS_VALUE; + d_video->prev_sorted_pts = MP_NOPTS_VALUE; return 1; } -struct mp_decoder_list *mp_video_decoder_list(void) +struct mp_decoder_list *video_decoder_list(void) { struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list); for (int i = 0; mpcodecs_vd_drivers[i] != NULL; i++) @@ -160,7 +153,7 @@ struct mp_decoder_list *mp_video_decoder_list(void) static struct mp_decoder_list *mp_select_video_decoders(const char *codec, char *selection) { - struct mp_decoder_list *list = mp_video_decoder_list(); + struct mp_decoder_list *list = video_decoder_list(); struct mp_decoder_list *new = mp_select_decoders(list, codec, selection); talloc_free(list); return new; @@ -175,13 +168,13 @@ static const struct vd_functions *find_driver(const char *name) return NULL; } -int init_best_video_codec(sh_video_t *sh_video, char* video_decoders) +int video_init_best_codec(struct dec_video *d_video, char* video_decoders) { - assert(!sh_video->initialized); + assert(!d_video->initialized); struct mp_decoder_entry *decoder = NULL; struct mp_decoder_list *list = - mp_select_video_decoders(sh_video->gsh->codec, video_decoders); + mp_select_video_decoders(d_video->header->codec, video_decoders); mp_print_decoders(MSGT_DECVIDEO, MSGL_V, "Codec list:", list); @@ -192,42 +185,43 @@ int init_best_video_codec(sh_video_t *sh_video, char* video_decoders) continue; mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Opening video decoder %s:%s\n", sel->family, sel->decoder); - sh_video->vd_driver = driver; - if (init_video_codec(sh_video, sel->decoder)) { + d_video->vd_driver = driver; + if (init_video_codec(d_video, sel->decoder)) { decoder = sel; break; } - sh_video->vd_driver = NULL; + d_video->vd_driver = NULL; mp_tmsg(MSGT_DECVIDEO, MSGL_WARN, "Video decoder init failed for " "%s:%s\n", sel->family, sel->decoder); } - if (sh_video->initialized) { - sh_video->gsh->decoder_desc = - talloc_asprintf(NULL, "%s [%s:%s]", decoder->desc, decoder->family, + if (d_video->initialized) { + d_video->decoder_desc = + talloc_asprintf(d_video, "%s [%s:%s]", decoder->desc, decoder->family, decoder->decoder); mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Selected video codec: %s\n", - sh_video->gsh->decoder_desc); + d_video->decoder_desc); } else { mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Failed to initialize a video decoder for codec '%s'.\n", - sh_video->gsh->codec ? sh_video->gsh->codec : "<unknown>"); + d_video->header->codec ? d_video->header->codec : "<unknown>"); } talloc_free(list); - return sh_video->initialized; + return d_video->initialized; } -void *decode_video(sh_video_t *sh_video, struct demux_packet *packet, +void *video_decode(struct dec_video *d_video, struct demux_packet *packet, int drop_frame, double pts) { mp_image_t *mpi = NULL; - struct MPOpts *opts = sh_video->opts; + struct MPOpts *opts = d_video->opts; if (opts->correct_pts && pts != MP_NOPTS_VALUE) { - int delay = get_current_video_decoder_lag(sh_video); + int delay = -1; + video_vd_control(d_video, VDCTRL_QUERY_UNSEEN_FRAMES, &delay); if (delay >= 0) { - if (delay > sh_video->num_buffered_pts) + if (delay > d_video->num_buffered_pts) #if 0 // this is disabled because vd_ffmpeg reports the same lag // after seek even when there are no buffered frames, @@ -237,24 +231,24 @@ void *decode_video(sh_video_t *sh_video, struct demux_packet *packet, ; #endif else - sh_video->num_buffered_pts = delay; + d_video->num_buffered_pts = delay; } - if (sh_video->num_buffered_pts == - sizeof(sh_video->buffered_pts) / sizeof(double)) + if (d_video->num_buffered_pts == + sizeof(d_video->buffered_pts) / sizeof(double)) mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Too many buffered pts\n"); else { int i, j; - for (i = 0; i < sh_video->num_buffered_pts; i++) - if (sh_video->buffered_pts[i] < pts) + for (i = 0; i < d_video->num_buffered_pts; i++) + if (d_video->buffered_pts[i] < pts) break; - for (j = sh_video->num_buffered_pts; j > i; j--) - sh_video->buffered_pts[j] = sh_video->buffered_pts[j - 1]; - sh_video->buffered_pts[i] = pts; - sh_video->num_buffered_pts++; + for (j = d_video->num_buffered_pts; j > i; j--) + d_video->buffered_pts[j] = d_video->buffered_pts[j - 1]; + d_video->buffered_pts[i] = pts; + d_video->num_buffered_pts++; } } - mpi = sh_video->vd_driver->decode(sh_video, packet, drop_frame, &pts); + mpi = d_video->vd_driver->decode(d_video, packet, drop_frame, &pts); //------------------------ frame decoded. -------------------- @@ -268,39 +262,41 @@ void *decode_video(sh_video_t *sh_video, struct demux_packet *packet, else if (opts->field_dominance == 1) mpi->fields &= ~MP_IMGFIELD_TOP_FIRST; - double prevpts = sh_video->codec_reordered_pts; - sh_video->prev_codec_reordered_pts = prevpts; - sh_video->codec_reordered_pts = pts; + double prevpts = d_video->codec_reordered_pts; + d_video->prev_codec_reordered_pts = prevpts; + d_video->codec_reordered_pts = pts; if (prevpts != MP_NOPTS_VALUE && pts <= prevpts || pts == MP_NOPTS_VALUE) - sh_video->num_reordered_pts_problems++; - prevpts = sh_video->sorted_pts; + d_video->num_reordered_pts_problems++; + prevpts = d_video->sorted_pts; if (opts->correct_pts) { - if (sh_video->num_buffered_pts) { - sh_video->num_buffered_pts--; - sh_video->sorted_pts = - sh_video->buffered_pts[sh_video->num_buffered_pts]; + if (d_video->num_buffered_pts) { + d_video->num_buffered_pts--; + d_video->sorted_pts = + d_video->buffered_pts[d_video->num_buffered_pts]; } else { mp_msg(MSGT_CPLAYER, MSGL_ERR, "No pts value from demuxer to use for frame!\n"); - sh_video->sorted_pts = MP_NOPTS_VALUE; + d_video->sorted_pts = MP_NOPTS_VALUE; } } - pts = sh_video->sorted_pts; + pts = d_video->sorted_pts; if (prevpts != MP_NOPTS_VALUE && pts <= prevpts || pts == MP_NOPTS_VALUE) - sh_video->num_sorted_pts_problems++; + d_video->num_sorted_pts_problems++; return mpi; } -int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params) +int mpcodecs_reconfig_vo(struct dec_video *d_video, + const struct mp_image_params *params) { - struct MPOpts *opts = sh->opts; - vf_instance_t *vf = sh->vfilter; + struct MPOpts *opts = d_video->opts; + vf_instance_t *vf = d_video->vfilter; int vocfg_flags = 0; struct mp_image_params p = *params; + struct sh_video *sh = d_video->header->video; - sh->vf_reconfig_count++; + d_video->vf_reconfig_count++; mp_msg(MSGT_DECVIDEO, MSGL_V, "VIDEO: %dx%d %5.3f fps %5.1f kbps (%4.1f kB/s)\n", @@ -336,24 +332,24 @@ int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params) "e.g. -vf filter,scale instead of -vf filter.\n"); mp_tmsg(MSGT_VFILTER, MSGL_WARN, "Attempted filter chain:\n"); vf_print_filter_chain(MSGL_WARN, vf); - sh->vf_initialized = -1; + d_video->vf_initialized = -1; return -1; // failed } - sh->vfilter = vf; + d_video->vfilter = vf; // autodetect flipping bool flip = opts->flip; if (flip && !(flags & VFCAP_FLIP)) { // we need to flip, but no flipping filter avail. vf_add_before_vo(&vf, "flip", NULL); - sh->vfilter = vf; + d_video->vfilter = vf; flip = false; } // time to do aspect ratio corrections... float force_aspect = opts->movie_aspect; - if (force_aspect > -1.0 && sh->stream_aspect != 0.0) - force_aspect = sh->stream_aspect; + if (force_aspect > -1.0 && d_video->stream_aspect != 0.0) + force_aspect = d_video->stream_aspect; if (force_aspect >= 0) vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, force_aspect); @@ -386,29 +382,29 @@ int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params) if (vf_reconfig_wrapper(vf, &p, vocfg_flags) < 0) { mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "FATAL: Cannot initialize video driver.\n"); - sh->vf_initialized = -1; + d_video->vf_initialized = -1; return -1; } mp_tmsg(MSGT_VFILTER, MSGL_V, "Video filter chain:\n"); vf_print_filter_chain(MSGL_V, vf); - sh->vf_initialized = 1; + d_video->vf_initialized = 1; - if (!sh->vf_input) - sh->vf_input = talloc(sh, struct mp_image_params); - *sh->vf_input = p; + if (!d_video->vf_input) + d_video->vf_input = talloc(sh, struct mp_image_params); + *d_video->vf_input = p; if (opts->gamma_gamma != 1000) - set_video_colors(sh, "gamma", opts->gamma_gamma); + video_set_colors(d_video, "gamma", opts->gamma_gamma); if (opts->gamma_brightness != 1000) - set_video_colors(sh, "brightness", opts->gamma_brightness); + video_set_colors(d_video, "brightness", opts->gamma_brightness); if (opts->gamma_contrast != 1000) - set_video_colors(sh, "contrast", opts->gamma_contrast); + video_set_colors(d_video, "contrast", opts->gamma_contrast); if (opts->gamma_saturation != 1000) - set_video_colors(sh, "saturation", opts->gamma_saturation); + video_set_colors(d_video, "saturation", opts->gamma_saturation); if (opts->gamma_hue != 1000) - set_video_colors(sh, "hue", opts->gamma_hue); + video_set_colors(d_video, "hue", opts->gamma_hue); return 0; } diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h index 3f163bb1f7..b706910e5b 100644 --- a/video/decode/dec_video.h +++ b/video/decode/dec_video.h @@ -20,24 +20,57 @@ #define MPLAYER_DEC_VIDEO_H #include "demux/stheader.h" +#include "video/hwdec.h" +#include "video/mp_image.h" struct osd_state; struct mp_decoder_list; -struct mp_decoder_list *mp_video_decoder_list(void); +struct dec_video { + struct MPOpts *opts; + struct vf_instance *vfilter; // video filter chain + const struct vd_functions *vd_driver; + int vf_initialized; // -1 failed, 0 not done, 1 done + long vf_reconfig_count; // incremented each mpcodecs_reconfig_vo() call + struct mp_image_params *vf_input; // video filter input params + struct mp_hwdec_info *hwdec_info; // video output hwdec handles + int initialized; + struct sh_stream *header; -int init_best_video_codec(sh_video_t *sh_video, char* video_decoders); -void uninit_video(sh_video_t *sh_video); + char *decoder_desc; + + void *priv; + + float next_frame_time; + double last_pts; + double buffered_pts[32]; + int num_buffered_pts; + double codec_reordered_pts; + double prev_codec_reordered_pts; + int num_reordered_pts_problems; + double sorted_pts; + double prev_sorted_pts; + int num_sorted_pts_problems; + int pts_assoc_mode; + double pts; + + float stream_aspect; // aspect ratio in media headers (DVD IFO files) + int i_bps; // == bitrate (compressed bytes/sec) +}; + +struct mp_decoder_list *video_decoder_list(void); + +int video_init_best_codec(struct dec_video *d_video, char* video_decoders); +void video_uninit(struct dec_video *d_video); struct demux_packet; -void *decode_video(sh_video_t *sh_video, struct demux_packet *packet, +void *video_decode(struct dec_video *d_video, struct demux_packet *packet, int drop_frame, double pts); -int get_video_colors(sh_video_t *sh_video, const char *item, int *value); -int set_video_colors(sh_video_t *sh_video, const char *item, int value); -void resync_video_stream(sh_video_t *sh_video); -void video_reinit_vo(struct sh_video *sh_video); -int get_current_video_decoder_lag(sh_video_t *sh_video); -int vd_control(struct sh_video *sh_video, int cmd, void *arg); +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); +void video_resync_stream(struct dec_video *d_video); +void video_reinit_vo(struct dec_video *d_video); +int video_vd_control(struct dec_video *d_video, int cmd, void *arg); #endif /* MPLAYER_DEC_VIDEO_H */ diff --git a/video/decode/lavc_dr1.c b/video/decode/lavc_dr1.c index 15fc44a445..a8de29eb1a 100644 --- a/video/decode/lavc_dr1.c +++ b/video/decode/lavc_dr1.c @@ -136,8 +136,8 @@ static int alloc_buffer(FramePool *pool, AVCodecContext *s) int mp_codec_get_buffer(AVCodecContext *s, AVFrame *frame) { - sh_video_t *sh = s->opaque; - struct lavc_ctx *ctx = sh->context; + struct dec_video *vd = s->opaque; + struct lavc_ctx *ctx = vd->priv; if (!ctx->dr1_buffer_pool) { ctx->dr1_buffer_pool = av_mallocz(sizeof(*ctx->dr1_buffer_pool)); diff --git a/video/decode/vd.h b/video/decode/vd.h index 488f9fa061..dd2536ab2a 100644 --- a/video/decode/vd.h +++ b/video/decode/vd.h @@ -21,6 +21,7 @@ #include "video/mp_image.h" #include "demux/stheader.h" +#include "dec_video.h" struct demux_packet; struct mp_decoder_list; @@ -30,10 +31,10 @@ typedef struct vd_functions { const char *name; void (*add_decoders)(struct mp_decoder_list *list); - int (*init)(sh_video_t *sh, const char *decoder); - void (*uninit)(sh_video_t *sh); - int (*control)(sh_video_t *sh, int cmd, void *arg); - struct mp_image *(*decode)(struct sh_video *sh, struct demux_packet *pkt, + int (*init)(struct dec_video *vd, const char *decoder); + 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); } vd_functions_t; @@ -47,6 +48,6 @@ enum vd_ctrl { VDCTRL_REINIT_VO, // reinit filter/VO chain }; -int mpcodecs_reconfig_vo(sh_video_t *sh, const struct mp_image_params *params); +int mpcodecs_reconfig_vo(struct dec_video *vd, const struct mp_image_params *params); #endif /* MPLAYER_VD_H */ diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index e6ed8e5602..f7768f130f 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -60,15 +60,15 @@ #include "mpvcore/m_option.h" -static void init_avctx(sh_video_t *sh, const char *decoder, +static void init_avctx(struct dec_video *vd, const char *decoder, struct vd_lavc_hwdec *hwdec); -static void uninit_avctx(sh_video_t *sh); +static void uninit_avctx(struct dec_video *vd); static void setup_refcounting_hw(struct AVCodecContext *s); static enum PixelFormat get_format_hwdec(struct AVCodecContext *avctx, const enum PixelFormat *pix_fmt); -static void uninit(struct sh_video *sh); +static void uninit(struct dec_video *vd); #define OPT_BASE_STRUCT struct MPOpts @@ -116,9 +116,9 @@ static struct vd_lavc_hwdec *find_hwcodec(enum hwdec_type api) return NULL; } -static bool hwdec_codec_allowed(sh_video_t *sh, const char *codec) +static bool hwdec_codec_allowed(struct dec_video *vd, const char *codec) { - bstr s = bstr0(sh->opts->hwdec_codecs); + bstr s = bstr0(vd->opts->hwdec_codecs); while (s.len) { bstr item; bstr_split_tok(s, ",", &item, &s); @@ -213,7 +213,7 @@ static int hwdec_probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info, return r; } -static bool probe_hwdec(sh_video_t *sh, bool autoprobe, enum hwdec_type api, +static bool probe_hwdec(struct dec_video *vd, bool autoprobe, enum hwdec_type api, const char *decoder, struct vd_lavc_hwdec **use_hwdec, const char **use_decoder) { @@ -224,7 +224,7 @@ static bool probe_hwdec(sh_video_t *sh, bool autoprobe, enum hwdec_type api, return false; } const char *hw_decoder = NULL; - int r = hwdec_probe(hwdec, sh->hwdec_info, decoder, &hw_decoder); + int r = hwdec_probe(hwdec, vd->hwdec_info, decoder, &hw_decoder); if (r >= 0) { *use_hwdec = hwdec; *use_decoder = hw_decoder; @@ -240,11 +240,11 @@ static bool probe_hwdec(sh_video_t *sh, bool autoprobe, enum hwdec_type api, } -static int init(sh_video_t *sh, const char *decoder) +static int init(struct dec_video *vd, const char *decoder) { vd_ffmpeg_ctx *ctx; - ctx = sh->context = talloc_zero(NULL, vd_ffmpeg_ctx); - ctx->opts = sh->opts; + ctx = vd->priv = talloc_zero(NULL, vd_ffmpeg_ctx); + ctx->opts = vd->opts; ctx->non_dr1_pool = talloc_steal(ctx, mp_image_pool_new(16)); if (bstr_endswith0(bstr0(decoder), "_vdpau")) { @@ -254,22 +254,22 @@ static int init(sh_video_t *sh, const char *decoder) "option can be used to restrict which codecs are\nenabled, " "otherwise all hardware decoding is tried for all codecs.\n", decoder); - uninit(sh); + uninit(vd); return 0; } struct vd_lavc_hwdec *hwdec = NULL; const char *hw_decoder = NULL; - if (hwdec_codec_allowed(sh, decoder)) { - if (sh->opts->hwdec_api == HWDEC_AUTO) { + if (hwdec_codec_allowed(vd, decoder)) { + if (vd->opts->hwdec_api == HWDEC_AUTO) { for (int n = 0; hwdec_list[n]; n++) { - if (probe_hwdec(sh, true, hwdec_list[n]->type, decoder, + if (probe_hwdec(vd, true, hwdec_list[n]->type, decoder, &hwdec, &hw_decoder)) break; } - } else if (sh->opts->hwdec_api != HWDEC_NONE) { - probe_hwdec(sh, false, sh->opts->hwdec_api, decoder, + } else if (vd->opts->hwdec_api != HWDEC_NONE) { + probe_hwdec(vd, false, vd->opts->hwdec_api, decoder, &hwdec, &hw_decoder); } } else { @@ -282,21 +282,21 @@ static int init(sh_video_t *sh, const char *decoder) if (hw_decoder) decoder = hw_decoder; mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Trying to use hardware decoding.\n"); - } else if (sh->opts->hwdec_api != HWDEC_NONE) { + } else if (vd->opts->hwdec_api != HWDEC_NONE) { mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Using software decoding.\n"); } - init_avctx(sh, decoder, hwdec); + init_avctx(vd, decoder, hwdec); if (!ctx->avctx) { if (ctx->software_fallback_decoder) { mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Error initializing hardware " "decoding, falling back to software decoding.\n"); decoder = ctx->software_fallback_decoder; ctx->software_fallback_decoder = NULL; - init_avctx(sh, decoder, NULL); + init_avctx(vd, decoder, NULL); } if (!ctx->avctx) { - uninit(sh); + uninit(vd); return 0; } } @@ -361,12 +361,13 @@ static void set_from_bih(AVCodecContext *avctx, uint32_t format, avctx->coded_height = bih->biHeight; } -static void init_avctx(sh_video_t *sh, const char *decoder, +static void init_avctx(struct dec_video *vd, const char *decoder, struct vd_lavc_hwdec *hwdec) { - vd_ffmpeg_ctx *ctx = sh->context; - struct lavc_param *lavc_param = &sh->opts->lavc_param; + vd_ffmpeg_ctx *ctx = vd->priv; + struct lavc_param *lavc_param = &vd->opts->lavc_param; bool mp_rawvideo = false; + struct sh_stream *sh = vd->header; assert(!ctx->avctx); @@ -379,7 +380,7 @@ static void init_avctx(sh_video_t *sh, const char *decoder, if (!lavc_codec) return; - ctx->hwdec_info = sh->hwdec_info; + ctx->hwdec_info = vd->hwdec_info; ctx->do_dr1 = ctx->do_hw_dr1 = 0; ctx->pix_fmt = PIX_FMT_NONE; @@ -388,7 +389,7 @@ static void init_avctx(sh_video_t *sh, const char *decoder, ctx->hwdec = hwdec; ctx->avctx = avcodec_alloc_context3(lavc_codec); AVCodecContext *avctx = ctx->avctx; - avctx->opaque = sh; + avctx->opaque = vd; avctx->codec_type = AVMEDIA_TYPE_VIDEO; avctx->codec_id = lavc_codec->id; @@ -409,7 +410,7 @@ static void init_avctx(sh_video_t *sh, const char *decoder, avctx->get_format = get_format_hwdec; setup_refcounting_hw(avctx); if (ctx->hwdec->init && ctx->hwdec->init(ctx) < 0) { - uninit_avctx(sh); + uninit_avctx(vd); return; } } else { @@ -445,7 +446,7 @@ static void init_avctx(sh_video_t *sh, const char *decoder, mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavc_param->avopt); - uninit_avctx(sh); + uninit_avctx(vd); return; } } @@ -453,33 +454,33 @@ static void init_avctx(sh_video_t *sh, const char *decoder, // Do this after the above avopt handling in case it changes values ctx->skip_frame = avctx->skip_frame; - avctx->codec_tag = sh->format; - avctx->coded_width = sh->disp_w; - avctx->coded_height = sh->disp_h; + avctx->codec_tag = sh->video->format; + avctx->coded_width = sh->video->disp_w; + avctx->coded_height = sh->video->disp_h; // demux_mkv - if (sh->bih) - set_from_bih(avctx, sh->format, sh->bih); + if (sh->video->bih) + set_from_bih(avctx, sh->video->format, sh->video->bih); - if (mp_rawvideo && sh->format >= IMGFMT_START && sh->format < IMGFMT_END) { - avctx->pix_fmt = imgfmt2pixfmt(sh->format); + if (mp_rawvideo) { + avctx->pix_fmt = imgfmt2pixfmt(sh->video->format); avctx->codec_tag = 0; } - if (sh->gsh->lav_headers) - mp_copy_lav_codec_headers(avctx, sh->gsh->lav_headers); + if (sh->lav_headers) + mp_copy_lav_codec_headers(avctx, sh->lav_headers); /* open it */ if (avcodec_open2(avctx, lavc_codec, NULL) < 0) { mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Could not open codec.\n"); - uninit_avctx(sh); + uninit_avctx(vd); return; } } -static void uninit_avctx(sh_video_t *sh) +static void uninit_avctx(struct dec_video *vd) { - vd_ffmpeg_ctx *ctx = sh->context; + vd_ffmpeg_ctx *ctx = vd->priv; AVCodecContext *avctx = ctx->avctx; if (avctx) { @@ -504,21 +505,19 @@ static void uninit_avctx(sh_video_t *sh) ctx->last_sample_aspect_ratio = (AVRational){0, 0}; } -static void uninit(sh_video_t *sh) +static void uninit(struct dec_video *vd) { - vd_ffmpeg_ctx *ctx = sh->context; - - uninit_avctx(sh); - talloc_free(ctx); + uninit_avctx(vd); } -static void update_image_params(sh_video_t *sh, AVFrame *frame) +static void update_image_params(struct dec_video *vd, AVFrame *frame) { - vd_ffmpeg_ctx *ctx = sh->context; + vd_ffmpeg_ctx *ctx = vd->priv; int width = frame->width; int height = frame->height; float aspect = av_q2d(frame->sample_aspect_ratio) * width / height; int pix_fmt = frame->format; + struct sh_video *sh = vd->header->video; #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 40, 0) pix_fmt = ctx->avctx->pix_fmt; @@ -566,8 +565,8 @@ static void update_image_params(sh_video_t *sh, AVFrame *frame) static enum PixelFormat get_format_hwdec(struct AVCodecContext *avctx, const enum PixelFormat *fmt) { - sh_video_t *sh = avctx->opaque; - vd_ffmpeg_ctx *ctx = sh->context; + struct dec_video *vd = avctx->opaque; + vd_ffmpeg_ctx *ctx = vd->priv; mp_msg(MSGT_DECVIDEO, MSGL_V, "Pixel formats supported by decoder:"); for (int i = 0; fmt[i] != PIX_FMT_NONE; i++) @@ -587,9 +586,9 @@ static enum PixelFormat get_format_hwdec(struct AVCodecContext *avctx, return PIX_FMT_NONE; } -static struct mp_image *get_surface_hwdec(struct sh_video *sh, AVFrame *pic) +static struct mp_image *get_surface_hwdec(struct dec_video *vd, AVFrame *pic) { - vd_ffmpeg_ctx *ctx = sh->context; + vd_ffmpeg_ctx *ctx = vd->priv; /* Decoders using ffmpeg's hwaccel architecture (everything except vdpau) * can fall back to software decoding automatically. However, we don't @@ -633,9 +632,9 @@ static void free_mpi(void *opaque, uint8_t *data) static int get_buffer2_hwdec(AVCodecContext *avctx, AVFrame *pic, int flags) { - sh_video_t *sh = avctx->opaque; + struct dec_video *vd = avctx->opaque; - struct mp_image *mpi = get_surface_hwdec(sh, pic); + struct mp_image *mpi = get_surface_hwdec(vd, pic); if (!mpi) return -1; @@ -653,9 +652,9 @@ static void setup_refcounting_hw(AVCodecContext *avctx) static int get_buffer_hwdec(AVCodecContext *avctx, AVFrame *pic) { - sh_video_t *sh = avctx->opaque; + struct dec_video *vd = avctx->opaque; - struct mp_image *mpi = get_surface_hwdec(sh, pic); + struct mp_image *mpi = get_surface_hwdec(vd, pic); if (!mpi) return -1; @@ -694,9 +693,9 @@ static void setup_refcounting_hw(AVCodecContext *avctx) #if HAVE_AVUTIL_REFCOUNTING -static struct mp_image *image_from_decoder(struct sh_video *sh) +static struct mp_image *image_from_decoder(struct dec_video *vd) { - vd_ffmpeg_ctx *ctx = sh->context; + vd_ffmpeg_ctx *ctx = vd->priv; AVFrame *pic = ctx->pic; struct mp_image *img = mp_image_from_av_frame(pic); @@ -722,9 +721,9 @@ static bool fb_is_unique(void *b) return mp_buffer_is_unique(b); } -static struct mp_image *image_from_decoder(struct sh_video *sh) +static struct mp_image *image_from_decoder(struct dec_video *vd) { - vd_ffmpeg_ctx *ctx = sh->context; + vd_ffmpeg_ctx *ctx = vd->priv; AVFrame *pic = ctx->pic; struct mp_image new = {0}; @@ -749,12 +748,12 @@ static struct mp_image *image_from_decoder(struct sh_video *sh) #endif /* HAVE_AVUTIL_REFCOUNTING */ -static int decode(struct sh_video *sh, struct demux_packet *packet, +static int decode(struct dec_video *vd, struct demux_packet *packet, int flags, double *reordered_pts, struct mp_image **out_image) { int got_picture = 0; int ret; - vd_ffmpeg_ctx *ctx = sh->context; + vd_ffmpeg_ctx *ctx = vd->priv; AVFrame *pic = ctx->pic; AVCodecContext *avctx = ctx->avctx; AVPacket pkt; @@ -781,9 +780,9 @@ static int decode(struct sh_video *sh, struct demux_packet *packet, if (!got_picture) return 0; // skipped image - update_image_params(sh, pic); + update_image_params(vd, pic); - struct mp_image *mpi = image_from_decoder(sh); + struct mp_image *mpi = image_from_decoder(vd); assert(mpi->planes[0]); mp_image_set_params(mpi, &ctx->image_params); @@ -794,7 +793,7 @@ static int decode(struct sh_video *sh, struct demux_packet *packet, mp_image_params_from_image(&vo_params, mpi); if (!mp_image_params_equals(&vo_params, &ctx->vo_image_params)) { - if (mpcodecs_reconfig_vo(sh, &vo_params) < 0) { + if (mpcodecs_reconfig_vo(vd, &vo_params) < 0) { talloc_free(mpi); return -1; } @@ -805,30 +804,30 @@ static int decode(struct sh_video *sh, struct demux_packet *packet, return 1; } -static struct mp_image *decode_with_fallback(struct sh_video *sh, +static struct mp_image *decode_with_fallback(struct dec_video *vd, struct demux_packet *packet, int flags, double *reordered_pts) { - vd_ffmpeg_ctx *ctx = sh->context; + vd_ffmpeg_ctx *ctx = vd->priv; if (!ctx->avctx) return NULL; struct mp_image *mpi = NULL; - int res = decode(sh, packet, flags, reordered_pts, &mpi); + int res = decode(vd, packet, flags, reordered_pts, &mpi); if (res >= 0) return mpi; // Failed hardware decoding? Try again in software. if (ctx->software_fallback_decoder) { - uninit_avctx(sh); + uninit_avctx(vd); mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Error using hardware " "decoding, falling back to software decoding.\n"); const char *decoder = ctx->software_fallback_decoder; ctx->software_fallback_decoder = NULL; - init_avctx(sh, decoder, NULL); + init_avctx(vd, decoder, NULL); if (ctx->avctx) { mpi = NULL; - decode(sh, packet, flags, reordered_pts, &mpi); + decode(vd, packet, flags, reordered_pts, &mpi); return mpi; } } @@ -836,9 +835,9 @@ static struct mp_image *decode_with_fallback(struct sh_video *sh, return NULL; } -static int control(sh_video_t *sh, int cmd, void *arg) +static int control(struct dec_video *vd, int cmd, void *arg) { - vd_ffmpeg_ctx *ctx = sh->context; + vd_ffmpeg_ctx *ctx = vd->priv; AVCodecContext *avctx = ctx->avctx; switch (cmd) { case VDCTRL_RESYNC_STREAM: @@ -853,7 +852,7 @@ static int control(sh_video_t *sh, int cmd, void *arg) return CONTROL_TRUE; case VDCTRL_REINIT_VO: if (ctx->vo_image_params.imgfmt) - mpcodecs_reconfig_vo(sh, &ctx->vo_image_params); + mpcodecs_reconfig_vo(vd, &ctx->vo_image_params); return true; case VDCTRL_GET_PARAMS: *(struct mp_image_params *)arg = ctx->vo_image_params; diff --git a/video/decode/vdpau_old.c b/video/decode/vdpau_old.c index 1ef6c7857a..caca5df1a5 100644 --- a/video/decode/vdpau_old.c +++ b/video/decode/vdpau_old.c @@ -130,8 +130,8 @@ static void draw_slice_hwdec(struct AVCodecContext *s, const AVFrame *src, int offset[4], int y, int type, int height) { - sh_video_t *sh = s->opaque; - struct lavc_ctx *ctx = sh->context; + struct dec_video *vd = s->opaque; + struct lavc_ctx *ctx = vd->priv; struct priv *p = ctx->hwdec_priv; struct vdp_functions *vdp = p->vdp; VdpStatus vdp_st;