aboutsummaryrefslogtreecommitdiffhomepage
path: root/libmpdemux
diff options
context:
space:
mode:
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/aviheader.c2
-rw-r--r--libmpdemux/demux_avi.c15
-rw-r--r--libmpdemux/demux_avs.c2
-rw-r--r--libmpdemux/demux_demuxers.c3
-rw-r--r--libmpdemux/demux_lavf.c16
-rw-r--r--libmpdemux/demux_mkv.c461
-rw-r--r--libmpdemux/demux_mov.c5
-rw-r--r--libmpdemux/demux_mpg.c6
-rw-r--r--libmpdemux/demux_nemesi.c2
-rw-r--r--libmpdemux/demux_ogg.c11
-rw-r--r--libmpdemux/demux_pva.c2
-rw-r--r--libmpdemux/demux_rtp.cpp10
-rw-r--r--libmpdemux/demuxer.c168
-rw-r--r--libmpdemux/demuxer.h83
-rw-r--r--libmpdemux/ebml.h3
-rw-r--r--libmpdemux/mp3_hdr.c3
-rw-r--r--libmpdemux/parse_mp4.c2
-rw-r--r--libmpdemux/stheader.h40
18 files changed, 440 insertions, 394 deletions
diff --git a/libmpdemux/aviheader.c b/libmpdemux/aviheader.c
index 85a84e8ca3..fa7f27c4fc 100644
--- a/libmpdemux/aviheader.c
+++ b/libmpdemux/aviheader.c
@@ -42,7 +42,7 @@ static int odml_get_vstream_id(int id, unsigned char res[])
return 0;
}
-int avi_idx_cmp(const void *elem1,const void *elem2) {
+static int avi_idx_cmp(const void *elem1,const void *elem2) {
register off_t a = AVI_IDX_OFFSET((AVIINDEXENTRY *)elem1);
register off_t b = AVI_IDX_OFFSET((AVIINDEXENTRY *)elem2);
return (a > b) - (b > a);
diff --git a/libmpdemux/demux_avi.c b/libmpdemux/demux_avi.c
index fa1fc91e48..9695fcb556 100644
--- a/libmpdemux/demux_avi.c
+++ b/libmpdemux/demux_avi.c
@@ -24,7 +24,9 @@ extern const demuxer_desc_t demuxer_desc_avi_nini;
int pts_from_bps=1;
// Select ds from ID
-demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id){
+static demux_stream_t* demux_avi_select_stream(demuxer_t *demux,
+ unsigned int id)
+{
int stream_id=avi_stream_id(id);
@@ -277,7 +279,7 @@ do{
// return value:
// 0 = EOF or no stream found
// 1 = successfully read a packet
-int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t* ds){
+static int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t* ds){
avi_priv_t *priv=demux->priv;
unsigned int id=0;
unsigned int len;
@@ -341,7 +343,7 @@ do{
// return value:
// 0 = EOF or no stream found
// 1 = successfully read a packet
-int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t* ds){
+static int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t* ds){
avi_priv_t *priv=demux->priv;
unsigned int id=0;
unsigned int len;
@@ -572,7 +574,7 @@ static demuxer_t* demux_open_avi(demuxer_t* demuxer){
}
-void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
+static void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
avi_priv_t *priv=demuxer->priv;
demux_stream_t *d_audio=demuxer->audio;
demux_stream_t *d_video=demuxer->video;
@@ -745,7 +747,7 @@ void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int
}
-void demux_close_avi(demuxer_t *demuxer) {
+static void demux_close_avi(demuxer_t *demuxer) {
avi_priv_t* priv=demuxer->priv;
if(!priv)
@@ -837,6 +839,7 @@ static int avi_check_file(demuxer_t *demuxer)
static demuxer_t* demux_open_hack_avi(demuxer_t *demuxer)
{
+ struct MPOpts *opts = demuxer->opts;
sh_audio_t* sh_a;
demuxer = demux_open_avi(demuxer);
@@ -851,7 +854,7 @@ static demuxer_t* demux_open_hack_avi(demuxer_t *demuxer)
stream_t* s;
demuxer_t *od;
s = new_ds_stream(demuxer->audio);
- od = new_demuxer(s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL);
+ od = new_demuxer(opts, s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL);
if(!demux_ogg_open(od)) {
mp_msg( MSGT_DEMUXER,MSGL_ERR,MSGTR_ErrorOpeningOGGDemuxer);
free_stream(s);
diff --git a/libmpdemux/demux_avs.c b/libmpdemux/demux_avs.c
index 8d2ac82046..444e06c90c 100644
--- a/libmpdemux/demux_avs.c
+++ b/libmpdemux/demux_avs.c
@@ -85,7 +85,7 @@ typedef struct tagAVS
imp_avs_get_audio avs_get_audio;
} AVS_T;
-AVS_T *initAVS(const char *filename)
+static AVS_T *initAVS(const char *filename)
{
AVS_T *AVS = malloc (sizeof(AVS_T));
AVS_Value arg0 = avs_new_value_string(filename);
diff --git a/libmpdemux/demux_demuxers.c b/libmpdemux/demux_demuxers.c
index a5f87e601b..dc04ecffd0 100644
--- a/libmpdemux/demux_demuxers.c
+++ b/libmpdemux/demux_demuxers.c
@@ -8,6 +8,7 @@
#include "stream/stream.h"
#include "demuxer.h"
#include "stheader.h"
+#include "talloc.h"
typedef struct dd_priv {
demuxer_t* vd;
@@ -21,7 +22,7 @@ demuxer_t* new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd) {
demuxer_t* ret;
dd_priv_t* priv;
- ret = calloc(1,sizeof(demuxer_t));
+ ret = talloc_zero(NULL, struct demuxer);
priv = malloc(sizeof(dd_priv_t));
priv->vd = vd;
diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c
index 5383e161c8..21f3d21155 100644
--- a/libmpdemux/demux_lavf.c
+++ b/libmpdemux/demux_lavf.c
@@ -22,8 +22,10 @@
#include <stdlib.h>
// #include <unistd.h>
#include <limits.h>
+#include <stdbool.h>
#include "config.h"
+#include "options.h"
#include "mp_msg.h"
#include "help_mp.h"
#include "av_opts.h"
@@ -43,9 +45,6 @@
#define PROBE_BUF_SIZE (32*1024)
-extern char *audio_lang;
-extern char *dvdsub_lang;
-extern int dvdsub_id;
static unsigned int opt_probesize = 0;
static unsigned int opt_analyzeduration = 0;
static char *opt_format;
@@ -418,6 +417,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
}
static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
+ struct MPOpts *opts = demuxer->opts;
AVFormatContext *avfc;
AVFormatParameters ap;
const AVOption *opt;
@@ -433,7 +433,7 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
if (opt_cryptokey)
parse_cryptokey(avfc, opt_cryptokey);
- if (user_correct_pts != 0)
+ if (opts->user_correct_pts != 0)
avfc->flags |= AVFMT_FLAG_GENPTS;
if (index_mode == 0)
avfc->flags |= AVFMT_FLAG_IGNIDX;
@@ -534,6 +534,8 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
demuxer->video->id=-2; // audio-only
} //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;
+ demuxer->accurate_seek = true;
+
return demuxer;
}
@@ -609,10 +611,14 @@ static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, float audio
mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %f, %d)\n", demuxer, rel_seek_secs, audio_delay, flags);
if (flags & SEEK_ABSOLUTE) {
- priv->last_pts = priv->avfc->start_time;
+ priv->last_pts = 0;
} else {
if (rel_seek_secs < 0) avsflags = AVSEEK_FLAG_BACKWARD;
}
+ if (flags & SEEK_FORWARD)
+ avsflags = 0;
+ else if (flags & SEEK_BACKWARD)
+ avsflags = AVSEEK_FLAG_BACKWARD;
if (flags & SEEK_FACTOR) {
if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
return;
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c
index 6d4429377c..e9853bc3e4 100644
--- a/libmpdemux/demux_mkv.c
+++ b/libmpdemux/demux_mkv.c
@@ -12,7 +12,10 @@
#include <stdio.h>
#include <ctype.h>
#include <inttypes.h>
+#include <stdbool.h>
+#include "talloc.h"
+#include "options.h"
#include "stream/stream.h"
#include "demuxer.h"
#include "stheader.h"
@@ -55,13 +58,12 @@ static const unsigned char sipr_swaps[38][2]={
#define ATRC_FLAVORS 8
#define COOK_FLAVORS 34
static const int sipr_fl2bps[SIPR_FLAVORS] = {813, 1062, 625, 2000};
-static const int atrc_fl2bps[ATRC_FLAVORS] =
- {8269, 11714, 13092, 16538, 18260, 22050, 33075, 44100};
-static const int cook_fl2bps[COOK_FLAVORS] =
- { 1000, 1378, 2024, 2584, 4005, 5513, 8010, 4005, 750, 2498,
- 4048, 5513, 8010, 11973, 8010, 2584, 4005, 2067, 2584, 2584,
- 4005, 4005, 5513, 5513, 8010, 12059, 1550, 8010, 12059, 5513,
- 12016, 16408, 22911, 33506};
+static const int atrc_fl2bps[ATRC_FLAVORS] = {8269, 11714, 13092, 16538, 18260, 22050, 33075, 44100};
+static const int cook_fl2bps[COOK_FLAVORS] = {
+ 1000, 1378, 2024, 2584, 4005, 5513, 8010, 4005, 750, 2498,
+ 4048, 5513, 8010, 11973, 8010, 2584, 4005, 2067, 2584, 2584,
+ 4005, 4005, 5513, 5513, 8010, 12059, 1550, 8010, 12059, 5513,
+ 12016, 16408, 22911, 33506};
typedef struct
{
@@ -93,7 +95,7 @@ typedef struct mkv_track
int default_track;
- void *private_data;
+ unsigned char *private_data;
unsigned int private_size;
/* stuff for realmedia */
@@ -151,8 +153,7 @@ typedef struct mkv_demuxer
mkv_track_t **tracks;
int num_tracks;
- uint64_t tc_scale, cluster_tc, first_tc;
- int has_first_tc;
+ uint64_t tc_scale, cluster_tc;
uint64_t cluster_size;
uint64_t blockgroup_size;
@@ -171,8 +172,6 @@ typedef struct mkv_demuxer
int64_t skip_to_timecode;
int v_skip_to_keyframe, a_skip_to_keyframe;
- int64_t stop_timecode;
-
int last_aid;
int audio_tracks[MAX_A_STREAMS];
} mkv_demuxer_t;
@@ -182,20 +181,16 @@ typedef struct mkv_demuxer
#define RAPROPERTIES4_SIZE 56
#define RAPROPERTIES5_SIZE 70
-/* for e.g. "-slang ger" */
-extern char *dvdsub_lang;
-extern char *audio_lang;
-extern int dvdsub_id;
-
/**
* \brief ensures there is space for at least one additional element
* \param array array to grow
* \param nelem current number of elements in array
* \param elsize size of one array element
*/
-static void grow_array(void **array, int nelem, size_t elsize) {
+static void *grow_array(void *array, int nelem, size_t elsize) {
if (!(nelem & 31))
- *array = realloc(*array, (nelem + 32) * elsize);
+ array = realloc(array, (nelem + 32) * elsize);
+ return array;
}
static mkv_track_t *
@@ -220,8 +215,9 @@ add_cluster_position (mkv_demuxer_t *mkv_d, uint64_t position)
if (mkv_d->cluster_positions[i] == position)
return;
- grow_array(&mkv_d->cluster_positions, mkv_d->num_cluster_pos,
- sizeof(uint64_t));
+ mkv_d->cluster_positions = grow_array(mkv_d->cluster_positions,
+ mkv_d->num_cluster_pos,
+ sizeof(uint64_t));
mkv_d->cluster_positions[mkv_d->num_cluster_pos++] = position;
}
@@ -378,52 +374,67 @@ lzo_fail:
}
-static int
-demux_mkv_read_info (demuxer_t *demuxer)
+static int demux_mkv_read_info(demuxer_t *demuxer)
{
- mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
- stream_t *s = demuxer->stream;
- uint64_t length, l;
- int il;
- uint64_t tc_scale = 1000000;
- long double duration = 0.;
-
- length = ebml_read_length (s, NULL);
- while (length > 0)
- {
- switch (ebml_read_id (s, &il))
- {
+ mkv_demuxer_t *mkv_d = demuxer->priv;
+ stream_t *s = demuxer->stream;
+ uint64_t length, l;
+ int i;
+ uint64_t tc_scale = 1000000;
+ long double duration = 0.;
+
+ length = ebml_read_length(s, NULL);
+ while (length > 0) {
+ uint32_t id = ebml_read_id(s, &i);
+ length -= i;
+ switch (id) {
case MATROSKA_ID_TIMECODESCALE:
- {
- uint64_t num = ebml_read_uint (s, &l);
- if (num == EBML_UINT_INVALID)
- return 1;
- tc_scale = num;
- mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + timecode scale: %"PRIu64"\n",
+ tc_scale = ebml_read_uint(s, &l);
+ length -= l;
+ if (tc_scale == EBML_UINT_INVALID)
+ return 1;
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + timecode scale: %"PRIu64"\n",
tc_scale);
break;
- }
case MATROSKA_ID_DURATION:
- {
- long double num = ebml_read_float (s, &l);
- if (num == EBML_FLOAT_INVALID)
- return 1;
- duration = num;
- mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + duration: %.3Lfs\n",
- duration * tc_scale / 1000000000.0);
+ duration = ebml_read_float(s, &l);
+ length -= l;
+ if (duration == EBML_FLOAT_INVALID)
+ return 1;
+ break;
+
+ case MATROSKA_ID_SEGMENTUID:;
+ l = ebml_read_length(s, &i);
+ length -= i;
+ if (l != sizeof(demuxer->matroska_data.segment_uid)) {
+ mp_msg(MSGT_DEMUX, MSGL_INFO,
+ "[mkv] segment uid invalid length %"PRIu64"\n", l);
+ stream_skip(s, l);
+ } else {
+ stream_read(s, demuxer->matroska_data.segment_uid, l);
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + segment uid");
+ for (int i = 0; i < l; i++)
+ mp_msg(MSGT_DEMUX, MSGL_V, " %02x",
+ demuxer->matroska_data.segment_uid[i]);
+ mp_msg(MSGT_DEMUX, MSGL_V, "\n");
+ }
+ length -= l;
break;
- }
default:
- ebml_read_skip (s, &l);
- break;
+ ebml_read_skip(s, &l);
+ length -= l;
+ break;
}
- length -= l + il;
}
- mkv_d->tc_scale = tc_scale;
- mkv_d->duration = duration * tc_scale / 1000000000.0;
- return 0;
+ mkv_d->tc_scale = tc_scale;
+ mkv_d->duration = duration * tc_scale / 1000000000.0;
+ if (duration)
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + duration: %.3fs\n",
+ mkv_d->duration);
+
+ return 0;
}
/**
@@ -1064,7 +1075,8 @@ demux_mkv_read_cues (demuxer_t *demuxer)
if (time != EBML_UINT_INVALID && track != EBML_UINT_INVALID
&& pos != EBML_UINT_INVALID)
{
- grow_array(&mkv_d->indexes, mkv_d->num_indexes, sizeof(mkv_index_t));
+ mkv_d->indexes = grow_array(mkv_d->indexes, mkv_d->num_indexes,
+ sizeof(mkv_index_t));
mkv_d->indexes[mkv_d->num_indexes].tnum = track;
mkv_d->indexes[mkv_d->num_indexes].timecode = time;
mkv_d->indexes[mkv_d->num_indexes].filepos =mkv_d->segment_start+pos;
@@ -1079,140 +1091,175 @@ demux_mkv_read_cues (demuxer_t *demuxer)
return 0;
}
-static int
-demux_mkv_read_chapters (demuxer_t *demuxer)
+static uint64_t read_one_chapter(struct demuxer *demuxer, stream_t *s)
{
- stream_t *s = demuxer->stream;
- uint64_t length, l;
- int il;
-
- if (demuxer->chapters)
- {
- ebml_read_skip (s, NULL);
- return 0;
- }
-
- mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n");
- length = ebml_read_length (s, NULL);
-
- while (length > 0)
- {
- switch (ebml_read_id (s, &il))
- {
- case MATROSKA_ID_EDITIONENTRY:
- {
- uint64_t len;
- int i;
-
- len = ebml_read_length (s, &i);
- l = len + i;
+ uint64_t len, l;
+ uint64_t start = 0, end = 0;
+ struct matroska_chapter chapter = {};
+ char *name = 0;
+ int i;
+ uint32_t id;
+
+ len = ebml_read_length(s, &i);
+ uint64_t bytes_read = len + i;
+
+ while (len > 0) {
+ id = ebml_read_id(s, &i);
+ len -= i;
+ switch (id) {
+ case MATROSKA_ID_CHAPTERTIMESTART:
+ start = ebml_read_uint(s, &l) / 1000000;
+ len -= l;
+ break;
- while (len > 0)
- {
- uint64_t l;
- int il;
+ case MATROSKA_ID_CHAPTERTIMEEND:
+ end = ebml_read_uint(s, &l) / 1000000;
+ len -= l;
+ break;
- switch (ebml_read_id (s, &il))
- {
- case MATROSKA_ID_CHAPTERATOM:
- {
- uint64_t len, start=0, end=0;
- char* name = 0;
- int i;
- int cid;
+ case MATROSKA_ID_CHAPTERDISPLAY:;
+ uint64_t displaylen = ebml_read_length(s, &i);
+ len -= displaylen + i;
+ while (displaylen > 0) {
+ id = ebml_read_id(s, &i);
+ displaylen -= i;
+ switch (id) {
+ case MATROSKA_ID_CHAPSTRING:
+ name = ebml_read_utf8(s, &l);
+ break;
+ default:
+ ebml_read_skip(s, &l);
+ break;
+ }
+ displaylen -= l;
+ }
+ break;
- len = ebml_read_length (s, &i);
- l = len + i;
+ case MATROSKA_ID_CHAPTERSEGMENTUID:
+ l = ebml_read_length(s, &i);
+ len -= l + i;
+ if (l != sizeof(chapter.segment_uid)) {
+ mp_msg(MSGT_DEMUX, MSGL_INFO,
+ "[mkv] chapter segment uid invalid length %"PRIu64"\n",
+ l);
+ stream_skip(s, l);
+ } else {
+ stream_read(s, chapter.segment_uid, l);
+ chapter.has_segment_uid = true;
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Chapter segment uid ");
+ for (int i = 0; i < l; i++)
+ mp_msg(MSGT_DEMUX, MSGL_V, "%02x ", chapter.segment_uid[i]);
+ mp_msg(MSGT_DEMUX, MSGL_V, "\n");
+ }
+ break;
- while (len > 0)
- {
- uint64_t l;
- int il;
+ default:
+ ebml_read_skip(s, &l);
+ len -= l;
+ break;
+ }
+ }
- switch (ebml_read_id (s, &il))
- {
- case MATROSKA_ID_CHAPTERTIMESTART:
- start = ebml_read_uint (s, &l) / 1000000;
- break;
+ if (!name)
+ name = strdup("(unnamed)");
+
+ int cid = demuxer_add_chapter(demuxer, name, start, end);
+ struct matroska_data *m = &demuxer->matroska_data;
+ m->ordered_chapters = talloc_realloc(demuxer, m->ordered_chapters,
+ struct matroska_chapter,
+ m->num_ordered_chapters + 1);
+ chapter.start = start;
+ chapter.end = end;
+ chapter.name = talloc_strdup(m->ordered_chapters, name);
+ // Will be undone later if this is a normal chapter rather than ordered
+ m->ordered_chapters[m->num_ordered_chapters] = chapter;
+ m->num_ordered_chapters++;
+
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Chapter %u from %02d:%02d:%02d."
+ "%03d to %02d:%02d:%02d.%03d, %s\n",
+ cid,
+ (int) (start / 60 / 60 / 1000),
+ (int) ((start / 60 / 1000) % 60),
+ (int) ((start / 1000) % 60),
+ (int) (start % 1000),
+ (int) (end / 60 / 60 / 1000),
+ (int) ((end / 60 / 1000) % 60),
+ (int) ((end / 1000) % 60),
+ (int) (end % 1000), name);
+
+ free(name);
+ return bytes_read;
+}
- case MATROSKA_ID_CHAPTERTIMEEND:
- end = ebml_read_uint (s, &l) / 1000000;
- break;
+static int demux_mkv_read_chapters(struct demuxer *demuxer)
+{
+ stream_t *s = demuxer->stream;
+ uint64_t length, l;
+ int i;
+ uint32_t id;
- case MATROSKA_ID_CHAPTERDISPLAY:
- {
- uint64_t len;
- int i;
-
- len = ebml_read_length (s, &i);
- l = len + i;
- while (len > 0)
- {
- uint64_t l;
- int il;
-
- switch (ebml_read_id (s, &il))
- {
- case MATROSKA_ID_CHAPSTRING:
- name = ebml_read_utf8 (s, &l);
- break;
- default:
- ebml_read_skip (s, &l);
- break;
- }
- len -= l + il;
- }
- }
- break;
+ if (demuxer->chapters) {
+ ebml_read_skip(s, NULL);
+ return 0;
+ }
- default:
- ebml_read_skip (s, &l);
- break;
- }
- len -= l + il;
- }
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n");
+ length = ebml_read_length(s, NULL);
- if (!name)
- name = strdup("(unnamed)");
-
- cid = demuxer_add_chapter(demuxer, name, start, end);
-
- mp_msg(MSGT_DEMUX, MSGL_V,
- "[mkv] Chapter %u from %02d:%02d:%02d."
- "%03d to %02d:%02d:%02d.%03d, %s\n",
- cid,
- (int) (start / 60 / 60 / 1000),
- (int) ((start / 60 / 1000) % 60),
- (int) ((start / 1000) % 60),
- (int) (start % 1000),
- (int) (end / 60 / 60 / 1000),
- (int) ((end / 60 / 1000) % 60),
- (int) ((end / 1000) % 60),
- (int) (end % 1000), name);
-
- free(name);
- break;
- }
+ bool have_edition = false;
+ while (length > 0) {
+ id = ebml_read_id(s, &i);
+ length -= i;
+ switch (id) {
+ case MATROSKA_ID_EDITIONENTRY:
+ if (have_edition) {
+ mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Multiple edition entries"
+ " - ignoring all but first!\n");
+ ebml_read_skip(s, &l);
+ length -= l;
+ break;
+ }
+ have_edition = true;
+ uint64_t editionlen = ebml_read_length(s, &i);
+ length -= editionlen + i;
+ bool ordered = false;
+ while (editionlen > 0) {
+ id = ebml_read_id(s, &i);
+ editionlen -= i;
+ switch (id) {
+ case MATROSKA_ID_CHAPTERATOM:
+ l = read_one_chapter(demuxer, s);
+ break;
+ case MATROSKA_ID_EDITIONFLAGORDERED:
+ ordered = ebml_read_uint(s, &l);
+ mp_msg(MSGT_DEMUX, MSGL_V,
+ "[mkv] Ordered chapter flag: %d\n", ordered);
+ break;
- default:
- ebml_read_skip (s, &l);
+ default:
+ ebml_read_skip(s, &l);
break;
- }
- len -= l + il;
- }
+ }
+ editionlen -= l;
+ }
+ if (!ordered) {
+ // The chapters should be interpreted as normal ones,
+ // so undo the addition of this information.
+ talloc_free(demuxer->matroska_data.ordered_chapters);
+ demuxer->matroska_data.ordered_chapters = NULL;
+ demuxer->matroska_data.num_ordered_chapters = 0;
+ }
break;
- }
default:
- ebml_read_skip (s, &l);
- break;
+ ebml_read_skip(s, &l);
+ length -= l;
+ break;
}
-
- length -= l + il;
}
- mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing chapters ] ---------\n");
- return 0;
+ mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing chapters ] ---------\n");
+ return 0;
}
static int
@@ -1514,6 +1561,7 @@ static const videocodec_info_t vinfo[] = {
static int
demux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid)
{
+ struct MPOpts *opts = demuxer->opts;
BITMAPINFOHEADER *bih;
void *ImageDesc = NULL;
sh_video_t *sh_v;
@@ -1624,7 +1672,7 @@ demux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid)
bih = realloc (bih, bih->biSize);
memcpy (bih + 1, track->private_data, track->private_size);
}
- track->reorder_timecodes = user_correct_pts == 0;
+ track->reorder_timecodes = opts->user_correct_pts == 0;
if (!vi->id) {
mp_msg (MSGT_DEMUX,MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownCodecID,
track->codec_id, track->tnum);
@@ -1950,13 +1998,13 @@ demux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid)
if (track->a_formattag == mmioFOURCC('f', 'L', 'a', 'C'))
{
- ptr = (unsigned char *)track->private_data;
+ ptr = track->private_data;
size = track->private_size;
}
else
{
sh_a->format = mmioFOURCC('f', 'L', 'a', 'C');
- ptr = (unsigned char *) track->private_data
+ ptr = track->private_data
+ sizeof (WAVEFORMATEX);
size = track->private_size - sizeof (WAVEFORMATEX);
}
@@ -2026,8 +2074,6 @@ demux_mkv_open_sub (demuxer_t *demuxer, mkv_track_t *track, int sid)
return 0;
}
-static void demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags);
-
static int
demux_mkv_open (demuxer_t *demuxer)
{
@@ -2117,8 +2163,6 @@ demux_mkv_open (demuxer_t *demuxer)
uint64_t num = ebml_read_uint (s, NULL);
if (num == EBML_UINT_INVALID)
return 0;
- mkv_d->first_tc = num * mkv_d->tc_scale / 1000000.0;
- mkv_d->has_first_tc = 1;
}
stream_seek (s, p - 4);
cont = 1;
@@ -2222,22 +2266,6 @@ demux_mkv_open (demuxer_t *demuxer)
}
}
- if (demuxer->chapters)
- {
- for (i=0; i < (int)demuxer->num_chapters; i++)
- {
- demuxer->chapters[i].start -= mkv_d->first_tc;
- demuxer->chapters[i].end -= mkv_d->first_tc;
- }
- if (dvd_last_chapter > 0 && dvd_last_chapter <= demuxer->num_chapters)
- {
- if (demuxer->chapters[dvd_last_chapter-1].end != 0)
- mkv_d->stop_timecode = demuxer->chapters[dvd_last_chapter-1].end;
- else if (dvd_last_chapter + 1 <= demuxer->num_chapters)
- mkv_d->stop_timecode = demuxer->chapters[dvd_last_chapter].start;
- }
- }
-
if (s->end_pos == 0 || (mkv_d->indexes == NULL && index_mode < 0))
demuxer->seekable = 0;
else
@@ -2247,6 +2275,8 @@ demux_mkv_open (demuxer_t *demuxer)
demuxer->seekable = 1;
}
+ demuxer->accurate_seek = true;
+
return DEMUXER_TYPE_MATROSKA;
}
@@ -2625,13 +2655,9 @@ handle_block (demuxer_t *demuxer, uint8_t *block, uint64_t length,
return 0;
block += old_length - length;
- tc = ((time*mkv_d->tc_scale+mkv_d->cluster_tc) /1000000.0 - mkv_d->first_tc);
+ tc = ((time*mkv_d->tc_scale+mkv_d->cluster_tc) /1000000.0);
if (tc < 0)
tc = 0;
- if (mkv_d->stop_timecode > 0 && tc > mkv_d->stop_timecode) {
- free(lace_size);
- return -1;
- }
current_pts = tc / 1000.0;
for (i=0; i<mkv_d->num_tracks; i++)
@@ -2854,11 +2880,6 @@ demux_mkv_fill_buffer (demuxer_t *demuxer, demux_stream_t *ds)
uint64_t num = ebml_read_uint (s, &l);
if (num == EBML_UINT_INVALID)
return 0;
- if (!mkv_d->has_first_tc)
- {
- mkv_d->first_tc = num * mkv_d->tc_scale / 1000000.0;
- mkv_d->has_first_tc = 1;
- }
mkv_d->cluster_tc = num * mkv_d->tc_scale;
break;
}
@@ -2914,6 +2935,16 @@ demux_mkv_fill_buffer (demuxer_t *demuxer, demux_stream_t *ds)
static void
demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags)
{
+ if (!(flags & (SEEK_BACKWARD | SEEK_FORWARD))) {
+ if (flags & SEEK_ABSOLUTE || rel_seek_secs < 0)
+ flags |= SEEK_BACKWARD;
+ else
+ flags |= SEEK_FORWARD;
+ }
+ // Adjust the target a little bit to catch cases where the target position
+ // specifies a keyframe with high, but not perfect, precision.
+ rel_seek_secs += flags & SEEK_FORWARD ? -0.001 : 0.001;
+
free_cached_dps (demuxer);
if (!(flags & SEEK_FACTOR)) /* time in secs */
{
@@ -2968,12 +2999,12 @@ demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int
for (i=0; i < mkv_d->num_cluster_pos; i++)
{
diff = mkv_d->cluster_positions[i] - target_filepos;
- if (rel_seek_secs < 0 && diff < 0 && -diff < min_diff)
+ if (flags & SEEK_BACKWARD && diff < 0 && -diff < min_diff)
{
cluster_pos = mkv_d->cluster_positions[i];
min_diff = -diff;
}
- else if (rel_seek_secs > 0
+ else if (flags & SEEK_FORWARD
&& (diff < 0 ? -1 * diff : diff) < min_diff)
{
cluster_pos = mkv_d->cluster_positions[i];
@@ -2994,17 +3025,17 @@ demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int
for (i=0; i < mkv_d->num_indexes; i++)
if (mkv_d->indexes[i].tnum == seek_id)
{
- diff = target_timecode + mkv_d->first_tc -
+ diff = target_timecode -
(int64_t) mkv_d->indexes[i].timecode * mkv_d->tc_scale / 1000000.0;
- if ((flags & SEEK_ABSOLUTE || target_timecode <= mkv_d->last_pts*1000)) {
- // Absolute seek or seek backward: find the last index
- // position before target time
+ if (flags & SEEK_BACKWARD) {
+ // Seek backward: find the last index position
+ // before target time
if (diff < 0 || diff >= min_diff)
continue;
}
else {
- // Relative seek forward: find the first index position
+ // Seek forward: find the first index position
// after target time. If no such index exists, find last
// position between current position and target time.
if (diff <= 0) {
@@ -3028,8 +3059,10 @@ demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int
if (demuxer->video->id >= 0)
mkv_d->v_skip_to_keyframe = 1;
- if (rel_seek_secs > 0.0)
+ if (flags & SEEK_FORWARD)
mkv_d->skip_to_timecode = target_timecode;
+ else
+ mkv_d->skip_to_timecode = 0;
mkv_d->a_skip_to_keyframe = 1;
demux_mkv_fill_buffer(demuxer, NULL);
diff --git a/libmpdemux/demux_mov.c b/libmpdemux/demux_mov.c
index bcb249b732..ecc23f2cc5 100644
--- a/libmpdemux/demux_mov.c
+++ b/libmpdemux/demux_mov.c
@@ -144,7 +144,7 @@ typedef struct {
void* desc; // image/sound/etc description (pointer to ImageDescription etc)
} mov_track_t;
-void mov_build_index(mov_track_t* trak,int timescale){
+static void mov_build_index(mov_track_t* trak,int timescale){
int i,j,s;
int last=trak->chunks_size;
unsigned int pts=0;
@@ -1917,6 +1917,7 @@ static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id,
}
static demuxer_t* mov_read_header(demuxer_t* demuxer){
+ struct MPOpts *opts = demuxer->opts;
mov_priv_t* priv=demuxer->priv;
int t_no;
int best_a_id=-1, best_a_len=0;
@@ -1992,7 +1993,7 @@ static demuxer_t* mov_read_header(demuxer_t* demuxer){
demuxer->video->id = t_no;
s = new_ds_stream(demuxer->video);
- od = demux_open(s, DEMUXER_TYPE_MPEG_PS, -1, -1, -1, NULL);
+ od = demux_open(opts, s, DEMUXER_TYPE_MPEG_PS, -1, -1, -1, NULL);
if(od) return new_demuxers_demuxer(od, od, od);
demuxer->video->id = -2; //new linked demuxer couldn't be allocated
break;
diff --git a/libmpdemux/demux_mpg.c b/libmpdemux/demux_mpg.c
index 8edb6e7a1e..489821f878 100644
--- a/libmpdemux/demux_mpg.c
+++ b/libmpdemux/demux_mpg.c
@@ -794,7 +794,7 @@ static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
return 1;
}
-int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
+static int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
unsigned int head=0;
int skipped=0;
int max_packs=256; // 512kbyte
@@ -881,7 +881,7 @@ do{
void skip_audio_frame(sh_audio_t *sh_audio);
-void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,float audio_delay, int flags){
+static void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,float audio_delay, int flags){
demux_stream_t *d_audio=demuxer->audio;
demux_stream_t *d_video=demuxer->video;
sh_audio_t *sh_audio=d_audio->sh;
@@ -987,7 +987,7 @@ void demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,float audio_delay, in
}
}
-int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){
+static int demux_mpg_control(demuxer_t *demuxer,int cmd, void *arg){
mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
switch(cmd) {
diff --git a/libmpdemux/demux_nemesi.c b/libmpdemux/demux_nemesi.c
index c1ed7f1089..704f14cf81 100644
--- a/libmpdemux/demux_nemesi.c
+++ b/libmpdemux/demux_nemesi.c
@@ -455,7 +455,7 @@ static void demux_seek_rtp(demuxer_t *demuxer, float rel_seek_secs,
mp_msg(MSGT_DEMUX, MSGL_ERR, "Unsupported seek type\n");
}
-static int demux_rtp_control(struct demuxer_st *demuxer, int cmd, void *arg)
+static int demux_rtp_control(struct demuxer *demuxer, int cmd, void *arg)
{
Nemesi_DemuxerStreamData * ndsd = demuxer->priv;
rtsp_ctrl * ctl = ndsd->rtsp;
diff --git a/libmpdemux/demux_ogg.c b/libmpdemux/demux_ogg.c
index 2561714517..013bff5a76 100644
--- a/libmpdemux/demux_ogg.c
+++ b/libmpdemux/demux_ogg.c
@@ -8,6 +8,7 @@
#include <math.h>
#include <inttypes.h>
+#include "options.h"
#include "mp_msg.h"
#include "help_mp.h"
#include "stream/stream.h"
@@ -146,7 +147,6 @@ typedef struct ogg_demuxer {
#define PACKET_IS_SYNCPOINT 0x08
extern char *dvdsub_lang, *audio_lang;
-extern int dvdsub_id;
//-------- subtitle support - should be moved to decoder layer, and queue
// - subtitles up in demuxer buffer...
@@ -158,7 +158,7 @@ extern int dvdsub_id;
static subtitle ogg_sub;
//FILE* subout;
-void demux_ogg_add_sub (ogg_stream_t* os,ogg_packet* pack) {
+static void demux_ogg_add_sub (ogg_stream_t* os,ogg_packet* pack) {
int lcv;
char *packet = pack->packet;
@@ -395,7 +395,7 @@ static void demux_ogg_check_comments(demuxer_t *d, ogg_stream_t *os, int id, vor
if (os->text && d->sub->id < 0 && demux_ogg_check_lang(val, dvdsub_lang))
{
d->sub->id = index;
- dvdsub_id = index;
+ d->opts->sub_id = index;
mp_msg(MSGT_DEMUX, MSGL_V, "Ogg demuxer: Displaying subtitle stream id %d which matched -slang %s\n", id, val);
}
else
@@ -491,7 +491,7 @@ static int demux_ogg_add_packet(demux_stream_t* ds,ogg_stream_t* os,int id,ogg_p
/// if -forceidx build a table of all syncpoints to make seeking easier
/// otherwise try to get at least the final_granulepos
-void demux_ogg_scan_stream(demuxer_t* demuxer) {
+static void demux_ogg_scan_stream(demuxer_t* demuxer) {
ogg_demuxer_t* ogg_d = demuxer->priv;
stream_t *s = demuxer->stream;
ogg_sync_state* sync = &ogg_d->sync;
@@ -1216,6 +1216,7 @@ static int demux_ogg_fill_buffer(demuxer_t *d, demux_stream_t *dsds) {
/// For avi with Ogg audio stream we have to create an ogg demuxer for this
// stream, then we join the avi and ogg demuxer with a demuxers demuxer
demuxer_t* init_avi_with_ogg(demuxer_t* demuxer) {
+ struct MPOpts *opts = demuxer->opts;
demuxer_t *od;
ogg_demuxer_t *ogg_d;
stream_t* s;
@@ -1277,7 +1278,7 @@ demuxer_t* init_avi_with_ogg(demuxer_t* demuxer) {
// Create the ds_stream and the ogg demuxer
s = new_ds_stream(demuxer->audio);
- od = new_demuxer(s,DEMUXER_TYPE_OGG,0,-2,-2,NULL);
+ od = new_demuxer(opts, s,DEMUXER_TYPE_OGG,0,-2,-2,NULL);
/// Add the header packets in the ogg demuxer audio stream
for (i = 0; i < 3; i++) {
diff --git a/libmpdemux/demux_pva.c b/libmpdemux/demux_pva.c
index 2ff8be63e3..af16f1c3da 100644
--- a/libmpdemux/demux_pva.c
+++ b/libmpdemux/demux_pva.c
@@ -62,7 +62,7 @@ typedef struct {
-int pva_sync(demuxer_t * demuxer)
+static int pva_sync(demuxer_t * demuxer)
{
uint8_t buffer[5]={0,0,0,0,0};
int count;
diff --git a/libmpdemux/demux_rtp.cpp b/libmpdemux/demux_rtp.cpp
index aaa525fc4c..fd6dffa0e3 100644
--- a/libmpdemux/demux_rtp.cpp
+++ b/libmpdemux/demux_rtp.cpp
@@ -8,6 +8,7 @@ extern "C" {
#endif
#include "demux_rtp.h"
#include "stheader.h"
+#include "options.h"
}
#include "demux_rtp_internal.h"
@@ -95,8 +96,8 @@ static char* openURL_sip(SIPClient* client, char const* url) {
int rtspStreamOverTCP = 0;
extern int rtsp_port;
-extern "C" int audio_id, video_id, dvdsub_id;
extern "C" demuxer_t* demux_open_rtp(demuxer_t* demuxer) {
+ struct MPOpts *opts = demuxer->opts;
Boolean success = False;
do {
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
@@ -256,8 +257,9 @@ extern "C" demuxer_t* demux_open_rtp(demuxer_t* demuxer) {
// code to recognize this:
if (demux_is_multiplexed_rtp_stream(demuxer)) {
stream_t* s = new_ds_stream(demuxer->video);
- demuxer_t* od = demux_open(s, DEMUXER_TYPE_UNKNOWN,
- audio_id, video_id, dvdsub_id, NULL);
+ demuxer_t* od = demux_open(opts, s, DEMUXER_TYPE_UNKNOWN,
+ opts->audio_id, opts->video_id, opts->sub_id,
+ NULL);
demuxer = new_demuxers_demuxer(od, od, od);
}
@@ -637,7 +639,7 @@ demux_packet_t* ReadBufferQueue::getPendingBuffer() {
return dp;
}
-static int demux_rtp_control(struct demuxer_st *demuxer, int cmd, void *arg) {
+static int demux_rtp_control(struct demuxer *demuxer, int cmd, void *arg) {
double endpts = ((RTPState*)demuxer->priv)->mediaSession->playEndTime();
switch(cmd) {
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index e360572d7f..f84c3d8b87 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -9,6 +9,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"
@@ -166,7 +168,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;
@@ -212,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;
@@ -229,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,
@@ -241,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) {
@@ -257,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);
@@ -286,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])
+ if (demuxer->a_streams[id]) {
mp_msg(MSGT_DEMUXER, MSGL_WARN, MSGTR_AudioStreamRedefined, id);
- else {
- sh_audio_t *sh = calloc(1, sizeof(sh_audio_t));
+ } else {
mp_msg(MSGT_DEMUXER, MSGL_V, MSGTR_FoundAudioStream, id);
+ sh_audio_t *sh = calloc(1, sizeof(sh_audio_t));
demuxer->a_streams[id] = sh;
sh->aid = aid;
sh->ds = demuxer->audio;
@@ -299,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];
@@ -326,11 +328,12 @@ sh_video_t *new_sh_video_vid(demuxer_t *demuxer, int id, int vid)
if (demuxer->v_streams[id])
mp_msg(MSGT_DEMUXER, MSGL_WARN, MSGTR_VideoStreamRedefined, id);
else {
- sh_video_t *sh = calloc(1, sizeof(sh_video_t));
mp_msg(MSGT_DEMUXER, MSGL_V, MSGTR_FoundVideoStream, 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];
@@ -387,7 +390,7 @@ void free_demuxer(demuxer_t *demuxer)
}
free(demuxer->attachments);
}
- free(demuxer);
+ talloc_free(demuxer);
}
@@ -492,6 +495,14 @@ 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;
}
if (demux->audio->packs >= MAX_PACKS
@@ -747,9 +758,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
@@ -763,9 +771,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;
@@ -778,7 +787,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);
@@ -800,8 +809,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
@@ -812,7 +822,7 @@ 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) {
@@ -831,7 +841,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)
@@ -853,8 +863,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...
@@ -865,7 +876,7 @@ 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) {
@@ -884,7 +895,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)
@@ -942,8 +953,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;
@@ -1001,7 +1013,7 @@ demuxer_t *demux_open(stream_t *vs, int file_format, int audio_id,
}
}
- 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) {
@@ -1012,7 +1024,7 @@ 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);
@@ -1025,7 +1037,8 @@ 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) {
@@ -1044,10 +1057,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;
}
@@ -1080,9 +1094,8 @@ int demux_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay,
mp_msg(MSGT_SEEK, MSGL_WARN, MSGTR_CantSeekFile);
return 0;
}
-
- demux_flush(demuxer);
// clear demux buffers:
+ demux_flush(demuxer);
if (sh_audio)
sh_audio->a_buffer_len = 0;
@@ -1141,8 +1154,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 *));
@@ -1318,31 +1331,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,
@@ -1362,60 +1363,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;
}
}
diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h
index 6a1e26dd02..544afe8add 100644
--- a/libmpdemux/demuxer.h
+++ b/libmpdemux/demuxer.h
@@ -5,11 +5,11 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
#include "stream/stream.h"
-#ifdef CONFIG_ASS
-#include "libass/ass_types.h"
-#endif
+
+struct MPOpts;
#ifdef HAVE_BUILTIN_EXPECT
#define likely(x) __builtin_expect ((x) != 0, 1)
@@ -20,7 +20,7 @@
#endif
#define MAX_PACKS 4096
-#define MAX_PACK_BYTES 0x2000000
+#define MAX_PACK_BYTES 0x8000000 // 128 MiB
#define DEMUXER_TYPE_UNKNOWN 0
#define DEMUXER_TYPE_MPEG_ES 1
@@ -96,11 +96,13 @@
#define SEEK_ABSOLUTE (1 << 0)
#define SEEK_FACTOR (1 << 1)
+#define SEEK_FORWARD (1 << 2)
+#define SEEK_BACKWARD (1 << 3)
#define MP_INPUT_BUFFER_PADDING_SIZE 8
// Holds one packet/frame/whatever
-typedef struct demux_packet_st {
+typedef struct demux_packet {
int len;
double pts;
double endpts;
@@ -109,11 +111,11 @@ typedef struct demux_packet_st {
unsigned char* buffer;
int flags; // keyframe, etc
int refcount; //refcounter for the master packet, if 0, buffer can be free()d
- struct demux_packet_st* master; //pointer to the master packet if this one is a cloned one
- struct demux_packet_st* next;
+ struct demux_packet *master; //pointer to the master packet if this one is a cloned one
+ struct demux_packet *next;
} demux_packet_t;
-typedef struct {
+typedef struct demux_stream {
int buffer_pos; // current buffer position
int buffer_size; // current buffer size
unsigned char* buffer; // current buffer, never free() it, always use free_demux_packet(buffer_ref);
@@ -131,7 +133,7 @@ typedef struct {
demux_packet_t *last; // append new packets from input stream to here
demux_packet_t *current;// needed for refcounting of the buffer
int id; // stream ID (for multiple audio/video streams)
- struct demuxer_st *demuxer; // parent demuxer structure (stream handler)
+ struct demuxer *demuxer; // parent demuxer structure (stream handler)
// ---- asf -----
demux_packet_t *asf_packet; // read asf fragments here
int asf_seq;
@@ -141,7 +143,7 @@ typedef struct {
void* sh;
} demux_stream_t;
-typedef struct demuxer_info_st {
+typedef struct demuxer_info {
char *name;
char *author;
char *encoder;
@@ -153,15 +155,12 @@ typedef struct demuxer_info_st {
#define MAX_V_STREAMS 256
#define MAX_S_STREAMS 256
-struct demuxer_st;
-
-extern int correct_pts;
-extern int user_correct_pts;
+struct demuxer;
/**
* Demuxer description structure
*/
-typedef struct demuxers_desc_st {
+typedef struct demuxer_desc {
const char *info; ///< What is it (long name and/or description)
const char *name; ///< Demuxer name, used with -demuxer switch
const char *shortdesc; ///< Description printed at demuxer detection
@@ -172,26 +171,39 @@ typedef struct demuxers_desc_st {
int safe_check; ///< If 1 detection is safe and fast, do it before file extension check
/// Check if can demux the file, return DEMUXER_TYPE_xxx on success
- int (*check_file)(struct demuxer_st *demuxer); ///< Mandatory if safe_check == 1, else optional
+ int (*check_file)(struct demuxer *demuxer); ///< Mandatory if safe_check == 1, else optional
/// Get packets from file, return 0 on eof
- int (*fill_buffer)(struct demuxer_st *demuxer, demux_stream_t *ds); ///< Mandatory
+ int (*fill_buffer)(struct demuxer *demuxer, demux_stream_t *ds); ///< Mandatory
/// Open the demuxer, return demuxer on success, NULL on failure
- struct demuxer_st* (*open)(struct demuxer_st *demuxer); ///< Optional
+ struct demuxer* (*open)(struct demuxer *demuxer); ///< Optional
/// Close the demuxer
- void (*close)(struct demuxer_st *demuxer); ///< Optional
+ void (*close)(struct demuxer *demuxer); ///< Optional
// Seek
- void (*seek)(struct demuxer_st *demuxer, float rel_seek_secs, float audio_delay, int flags); ///< Optional
+ void (*seek)(struct demuxer *demuxer, float rel_seek_secs, float audio_delay, int flags); ///< Optional
// Control
- int (*control)(struct demuxer_st *demuxer, int cmd, void *arg); ///< Optional
+ int (*control)(struct demuxer *demuxer, int cmd, void *arg); ///< Optional
} demuxer_desc_t;
-typedef struct demux_chapter_s
+typedef struct demux_chapter
{
uint64_t start, end;
char* name;
} demux_chapter_t;
-typedef struct demux_attachment_s
+struct matroska_data {
+ unsigned char segment_uid[16];
+ // Ordered chapter information if any
+ struct matroska_chapter {
+ uint64_t start;
+ uint64_t end;
+ bool has_segment_uid;
+ unsigned char segment_uid[16];
+ char *name;
+ } *ordered_chapters;
+ int num_ordered_chapters;
+};
+
+typedef struct demux_attachment
{
char* name;
char* type;
@@ -199,7 +211,7 @@ typedef struct demux_attachment_s
unsigned int data_size;
} demux_attachment_t;
-typedef struct demuxer_st {
+typedef struct demuxer {
const demuxer_desc_t *desc; ///< Demuxer description structure
off_t filepos; // input stream current pos.
off_t movi_start;
@@ -212,24 +224,30 @@ typedef struct demuxer_st {
int type; // demuxer type: mpeg PS, mpeg ES, avi, avi-ni, avi-nini, asf
int file_format; // file format: mpeg/avi/asf
int seekable; // flag
+ /* Set if using absolute seeks for small movements is OK (no pts resets
+ * that would make pts ambigious, preferably supports back/forward flags */
+ bool accurate_seek;
//
demux_stream_t *audio; // audio buffer/demuxer
demux_stream_t *video; // video buffer/demuxer
demux_stream_t *sub; // dvd subtitle buffer/demuxer
// stream headers:
- void* a_streams[MAX_A_STREAMS]; // audio streams (sh_audio_t)
- void* v_streams[MAX_V_STREAMS]; // video sterams (sh_video_t)
- void *s_streams[MAX_S_STREAMS]; // dvd subtitles (flag)
+ struct sh_audio *a_streams[MAX_A_STREAMS];
+ struct sh_video *v_streams[MAX_V_STREAMS];
+ struct sh_sub *s_streams[MAX_S_STREAMS];
demux_chapter_t* chapters;
int num_chapters;
-
+
demux_attachment_t* attachments;
int num_attachments;
+ struct matroska_data matroska_data;
+
void* priv; // fileformat-dependent data
char** info;
+ struct MPOpts *opts;
} demuxer_t;
typedef struct {
@@ -311,8 +329,8 @@ static inline void *realloc_struct(void *ptr, size_t nmemb, size_t size) {
return realloc(ptr, nmemb * size);
}
-demux_stream_t* new_demuxer_stream(struct demuxer_st *demuxer,int id);
-demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename);
+demux_stream_t* new_demuxer_stream(struct demuxer *demuxer,int id);
+demuxer_t* new_demuxer(struct MPOpts *opts, stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename);
void free_demuxer_stream(demux_stream_t *ds);
void free_demuxer(demuxer_t *demuxer);
@@ -375,7 +393,7 @@ static inline int avi_stream_id(unsigned int id){
return a*10+b;
}
-demuxer_t* demux_open(stream_t *stream,int file_format,int aid,int vid,int sid,char* filename);
+demuxer_t* demux_open(struct MPOpts *opts, stream_t *stream,int file_format,int aid,int vid,int sid,char* filename);
void demux_flush(demuxer_t *demuxer);
int demux_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags);
demuxer_t* new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd);
@@ -414,7 +432,8 @@ int demuxer_add_attachment(demuxer_t* demuxer, const char* name,
const char* type, const void* data, size_t size);
int demuxer_add_chapter(demuxer_t* demuxer, const char* name, uint64_t start, uint64_t end);
-int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, int mode, float *seek_pts, int *num_chapters, char **chapter_name);
+int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, double *seek_pts,
+ char **chapter_name);
/// Get current chapter index if available.
int demuxer_get_current_chapter(demuxer_t *demuxer);
diff --git a/libmpdemux/ebml.h b/libmpdemux/ebml.h
index c4d7256d91..345f08b46a 100644
--- a/libmpdemux/ebml.h
+++ b/libmpdemux/ebml.h
@@ -54,6 +54,7 @@
#define MATROSKA_ID_WRITINGAPP 0x5741
#define MATROSKA_ID_MUXINGAPP 0x4D80
#define MATROSKA_ID_DATEUTC 0x4461
+#define MATROSKA_ID_SEGMENTUID 0x73A4
/* ID in the tracks master */
#define MATROSKA_ID_TRACKENTRY 0xAE
@@ -126,11 +127,13 @@
/* IDs in the chapters master */
#define MATROSKA_ID_EDITIONENTRY 0x45B9
+#define MATROSKA_ID_EDITIONFLAGORDERED 0x45DD
#define MATROSKA_ID_CHAPTERATOM 0xB6
#define MATROSKA_ID_CHAPTERTIMESTART 0x91
#define MATROSKA_ID_CHAPTERTIMEEND 0x92
#define MATROSKA_ID_CHAPTERDISPLAY 0x80
#define MATROSKA_ID_CHAPSTRING 0x85
+#define MATROSKA_ID_CHAPTERSEGMENTUID 0x6E67
/* IDs in the cluster master */
#define MATROSKA_ID_CLUSTERTIMECODE 0xE7
diff --git a/libmpdemux/mp3_hdr.c b/libmpdemux/mp3_hdr.c
index cb59878466..da1826215c 100644
--- a/libmpdemux/mp3_hdr.c
+++ b/libmpdemux/mp3_hdr.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include "config.h"
+#include "mp3_hdr.h"
#include "mp_msg.h"
//----------------------- mp3 audio frame header parser -----------------------
@@ -19,7 +20,7 @@ static long freqs[9] = { 44100, 48000, 32000, // MPEG 1.0
22050, 24000, 16000, // MPEG 2.0
11025, 12000, 8000}; // MPEG 2.5
-int mp_mp3_get_lsf(unsigned char* hbuf){
+static int mp_mp3_get_lsf(unsigned char* hbuf){
unsigned long newhead =
hbuf[0] << 24 |
hbuf[1] << 16 |
diff --git a/libmpdemux/parse_mp4.c b/libmpdemux/parse_mp4.c
index f2a39abe6e..c9f9ff2e80 100644
--- a/libmpdemux/parse_mp4.c
+++ b/libmpdemux/parse_mp4.c
@@ -33,7 +33,7 @@
#define MP4_DL MSGL_V
#define freereturn(a,b) free(a); return b
-int mp4_read_descr_len(stream_t *s) {
+static int mp4_read_descr_len(stream_t *s) {
uint8_t b;
uint8_t numBytes = 0;
uint32_t length = 0;
diff --git a/libmpdemux/stheader.h b/libmpdemux/stheader.h
index 07ecfaeded..12a9144fc6 100644
--- a/libmpdemux/stheader.h
+++ b/libmpdemux/stheader.h
@@ -1,16 +1,18 @@
#ifndef MPLAYER_STHEADER_H
#define MPLAYER_STHEADER_H
-#include "demuxer.h"
#include "aviheader.h"
#include "ms_hdr.h"
+struct MPOpts;
+struct demuxer;
// Stream headers:
-typedef struct {
+typedef struct sh_audio {
+ struct MPOpts *opts;
int aid;
- demux_stream_t *ds;
- struct codecs_st *codec;
+ struct demux_stream *ds;
+ struct codecs *codec;
unsigned int format;
int initialized;
float stream_delay; // number of seconds stream should be delayed (according to dwStart or similar)
@@ -36,8 +38,8 @@ typedef struct {
int a_out_buffer_len;
int a_out_buffer_size;
// void* audio_out; // the audio_out handle, used for this audio stream
- struct af_stream_s *afilter; // the audio filter stream
- struct ad_functions_s* ad_driver;
+ struct af_stream *afilter; // the audio filter stream
+ struct ad_functions *ad_driver;
#ifdef CONFIG_DYNAMIC_PLUGINS
void *dec_handle;
#endif
@@ -54,10 +56,11 @@ typedef struct {
int default_track;
} sh_audio_t;
-typedef struct {
+typedef struct sh_video {
+ struct MPOpts *opts;
int vid;
- demux_stream_t *ds;
- struct codecs_st *codec;
+ struct demux_stream *ds;
+ struct codecs *codec;
unsigned int format;
int initialized;
float timer; // absolute time in video stream, since last start/seek
@@ -81,7 +84,9 @@ typedef struct {
int disp_w,disp_h; // display size (filled by fileformat parser)
// output driver/filters: (set by libmpcodecs core)
unsigned int outfmtidx;
- struct vf_instance_s *vfilter; // the video filter chain, used for this video stream
+ struct vf_instance *vfilter; // the video filter chain, used for this video stream
+ int output_flags; // query_format() results for output filters+vo
+ const struct vd_functions *vd_driver;
int vf_initialized;
#ifdef CONFIG_DYNAMIC_PLUGINS
void *dec_handle;
@@ -94,26 +99,25 @@ typedef struct {
void* context; // codec-specific stuff (usually HANDLE or struct pointer)
} sh_video_t;
-typedef struct {
+typedef struct sh_sub {
+ struct MPOpts *opts;
int sid;
char type; // t = text, v = VobSub, a = SSA/ASS
unsigned char* extradata; // extra header data passed from demuxer
int extradata_len;
-#ifdef CONFIG_ASS
- ass_track_t* ass_track; // for SSA/ASS streams (type == 'a')
-#endif
+ struct ass_track_s *ass_track; // for SSA/ASS streams (type == 'a')
char* lang; // track language
int default_track;
} sh_sub_t;
// demuxer.c:
#define new_sh_audio(d, i) new_sh_audio_aid(d, i, i)
-sh_audio_t* new_sh_audio_aid(demuxer_t *demuxer,int id,int aid);
+sh_audio_t* new_sh_audio_aid(struct demuxer *demuxer,int id,int aid);
#define new_sh_video(d, i) new_sh_video_vid(d, i, i)
-sh_video_t* new_sh_video_vid(demuxer_t *demuxer,int id,int vid);
+sh_video_t* new_sh_video_vid(struct demuxer *demuxer,int id,int vid);
#define new_sh_sub(d, i) new_sh_sub_sid(d, i, i)
-sh_sub_t *new_sh_sub_sid(demuxer_t *demuxer, int id, int sid);
-void free_sh_audio(demuxer_t *demuxer, int id);
+sh_sub_t *new_sh_sub_sid(struct demuxer *demuxer, int id, int sid);
+void free_sh_audio(struct demuxer *demuxer, int id);
void free_sh_video(sh_video_t *sh);
// video.c: