summaryrefslogtreecommitdiffstats
path: root/libmpdemux/demuxer.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmpdemux/demuxer.c')
-rw-r--r--libmpdemux/demuxer.c228
1 files changed, 102 insertions, 126 deletions
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index c46ba9d43d..c9142f1441 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"
@@ -184,7 +186,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->buffer_pos = ds->buffer_size = 0;
@@ -230,11 +232,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;
@@ -247,6 +248,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,
@@ -259,8 +261,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) {
@@ -275,16 +275,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);
@@ -304,11 +305,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;
@@ -317,6 +318,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];
@@ -342,13 +344,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];
@@ -405,7 +408,7 @@ void free_demuxer(demuxer_t *demuxer)
}
free(demuxer->attachments);
}
- free(demuxer);
+ talloc_free(demuxer);
}
@@ -510,20 +513,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)) {
@@ -684,16 +699,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))
@@ -765,9 +780,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
@@ -781,9 +793,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;
@@ -796,7 +809,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);
@@ -806,8 +819,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
@@ -818,8 +831,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
@@ -830,13 +844,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
@@ -849,7 +863,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)
@@ -871,8 +885,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...
@@ -883,13 +898,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
@@ -902,7 +917,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)
@@ -960,8 +975,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;
@@ -992,7 +1008,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;
}
@@ -1013,13 +1029,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) {
@@ -1030,12 +1046,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
@@ -1043,12 +1059,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);
}
}
@@ -1062,10 +1079,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;
}
@@ -1089,18 +1107,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;
@@ -1151,7 +1168,7 @@ int demux_info_add(demuxer_t *demuxer, const char *opt, const char *param)
for (n = 0; info && info[2 * n] != NULL; n++) {
if (!strcasecmp(opt, info[2 * n])) {
- 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);
@@ -1159,8 +1176,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 *));
@@ -1176,7 +1193,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]);
@@ -1326,7 +1343,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);
@@ -1343,31 +1360,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, &current);
- if (ris == STREAM_UNSUPPORTED)
- return -1;
- chapter += current;
- }
-
demux_flush(demuxer);
ris = stream_control(demuxer->stream, STREAM_CTRL_SEEK_TO_CHAPTER,
@@ -1387,60 +1392,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;
-
- *seek_pts = demuxer->chapters[current].start / 1000.0;
+ if (chapter < 0)
+ chapter = 0;
- if (num_chapters)
- *num_chapters = demuxer->num_chapters;
+ *seek_pts = demuxer->chapters[chapter].start / 1000.0;
- 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;
}
}