vidix/pci.c: Add config.h include
[mplayer/glamo.git] / libmpdemux / demux_lavf.c
blob87869f69e256eb52f9c94b75302135761fc156f6
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>
25 #include <stdbool.h>
27 #include "config.h"
28 #include "options.h"
29 #include "mp_msg.h"
30 #include "av_opts.h"
31 #include "bstr.h"
33 #include "stream/stream.h"
34 #include "aviprint.h"
35 #include "demuxer.h"
36 #include "stheader.h"
37 #include "m_option.h"
38 #include "libvo/sub.h"
40 #include "libavformat/avformat.h"
41 #include "libavformat/avio.h"
42 #include "libavutil/avutil.h"
43 #include "libavutil/avstring.h"
44 #include "libavcodec/opt.h"
46 #include "mp_taglists.h"
48 #define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE
49 #define SMALL_MAX_PROBE_SIZE (32 * 1024)
50 #define PROBE_BUF_SIZE (2*1024*1024)
52 const m_option_t lavfdopts_conf[] = {
53 OPT_INTRANGE("probesize", lavfdopts.probesize, 0, 32, INT_MAX),
54 OPT_STRING("format", lavfdopts.format, 0),
55 OPT_INTRANGE("analyzeduration", lavfdopts.analyzeduration, 0, 0, INT_MAX),
56 OPT_STRING("cryptokey", lavfdopts.cryptokey, 0),
57 OPT_STRING("o", lavfdopts.avopt, 0),
58 {NULL, NULL, 0, 0, 0, 0, NULL}
61 #define BIO_BUFFER_SIZE 32768
63 typedef struct lavf_priv {
64 AVInputFormat *avif;
65 AVFormatContext *avfc;
66 ByteIOContext *pb;
67 uint8_t buffer[BIO_BUFFER_SIZE];
68 int audio_streams;
69 int video_streams;
70 int sub_streams;
71 int64_t last_pts;
72 int astreams[MAX_A_STREAMS];
73 int vstreams[MAX_V_STREAMS];
74 int sstreams[MAX_S_STREAMS];
75 int cur_program;
76 }lavf_priv_t;
78 static int mp_read(void *opaque, uint8_t *buf, int size) {
79 struct demuxer *demuxer = opaque;
80 struct stream *stream = demuxer->stream;
81 int ret;
83 ret=stream_read(stream, buf, size);
85 mp_msg(MSGT_HEADER,MSGL_DBG2,"%d=mp_read(%p, %p, %d), pos: %"PRId64", eof:%d\n",
86 ret, stream, buf, size, stream_tell(stream), stream->eof);
87 return ret;
90 static int64_t mp_seek(void *opaque, int64_t pos, int whence) {
91 struct demuxer *demuxer = opaque;
92 struct stream *stream = demuxer->stream;
93 int64_t current_pos;
94 mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %"PRId64", %d)\n", stream, pos, whence);
95 if(whence == SEEK_CUR)
96 pos +=stream_tell(stream);
97 else if(whence == SEEK_END && stream->end_pos > 0)
98 pos += stream->end_pos;
99 else if(whence == SEEK_SET)
100 pos += stream->start_pos;
101 else if(whence == AVSEEK_SIZE && stream->end_pos > 0)
102 return stream->end_pos - stream->start_pos;
103 else
104 return -1;
106 if(pos<0)
107 return -1;
108 current_pos = stream_tell(stream);
109 if(stream_seek(stream, pos)==0) {
110 stream_reset(stream);
111 stream_seek(stream, current_pos);
112 return -1;
115 return pos - stream->start_pos;
118 static int64_t mp_read_seek(void *opaque, int stream_idx, int64_t ts, int flags)
120 struct demuxer *demuxer = opaque;
121 struct stream *stream = demuxer->stream;
122 struct lavf_priv *priv = demuxer->priv;
124 AVStream *st = priv->avfc->streams[stream_idx];
125 double pts = (double)ts * st->time_base.num / st->time_base.den;
126 int ret = stream_control(stream, STREAM_CTRL_SEEK_TO_TIME, &pts);
127 if (ret < 0)
128 ret = AVERROR(ENOSYS);
129 return ret;
132 static void list_formats(void) {
133 AVInputFormat *fmt;
134 mp_msg(MSGT_DEMUX, MSGL_INFO, "Available lavf input formats:\n");
135 for (fmt = first_iformat; fmt; fmt = fmt->next)
136 mp_msg(MSGT_DEMUX, MSGL_INFO, "%15s : %s\n", fmt->name, fmt->long_name);
139 static int lavf_check_file(demuxer_t *demuxer){
140 struct MPOpts *opts = demuxer->opts;
141 struct lavfdopts *lavfdopts = &opts->lavfdopts;
142 AVProbeData avpd;
143 lavf_priv_t *priv;
144 int probe_data_size = 0;
145 int read_size = INITIAL_PROBE_SIZE;
146 int score;
148 if(!demuxer->priv)
149 demuxer->priv=calloc(sizeof(lavf_priv_t),1);
150 priv= demuxer->priv;
152 av_register_all();
154 char *format = lavfdopts->format;
155 if (!format)
156 format = demuxer->stream->lavf_type;
157 if (format) {
158 if (strcmp(format, "help") == 0) {
159 list_formats();
160 return 0;
162 priv->avif = av_find_input_format(format);
163 if (!priv->avif) {
164 mp_msg(MSGT_DEMUX, MSGL_FATAL, "Unknown lavf format %s\n", format);
165 return 0;
167 mp_msg(MSGT_DEMUX,MSGL_INFO,"Forced lavf %s demuxer\n", priv->avif->long_name);
168 return DEMUXER_TYPE_LAVF;
171 avpd.buf = av_mallocz(FFMAX(BIO_BUFFER_SIZE, PROBE_BUF_SIZE) +
172 FF_INPUT_BUFFER_PADDING_SIZE);
173 do {
174 read_size = stream_read(demuxer->stream, avpd.buf + probe_data_size, read_size);
175 if(read_size < 0) {
176 av_free(avpd.buf);
177 return 0;
179 probe_data_size += read_size;
180 avpd.filename= demuxer->stream->url;
181 if (!avpd.filename) {
182 mp_msg(MSGT_DEMUX, MSGL_WARN, "Stream url is not set!\n");
183 avpd.filename = "";
185 if (!strncmp(avpd.filename, "ffmpeg://", 9))
186 avpd.filename += 9;
187 avpd.buf_size= probe_data_size;
189 score = 0;
190 priv->avif= av_probe_input_format2(&avpd, probe_data_size > 0, &score);
191 read_size = FFMIN(2*read_size, PROBE_BUF_SIZE - probe_data_size);
192 } while ((demuxer->desc->type != DEMUXER_TYPE_LAVF_PREFERRED ||
193 probe_data_size < SMALL_MAX_PROBE_SIZE) &&
194 score <= AVPROBE_SCORE_MAX / 4 &&
195 read_size > 0 && probe_data_size < PROBE_BUF_SIZE);
196 av_free(avpd.buf);
198 if(!priv->avif){
199 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: no clue about this gibberish!\n");
200 return 0;
201 }else
202 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name);
204 return DEMUXER_TYPE_LAVF;
207 static const char * const preferred_list[] = {
208 "dxa",
209 "flv",
210 "gxf",
211 "nut",
212 "nuv",
213 "mov,mp4,m4a,3gp,3g2,mj2",
214 "mpc",
215 "mpc8",
216 "mxf",
217 "ogg",
218 "swf",
219 "vqf",
220 "w64",
221 "wv",
222 NULL
225 static int lavf_check_preferred_file(demuxer_t *demuxer){
226 if (lavf_check_file(demuxer)) {
227 const char * const *p = preferred_list;
228 lavf_priv_t *priv = demuxer->priv;
229 while (*p) {
230 if (strcmp(*p, priv->avif->name) == 0)
231 return DEMUXER_TYPE_LAVF_PREFERRED;
232 p++;
235 return 0;
238 static uint8_t char2int(char c) {
239 if (c >= '0' && c <= '9') return c - '0';
240 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
241 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
242 return 0;
245 static void parse_cryptokey(AVFormatContext *avfc, const char *str) {
246 int len = strlen(str) / 2;
247 uint8_t *key = av_mallocz(len);
248 int i;
249 avfc->keylen = len;
250 avfc->key = key;
251 for (i = 0; i < len; i++, str += 2)
252 *key++ = (char2int(str[0]) << 4) | char2int(str[1]);
255 static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
256 lavf_priv_t *priv= demuxer->priv;
257 AVStream *st= avfc->streams[i];
258 AVCodecContext *codec= st->codec;
259 char *stream_type = NULL;
260 int stream_id;
261 AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0);
262 AVMetadataTag *title= av_metadata_get(st->metadata, "title", NULL, 0);
263 int g, override_tag = mp_av_codec_get_tag(mp_codecid_override_taglists,
264 codec->codec_id);
265 // For some formats (like PCM) always trust CODEC_ID_* more than codec_tag
266 if (override_tag)
267 codec->codec_tag = override_tag;
269 switch(codec->codec_type){
270 case CODEC_TYPE_AUDIO:{
271 WAVEFORMATEX *wf;
272 sh_audio_t* sh_audio;
273 sh_audio = new_sh_audio_aid(demuxer, i, priv->audio_streams);
274 if(!sh_audio)
275 break;
276 stream_type = "audio";
277 priv->astreams[priv->audio_streams] = i;
278 wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1);
279 // mp4a tag is used for all mp4 files no matter what they actually contain
280 if(codec->codec_tag == MKTAG('m', 'p', '4', 'a'))
281 codec->codec_tag= 0;
282 if(!codec->codec_tag)
283 codec->codec_tag= mp_av_codec_get_tag(mp_wav_taglists, codec->codec_id);
284 wf->wFormatTag= codec->codec_tag;
285 wf->nChannels= codec->channels;
286 wf->nSamplesPerSec= codec->sample_rate;
287 wf->nAvgBytesPerSec= codec->bit_rate/8;
288 wf->nBlockAlign= codec->block_align ? codec->block_align : 1;
289 wf->wBitsPerSample= codec->bits_per_coded_sample;
290 wf->cbSize= codec->extradata_size;
291 if(codec->extradata_size)
292 memcpy(wf + 1, codec->extradata, codec->extradata_size);
293 sh_audio->wf= wf;
294 sh_audio->audio.dwSampleSize= codec->block_align;
295 if(codec->frame_size && codec->sample_rate){
296 sh_audio->audio.dwScale=codec->frame_size;
297 sh_audio->audio.dwRate= codec->sample_rate;
298 }else{
299 sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8;
300 sh_audio->audio.dwRate = codec->bit_rate;
302 g= av_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate);
303 sh_audio->audio.dwScale /= g;
304 sh_audio->audio.dwRate /= g;
305 // 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);
306 sh_audio->ds= demuxer->audio;
307 sh_audio->format= codec->codec_tag;
308 sh_audio->channels= codec->channels;
309 sh_audio->samplerate= codec->sample_rate;
310 sh_audio->i_bps= codec->bit_rate/8;
311 switch (codec->codec_id) {
312 case CODEC_ID_PCM_S8:
313 case CODEC_ID_PCM_U8:
314 sh_audio->samplesize = 1;
315 break;
316 case CODEC_ID_PCM_S16LE:
317 case CODEC_ID_PCM_S16BE:
318 case CODEC_ID_PCM_U16LE:
319 case CODEC_ID_PCM_U16BE:
320 sh_audio->samplesize = 2;
321 break;
322 case CODEC_ID_PCM_ALAW:
323 sh_audio->format = 0x6;
324 break;
325 case CODEC_ID_PCM_MULAW:
326 sh_audio->format = 0x7;
327 break;
329 if (title && title->value)
330 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_NAME=%s\n", priv->audio_streams, title->value);
331 if (lang && lang->value) {
332 sh_audio->lang = strdup(lang->value);
333 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_LANG=%s\n", priv->audio_streams, sh_audio->lang);
335 if (st->disposition & AV_DISPOSITION_DEFAULT)
336 sh_audio->default_track = 1;
337 if(mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V);
338 // select the first audio stream
339 if (!demuxer->audio->sh) {
340 demuxer->audio->id = i;
341 demuxer->audio->sh= demuxer->a_streams[i];
342 } else
343 st->discard= AVDISCARD_ALL;
344 stream_id = priv->audio_streams++;
345 break;
347 case CODEC_TYPE_VIDEO:{
348 sh_video_t* sh_video;
349 BITMAPINFOHEADER *bih;
350 sh_video=new_sh_video_vid(demuxer, i, priv->video_streams);
351 if(!sh_video) break;
352 stream_type = "video";
353 priv->vstreams[priv->video_streams] = i;
354 bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1);
356 if(codec->codec_id == CODEC_ID_RAWVIDEO) {
357 switch (codec->pix_fmt) {
358 case PIX_FMT_RGB24:
359 codec->codec_tag= MKTAG(24, 'B', 'G', 'R');
362 if(!codec->codec_tag)
363 codec->codec_tag= mp_av_codec_get_tag(mp_bmp_taglists, codec->codec_id);
364 bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size;
365 bih->biWidth= codec->width;
366 bih->biHeight= codec->height;
367 bih->biBitCount= codec->bits_per_coded_sample;
368 bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;
369 bih->biCompression= codec->codec_tag;
370 sh_video->bih= bih;
371 sh_video->disp_w= codec->width;
372 sh_video->disp_h= codec->height;
373 if (st->time_base.den) { /* if container has time_base, use that */
374 sh_video->video.dwRate= st->time_base.den;
375 sh_video->video.dwScale= st->time_base.num;
376 } else {
377 sh_video->video.dwRate= codec->time_base.den;
378 sh_video->video.dwScale= codec->time_base.num;
380 sh_video->fps=av_q2d(st->r_frame_rate);
381 sh_video->frametime=1/av_q2d(st->r_frame_rate);
382 sh_video->format=bih->biCompression;
383 if(st->sample_aspect_ratio.num)
384 sh_video->aspect = codec->width * st->sample_aspect_ratio.num
385 / (float)(codec->height * st->sample_aspect_ratio.den);
386 else
387 sh_video->aspect=codec->width * codec->sample_aspect_ratio.num
388 / (float)(codec->height * codec->sample_aspect_ratio.den);
389 sh_video->i_bps=codec->bit_rate/8;
390 if (title && title->value)
391 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VID_%d_NAME=%s\n", priv->video_streams, title->value);
392 mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n",
393 codec->width, codec->sample_aspect_ratio.num,
394 codec->height, codec->sample_aspect_ratio.den);
396 sh_video->ds= demuxer->video;
397 if(codec->extradata_size)
398 memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size);
399 if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
401 short biPlanes;
402 int biXPelsPerMeter;
403 int biYPelsPerMeter;
404 int biClrUsed;
405 int biClrImportant;
407 if(demuxer->video->id != i && demuxer->video->id != -1)
408 st->discard= AVDISCARD_ALL;
409 else{
410 demuxer->video->id = i;
411 demuxer->video->sh= demuxer->v_streams[i];
413 stream_id = priv->video_streams++;
414 break;
416 case CODEC_TYPE_SUBTITLE:{
417 sh_sub_t* sh_sub;
418 char type;
419 /* only support text subtitles for now */
420 if(codec->codec_id == CODEC_ID_TEXT)
421 type = 't';
422 else if(codec->codec_id == CODEC_ID_MOV_TEXT)
423 type = 'm';
424 else if(codec->codec_id == CODEC_ID_SSA)
425 type = 'a';
426 else if(codec->codec_id == CODEC_ID_DVD_SUBTITLE)
427 type = 'v';
428 else if(codec->codec_id == CODEC_ID_DVB_TELETEXT)
429 type = 'd';
430 else
431 break;
432 sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams);
433 if(!sh_sub) break;
434 stream_type = "subtitle";
435 priv->sstreams[priv->sub_streams] = i;
436 sh_sub->type = type;
437 if (codec->extradata_size) {
438 sh_sub->extradata = malloc(codec->extradata_size);
439 memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
440 sh_sub->extradata_len = codec->extradata_size;
442 if (title && title->value)
443 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_NAME=%s\n", priv->sub_streams, title->value);
444 if (lang && lang->value) {
445 sh_sub->lang = strdup(lang->value);
446 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_LANG=%s\n", priv->sub_streams, sh_sub->lang);
448 if (st->disposition & AV_DISPOSITION_DEFAULT)
449 sh_sub->default_track = 1;
450 stream_id = priv->sub_streams++;
451 break;
453 case CODEC_TYPE_ATTACHMENT:{
454 if (st->codec->codec_id == CODEC_ID_TTF)
455 demuxer_add_attachment(demuxer, BSTR(st->filename),
456 BSTR("application/x-truetype-font"),
457 (struct bstr){codec->extradata,
458 codec->extradata_size});
459 break;
461 default:
462 st->discard= AVDISCARD_ALL;
464 if (stream_type) {
465 AVCodec *avc = avcodec_find_decoder(codec->codec_id);
466 mp_msg(MSGT_DEMUX, MSGL_INFO, "[lavf] stream %d: %s (%s), -%cid %d", i, stream_type, avc ? avc->name : "unknown", *stream_type, stream_id);
467 if (lang && lang->value && *stream_type != 'v')
468 mp_msg(MSGT_DEMUX, MSGL_INFO, ", -%clang %s", *stream_type, lang->value);
469 if (title && title->value)
470 mp_msg(MSGT_DEMUX, MSGL_INFO, ", %s", title->value);
471 mp_msg(MSGT_DEMUX, MSGL_INFO, "\n");
475 static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
476 struct MPOpts *opts = demuxer->opts;
477 struct lavfdopts *lavfdopts = &opts->lavfdopts;
478 AVFormatContext *avfc;
479 AVFormatParameters ap;
480 const AVOption *opt;
481 AVMetadataTag *t = NULL;
482 lavf_priv_t *priv= demuxer->priv;
483 int i;
484 char mp_filename[256]="mp:";
486 memset(&ap, 0, sizeof(AVFormatParameters));
488 stream_seek(demuxer->stream, 0);
490 avfc = avformat_alloc_context();
492 if (lavfdopts->cryptokey)
493 parse_cryptokey(avfc, lavfdopts->cryptokey);
494 if (opts->user_correct_pts != 0)
495 avfc->flags |= AVFMT_FLAG_GENPTS;
496 if (index_mode == 0)
497 avfc->flags |= AVFMT_FLAG_IGNIDX;
499 ap.prealloced_context = 1;
500 if (lavfdopts->probesize) {
501 opt = av_set_int(avfc, "probesize", lavfdopts->probesize);
502 if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %u\n", lavfdopts->probesize);
504 if (lavfdopts->analyzeduration) {
505 opt = av_set_int(avfc, "analyzeduration",
506 lavfdopts->analyzeduration * AV_TIME_BASE);
507 if (!opt)
508 mp_msg(MSGT_HEADER, MSGL_ERR, "demux_lavf, couldn't set option "
509 "analyzeduration to %u\n", lavfdopts->analyzeduration);
512 if (lavfdopts->avopt){
513 if(parse_avopts(avfc, lavfdopts->avopt) < 0){
514 mp_msg(MSGT_HEADER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavfdopts->avopt);
515 return NULL;
519 if(demuxer->stream->url) {
520 if (!strncmp(demuxer->stream->url, "ffmpeg://rtsp:", 14))
521 av_strlcpy(mp_filename, demuxer->stream->url + 9, sizeof(mp_filename));
522 else
523 av_strlcat(mp_filename, demuxer->stream->url, sizeof(mp_filename));
524 } else
525 av_strlcat(mp_filename, "foobar.dummy", sizeof(mp_filename));
527 priv->pb = av_alloc_put_byte(priv->buffer, BIO_BUFFER_SIZE, 0,
528 demuxer, mp_read, NULL, mp_seek);
529 priv->pb->read_seek = mp_read_seek;
530 priv->pb->is_streamed = !demuxer->stream->end_pos || (demuxer->stream->flags & MP_STREAM_SEEK) != MP_STREAM_SEEK;
532 if(av_open_input_stream(&avfc, priv->pb, mp_filename, priv->avif, &ap)<0){
533 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n");
534 return NULL;
537 priv->avfc= avfc;
539 if(av_find_stream_info(avfc) < 0){
540 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n");
541 return NULL;
544 /* Add metadata. */
545 av_metadata_conv(avfc, NULL, avfc->iformat->metadata_conv);
546 while((t = av_metadata_get(avfc->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
547 demux_info_add(demuxer, t->key, t->value);
549 for(i=0; i < avfc->nb_chapters; i++) {
550 AVChapter *c = avfc->chapters[i];
551 uint64_t start = av_rescale_q(c->start, c->time_base, (AVRational){1,1000});
552 uint64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,1000});
553 t = av_metadata_get(c->metadata, "title", NULL, 0);
554 demuxer_add_chapter(demuxer, t ? BSTR(t->value) : BSTR(NULL), start, end);
557 for(i=0; i<avfc->nb_streams; i++)
558 handle_stream(demuxer, avfc, i);
559 if(avfc->nb_programs) {
560 int p;
561 for (p = 0; p < avfc->nb_programs; p++) {
562 AVProgram *program = avfc->programs[p];
563 t = av_metadata_get(program->metadata, "title", NULL, 0);
564 mp_msg(MSGT_HEADER,MSGL_INFO,"LAVF: Program %d %s\n", program->id, t ? t->value : "");
568 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams);
569 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD);
570 if(!priv->audio_streams) demuxer->audio->id=-2; // nosound
571 // else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
572 if(!priv->video_streams){
573 if(!priv->audio_streams){
574 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n");
575 return NULL;
577 demuxer->video->id=-2; // audio-only
578 } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;
580 demuxer->accurate_seek = true;
582 return demuxer;
585 static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
586 lavf_priv_t *priv= demux->priv;
587 AVPacket pkt;
588 demux_packet_t *dp;
589 demux_stream_t *ds;
590 int id;
591 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_lavf_fill_buffer()\n");
593 demux->filepos=stream_tell(demux->stream);
595 if(av_read_frame(priv->avfc, &pkt) < 0)
596 return 0;
598 id= pkt.stream_index;
600 if(id==demux->audio->id){
601 // audio
602 ds=demux->audio;
603 if(!ds->sh){
604 ds->sh=demux->a_streams[id];
605 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id);
607 } else if(id==demux->video->id){
608 // video
609 ds=demux->video;
610 if(!ds->sh){
611 ds->sh=demux->v_streams[id];
612 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id);
614 } else if(id==demux->sub->id){
615 // subtitle
616 ds=demux->sub;
617 sub_utf8=1;
618 } else {
619 av_free_packet(&pkt);
620 return 1;
623 if(0/*pkt.destruct == av_destruct_packet*/){
624 //ok kids, dont try this at home :)
625 dp=malloc(sizeof(demux_packet_t));
626 dp->len=pkt.size;
627 dp->next=NULL;
628 dp->refcount=1;
629 dp->master=NULL;
630 dp->buffer=pkt.data;
631 pkt.destruct= NULL;
632 }else{
633 dp=new_demux_packet(pkt.size);
634 memcpy(dp->buffer, pkt.data, pkt.size);
635 av_free_packet(&pkt);
638 if(pkt.pts != AV_NOPTS_VALUE){
639 dp->pts=pkt.pts * av_q2d(priv->avfc->streams[id]->time_base);
640 priv->last_pts= dp->pts * AV_TIME_BASE;
641 if(pkt.convergence_duration)
642 dp->endpts = dp->pts + pkt.convergence_duration * av_q2d(priv->avfc->streams[id]->time_base);
644 dp->pos=demux->filepos;
645 dp->flags= !!(pkt.flags&PKT_FLAG_KEY);
646 // append packet to DS stream:
647 ds_add_packet(ds,dp);
648 return 1;
651 static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags){
652 lavf_priv_t *priv = demuxer->priv;
653 int avsflags = 0;
654 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %f, %d)\n", demuxer, rel_seek_secs, audio_delay, flags);
656 if (flags & SEEK_ABSOLUTE) {
657 priv->last_pts = 0;
658 } else {
659 if (rel_seek_secs < 0) avsflags = AVSEEK_FLAG_BACKWARD;
661 if (flags & SEEK_FORWARD)
662 avsflags = 0;
663 else if (flags & SEEK_BACKWARD)
664 avsflags = AVSEEK_FLAG_BACKWARD;
665 if (flags & SEEK_FACTOR) {
666 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
667 return;
668 priv->last_pts += rel_seek_secs * priv->avfc->duration;
669 } else {
670 priv->last_pts += rel_seek_secs * AV_TIME_BASE;
672 if (av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags) < 0) {
673 avsflags ^= AVSEEK_FLAG_BACKWARD;
674 av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
678 static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
680 lavf_priv_t *priv = demuxer->priv;
682 switch (cmd) {
683 case DEMUXER_CTRL_CORRECT_PTS:
684 return DEMUXER_CTRL_OK;
685 case DEMUXER_CTRL_GET_TIME_LENGTH:
686 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
687 return DEMUXER_CTRL_DONTKNOW;
689 *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
690 return DEMUXER_CTRL_OK;
692 case DEMUXER_CTRL_GET_PERCENT_POS:
693 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
694 return DEMUXER_CTRL_DONTKNOW;
696 *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration);
697 return DEMUXER_CTRL_OK;
698 case DEMUXER_CTRL_SWITCH_AUDIO:
699 case DEMUXER_CTRL_SWITCH_VIDEO:
701 int id = *((int*)arg);
702 int newid = -2;
703 int i, curridx = -1;
704 int nstreams, *pstreams;
705 demux_stream_t *ds;
707 if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)
709 ds = demuxer->video;
710 nstreams = priv->video_streams;
711 pstreams = priv->vstreams;
713 else
715 ds = demuxer->audio;
716 nstreams = priv->audio_streams;
717 pstreams = priv->astreams;
719 for(i = 0; i < nstreams; i++)
721 if(pstreams[i] == ds->id) //current stream id
723 curridx = i;
724 break;
728 if(id == -2) { // no sound
729 i = -1;
730 } else if(id == -1) { // next track
731 i = (curridx + 2) % (nstreams + 1) - 1;
732 if (i >= 0)
733 newid = pstreams[i];
735 else // select track by id
737 if (id >= 0 && id < nstreams) {
738 i = id;
739 newid = pstreams[i];
742 if (i == curridx) {
743 *(int *) arg = curridx;
744 return DEMUXER_CTRL_OK;
745 } else {
746 ds_free_packs(ds);
747 if(ds->id >= 0)
748 priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
749 ds->id = newid;
750 *(int *) arg = i < 0 ? -2 : i;
751 if(newid >= 0)
752 priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
753 return DEMUXER_CTRL_OK;
756 case DEMUXER_CTRL_IDENTIFY_PROGRAM:
758 demux_program_t *prog = arg;
759 AVProgram *program;
760 int p, i;
761 int start;
763 prog->vid = prog->aid = prog->sid = -2; //no audio and no video by default
764 if(priv->avfc->nb_programs < 1)
765 return DEMUXER_CTRL_DONTKNOW;
767 if(prog->progid == -1)
769 p = 0;
770 while(p<priv->avfc->nb_programs && priv->avfc->programs[p]->id != priv->cur_program)
771 p++;
772 p = (p + 1) % priv->avfc->nb_programs;
774 else
776 for(i=0; i<priv->avfc->nb_programs; i++)
777 if(priv->avfc->programs[i]->id == prog->progid)
778 break;
779 if(i==priv->avfc->nb_programs)
780 return DEMUXER_CTRL_DONTKNOW;
781 p = i;
783 start = p;
784 redo:
785 program = priv->avfc->programs[p];
786 for(i=0; i<program->nb_stream_indexes; i++)
788 switch(priv->avfc->streams[program->stream_index[i]]->codec->codec_type)
790 case CODEC_TYPE_VIDEO:
791 if(prog->vid == -2)
792 prog->vid = program->stream_index[i];
793 break;
794 case CODEC_TYPE_AUDIO:
795 if(prog->aid == -2)
796 prog->aid = program->stream_index[i];
797 break;
798 case CODEC_TYPE_SUBTITLE:
799 if(prog->sid == -2 && priv->avfc->streams[program->stream_index[i]]->codec->codec_id == CODEC_ID_TEXT)
800 prog->sid = program->stream_index[i];
801 break;
804 if(prog->progid == -1 && prog->vid == -2 && prog->aid == -2)
806 p = (p + 1) % priv->avfc->nb_programs;
807 if (p == start)
808 return DEMUXER_CTRL_DONTKNOW;
809 goto redo;
811 priv->cur_program = prog->progid = program->id;
812 return DEMUXER_CTRL_OK;
814 default:
815 return DEMUXER_CTRL_NOTIMPL;
819 static void demux_close_lavf(demuxer_t *demuxer)
821 lavf_priv_t* priv = demuxer->priv;
822 if (priv){
823 if(priv->avfc)
825 av_freep(&priv->avfc->key);
826 av_close_input_stream(priv->avfc);
828 av_freep(&priv->pb);
829 free(priv); demuxer->priv= NULL;
834 const demuxer_desc_t demuxer_desc_lavf = {
835 "libavformat demuxer",
836 "lavf",
837 "libavformat",
838 "Michael Niedermayer",
839 "supports many formats, requires libavformat",
840 DEMUXER_TYPE_LAVF,
841 0, // Check after other demuxer
842 lavf_check_file,
843 demux_lavf_fill_buffer,
844 demux_open_lavf,
845 demux_close_lavf,
846 demux_seek_lavf,
847 demux_lavf_control
850 const demuxer_desc_t demuxer_desc_lavf_preferred = {
851 "libavformat preferred demuxer",
852 "lavfpref",
853 "libavformat",
854 "Michael Niedermayer",
855 "supports many formats, requires libavformat",
856 DEMUXER_TYPE_LAVF_PREFERRED,
858 lavf_check_preferred_file,
859 demux_lavf_fill_buffer,
860 demux_open_lavf,
861 demux_close_lavf,
862 demux_seek_lavf,
863 demux_lavf_control