2009-05-08 21:51:13 +00:00
|
|
|
/*
|
|
|
|
* This file is part of MPlayer.
|
|
|
|
*
|
|
|
|
* MPlayer is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* MPlayer is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
2008-02-22 09:09:46 +00:00
|
|
|
#ifndef MPLAYER_DEMUXER_H
|
|
|
|
#define MPLAYER_DEMUXER_H
|
2001-04-23 16:12:21 +00:00
|
|
|
|
2008-06-17 09:09:36 +00:00
|
|
|
#include <sys/types.h>
|
2008-03-05 23:32:01 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2009-03-16 21:30:48 +00:00
|
|
|
#include <stdbool.h>
|
2008-03-05 23:32:01 +00:00
|
|
|
|
2014-08-29 10:09:04 +00:00
|
|
|
#include "misc/bstr.h"
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/common.h"
|
2014-04-13 12:01:55 +00:00
|
|
|
#include "common/tags.h"
|
2013-11-18 17:46:44 +00:00
|
|
|
#include "packet.h"
|
2012-08-19 16:01:30 +00:00
|
|
|
#include "stheader.h"
|
2006-07-07 18:26:51 +00:00
|
|
|
|
2014-07-16 20:40:21 +00:00
|
|
|
// Maximum total size of packets queued - if larger, no new packets are read,
|
|
|
|
// and the demuxer pretends EOF was reached.
|
|
|
|
#define MAX_PACKS 16000
|
|
|
|
#define MAX_PACK_BYTES (400 * 1024 * 1024)
|
2001-04-23 16:12:21 +00:00
|
|
|
|
2011-02-11 17:52:44 +00:00
|
|
|
enum demuxer_type {
|
2013-07-12 19:58:11 +00:00
|
|
|
DEMUXER_TYPE_GENERIC = 0,
|
2011-02-11 17:52:44 +00:00
|
|
|
DEMUXER_TYPE_MATROSKA,
|
EDL: add support for new EDL file format
The timeline code previously added to support Matroska ordered
chapters allows constructing a playback timeline from segments picked
from multiple source files. Add support for a new EDL format to make
this machinery available for use with file formats other than Matroska
and in a manner easier to use than creating files with ordered
chapters.
Unlike the old -edl option which specifies an additional file with
edits to apply to the video file given as the main argument, the new
EDL format is used by giving only the EDL file as the file to play;
that file then contains the filename(s) to use as source files where
actual video segments come from. Filename paths in the EDL file are
ignored. Currently the source files are only searched for in the
directory of the EDL file; support for a search path option will
likely be added in the future.
Format of the EDL files
The first line in the file must be "mplayer EDL file, version 2".
The rest of the lines belong to one of these classes:
1) lines specifying source files
2) empty lines
3) lines specifying timeline segments.
Lines beginning with '<' specify source files. These lines first
contain an identifier used to refer to the source file later, then the
filename separated by whitespace. The identifier must start with a
letter. Filenames that start or end with whitespace or contain
newlines are not supported.
On other lines '#' characters delimit comments. Lines that contain
only whitespace after comments have been removed are ignored.
Timeline segments must appear in the file in chronological order. Each
segment has the following information associated with it:
- duration
- output start time
- output end time (= output start time + duration)
- source id (specifies the file the content of the segment comes from)
- source start time (timestamp in the source file)
- source end time (= source start time + duration)
The output timestamps must form a continuous timeline from 0 to the
end of the last segment, such that each new segment starts from the
time the previous one ends at. Source files and times may change
arbitrarily between segments.
The general format for lines specifying timeline segments is
[output time info] source_id [source time info]
source_id must be an identifier defined on a '<' line. Both the time
info parts consists of zero or more of the following elements:
1) timestamp
2) -timestamp
3) +duration
4) *
5) -*
, where "timestamp" and "duration" are decimal numbers (computations
are done with nanosecond precision). Whitespace around "+" and "-" is
optional. 1) and 2) specify start and end time of the segment on
output or source side. 3) specifies duration; the semantics are the
same whether this appears on output or source side. 4) and 5) are
ignored on the output side (they're always implicitly assumed). On the
source side 4) specifies that the segment starts where the previous
segment _using this source_ ended; if there was no previous segment
time 0 is used. 5) specifies that the segment ends where the next
segment using this source starts.
Redundant information may be omitted. It will be filled in using the
following rules:
- output start for first segment is 0
- two of [output start, output end, duration] imply third
- two of [source start, source end, duration] imply third
- output start = output end of previous segment
- output end = output start of next segment
- if "*", source start = source end of earlier segment
- if "-*", source end = source start of a later segment
As a special rule, a last zero-duration segment without a source
specification may appear. This will produce no corresponding segment
in the resulting timeline, but can be used as syntax to specify the
end time of the timeline (with effect equal to adding -time on the
previous line).
Examples:
----- begin -----
mplayer EDL file, version 2
< id1 filename
0 id1 123
100 id1 456
200 id1 789
300
----- end -----
All segments come from the source file "filename". First segment
(output time 0-100) comes from time 123-223, second 456-556, third
789-889.
----- begin -----
mplayer EDL file, version 2
< f filename
f 60-120
f 600-660
f 30- 90
----- end -----
Play first seconds 60-120 from the file, then 600-660, then 30-90.
----- begin -----
mplayer EDL file, version 2
< id1 filename1
< id2 filename2
+10 id1 *
+10 id2 *
+10 id1 *
+10 id2 *
+10 id1 *
+10 id2 *
----- end -----
This plays time 0-10 from filename1, then 0-10 from filename1, then
10-20 from filename1, then 10-20 from filename2, then 20-30 from
filename1, then 20-30 from filename2.
----- begin -----
mplayer EDL file, version 2
< t1 filename1
< t2 filename2
t1 * +2 # segment 1
+2 t2 100 # segment 2
t1 * # segment 3
t2 *-* # segment 4
t1 3 -* # segment 5
+0.111111 t2 102.5 # segment 6
7.37 t1 5 +1 # segment 7
----- end -----
This rather pathological example illustrates the rules for filling in
implied data. All the values can be determined by recursively applying
the rules given above, and the full end result is this:
+2 0-2 t1 0-2 # segment 1
+2 2-4 t2 100-102 # segment 2
+0.758889 4-4.758889 t1 2-2.758889 # segment 3
+0.5 4.4758889-5.258889 t2 102-102.5 # segment 4
+2 5.258889-7.258889 t1 3-5 # segment 5
+0.111111 7.258889-7.37 t2 102.5-102.611111 # segment 6
+1 7.37-8.37 t1 5-6 # segment 7
2011-02-14 11:05:35 +00:00
|
|
|
DEMUXER_TYPE_EDL,
|
2012-01-01 16:45:24 +00:00
|
|
|
DEMUXER_TYPE_CUE,
|
2011-02-11 17:52:44 +00:00
|
|
|
};
|
2002-02-21 13:14:52 +00:00
|
|
|
|
2002-11-16 03:42:14 +00:00
|
|
|
// DEMUXER control commands/answers
|
|
|
|
#define DEMUXER_CTRL_NOTIMPL -1
|
|
|
|
#define DEMUXER_CTRL_DONTKNOW 0
|
|
|
|
#define DEMUXER_CTRL_OK 1
|
2013-04-14 04:20:31 +00:00
|
|
|
|
2013-10-02 19:19:16 +00:00
|
|
|
enum demux_ctrl {
|
2014-02-06 12:41:20 +00:00
|
|
|
DEMUXER_CTRL_SWITCHED_TRACKS = 1,
|
2013-10-02 19:19:16 +00:00
|
|
|
DEMUXER_CTRL_GET_TIME_LENGTH,
|
|
|
|
DEMUXER_CTRL_RESYNC,
|
|
|
|
DEMUXER_CTRL_IDENTIFY_PROGRAM,
|
2014-07-16 20:40:21 +00:00
|
|
|
DEMUXER_CTRL_STREAM_CTRL,
|
player: redo how stream caching and pausing on low cache works
Add the --cache-secs option, which literally overrides the value of
--demuxer-readahead-secs if the stream cache is active. The default
value is very high (10 seconds), which means it can act as network
cache.
Remove the old behavior of trying to pause once the byte cache runs
low. Instead, do something similar wit the demuxer cache. The nice
thing is that we can guess how many seconds of video it has cached,
and we can make better decisions. But for now, apply a relatively
naive heuristic: if the cache is below 0.5 secs, pause, and wait
until at least 2 secs are available.
Note that due to timestamp reordering, the estimated cached duration
of video might be inaccurate, depending on the file format. If the
file format has DTS, it's easy, otherwise the duration will seemingly
jump back and forth.
2014-08-26 23:13:20 +00:00
|
|
|
DEMUXER_CTRL_GET_READER_STATE,
|
2014-12-04 20:06:18 +00:00
|
|
|
DEMUXER_CTRL_GET_NAV_EVENT,
|
2014-12-12 00:00:58 +00:00
|
|
|
DEMUXER_CTRL_GET_BITRATE_STATS, // double[STREAM_TYPE_COUNT]
|
player: redo how stream caching and pausing on low cache works
Add the --cache-secs option, which literally overrides the value of
--demuxer-readahead-secs if the stream cache is active. The default
value is very high (10 seconds), which means it can act as network
cache.
Remove the old behavior of trying to pause once the byte cache runs
low. Instead, do something similar wit the demuxer cache. The nice
thing is that we can guess how many seconds of video it has cached,
and we can make better decisions. But for now, apply a relatively
naive heuristic: if the cache is below 0.5 secs, pause, and wait
until at least 2 secs are available.
Note that due to timestamp reordering, the estimated cached duration
of video might be inaccurate, depending on the file format. If the
file format has DTS, it's easy, otherwise the duration will seemingly
jump back and forth.
2014-08-26 23:13:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct demux_ctrl_reader_state {
|
|
|
|
bool eof, underrun, idle;
|
|
|
|
double ts_range[2]; // start, end
|
2014-08-27 20:42:28 +00:00
|
|
|
double ts_duration;
|
command: redo ancient TV/DVB/PVR commands
Convert all these commands to properties. (Except tv_last_channel, not
sure what to do with this.) Also, internally, don't access stream
details directly, but dispatch commands with stream ctrls.
Many of the new properties are a bit strange, because they're write-
only. Also remove some OSD output these commands produced, because I
couldn't be bothered to port these.
In general, this makes everything much cleaner, and will also make it
easier to e.g. move the demuxer to its own thread.
Don't bother updating input.conf, but changes.rst documents how old
commands map to the new ones.
Mostly untested, due to lack of hardware.
2014-06-09 21:38:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct demux_ctrl_stream_ctrl {
|
|
|
|
int ctrl;
|
|
|
|
void *arg;
|
|
|
|
int res;
|
2013-10-02 19:19:16 +00:00
|
|
|
};
|
2002-11-16 03:42:14 +00:00
|
|
|
|
2008-01-29 15:11:38 +00:00
|
|
|
#define SEEK_ABSOLUTE (1 << 0)
|
|
|
|
#define SEEK_FACTOR (1 << 1)
|
2009-03-19 03:25:12 +00:00
|
|
|
#define SEEK_FORWARD (1 << 2)
|
|
|
|
#define SEEK_BACKWARD (1 << 3)
|
2013-04-03 23:43:14 +00:00
|
|
|
#define SEEK_SUBPREROLL (1 << 4)
|
2008-01-29 15:11:38 +00:00
|
|
|
|
2013-07-12 19:58:11 +00:00
|
|
|
// Strictness of the demuxer open format check.
|
|
|
|
// demux.c will try by default: NORMAL, UNSAFE (in this order)
|
|
|
|
// Using "-demuxer format" will try REQUEST
|
|
|
|
// Using "-demuxer +format" will try FORCE
|
|
|
|
// REQUEST can be used as special value for raw demuxers which have no file
|
|
|
|
// header check; then they should fail if check!=FORCE && check!=REQUEST.
|
|
|
|
//
|
|
|
|
// In general, the list is sorted from weakest check to normal check.
|
|
|
|
// You can use relation operators to compare the check level.
|
|
|
|
enum demux_check {
|
|
|
|
DEMUX_CHECK_FORCE, // force format if possible
|
|
|
|
DEMUX_CHECK_UNSAFE, // risky/fuzzy detection
|
|
|
|
DEMUX_CHECK_REQUEST,// requested by user or stream implementation
|
|
|
|
DEMUX_CHECK_NORMAL, // normal, safe detection
|
|
|
|
};
|
|
|
|
|
2014-07-05 14:45:56 +00:00
|
|
|
enum demux_event {
|
2014-07-16 20:40:21 +00:00
|
|
|
DEMUX_EVENT_INIT = 1 << 0, // complete (re-)initialization
|
|
|
|
DEMUX_EVENT_STREAMS = 1 << 1, // a stream was added
|
|
|
|
DEMUX_EVENT_METADATA = 1 << 2, // metadata or stream_metadata changed
|
|
|
|
DEMUX_EVENT_ALL = 0xFFFF,
|
2014-07-05 14:45:56 +00:00
|
|
|
};
|
|
|
|
|
2012-08-03 10:24:55 +00:00
|
|
|
#define MAX_SH_STREAMS 256
|
2002-02-10 18:09:20 +00:00
|
|
|
|
2008-04-24 02:49:44 +00:00
|
|
|
struct demuxer;
|
2005-08-05 19:57:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Demuxer description structure
|
|
|
|
*/
|
2008-04-24 02:49:44 +00:00
|
|
|
typedef struct demuxer_desc {
|
2011-02-10 10:05:26 +00:00
|
|
|
const char *name; // Demuxer name, used with -demuxer switch
|
2013-07-12 20:12:02 +00:00
|
|
|
const char *desc; // Displayed to user
|
2011-02-10 10:05:26 +00:00
|
|
|
|
2013-07-12 19:58:11 +00:00
|
|
|
enum demuxer_type type; // optional
|
2011-02-10 10:05:26 +00:00
|
|
|
|
2013-07-11 18:08:12 +00:00
|
|
|
// Return 0 on success, otherwise -1
|
2013-07-12 19:58:11 +00:00
|
|
|
int (*open)(struct demuxer *demuxer, enum demux_check check);
|
2013-07-11 18:08:12 +00:00
|
|
|
// The following functions are all optional
|
|
|
|
int (*fill_buffer)(struct demuxer *demuxer); // 0 on EOF, otherwise 1
|
|
|
|
void (*close)(struct demuxer *demuxer);
|
2014-07-21 17:28:18 +00:00
|
|
|
void (*seek)(struct demuxer *demuxer, double rel_seek_secs, int flags);
|
2011-02-10 10:05:26 +00:00
|
|
|
int (*control)(struct demuxer *demuxer, int cmd, void *arg);
|
2005-08-05 19:57:47 +00:00
|
|
|
} demuxer_desc_t;
|
|
|
|
|
2008-04-24 02:49:44 +00:00
|
|
|
typedef struct demux_chapter
|
2006-08-06 18:55:34 +00:00
|
|
|
{
|
2013-04-12 11:20:37 +00:00
|
|
|
int original_index;
|
2014-11-02 16:20:04 +00:00
|
|
|
double pts;
|
2011-02-10 10:05:26 +00:00
|
|
|
char *name;
|
2013-09-08 05:42:05 +00:00
|
|
|
struct mp_tags *metadata;
|
|
|
|
uint64_t demuxer_id; // for mapping to internal demuxer data structures
|
2006-08-06 18:55:34 +00:00
|
|
|
} demux_chapter_t;
|
|
|
|
|
2014-01-22 23:54:08 +00:00
|
|
|
struct demux_edition {
|
|
|
|
uint64_t demuxer_id;
|
|
|
|
bool default_edition;
|
|
|
|
struct mp_tags *metadata;
|
|
|
|
};
|
|
|
|
|
2013-10-07 00:49:12 +00:00
|
|
|
struct matroska_segment_uid {
|
|
|
|
unsigned char segment[16];
|
|
|
|
uint64_t edition;
|
|
|
|
};
|
|
|
|
|
2009-03-16 21:30:48 +00:00
|
|
|
struct matroska_data {
|
2013-10-07 00:49:12 +00:00
|
|
|
struct matroska_segment_uid uid;
|
2009-03-16 21:30:48 +00:00
|
|
|
// Ordered chapter information if any
|
|
|
|
struct matroska_chapter {
|
|
|
|
uint64_t start;
|
|
|
|
uint64_t end;
|
|
|
|
bool has_segment_uid;
|
2013-10-07 00:49:12 +00:00
|
|
|
struct matroska_segment_uid uid;
|
2009-04-02 02:00:22 +00:00
|
|
|
char *name;
|
2009-03-16 21:30:48 +00:00
|
|
|
} *ordered_chapters;
|
|
|
|
int num_ordered_chapters;
|
|
|
|
};
|
|
|
|
|
2014-03-25 10:46:10 +00:00
|
|
|
struct replaygain_data {
|
|
|
|
float track_gain;
|
|
|
|
float track_peak;
|
|
|
|
float album_gain;
|
|
|
|
float album_peak;
|
|
|
|
};
|
|
|
|
|
2008-04-24 02:49:44 +00:00
|
|
|
typedef struct demux_attachment
|
2008-01-12 01:12:36 +00:00
|
|
|
{
|
2011-02-10 10:05:26 +00:00
|
|
|
char *name;
|
|
|
|
char *type;
|
|
|
|
void *data;
|
|
|
|
unsigned int data_size;
|
2008-01-12 01:12:36 +00:00
|
|
|
} demux_attachment_t;
|
|
|
|
|
2011-08-04 05:38:39 +00:00
|
|
|
struct demuxer_params {
|
2013-09-26 06:22:06 +00:00
|
|
|
int matroska_num_wanted_uids;
|
2013-10-07 00:49:12 +00:00
|
|
|
struct matroska_segment_uid *matroska_wanted_uids;
|
2013-04-14 00:49:07 +00:00
|
|
|
int matroska_wanted_segment;
|
|
|
|
bool *matroska_was_valid;
|
2014-01-04 18:00:01 +00:00
|
|
|
bool expect_subtitle;
|
2011-08-04 05:38:39 +00:00
|
|
|
};
|
|
|
|
|
2008-04-24 02:49:44 +00:00
|
|
|
typedef struct demuxer {
|
2011-02-10 10:05:26 +00:00
|
|
|
const demuxer_desc_t *desc; ///< Demuxer description structure
|
2011-05-04 20:12:55 +00:00
|
|
|
const char *filetype; // format name when not identified by demuxer (libavformat)
|
2012-11-18 19:46:12 +00:00
|
|
|
int64_t filepos; // input stream current pos.
|
2013-07-12 19:58:11 +00:00
|
|
|
char *filename; // same as stream->url
|
2011-02-11 17:52:44 +00:00
|
|
|
enum demuxer_type type;
|
2011-02-10 10:05:26 +00:00
|
|
|
int seekable; // flag
|
2014-07-05 14:54:49 +00:00
|
|
|
double start_time;
|
2013-03-01 12:20:33 +00:00
|
|
|
// File format allows PTS resets (even if the current file is without)
|
|
|
|
bool ts_resets_possible;
|
2001-04-23 16:12:21 +00:00
|
|
|
|
2014-07-05 14:45:56 +00:00
|
|
|
// Bitmask of DEMUX_EVENT_*
|
|
|
|
int events;
|
|
|
|
|
2012-08-03 10:24:55 +00:00
|
|
|
struct sh_stream **streams;
|
|
|
|
int num_streams;
|
2009-11-07 12:31:05 +00:00
|
|
|
|
2014-01-22 23:54:08 +00:00
|
|
|
struct demux_edition *editions;
|
2012-08-25 23:19:42 +00:00
|
|
|
int num_editions;
|
|
|
|
int edition;
|
2011-12-31 12:20:08 +00:00
|
|
|
|
2011-02-10 10:05:26 +00:00
|
|
|
struct demux_chapter *chapters;
|
|
|
|
int num_chapters;
|
|
|
|
|
|
|
|
struct demux_attachment *attachments;
|
|
|
|
int num_attachments;
|
2008-01-12 01:12:36 +00:00
|
|
|
|
2009-03-16 21:30:48 +00:00
|
|
|
struct matroska_data matroska_data;
|
EDL: add support for new EDL file format
The timeline code previously added to support Matroska ordered
chapters allows constructing a playback timeline from segments picked
from multiple source files. Add support for a new EDL format to make
this machinery available for use with file formats other than Matroska
and in a manner easier to use than creating files with ordered
chapters.
Unlike the old -edl option which specifies an additional file with
edits to apply to the video file given as the main argument, the new
EDL format is used by giving only the EDL file as the file to play;
that file then contains the filename(s) to use as source files where
actual video segments come from. Filename paths in the EDL file are
ignored. Currently the source files are only searched for in the
directory of the EDL file; support for a search path option will
likely be added in the future.
Format of the EDL files
The first line in the file must be "mplayer EDL file, version 2".
The rest of the lines belong to one of these classes:
1) lines specifying source files
2) empty lines
3) lines specifying timeline segments.
Lines beginning with '<' specify source files. These lines first
contain an identifier used to refer to the source file later, then the
filename separated by whitespace. The identifier must start with a
letter. Filenames that start or end with whitespace or contain
newlines are not supported.
On other lines '#' characters delimit comments. Lines that contain
only whitespace after comments have been removed are ignored.
Timeline segments must appear in the file in chronological order. Each
segment has the following information associated with it:
- duration
- output start time
- output end time (= output start time + duration)
- source id (specifies the file the content of the segment comes from)
- source start time (timestamp in the source file)
- source end time (= source start time + duration)
The output timestamps must form a continuous timeline from 0 to the
end of the last segment, such that each new segment starts from the
time the previous one ends at. Source files and times may change
arbitrarily between segments.
The general format for lines specifying timeline segments is
[output time info] source_id [source time info]
source_id must be an identifier defined on a '<' line. Both the time
info parts consists of zero or more of the following elements:
1) timestamp
2) -timestamp
3) +duration
4) *
5) -*
, where "timestamp" and "duration" are decimal numbers (computations
are done with nanosecond precision). Whitespace around "+" and "-" is
optional. 1) and 2) specify start and end time of the segment on
output or source side. 3) specifies duration; the semantics are the
same whether this appears on output or source side. 4) and 5) are
ignored on the output side (they're always implicitly assumed). On the
source side 4) specifies that the segment starts where the previous
segment _using this source_ ended; if there was no previous segment
time 0 is used. 5) specifies that the segment ends where the next
segment using this source starts.
Redundant information may be omitted. It will be filled in using the
following rules:
- output start for first segment is 0
- two of [output start, output end, duration] imply third
- two of [source start, source end, duration] imply third
- output start = output end of previous segment
- output end = output start of next segment
- if "*", source start = source end of earlier segment
- if "-*", source end = source start of a later segment
As a special rule, a last zero-duration segment without a source
specification may appear. This will produce no corresponding segment
in the resulting timeline, but can be used as syntax to specify the
end time of the timeline (with effect equal to adding -time on the
previous line).
Examples:
----- begin -----
mplayer EDL file, version 2
< id1 filename
0 id1 123
100 id1 456
200 id1 789
300
----- end -----
All segments come from the source file "filename". First segment
(output time 0-100) comes from time 123-223, second 456-556, third
789-889.
----- begin -----
mplayer EDL file, version 2
< f filename
f 60-120
f 600-660
f 30- 90
----- end -----
Play first seconds 60-120 from the file, then 600-660, then 30-90.
----- begin -----
mplayer EDL file, version 2
< id1 filename1
< id2 filename2
+10 id1 *
+10 id2 *
+10 id1 *
+10 id2 *
+10 id1 *
+10 id2 *
----- end -----
This plays time 0-10 from filename1, then 0-10 from filename1, then
10-20 from filename1, then 10-20 from filename2, then 20-30 from
filename1, then 20-30 from filename2.
----- begin -----
mplayer EDL file, version 2
< t1 filename1
< t2 filename2
t1 * +2 # segment 1
+2 t2 100 # segment 2
t1 * # segment 3
t2 *-* # segment 4
t1 3 -* # segment 5
+0.111111 t2 102.5 # segment 6
7.37 t1 5 +1 # segment 7
----- end -----
This rather pathological example illustrates the rules for filling in
implied data. All the values can be determined by recursively applying
the rules given above, and the full end result is this:
+2 0-2 t1 0-2 # segment 1
+2 2-4 t2 100-102 # segment 2
+0.758889 4-4.758889 t1 2-2.758889 # segment 3
+0.5 4.4758889-5.258889 t2 102-102.5 # segment 4
+2 5.258889-7.258889 t1 3-5 # segment 5
+0.111111 7.258889-7.37 t2 102.5-102.611111 # segment 6
+1 7.37-8.37 t1 5-6 # segment 7
2011-02-14 11:05:35 +00:00
|
|
|
// for trivial demuxers which just read the whole file for codec to use
|
|
|
|
struct bstr file_contents;
|
2009-03-16 21:30:48 +00:00
|
|
|
|
2013-08-25 18:40:21 +00:00
|
|
|
// If the file is a playlist file
|
|
|
|
struct playlist *playlist;
|
|
|
|
|
2013-09-08 04:32:48 +00:00
|
|
|
struct mp_tags *metadata;
|
2014-07-05 14:45:56 +00:00
|
|
|
|
2011-02-10 10:05:26 +00:00
|
|
|
void *priv; // demuxer-specific internal data
|
|
|
|
struct MPOpts *opts;
|
2013-12-21 19:24:20 +00:00
|
|
|
struct mpv_global *global;
|
2013-12-21 20:55:41 +00:00
|
|
|
struct mp_log *log, *glog;
|
2011-08-04 05:38:39 +00:00
|
|
|
struct demuxer_params *params;
|
2014-07-16 20:40:21 +00:00
|
|
|
|
|
|
|
struct demux_internal *in; // internal to demux.c
|
|
|
|
|
|
|
|
// Since the demuxer can run in its own thread, and the stream is not
|
|
|
|
// thread-safe, only the demuxer is allowed to access the stream directly.
|
|
|
|
// You can freely use demux_stream_control() to send STREAM_CTRLs, or use
|
|
|
|
// demux_pause() to get exclusive access to the stream.
|
|
|
|
struct stream *stream;
|
2001-04-23 16:12:21 +00:00
|
|
|
} demuxer_t;
|
|
|
|
|
2006-11-18 14:31:31 +00:00
|
|
|
typedef struct {
|
2011-02-10 10:05:26 +00:00
|
|
|
int progid; //program id
|
|
|
|
int aid, vid, sid; //audio, video and subtitle id
|
2006-11-18 14:31:31 +00:00
|
|
|
} demux_program_t;
|
|
|
|
|
2011-02-10 10:05:26 +00:00
|
|
|
void free_demuxer(struct demuxer *demuxer);
|
2001-04-23 16:12:21 +00:00
|
|
|
|
2014-07-05 14:59:44 +00:00
|
|
|
int demux_add_packet(struct sh_stream *stream, demux_packet_t *dp);
|
2013-07-11 17:10:33 +00:00
|
|
|
|
|
|
|
struct demux_packet *demux_read_packet(struct sh_stream *sh);
|
2014-07-18 13:08:05 +00:00
|
|
|
int demux_read_packet_async(struct sh_stream *sh, struct demux_packet **out_pkt);
|
2014-07-06 17:02:21 +00:00
|
|
|
bool demux_stream_is_selected(struct sh_stream *stream);
|
2013-07-11 17:10:33 +00:00
|
|
|
double demux_get_next_pts(struct sh_stream *sh);
|
|
|
|
bool demux_has_packet(struct sh_stream *sh);
|
2014-07-05 14:57:56 +00:00
|
|
|
struct demux_packet *demux_read_any_packet(struct demuxer *demuxer);
|
2001-04-23 16:12:21 +00:00
|
|
|
|
2013-07-11 17:35:09 +00:00
|
|
|
struct sh_stream *new_sh_stream(struct demuxer *demuxer, enum stream_type type);
|
|
|
|
|
2013-07-11 19:10:42 +00:00
|
|
|
struct demuxer *demux_open(struct stream *stream, char *force_format,
|
2013-12-21 19:24:20 +00:00
|
|
|
struct demuxer_params *params,
|
|
|
|
struct mpv_global *global);
|
2011-08-04 05:38:39 +00:00
|
|
|
|
2014-07-16 20:40:21 +00:00
|
|
|
void demux_start_thread(struct demuxer *demuxer);
|
|
|
|
void demux_stop_thread(struct demuxer *demuxer);
|
|
|
|
void demux_set_wakeup_cb(struct demuxer *demuxer, void (*cb)(void *ctx), void *ctx);
|
|
|
|
|
2011-02-10 10:05:26 +00:00
|
|
|
void demux_flush(struct demuxer *demuxer);
|
2014-10-29 21:47:25 +00:00
|
|
|
int demux_seek(struct demuxer *demuxer, double rel_seek_secs, int flags);
|
2001-04-23 16:12:21 +00:00
|
|
|
|
2011-02-10 10:05:26 +00:00
|
|
|
int demux_control(struct demuxer *demuxer, int cmd, void *arg);
|
2002-03-03 18:47:29 +00:00
|
|
|
|
2012-08-19 16:01:30 +00:00
|
|
|
void demuxer_switch_track(struct demuxer *demuxer, enum stream_type type,
|
|
|
|
struct sh_stream *stream);
|
2013-07-11 17:22:24 +00:00
|
|
|
void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream,
|
|
|
|
bool selected);
|
2014-07-16 20:40:21 +00:00
|
|
|
void demux_set_stream_autoselect(struct demuxer *demuxer, bool autoselect);
|
2003-01-19 00:21:54 +00:00
|
|
|
|
2013-12-21 19:24:20 +00:00
|
|
|
void demuxer_help(struct mp_log *log);
|
2006-08-06 18:55:34 +00:00
|
|
|
|
2011-02-10 10:05:26 +00:00
|
|
|
int demuxer_add_attachment(struct demuxer *demuxer, struct bstr name,
|
2010-05-19 10:44:37 +00:00
|
|
|
struct bstr type, struct bstr data);
|
2014-11-02 16:20:04 +00:00
|
|
|
int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name,
|
|
|
|
double pts, uint64_t demuxer_id);
|
2006-08-06 18:55:34 +00:00
|
|
|
|
2013-05-03 18:07:04 +00:00
|
|
|
double demuxer_get_time_length(struct demuxer *demuxer);
|
|
|
|
|
2014-07-16 20:40:21 +00:00
|
|
|
int demux_stream_control(demuxer_t *demuxer, int ctrl, void *arg);
|
|
|
|
|
|
|
|
void demux_pause(demuxer_t *demuxer);
|
|
|
|
void demux_unpause(demuxer_t *demuxer);
|
|
|
|
|
|
|
|
void demux_changed(demuxer_t *demuxer, int events);
|
|
|
|
void demux_update(demuxer_t *demuxer);
|
|
|
|
|
2012-08-19 16:01:30 +00:00
|
|
|
struct sh_stream *demuxer_stream_by_demuxer_id(struct demuxer *d,
|
|
|
|
enum stream_type t, int id);
|
2008-03-30 16:55:46 +00:00
|
|
|
|
2014-11-02 16:20:04 +00:00
|
|
|
struct demux_chapter *demux_copy_chapter_data(struct demux_chapter *c, int num);
|
|
|
|
|
2013-10-07 00:49:12 +00:00
|
|
|
bool demux_matroska_uid_cmp(struct matroska_segment_uid *a,
|
|
|
|
struct matroska_segment_uid *b);
|
|
|
|
|
2014-02-15 15:48:56 +00:00
|
|
|
const char *stream_type_name(enum stream_type type);
|
|
|
|
|
2008-02-22 09:09:46 +00:00
|
|
|
#endif /* MPLAYER_DEMUXER_H */
|