diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2009-11-16 06:54:22 +0200 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2009-11-16 07:01:46 +0200 |
commit | 287b62163eed8811b6cd33716c0691d328947d48 (patch) | |
tree | 3143d2cb17b32a19e3e7e0aa428210d1bba3eb0b /libmpdemux | |
parent | 507f4fe6c7811558b1367e4b64855ae7f9bc8da8 (diff) | |
parent | b411278fbb00767b8013604157a43e0203f66f4c (diff) | |
download | mpv-287b62163eed8811b6cd33716c0691d328947d48.tar.bz2 mpv-287b62163eed8811b6cd33716c0691d328947d48.tar.xz |
Merge svn changes up to r29912
Diffstat (limited to 'libmpdemux')
-rw-r--r-- | libmpdemux/asf.h | 2 | ||||
-rw-r--r-- | libmpdemux/asfheader.c | 2 | ||||
-rw-r--r-- | libmpdemux/demux_asf.c | 2 | ||||
-rw-r--r-- | libmpdemux/demux_demuxers.c | 6 | ||||
-rw-r--r-- | libmpdemux/demux_lavf.c | 41 | ||||
-rw-r--r-- | libmpdemux/demux_ogg.c | 53 | ||||
-rw-r--r-- | libmpdemux/demuxer.c | 29 | ||||
-rw-r--r-- | libmpdemux/demuxer.h | 5 | ||||
-rw-r--r-- | libmpdemux/mp_taglists.c | 1 |
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')}, |