diff options
Diffstat (limited to 'libmpdemux/demuxer.c')
-rw-r--r-- | libmpdemux/demuxer.c | 233 |
1 files changed, 103 insertions, 130 deletions
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c index 038b2999cf..be1cfde73c 100644 --- a/libmpdemux/demuxer.c +++ b/libmpdemux/demuxer.c @@ -27,6 +27,8 @@ #include <sys/stat.h> #include "config.h" +#include "options.h" +#include "talloc.h" #include "mp_msg.h" #include "help_mp.h" #include "m_config.h" @@ -41,10 +43,7 @@ #include "libaf/af_format.h" #include "libmpcodecs/dec_teletext.h" -#ifdef CONFIG_ASS -#include "libass/ass.h" -#include "libass/ass_mp.h" -#endif +#include "ass_mp.h" #ifdef CONFIG_LIBAVCODEC #include "libavcodec/avcodec.h" @@ -185,7 +184,7 @@ void free_demuxer_stream(demux_stream_t *ds) free(ds); } -demux_stream_t *new_demuxer_stream(struct demuxer_st *demuxer, int id) +demux_stream_t *new_demuxer_stream(struct demuxer *demuxer, int id) { demux_stream_t *ds = malloc(sizeof(demux_stream_t)); *ds = (demux_stream_t){ @@ -215,11 +214,10 @@ static const demuxer_desc_t *get_demuxer_desc_from_type(int file_format) } -demuxer_t *new_demuxer(stream_t *stream, int type, int a_id, int v_id, - int s_id, char *filename) +demuxer_t *new_demuxer(struct MPOpts *opts, stream_t *stream, int type, + int a_id, int v_id, int s_id, char *filename) { - demuxer_t *d = malloc(sizeof(demuxer_t)); - memset(d, 0, sizeof(demuxer_t)); + struct demuxer *d = talloc_zero(NULL, struct demuxer); d->stream = stream; d->stream_pts = MP_NOPTS_VALUE; d->reference_clock = MP_NOPTS_VALUE; @@ -232,6 +230,7 @@ demuxer_t *new_demuxer(stream_t *stream, int type, int a_id, int v_id, d->video = new_demuxer_stream(d, v_id); d->sub = new_demuxer_stream(d, s_id); d->type = type; + d->opts = opts; if (type) if (!(d->desc = get_demuxer_desc_from_type(type))) mp_msg(MSGT_DEMUXER, MSGL_ERR, @@ -244,8 +243,6 @@ demuxer_t *new_demuxer(stream_t *stream, int type, int a_id, int v_id, return d; } -extern int dvdsub_id; - sh_sub_t *new_sh_sub_sid(demuxer_t *demuxer, int id, int sid) { if (id > MAX_S_STREAMS - 1 || id < 0) { @@ -260,16 +257,17 @@ sh_sub_t *new_sh_sub_sid(demuxer_t *demuxer, int id, int sid) sh_sub_t *sh = calloc(1, sizeof(sh_sub_t)); demuxer->s_streams[id] = sh; sh->sid = sid; + sh->opts = demuxer->opts; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", sid); } - if (sid == dvdsub_id) { + if (sid == demuxer->opts->sub_id) { demuxer->sub->id = id; demuxer->sub->sh = demuxer->s_streams[id]; } return demuxer->s_streams[id]; } -void free_sh_sub(sh_sub_t *sh) +static void free_sh_sub(sh_sub_t *sh) { mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing sh_sub at %p\n", sh); free(sh->extradata); @@ -289,11 +287,11 @@ sh_audio_t *new_sh_audio_aid(demuxer_t *demuxer, int id, int aid) MAX_A_STREAMS); return NULL; } - if (demuxer->a_streams[id]) - mp_msg(MSGT_DEMUXER, MSGL_WARN, MSGTR_AudioStreamRedefined, id); - else { + if (demuxer->a_streams[id]) { + mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "WARNING: Audio stream header %d redefined.\n", id); + } else { + mp_tmsg(MSGT_DEMUXER, MSGL_V, "==> Found audio stream: %d\n", id); sh_audio_t *sh = calloc(1, sizeof(sh_audio_t)); - mp_msg(MSGT_DEMUXER, MSGL_V, MSGTR_FoundAudioStream, id); demuxer->a_streams[id] = sh; sh->aid = aid; sh->ds = demuxer->audio; @@ -302,6 +300,7 @@ sh_audio_t *new_sh_audio_aid(demuxer_t *demuxer, int id, int aid) sh->sample_format = AF_FORMAT_S16_NE; sh->audio_out_minsize = 8192; /* default size, maybe not enough for Win32/ACM */ sh->pts = MP_NOPTS_VALUE; + sh->opts = demuxer->opts; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_ID=%d\n", aid); } return demuxer->a_streams[id]; @@ -327,13 +326,14 @@ sh_video_t *new_sh_video_vid(demuxer_t *demuxer, int id, int vid) return NULL; } if (demuxer->v_streams[id]) - mp_msg(MSGT_DEMUXER, MSGL_WARN, MSGTR_VideoStreamRedefined, id); + mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "WARNING: Video stream header %d redefined.\n", id); else { - sh_video_t *sh = calloc(1, sizeof(sh_video_t)); - mp_msg(MSGT_DEMUXER, MSGL_V, MSGTR_FoundVideoStream, id); + mp_tmsg(MSGT_DEMUXER, MSGL_V, "==> Found video stream: %d\n", id); + sh_video_t *sh = calloc(1, sizeof *sh); demuxer->v_streams[id] = sh; sh->vid = vid; sh->ds = demuxer->video; + sh->opts = demuxer->opts; mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_ID=%d\n", vid); } return demuxer->v_streams[id]; @@ -392,7 +392,7 @@ void free_demuxer(demuxer_t *demuxer) } if (demuxer->teletext) teletext_control(demuxer->teletext, TV_VBI_CONTROL_STOP, NULL); - free(demuxer); + talloc_free(demuxer); } @@ -497,20 +497,32 @@ int ds_fill_buffer(demux_stream_t *ds) if (!ds->first) ds->last = NULL; --ds->packs; + /* The code below can set ds->eof to 1 when another stream runs + * out of buffer space. That makes sense because in that situation + * the calling code should not count on being able to demux more + * packets from this stream. + * If however the situation improves and we're called again + * despite the eof flag then it's better to clear it to avoid + * weird behavior. */ + ds->eof = 0; return 1; } + +#define MaybeNI _("Maybe you are playing a non-interleaved stream/file or the codec failed?\n" \ + "For AVI files, try to force non-interleaved mode with the -ni option.\n") + if (demux->audio->packs >= MAX_PACKS || demux->audio->bytes >= MAX_PACK_BYTES) { - mp_msg(MSGT_DEMUXER, MSGL_ERR, MSGTR_TooManyAudioInBuffer, + mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many audio packets in the buffer: (%d in %d bytes).\n", demux->audio->packs, demux->audio->bytes); - mp_msg(MSGT_DEMUXER, MSGL_HINT, MSGTR_MaybeNI); + mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI); break; } if (demux->video->packs >= MAX_PACKS || demux->video->bytes >= MAX_PACK_BYTES) { - mp_msg(MSGT_DEMUXER, MSGL_ERR, MSGTR_TooManyVideoInBuffer, + mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many video packets in the buffer: (%d in %d bytes).\n", demux->video->packs, demux->video->bytes); - mp_msg(MSGT_DEMUXER, MSGL_HINT, MSGTR_MaybeNI); + mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI); break; } if (!demux_fill_buffer(demux, ds)) { @@ -664,16 +676,16 @@ double ds_get_next_pts(demux_stream_t *ds) while (!ds->first) { if (demux->audio->packs >= MAX_PACKS || demux->audio->bytes >= MAX_PACK_BYTES) { - mp_msg(MSGT_DEMUXER, MSGL_ERR, MSGTR_TooManyAudioInBuffer, + mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many audio packets in the buffer: (%d in %d bytes).\n", demux->audio->packs, demux->audio->bytes); - mp_msg(MSGT_DEMUXER, MSGL_HINT, MSGTR_MaybeNI); + mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI); return MP_NOPTS_VALUE; } if (demux->video->packs >= MAX_PACKS || demux->video->bytes >= MAX_PACK_BYTES) { - mp_msg(MSGT_DEMUXER, MSGL_ERR, MSGTR_TooManyVideoInBuffer, + mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "\nToo many video packets in the buffer: (%d in %d bytes).\n", demux->video->packs, demux->video->bytes); - mp_msg(MSGT_DEMUXER, MSGL_HINT, MSGTR_MaybeNI); + mp_tmsg(MSGT_DEMUXER, MSGL_HINT, MaybeNI); return MP_NOPTS_VALUE; } if (!demux_fill_buffer(demux, ds)) @@ -745,9 +757,6 @@ int get_demuxer_type_from_name(char *demuxer_name, int *force) int extension_parsing = 1; // 0=off 1=mixed (used only for unstable formats) -int correct_pts = 0; -int user_correct_pts = -1; - /* NOTE : Several demuxers may be opened at the same time so demuxers should NEVER rely on an external var to enable them @@ -761,9 +770,10 @@ int user_correct_pts = -1; (ex: tv,mf). */ -static demuxer_t *demux_open_stream(stream_t *stream, int file_format, - int force, int audio_id, int video_id, - int dvdsub_id, char *filename) +static demuxer_t *demux_open_stream(struct MPOpts *opts, stream_t *stream, + int file_format, int force, int audio_id, + int video_id, int dvdsub_id, + char *filename) { demuxer_t *demuxer = NULL; @@ -776,7 +786,7 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, // If somebody requested a demuxer check it if (file_format) { if ((demuxer_desc = get_demuxer_desc_from_type(file_format))) { - demuxer = new_demuxer(stream, demuxer_desc->type, audio_id, + demuxer = new_demuxer(opts, stream, demuxer_desc->type, audio_id, video_id, dvdsub_id, filename); if (demuxer_desc->check_file) fformat = demuxer_desc->check_file(demuxer); @@ -786,8 +796,8 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, if (fformat == demuxer_desc->type) { demuxer_t *demux2 = demuxer; // Move messages to demuxer detection code? - mp_msg(MSGT_DEMUXER, MSGL_INFO, - MSGTR_Detected_XXX_FileFormat, + mp_tmsg(MSGT_DEMUXER, MSGL_INFO, + "%s file format detected.\n", demuxer_desc->shortdesc); file_format = fformat; if (!demuxer->desc->open @@ -798,8 +808,9 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, } else { // Format changed after check, recurse free_demuxer(demuxer); - return demux_open_stream(stream, fformat, force, audio_id, - video_id, dvdsub_id, filename); + return demux_open_stream(opts, stream, fformat, force, + audio_id, video_id, dvdsub_id, + filename); } } // Check failed for forced demuxer, quit @@ -810,13 +821,13 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, // Test demuxers with safe file checks for (i = 0; (demuxer_desc = demuxer_list[i]); i++) { if (demuxer_desc->safe_check) { - demuxer = new_demuxer(stream, demuxer_desc->type, audio_id, + demuxer = new_demuxer(opts, stream, demuxer_desc->type, audio_id, video_id, dvdsub_id, filename); if ((fformat = demuxer_desc->check_file(demuxer)) != 0) { if (fformat == demuxer_desc->type) { demuxer_t *demux2 = demuxer; - mp_msg(MSGT_DEMUXER, MSGL_INFO, - MSGTR_Detected_XXX_FileFormat, + mp_tmsg(MSGT_DEMUXER, MSGL_INFO, + "%s file format detected.\n", demuxer_desc->shortdesc); file_format = fformat; if (!demuxer->desc->open @@ -829,7 +840,7 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, return demuxer; // handled in mplayer.c // Format changed after check, recurse free_demuxer(demuxer); - demuxer = demux_open_stream(stream, fformat, force, + demuxer = demux_open_stream(opts, stream, fformat, force, audio_id, video_id, dvdsub_id, filename); if (demuxer) @@ -851,8 +862,9 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, file_format = demuxer_type_by_filename(filename); if (file_format != DEMUXER_TYPE_UNKNOWN) { // we like recursion :) - demuxer = demux_open_stream(stream, file_format, force, audio_id, - video_id, dvdsub_id, filename); + demuxer = demux_open_stream(opts, stream, file_format, force, + audio_id, video_id, dvdsub_id, + filename); if (demuxer) return demuxer; // done! file_format = DEMUXER_TYPE_UNKNOWN; // continue fuzzy guessing... @@ -863,13 +875,13 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, // Try detection for all other demuxers for (i = 0; (demuxer_desc = demuxer_list[i]); i++) { if (!demuxer_desc->safe_check && demuxer_desc->check_file) { - demuxer = new_demuxer(stream, demuxer_desc->type, audio_id, + demuxer = new_demuxer(opts, stream, demuxer_desc->type, audio_id, video_id, dvdsub_id, filename); if ((fformat = demuxer_desc->check_file(demuxer)) != 0) { if (fformat == demuxer_desc->type) { demuxer_t *demux2 = demuxer; - mp_msg(MSGT_DEMUXER, MSGL_INFO, - MSGTR_Detected_XXX_FileFormat, + mp_tmsg(MSGT_DEMUXER, MSGL_INFO, + "%s file format detected.\n", demuxer_desc->shortdesc); file_format = fformat; if (!demuxer->desc->open @@ -882,7 +894,7 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format, return demuxer; // handled in mplayer.c // Format changed after check, recurse free_demuxer(demuxer); - demuxer = demux_open_stream(stream, fformat, force, + demuxer = demux_open_stream(opts, stream, fformat, force, audio_id, video_id, dvdsub_id, filename); if (demuxer) @@ -940,8 +952,9 @@ extern int hr_mp3_seek; extern float stream_cache_min_percent; extern float stream_cache_seek_min_percent; -demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, - int video_id, int dvdsub_id, char *filename) +demuxer_t *demux_open(struct MPOpts *opts, stream_t *vs, int file_format, + int audio_id, int video_id, int dvdsub_id, + char *filename) { stream_t *as = NULL, *ss = NULL; demuxer_t *vd, *ad = NULL, *sd = NULL; @@ -972,7 +985,7 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, if (audio_stream) { as = open_stream(audio_stream, 0, &afmt); if (!as) { - mp_msg(MSGT_DEMUXER, MSGL_ERR, MSGTR_CannotOpenAudioStream, + mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "Cannot open audio stream: %s\n", audio_stream); return NULL; } @@ -993,13 +1006,13 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, if (sub_stream) { ss = open_stream(sub_stream, 0, &sfmt); if (!ss) { - mp_msg(MSGT_DEMUXER, MSGL_ERR, MSGTR_CannotOpenSubtitlesStream, + mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "Cannot open subtitle stream: %s\n", sub_stream); return NULL; } } - vd = demux_open_stream(vs, demuxer_type ? demuxer_type : file_format, + vd = demux_open_stream(opts, vs, demuxer_type ? demuxer_type : file_format, demuxer_force, audio_stream ? -2 : audio_id, video_id, sub_stream ? -2 : dvdsub_id, filename); if (!vd) { @@ -1010,12 +1023,12 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, return NULL; } if (as) { - ad = demux_open_stream(as, + ad = demux_open_stream(opts, as, audio_demuxer_type ? audio_demuxer_type : afmt, audio_demuxer_force, audio_id, -2, -2, audio_stream); if (!ad) { - mp_msg(MSGT_DEMUXER, MSGL_WARN, MSGTR_OpeningAudioDemuxerFailed, + mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "Failed to open audio demuxer: %s\n", audio_stream); free_stream(as); } else if (ad->audio->sh @@ -1023,12 +1036,13 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, hr_mp3_seek = 1; // Enable high res seeking } if (ss) { - sd = demux_open_stream(ss, sub_demuxer_type ? sub_demuxer_type : sfmt, + sd = demux_open_stream(opts, ss, + sub_demuxer_type ? sub_demuxer_type : sfmt, sub_demuxer_force, -2, -2, dvdsub_id, sub_stream); if (!sd) { - mp_msg(MSGT_DEMUXER, MSGL_WARN, - MSGTR_OpeningSubtitlesDemuxerFailed, sub_stream); + mp_tmsg(MSGT_DEMUXER, MSGL_WARN, + "Failed to open subtitle demuxer: %s\n", sub_stream); free_stream(ss); } } @@ -1042,10 +1056,11 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id, else res = vd; - correct_pts = user_correct_pts; - if (correct_pts < 0) - correct_pts = demux_control(res, DEMUXER_CTRL_CORRECT_PTS, NULL) - == DEMUXER_CTRL_OK; + opts->correct_pts = opts->user_correct_pts; + if (opts->correct_pts < 0) + opts->correct_pts = + demux_control(res, DEMUXER_CTRL_CORRECT_PTS, + NULL) == DEMUXER_CTRL_OK; return res; } @@ -1069,18 +1084,17 @@ int demux_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, if (!demuxer->seekable) { if (demuxer->file_format == DEMUXER_TYPE_AVI) - mp_msg(MSGT_SEEK, MSGL_WARN, MSGTR_CantSeekRawAVI); + mp_tmsg(MSGT_SEEK, MSGL_WARN, "Cannot seek in raw AVI streams. (Index required, try with the -idx switch.)\n"); #ifdef CONFIG_TV else if (demuxer->file_format == DEMUXER_TYPE_TV) - mp_msg(MSGT_SEEK, MSGL_WARN, MSGTR_TVInputNotSeekable); + mp_tmsg(MSGT_SEEK, MSGL_WARN, "TV input is not seekable! (Seeking will probably be for changing channels ;)\n"); #endif else - mp_msg(MSGT_SEEK, MSGL_WARN, MSGTR_CantSeekFile); + mp_tmsg(MSGT_SEEK, MSGL_WARN, "Cannot seek in this file.\n"); return 0; } - - demux_flush(demuxer); // clear demux buffers: + demux_flush(demuxer); if (sh_audio) sh_audio->a_buffer_len = 0; @@ -1135,7 +1149,7 @@ int demux_info_add(demuxer_t *demuxer, const char *opt, const char *param) mp_msg(MSGT_DEMUX, MSGL_V, "Demuxer info %s set to unchanged value %s\n", opt, param); return 0; } - mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_DemuxerInfoChanged, opt, + mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Demuxer info %s changed to %s\n", opt, param); free(info[2 * n + 1]); info[2 * n + 1] = strdup(param); @@ -1143,8 +1157,8 @@ int demux_info_add(demuxer_t *demuxer, const char *opt, const char *param) } } - info = demuxer->info = (char **) realloc(info, - (2 * (n + 2)) * sizeof(char *)); + info = demuxer->info = + (char **) realloc(info, (2 * (n + 2)) * sizeof(char *)); info[2 * n] = strdup(opt); info[2 * n + 1] = strdup(param); memset(&info[2 * (n + 1)], 0, 2 * sizeof(char *)); @@ -1160,7 +1174,7 @@ int demux_info_print(demuxer_t *demuxer) if (!info) return 0; - mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_ClipInfo); + mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Clip info:\n"); for (n = 0; info[2 * n] != NULL; n++) { mp_msg(MSGT_DEMUX, MSGL_INFO, " %s: %s\n", info[2 * n], info[2 * n + 1]); @@ -1311,7 +1325,7 @@ int demuxer_add_chapter(demuxer_t *demuxer, const char *name, uint64_t start, demuxer->chapters[demuxer->num_chapters].start = start; demuxer->chapters[demuxer->num_chapters].end = end; - demuxer->chapters[demuxer->num_chapters].name = strdup(name ? name : MSGTR_Unknown); + demuxer->chapters[demuxer->num_chapters].name = strdup(name ? name : mp_gtext("unknown")); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_ID=%d\n", demuxer->num_chapters); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_START=%"PRIu64"\n", demuxer->num_chapters, start); @@ -1328,31 +1342,19 @@ int demuxer_add_chapter(demuxer_t *demuxer, const char *name, uint64_t start, * either using the demuxer->chapters structure set by the demuxer * or asking help to the stream layer (e.g. dvd) * \param chapter - chapter number wished - 0-based - * \param mode 0: relative to current main pts, 1: absolute * \param seek_pts set by the function to the pts to seek to (if demuxer->chapters is set) - * \param num_chapters number of chapters present (set by this function is param is not null) * \param chapter_name name of chapter found (set by this function is param is not null) * \return -1 on error, current chapter if successful */ -int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, int mode, - float *seek_pts, int *num_chapters, +int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, double *seek_pts, char **chapter_name) { int ris; - int current, total; sh_video_t *sh_video = demuxer->video->sh; sh_audio_t *sh_audio = demuxer->audio->sh; if (!demuxer->num_chapters || !demuxer->chapters) { - if (!mode) { - ris = stream_control(demuxer->stream, - STREAM_CTRL_GET_CURRENT_CHAPTER, ¤t); - if (ris == STREAM_UNSUPPORTED) - return -1; - chapter += current; - } - demux_flush(demuxer); ris = stream_control(demuxer->stream, STREAM_CTRL_SEEK_TO_CHAPTER, @@ -1372,60 +1374,31 @@ int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, int mode, // (because e.g. dvds depend on sectors, not on pts) *seek_pts = -1.0; - if (num_chapters) { - if (stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_CHAPTERS, - num_chapters) == STREAM_UNSUPPORTED) - *num_chapters = 0; - } - if (chapter_name) { *chapter_name = NULL; - if (num_chapters && *num_chapters) { - char *tmp = malloc(16); - if (tmp) { - sprintf(tmp, " of %3d", *num_chapters); - *chapter_name = tmp; - } + int num_chapters; + if (stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_CHAPTERS, + &num_chapters) == STREAM_UNSUPPORTED) + num_chapters = 0; + if (num_chapters) { + *chapter_name = talloc_size(NULL, 16); + sprintf(*chapter_name, " of %3d", num_chapters); } } return ris != STREAM_UNSUPPORTED ? chapter : -1; } else { // chapters structure is set in the demuxer - total = demuxer->num_chapters; - - if (mode == 1) //absolute seeking - current = chapter; - else { //relative seeking - uint64_t now; - now = (sh_video ? sh_video->pts : (sh_audio ? sh_audio->pts : 0.)) - * 1000 + .5; - - for (current = total - 1; current >= 0; --current) { - demux_chapter_t *chapter = demuxer->chapters + current; - if (chapter->start <= now) - break; - } - current += chapter; - } - - if (current >= total) + if (chapter >= demuxer->num_chapters) return -1; - if (current < 0) - current = 0; + if (chapter < 0) + chapter = 0; - *seek_pts = demuxer->chapters[current].start / 1000.0; + *seek_pts = demuxer->chapters[chapter].start / 1000.0; - if (num_chapters) - *num_chapters = demuxer->num_chapters; - - if (chapter_name) { - if (demuxer->chapters[current].name) - *chapter_name = strdup(demuxer->chapters[current].name); - else - *chapter_name = NULL; - } + if (chapter_name) + *chapter_name = talloc_strdup(NULL, demuxer->chapters[chapter].name); - return current; + return chapter; } } |