summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2009-11-16 06:54:22 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2009-11-16 07:01:46 +0200
commit287b62163eed8811b6cd33716c0691d328947d48 (patch)
tree3143d2cb17b32a19e3e7e0aa428210d1bba3eb0b /libmpdemux
parent507f4fe6c7811558b1367e4b64855ae7f9bc8da8 (diff)
parentb411278fbb00767b8013604157a43e0203f66f4c (diff)
downloadmpv-287b62163eed8811b6cd33716c0691d328947d48.tar.bz2
mpv-287b62163eed8811b6cd33716c0691d328947d48.tar.xz
Merge svn changes up to r29912
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/asf.h2
-rw-r--r--libmpdemux/asfheader.c2
-rw-r--r--libmpdemux/demux_asf.c2
-rw-r--r--libmpdemux/demux_demuxers.c6
-rw-r--r--libmpdemux/demux_lavf.c41
-rw-r--r--libmpdemux/demux_ogg.c53
-rw-r--r--libmpdemux/demuxer.c29
-rw-r--r--libmpdemux/demuxer.h5
-rw-r--r--libmpdemux/mp_taglists.c1
9 files changed, 70 insertions, 71 deletions
diff --git a/libmpdemux/asf.h b/libmpdemux/asf.h
index a1e29a942f..a3d2b01c17 100644
--- a/libmpdemux/asf.h
+++ b/libmpdemux/asf.h
@@ -222,7 +222,7 @@ struct asf_priv {
int scrambling_b;
unsigned packetsize;
double packetrate;
- unsigned movielength;
+ double movielength;
int asf_is_dvr_ms;
uint32_t asf_frame_state;
int asf_frame_start_found;
diff --git a/libmpdemux/asfheader.c b/libmpdemux/asfheader.c
index 905ec83949..186a1a967d 100644
--- a/libmpdemux/asfheader.c
+++ b/libmpdemux/asfheader.c
@@ -544,7 +544,7 @@ int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf){
asf->packetsize=fileh->max_packet_size;
asf->packet=malloc(asf->packetsize); // !!!
asf->packetrate=fileh->max_bitrate/8.0/(double)asf->packetsize;
- asf->movielength=(fileh->play_duration-fileh->preroll)/10000000LL;
+ asf->movielength=(fileh->play_duration-10000*fileh->preroll)/10000000.0;
}
// find content header
diff --git a/libmpdemux/demux_asf.c b/libmpdemux/demux_asf.c
index 0290034b7a..e205524d62 100644
--- a/libmpdemux/demux_asf.c
+++ b/libmpdemux/demux_asf.c
@@ -613,7 +613,7 @@ static int demux_asf_control(demuxer_t *demuxer,int cmd, void *arg){
*/
switch(cmd) {
case DEMUXER_CTRL_GET_TIME_LENGTH:
- *((double *)arg)=(double)(asf->movielength);
+ *((double *)arg)=asf->movielength;
return DEMUXER_CTRL_OK;
case DEMUXER_CTRL_GET_PERCENT_POS:
diff --git a/libmpdemux/demux_demuxers.c b/libmpdemux/demux_demuxers.c
index 3b4f958394..14a05d65a3 100644
--- a/libmpdemux/demux_demuxers.c
+++ b/libmpdemux/demux_demuxers.c
@@ -55,9 +55,15 @@ demuxer_t* new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd) {
ret->video = vd->video;
ret->audio = ad->audio;
ret->sub = sd->sub;
+ if (sd && sd != vd && sd != ad) sd->sub->non_interleaved = 1;
+
+ // without these, demux_demuxers_fill_buffer will never be called,
+ // but they break the demuxer-specific code in video.c
+#if 0
if (vd) vd->video->demuxer = ret;
if (ad) ad->audio->demuxer = ret;
if (sd) sd->sub->demuxer = ret;
+#endif
// HACK?, necessary for subtitle (and audio and video when implemented) switching
memcpy(ret->v_streams, vd->v_streams, sizeof(ret->v_streams));
diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c
index f69f2715ff..0d44a0fc18 100644
--- a/libmpdemux/demux_lavf.c
+++ b/libmpdemux/demux_lavf.c
@@ -49,7 +49,6 @@ static unsigned int opt_probesize = 0;
static unsigned int opt_analyzeduration = 0;
static char *opt_format;
static char *opt_cryptokey;
-extern int ts_prog;
static char *opt_avopt = NULL;
const m_option_t lavfdopts_conf[] = {
@@ -133,6 +132,7 @@ static int lavf_check_file(demuxer_t *demuxer){
AVProbeData avpd;
uint8_t buf[PROBE_BUF_SIZE];
lavf_priv_t *priv;
+ int probe_data_size;
if(!demuxer->priv)
demuxer->priv=calloc(sizeof(lavf_priv_t),1);
@@ -154,11 +154,12 @@ static int lavf_check_file(demuxer_t *demuxer){
return DEMUXER_TYPE_LAVF;
}
- if(stream_read(demuxer->stream, buf, PROBE_BUF_SIZE)!=PROBE_BUF_SIZE)
+ probe_data_size = stream_read(demuxer->stream, buf, PROBE_BUF_SIZE);
+ if(probe_data_size <= 0)
return 0;
avpd.filename= demuxer->stream->url;
avpd.buf= buf;
- avpd.buf_size= PROBE_BUF_SIZE;
+ avpd.buf_size= probe_data_size;
priv->avif= av_probe_input_format(&avpd, 1);
if(!priv->avif){
@@ -383,6 +384,8 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
type = 'a';
else if(codec->codec_id == CODEC_ID_DVD_SUBTITLE)
type = 'v';
+ else if(codec->codec_id == CODEC_ID_DVB_TELETEXT)
+ type = 'd';
else
break;
sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams);
@@ -493,30 +496,12 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
for(i=0; i<avfc->nb_streams; i++)
handle_stream(demuxer, avfc, i);
if(avfc->nb_programs) {
- int p, start=0, found=0;
-
- if(ts_prog) {
- for(p=0; p<avfc->nb_programs; p++) {
- if(avfc->programs[p]->id == ts_prog) {
- start = p;
- found = 1;
- break;
- }
- }
- if(!found) {
- mp_msg(MSGT_HEADER,MSGL_ERR,"DEMUX_LAVF: program %d doesn't seem to be present\n", ts_prog);
- return NULL;
- }
- }
- p = start;
- do {
+ int p;
+ for (p = 0; p < avfc->nb_programs; p++) {
AVProgram *program = avfc->programs[p];
t = av_metadata_get(program->metadata, "title", NULL, 0);
mp_msg(MSGT_HEADER,MSGL_INFO,"LAVF: Program %d %s\n", program->id, t ? t->value : "");
- if(!priv->cur_program && (demuxer->video->sh || demuxer->audio->sh))
- priv->cur_program = program->id;
- p = (p + 1) % avfc->nb_programs;
- } while(p!=start);
+ }
}
mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams);
@@ -717,8 +702,9 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
int p, i;
int start;
- if(priv->avfc->nb_programs < 2)
- return DEMUXER_CTRL_NOTIMPL;
+ prog->vid = prog->aid = prog->sid = -2; //no audio and no video by default
+ if(priv->avfc->nb_programs < 1)
+ return DEMUXER_CTRL_DONTKNOW;
if(prog->progid == -1)
{
@@ -733,10 +719,9 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
if(priv->avfc->programs[i]->id == prog->progid)
break;
if(i==priv->avfc->nb_programs)
- return DEMUXER_CTRL_NOTIMPL;
+ return DEMUXER_CTRL_DONTKNOW;
p = i;
}
- prog->vid = prog->aid = prog->sid = -2; //no audio and no video by default
start = p;
redo:
program = priv->avfc->programs[p];
diff --git a/libmpdemux/demux_ogg.c b/libmpdemux/demux_ogg.c
index 4816c789ec..2bd6781cf2 100644
--- a/libmpdemux/demux_ogg.c
+++ b/libmpdemux/demux_ogg.c
@@ -146,7 +146,9 @@ typedef struct ogg_demuxer {
ogg_syncpoint_t* syncpoints;
int num_syncpoint;
off_t pos, last_size;
+ int64_t initial_granulepos;
int64_t final_granulepos;
+ int64_t duration;
/* Used for subtitle switching. */
int n_text;
@@ -263,20 +265,23 @@ static unsigned char* demux_ogg_read_packet(ogg_stream_t* os,ogg_packet* pack,fl
if(os->vorbis) {
if(*pack->packet & PACKET_TYPE_HEADER)
os->hdr_packets++;
- else if (os->vi_initialized)
+ else
{
vorbis_info *vi;
- int32_t blocksize;
+ int32_t blocksize = 0;
// When we dump the audio, there is no vi, but we don't care of timestamp in this case
- vi = &(os->vi);
+ vi = os->vi_initialized ? &os->vi : NULL;
+ if (vi)
blocksize = vorbis_packet_blocksize(vi,pack) / samplesize;
// Calculate the timestamp if the packet don't have any
if(pack->granulepos == -1) {
pack->granulepos = os->lastpos;
if(os->lastsize > 0)
pack->granulepos += os->lastsize;
- }
+ } else
+ *flags = 1;
+ if (vi)
*pts = pack->granulepos / (float)vi->rate;
os->lastsize = blocksize;
os->lastpos = pack->granulepos;
@@ -521,12 +526,7 @@ static void demux_ogg_scan_stream(demuxer_t* demuxer) {
pos = last_pos = demuxer->movi_start;
// Reset the stream
- if(index_mode == 2) {
stream_seek(s,demuxer->movi_start);
- } else {
- //the 270000 are just a wild guess
- stream_seek(s,FFMAX(ogg_d->pos,demuxer->movi_end-270000));
- }
ogg_sync_reset(sync);
// Get the serial number of the stream we use
@@ -574,7 +574,18 @@ static void demux_ogg_scan_stream(demuxer_t* demuxer) {
float pts;
int flags;
demux_ogg_read_packet(os,&op,&pts,&flags,samplesize);
- if(op.granulepos >= 0) ogg_d->final_granulepos = op.granulepos;
+ if(op.granulepos >= 0) {
+ ogg_d->final_granulepos = op.granulepos;
+ if(ogg_d->initial_granulepos == MP_NOPTS_VALUE && (flags & 1)) {
+ ogg_d->initial_granulepos = op.granulepos;
+ if (index_mode != 2 && ogg_d->pos < demuxer->movi_end-2*270000) {
+ //the 270000 are just a wild guess
+ stream_seek(s,FFMAX(ogg_d->pos,demuxer->movi_end-270000));
+ ogg_sync_reset(sync);
+ continue;
+ }
+ }
+ }
if(index_mode == 2 && (flags || (os->vorbis && op.granulepos >= 0))) {
if (ogg_d->num_syncpoint > SIZE_MAX / sizeof(ogg_syncpoint_t) - 1) break;
ogg_d->syncpoints = realloc_struct(ogg_d->syncpoints,(ogg_d->num_syncpoint+1), sizeof(ogg_syncpoint_t));
@@ -1122,6 +1133,7 @@ int demux_ogg_open(demuxer_t* demuxer) {
}
ogg_d->final_granulepos=0;
+ ogg_d->initial_granulepos = MP_NOPTS_VALUE;
if(!s->end_pos)
demuxer->seekable = 0;
else {
@@ -1130,6 +1142,9 @@ int demux_ogg_open(demuxer_t* demuxer) {
demuxer->seekable = 1;
demux_ogg_scan_stream(demuxer);
}
+ if (ogg_d->initial_granulepos == MP_NOPTS_VALUE)
+ ogg_d->initial_granulepos = 0;
+ ogg_d->duration = ogg_d->final_granulepos - ogg_d->initial_granulepos;
mp_msg(MSGT_DEMUX,MSGL_V,"Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",n_audio,n_audio>1?"s":"",n_video,n_video>1?"s":"",ogg_d->n_text,ogg_d->n_text>1?"s":"");
@@ -1362,10 +1377,10 @@ static void demux_ogg_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_de
old_pos = ogg_d->pos;
//calculate the granulepos to seek to
- gp = flags & SEEK_ABSOLUTE ? 0 : os->lastpos;
+ gp = flags & SEEK_ABSOLUTE ? ogg_d->initial_granulepos : os->lastpos;
if(flags & SEEK_FACTOR) {
- if (ogg_d->final_granulepos > 0)
- gp += ogg_d->final_granulepos * rel_seek_secs;
+ if (ogg_d->duration > 0)
+ gp += ogg_d->duration * rel_seek_secs;
else
gp += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * os->lastpos / ogg_d->pos;
} else
@@ -1392,8 +1407,8 @@ static void demux_ogg_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_de
if(flags & SEEK_FACTOR)
pos += (demuxer->movi_end - demuxer->movi_start) * rel_seek_secs;
else {
- if (ogg_d->final_granulepos > 0) {
- pos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / (ogg_d->final_granulepos / rate);
+ if (ogg_d->duration > 0) {
+ pos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / (ogg_d->duration / rate);
} else if (os->lastpos > 0) {
pos += rel_seek_secs * ogg_d->pos / (os->lastpos / rate);
}
@@ -1548,13 +1563,13 @@ static int demux_ogg_control(demuxer_t *demuxer,int cmd, void *arg){
switch(cmd) {
case DEMUXER_CTRL_GET_TIME_LENGTH:
- if (ogg_d->final_granulepos<=0) return DEMUXER_CTRL_DONTKNOW;
- *(double *)arg=(double)ogg_d->final_granulepos / rate;
+ if (ogg_d->duration<=0) return DEMUXER_CTRL_DONTKNOW;
+ *(double *)arg=(double)(ogg_d->duration) / rate;
return DEMUXER_CTRL_GUESS;
case DEMUXER_CTRL_GET_PERCENT_POS:
- if (ogg_d->final_granulepos<=0) return DEMUXER_CTRL_DONTKNOW;
- *(int *)arg=(os->lastpos*100) / ogg_d->final_granulepos;
+ if (ogg_d->duration<=0) return DEMUXER_CTRL_DONTKNOW;
+ *(int *)arg=((os->lastpos - ogg_d->initial_granulepos)*100) / ogg_d->duration;
return DEMUXER_CTRL_OK;
default:
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index d08d97468b..be1cfde73c 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -41,6 +41,7 @@
#include "mf.h"
#include "libaf/af_format.h"
+#include "libmpcodecs/dec_teletext.h"
#include "ass_mp.h"
@@ -186,27 +187,11 @@ void free_demuxer_stream(demux_stream_t *ds)
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;
- ds->buffer = NULL;
- ds->pts = 0;
- ds->pts_bytes = 0;
- ds->eof = 0;
- ds->pos = 0;
- ds->dpos = 0;
- ds->pack_no = 0;
-
- ds->packs = 0;
- ds->bytes = 0;
- ds->first = ds->last = ds->current = NULL;
- ds->id = id;
- ds->demuxer = demuxer;
-
- ds->asf_seq = -1;
- ds->asf_packet = NULL;
-
- ds->ss_mul = ds->ss_div = 0;
-
- ds->sh = NULL;
+ *ds = (demux_stream_t){
+ .id = id,
+ .demuxer = demuxer,
+ .asf_seq = -1,
+ };
return ds;
}
@@ -405,6 +390,8 @@ void free_demuxer(demuxer_t *demuxer)
}
free(demuxer->attachments);
}
+ if (demuxer->teletext)
+ teletext_control(demuxer->teletext, TV_VBI_CONTROL_STOP, NULL);
talloc_free(demuxer);
}
diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h
index deb3732c5b..44cd642ed3 100644
--- a/libmpdemux/demuxer.h
+++ b/libmpdemux/demuxer.h
@@ -144,6 +144,8 @@ typedef struct demux_stream {
off_t dpos; // position in the demuxed stream
int pack_no; // serial number of packet
int flags; // flags of current packet (keyframe etc)
+ int non_interleaved; // 1 if this stream is not properly interleaved,
+ // so e.g. subtitle handling must do explicit reads.
//---------------
int packs; // number of packets in buffer
int bytes; // total bytes of packets in buffer
@@ -255,6 +257,9 @@ typedef struct demuxer {
struct sh_video *v_streams[MAX_V_STREAMS];
struct sh_sub *s_streams[MAX_S_STREAMS];
+ // pointer to teletext decoder private data, if demuxer stream contains teletext
+ void *teletext;
+
demux_chapter_t* chapters;
int num_chapters;
diff --git a/libmpdemux/mp_taglists.c b/libmpdemux/mp_taglists.c
index 286a755f8b..de3e3a707c 100644
--- a/libmpdemux/mp_taglists.c
+++ b/libmpdemux/mp_taglists.c
@@ -103,6 +103,7 @@ static const struct mp_AVCodecTag mp_bmp_tags[] = {
{ CODEC_ID_RV20, MKTAG('R', 'V', '2', '0')},
{ CODEC_ID_RV30, MKTAG('R', 'V', '3', '0')},
{ CODEC_ID_RV40, MKTAG('R', 'V', '4', '0')},
+ { CODEC_ID_TGV, MKTAG('f', 'V', 'G', 'T')},
{ CODEC_ID_THP, MKTAG('T', 'H', 'P', 'V')},
{ CODEC_ID_TIERTEXSEQVIDEO, MKTAG('T', 'S', 'E', 'Q')},
{ CODEC_ID_TXD, MKTAG('T', 'X', 'D', 'V')},