Enable the read-based forward seek fallback also when CONFIG_NETWORK is
[mplayer/greg.git] / libmpdemux / demux_lavf.c
blob4d4137babd58be51ae8ca592f7d3ac07db161be7
1 /*
2 * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 // #include <stdio.h>
22 #include <stdlib.h>
23 // #include <unistd.h>
24 #include <limits.h>
26 #include "config.h"
27 #include "mp_msg.h"
28 #include "help_mp.h"
29 #include "av_opts.h"
31 #include "stream/stream.h"
32 #include "demuxer.h"
33 #include "stheader.h"
34 #include "m_option.h"
35 #include "libvo/sub.h"
37 #include "libavformat/avformat.h"
38 #include "libavformat/avio.h"
39 #include "libavutil/avutil.h"
40 #include "libavcodec/opt.h"
42 #include "mp_taglists.h"
44 #define PROBE_BUF_SIZE (32*1024)
46 extern char *audio_lang;
47 extern char *dvdsub_lang;
48 extern int dvdsub_id;
49 static unsigned int opt_probesize = 0;
50 static unsigned int opt_analyzeduration = 0;
51 static char *opt_format;
52 static char *opt_cryptokey;
53 static char *opt_avopt = NULL;
55 const m_option_t lavfdopts_conf[] = {
56 {"probesize", &(opt_probesize), CONF_TYPE_INT, CONF_RANGE, 32, INT_MAX, NULL},
57 {"format", &(opt_format), CONF_TYPE_STRING, 0, 0, 0, NULL},
58 {"analyzeduration", &(opt_analyzeduration), CONF_TYPE_INT, CONF_RANGE, 0, INT_MAX, NULL},
59 {"cryptokey", &(opt_cryptokey), CONF_TYPE_STRING, 0, 0, 0, NULL},
60 {"o", &opt_avopt, CONF_TYPE_STRING, 0, 0, 0, NULL},
61 {NULL, NULL, 0, 0, 0, 0, NULL}
64 #define BIO_BUFFER_SIZE 32768
66 typedef struct lavf_priv_t{
67 AVInputFormat *avif;
68 AVFormatContext *avfc;
69 ByteIOContext *pb;
70 uint8_t buffer[BIO_BUFFER_SIZE];
71 int audio_streams;
72 int video_streams;
73 int sub_streams;
74 int64_t last_pts;
75 int astreams[MAX_A_STREAMS];
76 int vstreams[MAX_V_STREAMS];
77 int sstreams[MAX_S_STREAMS];
78 int cur_program;
79 }lavf_priv_t;
81 void print_wave_header(WAVEFORMATEX *h, int verbose_level);
82 void print_video_header(BITMAPINFOHEADER *h, int verbose_level);
84 static int mp_read(void *opaque, uint8_t *buf, int size) {
85 stream_t *stream = opaque;
86 int ret;
88 if(stream_eof(stream)) //needed?
89 return -1;
90 ret=stream_read(stream, buf, size);
92 mp_msg(MSGT_HEADER,MSGL_DBG2,"%d=mp_read(%p, %p, %d), eof:%d\n", ret, stream, buf, size, stream->eof);
93 return ret;
96 static int64_t mp_seek(void *opaque, int64_t pos, int whence) {
97 stream_t *stream = opaque;
98 int64_t current_pos;
99 mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %d, %d)\n", stream, (int)pos, whence);
100 if(whence == SEEK_CUR)
101 pos +=stream_tell(stream);
102 else if(whence == SEEK_END && stream->end_pos > 0)
103 pos += stream->end_pos;
104 else if(whence == SEEK_SET)
105 pos += stream->start_pos;
106 else if(whence == AVSEEK_SIZE && stream->end_pos > 0)
107 return stream->end_pos - stream->start_pos;
108 else
109 return -1;
111 if(pos<0)
112 return -1;
113 if(pos<stream->end_pos && stream->eof)
114 stream_reset(stream);
115 current_pos = stream_tell(stream);
116 if(stream_seek(stream, pos)==0) {
117 stream_reset(stream);
118 stream_seek(stream, current_pos);
119 return -1;
122 return pos - stream->start_pos;
125 static void list_formats(void) {
126 AVInputFormat *fmt;
127 mp_msg(MSGT_DEMUX, MSGL_INFO, "Available lavf input formats:\n");
128 for (fmt = first_iformat; fmt; fmt = fmt->next)
129 mp_msg(MSGT_DEMUX, MSGL_INFO, "%15s : %s\n", fmt->name, fmt->long_name);
132 static int lavf_check_file(demuxer_t *demuxer){
133 AVProbeData avpd;
134 uint8_t buf[PROBE_BUF_SIZE];
135 lavf_priv_t *priv;
136 int probe_data_size;
138 if(!demuxer->priv)
139 demuxer->priv=calloc(sizeof(lavf_priv_t),1);
140 priv= demuxer->priv;
142 av_register_all();
144 if (opt_format) {
145 if (strcmp(opt_format, "help") == 0) {
146 list_formats();
147 return 0;
149 priv->avif= av_find_input_format(opt_format);
150 if (!priv->avif) {
151 mp_msg(MSGT_DEMUX,MSGL_FATAL,"Unknown lavf format %s\n", opt_format);
152 return 0;
154 mp_msg(MSGT_DEMUX,MSGL_INFO,"Forced lavf %s demuxer\n", priv->avif->long_name);
155 return DEMUXER_TYPE_LAVF;
158 probe_data_size = stream_read(demuxer->stream, buf, PROBE_BUF_SIZE);
159 if(probe_data_size <= 0)
160 return 0;
161 avpd.filename= demuxer->stream->url;
162 avpd.buf= buf;
163 avpd.buf_size= probe_data_size;
165 priv->avif= av_probe_input_format(&avpd, 1);
166 if(!priv->avif){
167 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: no clue about this gibberish!\n");
168 return 0;
169 }else
170 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name);
172 return DEMUXER_TYPE_LAVF;
175 static const char * const preferred_list[] = {
176 "dxa",
177 "flv",
178 "gxf",
179 "nut",
180 "nuv",
181 "mov,mp4,m4a,3gp,3g2,mj2",
182 "mpc",
183 "mpc8",
184 "mxf",
185 "swf",
186 "vqf",
187 "w64",
188 "wv",
189 NULL
192 static int lavf_check_preferred_file(demuxer_t *demuxer){
193 if (lavf_check_file(demuxer)) {
194 const char * const *p = preferred_list;
195 lavf_priv_t *priv = demuxer->priv;
196 while (*p) {
197 if (strcmp(*p, priv->avif->name) == 0)
198 return DEMUXER_TYPE_LAVF_PREFERRED;
199 p++;
202 return 0;
205 static uint8_t char2int(char c) {
206 if (c >= '0' && c <= '9') return c - '0';
207 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
208 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
209 return 0;
212 static void parse_cryptokey(AVFormatContext *avfc, const char *str) {
213 int len = strlen(str) / 2;
214 uint8_t *key = av_mallocz(len);
215 int i;
216 avfc->keylen = len;
217 avfc->key = key;
218 for (i = 0; i < len; i++, str += 2)
219 *key++ = (char2int(str[0]) << 4) | char2int(str[1]);
222 static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
223 lavf_priv_t *priv= demuxer->priv;
224 AVStream *st= avfc->streams[i];
225 AVCodecContext *codec= st->codec;
226 AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0);
227 int g, override_tag = av_codec_get_tag(mp_codecid_override_taglists,
228 codec->codec_id);
229 // For some formats (like PCM) always trust CODEC_ID_* more than codec_tag
230 if (override_tag)
231 codec->codec_tag = override_tag;
233 switch(codec->codec_type){
234 case CODEC_TYPE_AUDIO:{
235 WAVEFORMATEX *wf;
236 sh_audio_t* sh_audio;
237 sh_audio=new_sh_audio(demuxer, i);
238 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "lavf", i);
239 if(!sh_audio)
240 break;
241 priv->astreams[priv->audio_streams] = i;
242 priv->audio_streams++;
243 wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1);
244 // mp4a tag is used for all mp4 files no matter what they actually contain
245 if(codec->codec_tag == MKTAG('m', 'p', '4', 'a'))
246 codec->codec_tag= 0;
247 if(!codec->codec_tag)
248 codec->codec_tag= av_codec_get_tag(mp_wav_taglists, codec->codec_id);
249 wf->wFormatTag= codec->codec_tag;
250 wf->nChannels= codec->channels;
251 wf->nSamplesPerSec= codec->sample_rate;
252 wf->nAvgBytesPerSec= codec->bit_rate/8;
253 wf->nBlockAlign= codec->block_align ? codec->block_align : 1;
254 wf->wBitsPerSample= codec->bits_per_coded_sample;
255 wf->cbSize= codec->extradata_size;
256 if(codec->extradata_size)
257 memcpy(wf + 1, codec->extradata, codec->extradata_size);
258 sh_audio->wf= wf;
259 sh_audio->audio.dwSampleSize= codec->block_align;
260 if(codec->frame_size && codec->sample_rate){
261 sh_audio->audio.dwScale=codec->frame_size;
262 sh_audio->audio.dwRate= codec->sample_rate;
263 }else{
264 sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8;
265 sh_audio->audio.dwRate = codec->bit_rate;
267 g= av_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate);
268 sh_audio->audio.dwScale /= g;
269 sh_audio->audio.dwRate /= g;
270 // printf("sca:%d rat:%d fs:%d sr:%d ba:%d\n", sh_audio->audio.dwScale, sh_audio->audio.dwRate, codec->frame_size, codec->sample_rate, codec->block_align);
271 sh_audio->ds= demuxer->audio;
272 sh_audio->format= codec->codec_tag;
273 sh_audio->channels= codec->channels;
274 sh_audio->samplerate= codec->sample_rate;
275 sh_audio->i_bps= codec->bit_rate/8;
276 switch (codec->codec_id) {
277 case CODEC_ID_PCM_S8:
278 case CODEC_ID_PCM_U8:
279 sh_audio->samplesize = 1;
280 break;
281 case CODEC_ID_PCM_S16LE:
282 case CODEC_ID_PCM_S16BE:
283 case CODEC_ID_PCM_U16LE:
284 case CODEC_ID_PCM_U16BE:
285 sh_audio->samplesize = 2;
286 break;
287 case CODEC_ID_PCM_ALAW:
288 sh_audio->format = 0x6;
289 break;
290 case CODEC_ID_PCM_MULAW:
291 sh_audio->format = 0x7;
292 break;
294 if (lang && lang->value) {
295 sh_audio->lang = strdup(lang->value);
296 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_LANG=%s\n", i, sh_audio->lang);
298 if (st->disposition & AV_DISPOSITION_DEFAULT)
299 sh_audio->default_track = 1;
300 if(mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V);
301 // select the first audio stream
302 if (!demuxer->audio->sh) {
303 demuxer->audio->id = i;
304 demuxer->audio->sh= demuxer->a_streams[i];
305 } else
306 st->discard= AVDISCARD_ALL;
307 break;
309 case CODEC_TYPE_VIDEO:{
310 sh_video_t* sh_video;
311 BITMAPINFOHEADER *bih;
312 sh_video=new_sh_video(demuxer, i);
313 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "lavf", i);
314 if(!sh_video) break;
315 priv->vstreams[priv->video_streams] = i;
316 priv->video_streams++;
317 bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1);
319 if(codec->codec_id == CODEC_ID_RAWVIDEO) {
320 switch (codec->pix_fmt) {
321 case PIX_FMT_RGB24:
322 codec->codec_tag= MKTAG(24, 'B', 'G', 'R');
325 if(!codec->codec_tag)
326 codec->codec_tag= av_codec_get_tag(mp_bmp_taglists, codec->codec_id);
327 bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size;
328 bih->biWidth= codec->width;
329 bih->biHeight= codec->height;
330 bih->biBitCount= codec->bits_per_coded_sample;
331 bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;
332 bih->biCompression= codec->codec_tag;
333 sh_video->bih= bih;
334 sh_video->disp_w= codec->width;
335 sh_video->disp_h= codec->height;
336 if (st->time_base.den) { /* if container has time_base, use that */
337 sh_video->video.dwRate= st->time_base.den;
338 sh_video->video.dwScale= st->time_base.num;
339 } else {
340 sh_video->video.dwRate= codec->time_base.den;
341 sh_video->video.dwScale= codec->time_base.num;
343 sh_video->fps=av_q2d(st->r_frame_rate);
344 sh_video->frametime=1/av_q2d(st->r_frame_rate);
345 sh_video->format=bih->biCompression;
346 if(st->sample_aspect_ratio.num)
347 sh_video->aspect = codec->width * st->sample_aspect_ratio.num
348 / (float)(codec->height * st->sample_aspect_ratio.den);
349 else
350 sh_video->aspect=codec->width * codec->sample_aspect_ratio.num
351 / (float)(codec->height * codec->sample_aspect_ratio.den);
352 sh_video->i_bps=codec->bit_rate/8;
353 mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n",
354 codec->width, codec->sample_aspect_ratio.num,
355 codec->height, codec->sample_aspect_ratio.den);
357 sh_video->ds= demuxer->video;
358 if(codec->extradata_size)
359 memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size);
360 if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
362 short biPlanes;
363 int biXPelsPerMeter;
364 int biYPelsPerMeter;
365 int biClrUsed;
366 int biClrImportant;
368 if(demuxer->video->id != i && demuxer->video->id != -1)
369 st->discard= AVDISCARD_ALL;
370 else{
371 demuxer->video->id = i;
372 demuxer->video->sh= demuxer->v_streams[i];
374 break;
376 case CODEC_TYPE_SUBTITLE:{
377 sh_sub_t* sh_sub;
378 char type;
379 /* only support text subtitles for now */
380 if(codec->codec_id == CODEC_ID_TEXT)
381 type = 't';
382 else if(codec->codec_id == CODEC_ID_MOV_TEXT)
383 type = 'm';
384 else if(codec->codec_id == CODEC_ID_SSA)
385 type = 'a';
386 else if(codec->codec_id == CODEC_ID_DVD_SUBTITLE)
387 type = 'v';
388 else if(codec->codec_id == CODEC_ID_DVB_TELETEXT)
389 type = 'd';
390 else
391 break;
392 sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams);
393 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_SubtitleID, "lavf", priv->sub_streams);
394 if(!sh_sub) break;
395 priv->sstreams[priv->sub_streams] = i;
396 sh_sub->type = type;
397 if (codec->extradata_size) {
398 sh_sub->extradata = malloc(codec->extradata_size);
399 memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
400 sh_sub->extradata_len = codec->extradata_size;
402 if (lang && lang->value) {
403 sh_sub->lang = strdup(lang->value);
404 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_LANG=%s\n", priv->sub_streams, sh_sub->lang);
406 if (st->disposition & AV_DISPOSITION_DEFAULT)
407 sh_sub->default_track = 1;
408 priv->sub_streams++;
409 break;
411 case CODEC_TYPE_ATTACHMENT:{
412 if (st->codec->codec_id == CODEC_ID_TTF)
413 demuxer_add_attachment(demuxer, st->filename,
414 "application/x-truetype-font",
415 codec->extradata, codec->extradata_size);
416 break;
418 default:
419 st->discard= AVDISCARD_ALL;
423 static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
424 AVFormatContext *avfc;
425 AVFormatParameters ap;
426 const AVOption *opt;
427 AVMetadataTag *t = NULL;
428 lavf_priv_t *priv= demuxer->priv;
429 int i;
430 char mp_filename[256]="mp:";
432 memset(&ap, 0, sizeof(AVFormatParameters));
434 stream_seek(demuxer->stream, 0);
436 avfc = av_alloc_format_context();
438 if (opt_cryptokey)
439 parse_cryptokey(avfc, opt_cryptokey);
440 if (user_correct_pts != 0)
441 avfc->flags |= AVFMT_FLAG_GENPTS;
442 if (index_mode == 0)
443 avfc->flags |= AVFMT_FLAG_IGNIDX;
445 ap.prealloced_context = 1;
446 if(opt_probesize) {
447 opt = av_set_int(avfc, "probesize", opt_probesize);
448 if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %u\n", opt_probesize);
450 if(opt_analyzeduration) {
451 opt = av_set_int(avfc, "analyzeduration", opt_analyzeduration * AV_TIME_BASE);
452 if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option analyzeduration to %u\n", opt_analyzeduration);
455 if(opt_avopt){
456 if(parse_avopts(avfc, opt_avopt) < 0){
457 mp_msg(MSGT_HEADER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", opt_avopt);
458 return NULL;
462 if(demuxer->stream->url)
463 strncpy(mp_filename + 3, demuxer->stream->url, sizeof(mp_filename)-3);
464 else
465 strncpy(mp_filename + 3, "foobar.dummy", sizeof(mp_filename)-3);
467 priv->pb = av_alloc_put_byte(priv->buffer, BIO_BUFFER_SIZE, 0,
468 demuxer->stream, mp_read, NULL, mp_seek);
469 priv->pb->is_streamed = !demuxer->stream->end_pos || (demuxer->stream->flags & STREAM_SEEK) != STREAM_SEEK;
471 if(av_open_input_stream(&avfc, priv->pb, mp_filename, priv->avif, &ap)<0){
472 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n");
473 return NULL;
476 priv->avfc= avfc;
478 if(av_find_stream_info(avfc) < 0){
479 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n");
480 return NULL;
483 /* Add metadata. */
484 av_metadata_conv(avfc, NULL, avfc->iformat->metadata_conv);
485 while((t = av_metadata_get(avfc->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
486 demux_info_add(demuxer, t->key, t->value);
488 for(i=0; i < avfc->nb_chapters; i++) {
489 AVChapter *c = avfc->chapters[i];
490 uint64_t start = av_rescale_q(c->start, c->time_base, (AVRational){1,1000});
491 uint64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,1000});
492 t = av_metadata_get(c->metadata, "title", NULL, 0);
493 demuxer_add_chapter(demuxer, t ? t->value : NULL, start, end);
496 for(i=0; i<avfc->nb_streams; i++)
497 handle_stream(demuxer, avfc, i);
498 if(avfc->nb_programs) {
499 int p;
500 for (p = 0; p < avfc->nb_programs; p++) {
501 AVProgram *program = avfc->programs[p];
502 t = av_metadata_get(program->metadata, "title", NULL, 0);
503 mp_msg(MSGT_HEADER,MSGL_INFO,"LAVF: Program %d %s\n", program->id, t ? t->value : "");
507 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams);
508 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD);
509 if(!priv->audio_streams) demuxer->audio->id=-2; // nosound
510 // else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
511 if(!priv->video_streams){
512 if(!priv->audio_streams){
513 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n");
514 return NULL;
516 demuxer->video->id=-2; // audio-only
517 } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;
519 return demuxer;
522 static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
523 lavf_priv_t *priv= demux->priv;
524 AVPacket pkt;
525 demux_packet_t *dp;
526 demux_stream_t *ds;
527 int id;
528 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_lavf_fill_buffer()\n");
530 demux->filepos=stream_tell(demux->stream);
532 if(av_read_frame(priv->avfc, &pkt) < 0)
533 return 0;
535 id= pkt.stream_index;
537 if(id==demux->audio->id){
538 // audio
539 ds=demux->audio;
540 if(!ds->sh){
541 ds->sh=demux->a_streams[id];
542 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id);
544 } else if(id==demux->video->id){
545 // video
546 ds=demux->video;
547 if(!ds->sh){
548 ds->sh=demux->v_streams[id];
549 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id);
551 } else if(id==demux->sub->id){
552 // subtitle
553 ds=demux->sub;
554 sub_utf8=1;
555 } else {
556 av_free_packet(&pkt);
557 return 1;
560 if(0/*pkt.destruct == av_destruct_packet*/){
561 //ok kids, dont try this at home :)
562 dp=malloc(sizeof(demux_packet_t));
563 dp->len=pkt.size;
564 dp->next=NULL;
565 dp->refcount=1;
566 dp->master=NULL;
567 dp->buffer=pkt.data;
568 pkt.destruct= NULL;
569 }else{
570 dp=new_demux_packet(pkt.size);
571 memcpy(dp->buffer, pkt.data, pkt.size);
572 av_free_packet(&pkt);
575 if(pkt.pts != AV_NOPTS_VALUE){
576 dp->pts=pkt.pts * av_q2d(priv->avfc->streams[id]->time_base);
577 priv->last_pts= dp->pts * AV_TIME_BASE;
578 if(pkt.convergence_duration)
579 dp->endpts = dp->pts + pkt.convergence_duration * av_q2d(priv->avfc->streams[id]->time_base);
581 dp->pos=demux->filepos;
582 dp->flags= !!(pkt.flags&PKT_FLAG_KEY);
583 // append packet to DS stream:
584 ds_add_packet(ds,dp);
585 return 1;
588 static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags){
589 lavf_priv_t *priv = demuxer->priv;
590 int avsflags = 0;
591 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %f, %d)\n", demuxer, rel_seek_secs, audio_delay, flags);
593 if (flags & SEEK_ABSOLUTE) {
594 priv->last_pts = priv->avfc->start_time;
595 } else {
596 if (rel_seek_secs < 0) avsflags = AVSEEK_FLAG_BACKWARD;
598 if (flags & SEEK_FACTOR) {
599 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
600 return;
601 priv->last_pts += rel_seek_secs * priv->avfc->duration;
602 } else {
603 priv->last_pts += rel_seek_secs * AV_TIME_BASE;
605 if (av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags) < 0) {
606 avsflags ^= AVSEEK_FLAG_BACKWARD;
607 av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
611 static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
613 lavf_priv_t *priv = demuxer->priv;
615 switch (cmd) {
616 case DEMUXER_CTRL_CORRECT_PTS:
617 return DEMUXER_CTRL_OK;
618 case DEMUXER_CTRL_GET_TIME_LENGTH:
619 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
620 return DEMUXER_CTRL_DONTKNOW;
622 *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
623 return DEMUXER_CTRL_OK;
625 case DEMUXER_CTRL_GET_PERCENT_POS:
626 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
627 return DEMUXER_CTRL_DONTKNOW;
629 *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration);
630 return DEMUXER_CTRL_OK;
631 case DEMUXER_CTRL_SWITCH_AUDIO:
632 case DEMUXER_CTRL_SWITCH_VIDEO:
634 int id = *((int*)arg);
635 int newid = -2;
636 int i, curridx = -1;
637 int nstreams, *pstreams;
638 demux_stream_t *ds;
640 if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)
642 ds = demuxer->video;
643 nstreams = priv->video_streams;
644 pstreams = priv->vstreams;
646 else
648 ds = demuxer->audio;
649 nstreams = priv->audio_streams;
650 pstreams = priv->astreams;
652 for(i = 0; i < nstreams; i++)
654 if(pstreams[i] == ds->id) //current stream id
656 curridx = i;
657 break;
661 if(id == -2) { // no sound
662 i = -1;
663 } else if(id == -1) { // next track
664 i = (curridx + 2) % (nstreams + 1) - 1;
665 if (i >= 0)
666 newid = pstreams[i];
668 else // select track by id
670 for(i = 0; i < nstreams; i++)
672 if(pstreams[i] == id)
674 newid = id;
675 break;
679 if(i == curridx)
680 return DEMUXER_CTRL_NOTIMPL;
681 else
683 ds_free_packs(ds);
684 if(ds->id >= 0)
685 priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
686 *((int*)arg) = ds->id = newid;
687 if(newid >= 0)
688 priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
689 return DEMUXER_CTRL_OK;
692 case DEMUXER_CTRL_IDENTIFY_PROGRAM:
694 demux_program_t *prog = arg;
695 AVProgram *program;
696 int p, i;
697 int start;
699 prog->vid = prog->aid = prog->sid = -2; //no audio and no video by default
700 if(priv->avfc->nb_programs < 1)
701 return DEMUXER_CTRL_DONTKNOW;
703 if(prog->progid == -1)
705 p = 0;
706 while(p<priv->avfc->nb_programs && priv->avfc->programs[p]->id != priv->cur_program)
707 p++;
708 p = (p + 1) % priv->avfc->nb_programs;
710 else
712 for(i=0; i<priv->avfc->nb_programs; i++)
713 if(priv->avfc->programs[i]->id == prog->progid)
714 break;
715 if(i==priv->avfc->nb_programs)
716 return DEMUXER_CTRL_DONTKNOW;
717 p = i;
719 start = p;
720 redo:
721 program = priv->avfc->programs[p];
722 for(i=0; i<program->nb_stream_indexes; i++)
724 switch(priv->avfc->streams[program->stream_index[i]]->codec->codec_type)
726 case CODEC_TYPE_VIDEO:
727 if(prog->vid == -2)
728 prog->vid = program->stream_index[i];
729 break;
730 case CODEC_TYPE_AUDIO:
731 if(prog->aid == -2)
732 prog->aid = program->stream_index[i];
733 break;
734 case CODEC_TYPE_SUBTITLE:
735 if(prog->sid == -2 && priv->avfc->streams[program->stream_index[i]]->codec->codec_id == CODEC_ID_TEXT)
736 prog->sid = program->stream_index[i];
737 break;
740 if(prog->progid == -1 && prog->vid == -2 && prog->aid == -2)
742 p = (p + 1) % priv->avfc->nb_programs;
743 if (p == start)
744 return DEMUXER_CTRL_DONTKNOW;
745 goto redo;
747 priv->cur_program = prog->progid = program->id;
748 return DEMUXER_CTRL_OK;
750 default:
751 return DEMUXER_CTRL_NOTIMPL;
755 static void demux_close_lavf(demuxer_t *demuxer)
757 lavf_priv_t* priv = demuxer->priv;
758 if (priv){
759 if(priv->avfc)
761 av_freep(&priv->avfc->key);
762 av_close_input_stream(priv->avfc);
764 av_freep(&priv->pb);
765 free(priv); demuxer->priv= NULL;
770 const demuxer_desc_t demuxer_desc_lavf = {
771 "libavformat demuxer",
772 "lavf",
773 "libavformat",
774 "Michael Niedermayer",
775 "supports many formats, requires libavformat",
776 DEMUXER_TYPE_LAVF,
777 0, // Check after other demuxer
778 lavf_check_file,
779 demux_lavf_fill_buffer,
780 demux_open_lavf,
781 demux_close_lavf,
782 demux_seek_lavf,
783 demux_lavf_control
786 const demuxer_desc_t demuxer_desc_lavf_preferred = {
787 "libavformat preferred demuxer",
788 "lavfpref",
789 "libavformat",
790 "Michael Niedermayer",
791 "supports many formats, requires libavformat",
792 DEMUXER_TYPE_LAVF_PREFERRED,
794 lavf_check_preferred_file,
795 demux_lavf_fill_buffer,
796 demux_open_lavf,
797 demux_close_lavf,
798 demux_seek_lavf,
799 demux_lavf_control