stream: Use MSG_NOSIGNAL flag if available for send().
[mplayer/glamo.git] / libmpdemux / demux_lavf.c
blobec8075d219711df5dbd06856e023e6093f442115
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 (!strncmp(avpd.filename, "ffmpeg://", 9))
182 avpd.filename += 9;
183 avpd.buf_size= probe_data_size;
185 score = 0;
186 priv->avif= av_probe_input_format2(&avpd, probe_data_size > 0, &score);
187 read_size = FFMIN(2*read_size, PROBE_BUF_SIZE - probe_data_size);
188 } while ((demuxer->desc->type != DEMUXER_TYPE_LAVF_PREFERRED ||
189 probe_data_size < SMALL_MAX_PROBE_SIZE) &&
190 score <= AVPROBE_SCORE_MAX / 4 &&
191 read_size > 0 && probe_data_size < PROBE_BUF_SIZE);
192 av_free(avpd.buf);
194 if(!priv->avif){
195 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: no clue about this gibberish!\n");
196 return 0;
197 }else
198 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name);
200 return DEMUXER_TYPE_LAVF;
203 static const char * const preferred_list[] = {
204 "dxa",
205 "flv",
206 "gxf",
207 "nut",
208 "nuv",
209 "mov,mp4,m4a,3gp,3g2,mj2",
210 "mpc",
211 "mpc8",
212 "mxf",
213 "ogg",
214 "swf",
215 "vqf",
216 "w64",
217 "wv",
218 NULL
221 static int lavf_check_preferred_file(demuxer_t *demuxer){
222 if (lavf_check_file(demuxer)) {
223 const char * const *p = preferred_list;
224 lavf_priv_t *priv = demuxer->priv;
225 while (*p) {
226 if (strcmp(*p, priv->avif->name) == 0)
227 return DEMUXER_TYPE_LAVF_PREFERRED;
228 p++;
231 return 0;
234 static uint8_t char2int(char c) {
235 if (c >= '0' && c <= '9') return c - '0';
236 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
237 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
238 return 0;
241 static void parse_cryptokey(AVFormatContext *avfc, const char *str) {
242 int len = strlen(str) / 2;
243 uint8_t *key = av_mallocz(len);
244 int i;
245 avfc->keylen = len;
246 avfc->key = key;
247 for (i = 0; i < len; i++, str += 2)
248 *key++ = (char2int(str[0]) << 4) | char2int(str[1]);
251 static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
252 lavf_priv_t *priv= demuxer->priv;
253 AVStream *st= avfc->streams[i];
254 AVCodecContext *codec= st->codec;
255 char *stream_type = NULL;
256 int stream_id;
257 AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0);
258 AVMetadataTag *title= av_metadata_get(st->metadata, "title", NULL, 0);
259 int g, override_tag = mp_av_codec_get_tag(mp_codecid_override_taglists,
260 codec->codec_id);
261 // For some formats (like PCM) always trust CODEC_ID_* more than codec_tag
262 if (override_tag)
263 codec->codec_tag = override_tag;
265 switch(codec->codec_type){
266 case CODEC_TYPE_AUDIO:{
267 WAVEFORMATEX *wf;
268 sh_audio_t* sh_audio;
269 sh_audio = new_sh_audio_aid(demuxer, i, priv->audio_streams);
270 if(!sh_audio)
271 break;
272 stream_type = "audio";
273 priv->astreams[priv->audio_streams] = i;
274 wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1);
275 // mp4a tag is used for all mp4 files no matter what they actually contain
276 if(codec->codec_tag == MKTAG('m', 'p', '4', 'a'))
277 codec->codec_tag= 0;
278 if(!codec->codec_tag)
279 codec->codec_tag= mp_av_codec_get_tag(mp_wav_taglists, codec->codec_id);
280 wf->wFormatTag= codec->codec_tag;
281 wf->nChannels= codec->channels;
282 wf->nSamplesPerSec= codec->sample_rate;
283 wf->nAvgBytesPerSec= codec->bit_rate/8;
284 wf->nBlockAlign= codec->block_align ? codec->block_align : 1;
285 wf->wBitsPerSample= codec->bits_per_coded_sample;
286 wf->cbSize= codec->extradata_size;
287 if(codec->extradata_size)
288 memcpy(wf + 1, codec->extradata, codec->extradata_size);
289 sh_audio->wf= wf;
290 sh_audio->audio.dwSampleSize= codec->block_align;
291 if(codec->frame_size && codec->sample_rate){
292 sh_audio->audio.dwScale=codec->frame_size;
293 sh_audio->audio.dwRate= codec->sample_rate;
294 }else{
295 sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8;
296 sh_audio->audio.dwRate = codec->bit_rate;
298 g= av_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate);
299 sh_audio->audio.dwScale /= g;
300 sh_audio->audio.dwRate /= g;
301 // 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);
302 sh_audio->ds= demuxer->audio;
303 sh_audio->format= codec->codec_tag;
304 sh_audio->channels= codec->channels;
305 sh_audio->samplerate= codec->sample_rate;
306 sh_audio->i_bps= codec->bit_rate/8;
307 switch (codec->codec_id) {
308 case CODEC_ID_PCM_S8:
309 case CODEC_ID_PCM_U8:
310 sh_audio->samplesize = 1;
311 break;
312 case CODEC_ID_PCM_S16LE:
313 case CODEC_ID_PCM_S16BE:
314 case CODEC_ID_PCM_U16LE:
315 case CODEC_ID_PCM_U16BE:
316 sh_audio->samplesize = 2;
317 break;
318 case CODEC_ID_PCM_ALAW:
319 sh_audio->format = 0x6;
320 break;
321 case CODEC_ID_PCM_MULAW:
322 sh_audio->format = 0x7;
323 break;
325 if (title && title->value)
326 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_NAME=%s\n", priv->audio_streams, title->value);
327 if (lang && lang->value) {
328 sh_audio->lang = strdup(lang->value);
329 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_LANG=%s\n", priv->audio_streams, sh_audio->lang);
331 if (st->disposition & AV_DISPOSITION_DEFAULT)
332 sh_audio->default_track = 1;
333 if(mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V);
334 // select the first audio stream
335 if (!demuxer->audio->sh) {
336 demuxer->audio->id = i;
337 demuxer->audio->sh= demuxer->a_streams[i];
338 } else
339 st->discard= AVDISCARD_ALL;
340 stream_id = priv->audio_streams++;
341 break;
343 case CODEC_TYPE_VIDEO:{
344 sh_video_t* sh_video;
345 BITMAPINFOHEADER *bih;
346 sh_video=new_sh_video_vid(demuxer, i, priv->video_streams);
347 if(!sh_video) break;
348 stream_type = "video";
349 priv->vstreams[priv->video_streams] = i;
350 bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1);
352 if(codec->codec_id == CODEC_ID_RAWVIDEO) {
353 switch (codec->pix_fmt) {
354 case PIX_FMT_RGB24:
355 codec->codec_tag= MKTAG(24, 'B', 'G', 'R');
358 if(!codec->codec_tag)
359 codec->codec_tag= mp_av_codec_get_tag(mp_bmp_taglists, codec->codec_id);
360 bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size;
361 bih->biWidth= codec->width;
362 bih->biHeight= codec->height;
363 bih->biBitCount= codec->bits_per_coded_sample;
364 bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;
365 bih->biCompression= codec->codec_tag;
366 sh_video->bih= bih;
367 sh_video->disp_w= codec->width;
368 sh_video->disp_h= codec->height;
369 if (st->time_base.den) { /* if container has time_base, use that */
370 sh_video->video.dwRate= st->time_base.den;
371 sh_video->video.dwScale= st->time_base.num;
372 } else {
373 sh_video->video.dwRate= codec->time_base.den;
374 sh_video->video.dwScale= codec->time_base.num;
376 sh_video->fps=av_q2d(st->r_frame_rate);
377 sh_video->frametime=1/av_q2d(st->r_frame_rate);
378 sh_video->format=bih->biCompression;
379 if(st->sample_aspect_ratio.num)
380 sh_video->aspect = codec->width * st->sample_aspect_ratio.num
381 / (float)(codec->height * st->sample_aspect_ratio.den);
382 else
383 sh_video->aspect=codec->width * codec->sample_aspect_ratio.num
384 / (float)(codec->height * codec->sample_aspect_ratio.den);
385 sh_video->i_bps=codec->bit_rate/8;
386 if (title && title->value)
387 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VID_%d_NAME=%s\n", priv->video_streams, title->value);
388 mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n",
389 codec->width, codec->sample_aspect_ratio.num,
390 codec->height, codec->sample_aspect_ratio.den);
392 sh_video->ds= demuxer->video;
393 if(codec->extradata_size)
394 memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size);
395 if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
397 short biPlanes;
398 int biXPelsPerMeter;
399 int biYPelsPerMeter;
400 int biClrUsed;
401 int biClrImportant;
403 if(demuxer->video->id != i && demuxer->video->id != -1)
404 st->discard= AVDISCARD_ALL;
405 else{
406 demuxer->video->id = i;
407 demuxer->video->sh= demuxer->v_streams[i];
409 stream_id = priv->video_streams++;
410 break;
412 case CODEC_TYPE_SUBTITLE:{
413 sh_sub_t* sh_sub;
414 char type;
415 /* only support text subtitles for now */
416 if(codec->codec_id == CODEC_ID_TEXT)
417 type = 't';
418 else if(codec->codec_id == CODEC_ID_MOV_TEXT)
419 type = 'm';
420 else if(codec->codec_id == CODEC_ID_SSA)
421 type = 'a';
422 else if(codec->codec_id == CODEC_ID_DVD_SUBTITLE)
423 type = 'v';
424 else if(codec->codec_id == CODEC_ID_DVB_TELETEXT)
425 type = 'd';
426 else
427 break;
428 sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams);
429 if(!sh_sub) break;
430 stream_type = "subtitle";
431 priv->sstreams[priv->sub_streams] = i;
432 sh_sub->type = type;
433 if (codec->extradata_size) {
434 sh_sub->extradata = malloc(codec->extradata_size);
435 memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
436 sh_sub->extradata_len = codec->extradata_size;
438 if (title && title->value)
439 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_NAME=%s\n", priv->sub_streams, title->value);
440 if (lang && lang->value) {
441 sh_sub->lang = strdup(lang->value);
442 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_LANG=%s\n", priv->sub_streams, sh_sub->lang);
444 if (st->disposition & AV_DISPOSITION_DEFAULT)
445 sh_sub->default_track = 1;
446 stream_id = priv->sub_streams++;
447 break;
449 case CODEC_TYPE_ATTACHMENT:{
450 if (st->codec->codec_id == CODEC_ID_TTF)
451 demuxer_add_attachment(demuxer, BSTR(st->filename),
452 BSTR("application/x-truetype-font"),
453 (struct bstr){codec->extradata,
454 codec->extradata_size});
455 break;
457 default:
458 st->discard= AVDISCARD_ALL;
460 if (stream_type) {
461 AVCodec *avc = avcodec_find_decoder(codec->codec_id);
462 mp_msg(MSGT_DEMUX, MSGL_INFO, "[lavf] stream %d: %s (%s), -%cid %d", i, stream_type, avc ? avc->name : "unknown", *stream_type, stream_id);
463 if (lang && lang->value && *stream_type != 'v')
464 mp_msg(MSGT_DEMUX, MSGL_INFO, ", -%clang %s", *stream_type, lang->value);
465 if (title && title->value)
466 mp_msg(MSGT_DEMUX, MSGL_INFO, ", %s", title->value);
467 mp_msg(MSGT_DEMUX, MSGL_INFO, "\n");
471 static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
472 struct MPOpts *opts = demuxer->opts;
473 struct lavfdopts *lavfdopts = &opts->lavfdopts;
474 AVFormatContext *avfc;
475 AVFormatParameters ap;
476 const AVOption *opt;
477 AVMetadataTag *t = NULL;
478 lavf_priv_t *priv= demuxer->priv;
479 int i;
480 char mp_filename[256]="mp:";
482 memset(&ap, 0, sizeof(AVFormatParameters));
484 stream_seek(demuxer->stream, 0);
486 avfc = avformat_alloc_context();
488 if (lavfdopts->cryptokey)
489 parse_cryptokey(avfc, lavfdopts->cryptokey);
490 if (opts->user_correct_pts != 0)
491 avfc->flags |= AVFMT_FLAG_GENPTS;
492 if (index_mode == 0)
493 avfc->flags |= AVFMT_FLAG_IGNIDX;
495 ap.prealloced_context = 1;
496 if (lavfdopts->probesize) {
497 opt = av_set_int(avfc, "probesize", lavfdopts->probesize);
498 if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %u\n", lavfdopts->probesize);
500 if (lavfdopts->analyzeduration) {
501 opt = av_set_int(avfc, "analyzeduration",
502 lavfdopts->analyzeduration * AV_TIME_BASE);
503 if (!opt)
504 mp_msg(MSGT_HEADER, MSGL_ERR, "demux_lavf, couldn't set option "
505 "analyzeduration to %u\n", lavfdopts->analyzeduration);
508 if (lavfdopts->avopt){
509 if(parse_avopts(avfc, lavfdopts->avopt) < 0){
510 mp_msg(MSGT_HEADER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavfdopts->avopt);
511 return NULL;
515 if(demuxer->stream->url) {
516 if (!strncmp(demuxer->stream->url, "ffmpeg://rtsp:", 14))
517 av_strlcpy(mp_filename, demuxer->stream->url + 9, sizeof(mp_filename));
518 else
519 av_strlcat(mp_filename, demuxer->stream->url, sizeof(mp_filename));
520 } else
521 av_strlcat(mp_filename, "foobar.dummy", sizeof(mp_filename));
523 priv->pb = av_alloc_put_byte(priv->buffer, BIO_BUFFER_SIZE, 0,
524 demuxer, mp_read, NULL, mp_seek);
525 priv->pb->read_seek = mp_read_seek;
526 priv->pb->is_streamed = !demuxer->stream->end_pos || (demuxer->stream->flags & MP_STREAM_SEEK) != MP_STREAM_SEEK;
528 if(av_open_input_stream(&avfc, priv->pb, mp_filename, priv->avif, &ap)<0){
529 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n");
530 return NULL;
533 priv->avfc= avfc;
535 if(av_find_stream_info(avfc) < 0){
536 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n");
537 return NULL;
540 /* Add metadata. */
541 av_metadata_conv(avfc, NULL, avfc->iformat->metadata_conv);
542 while((t = av_metadata_get(avfc->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
543 demux_info_add(demuxer, t->key, t->value);
545 for(i=0; i < avfc->nb_chapters; i++) {
546 AVChapter *c = avfc->chapters[i];
547 uint64_t start = av_rescale_q(c->start, c->time_base, (AVRational){1,1000});
548 uint64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,1000});
549 t = av_metadata_get(c->metadata, "title", NULL, 0);
550 demuxer_add_chapter(demuxer, t ? BSTR(t->value) : BSTR(NULL), start, end);
553 for(i=0; i<avfc->nb_streams; i++)
554 handle_stream(demuxer, avfc, i);
555 if(avfc->nb_programs) {
556 int p;
557 for (p = 0; p < avfc->nb_programs; p++) {
558 AVProgram *program = avfc->programs[p];
559 t = av_metadata_get(program->metadata, "title", NULL, 0);
560 mp_msg(MSGT_HEADER,MSGL_INFO,"LAVF: Program %d %s\n", program->id, t ? t->value : "");
564 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams);
565 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD);
566 if(!priv->audio_streams) demuxer->audio->id=-2; // nosound
567 // else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
568 if(!priv->video_streams){
569 if(!priv->audio_streams){
570 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n");
571 return NULL;
573 demuxer->video->id=-2; // audio-only
574 } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;
576 demuxer->accurate_seek = true;
578 return demuxer;
581 static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
582 lavf_priv_t *priv= demux->priv;
583 AVPacket pkt;
584 demux_packet_t *dp;
585 demux_stream_t *ds;
586 int id;
587 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_lavf_fill_buffer()\n");
589 demux->filepos=stream_tell(demux->stream);
591 if(av_read_frame(priv->avfc, &pkt) < 0)
592 return 0;
594 id= pkt.stream_index;
596 if(id==demux->audio->id){
597 // audio
598 ds=demux->audio;
599 if(!ds->sh){
600 ds->sh=demux->a_streams[id];
601 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id);
603 } else if(id==demux->video->id){
604 // video
605 ds=demux->video;
606 if(!ds->sh){
607 ds->sh=demux->v_streams[id];
608 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id);
610 } else if(id==demux->sub->id){
611 // subtitle
612 ds=demux->sub;
613 sub_utf8=1;
614 } else {
615 av_free_packet(&pkt);
616 return 1;
619 if(0/*pkt.destruct == av_destruct_packet*/){
620 //ok kids, dont try this at home :)
621 dp=malloc(sizeof(demux_packet_t));
622 dp->len=pkt.size;
623 dp->next=NULL;
624 dp->refcount=1;
625 dp->master=NULL;
626 dp->buffer=pkt.data;
627 pkt.destruct= NULL;
628 }else{
629 dp=new_demux_packet(pkt.size);
630 memcpy(dp->buffer, pkt.data, pkt.size);
631 av_free_packet(&pkt);
634 if(pkt.pts != AV_NOPTS_VALUE){
635 dp->pts=pkt.pts * av_q2d(priv->avfc->streams[id]->time_base);
636 priv->last_pts= dp->pts * AV_TIME_BASE;
637 if(pkt.convergence_duration)
638 dp->endpts = dp->pts + pkt.convergence_duration * av_q2d(priv->avfc->streams[id]->time_base);
640 dp->pos=demux->filepos;
641 dp->flags= !!(pkt.flags&PKT_FLAG_KEY);
642 // append packet to DS stream:
643 ds_add_packet(ds,dp);
644 return 1;
647 static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags){
648 lavf_priv_t *priv = demuxer->priv;
649 int avsflags = 0;
650 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %f, %d)\n", demuxer, rel_seek_secs, audio_delay, flags);
652 if (flags & SEEK_ABSOLUTE) {
653 priv->last_pts = 0;
654 } else {
655 if (rel_seek_secs < 0) avsflags = AVSEEK_FLAG_BACKWARD;
657 if (flags & SEEK_FORWARD)
658 avsflags = 0;
659 else if (flags & SEEK_BACKWARD)
660 avsflags = AVSEEK_FLAG_BACKWARD;
661 if (flags & SEEK_FACTOR) {
662 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
663 return;
664 priv->last_pts += rel_seek_secs * priv->avfc->duration;
665 } else {
666 priv->last_pts += rel_seek_secs * AV_TIME_BASE;
668 if (av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags) < 0) {
669 avsflags ^= AVSEEK_FLAG_BACKWARD;
670 av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
674 static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
676 lavf_priv_t *priv = demuxer->priv;
678 switch (cmd) {
679 case DEMUXER_CTRL_CORRECT_PTS:
680 return DEMUXER_CTRL_OK;
681 case DEMUXER_CTRL_GET_TIME_LENGTH:
682 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
683 return DEMUXER_CTRL_DONTKNOW;
685 *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
686 return DEMUXER_CTRL_OK;
688 case DEMUXER_CTRL_GET_PERCENT_POS:
689 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
690 return DEMUXER_CTRL_DONTKNOW;
692 *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration);
693 return DEMUXER_CTRL_OK;
694 case DEMUXER_CTRL_SWITCH_AUDIO:
695 case DEMUXER_CTRL_SWITCH_VIDEO:
697 int id = *((int*)arg);
698 int newid = -2;
699 int i, curridx = -1;
700 int nstreams, *pstreams;
701 demux_stream_t *ds;
703 if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)
705 ds = demuxer->video;
706 nstreams = priv->video_streams;
707 pstreams = priv->vstreams;
709 else
711 ds = demuxer->audio;
712 nstreams = priv->audio_streams;
713 pstreams = priv->astreams;
715 for(i = 0; i < nstreams; i++)
717 if(pstreams[i] == ds->id) //current stream id
719 curridx = i;
720 break;
724 if(id == -2) { // no sound
725 i = -1;
726 } else if(id == -1) { // next track
727 i = (curridx + 2) % (nstreams + 1) - 1;
728 if (i >= 0)
729 newid = pstreams[i];
731 else // select track by id
733 if (id >= 0 && id < nstreams) {
734 i = id;
735 newid = pstreams[i];
738 if (i == curridx) {
739 *(int *) arg = curridx;
740 return DEMUXER_CTRL_OK;
741 } else {
742 ds_free_packs(ds);
743 if(ds->id >= 0)
744 priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
745 ds->id = newid;
746 *(int *) arg = i < 0 ? -2 : i;
747 if(newid >= 0)
748 priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
749 return DEMUXER_CTRL_OK;
752 case DEMUXER_CTRL_IDENTIFY_PROGRAM:
754 demux_program_t *prog = arg;
755 AVProgram *program;
756 int p, i;
757 int start;
759 prog->vid = prog->aid = prog->sid = -2; //no audio and no video by default
760 if(priv->avfc->nb_programs < 1)
761 return DEMUXER_CTRL_DONTKNOW;
763 if(prog->progid == -1)
765 p = 0;
766 while(p<priv->avfc->nb_programs && priv->avfc->programs[p]->id != priv->cur_program)
767 p++;
768 p = (p + 1) % priv->avfc->nb_programs;
770 else
772 for(i=0; i<priv->avfc->nb_programs; i++)
773 if(priv->avfc->programs[i]->id == prog->progid)
774 break;
775 if(i==priv->avfc->nb_programs)
776 return DEMUXER_CTRL_DONTKNOW;
777 p = i;
779 start = p;
780 redo:
781 program = priv->avfc->programs[p];
782 for(i=0; i<program->nb_stream_indexes; i++)
784 switch(priv->avfc->streams[program->stream_index[i]]->codec->codec_type)
786 case CODEC_TYPE_VIDEO:
787 if(prog->vid == -2)
788 prog->vid = program->stream_index[i];
789 break;
790 case CODEC_TYPE_AUDIO:
791 if(prog->aid == -2)
792 prog->aid = program->stream_index[i];
793 break;
794 case CODEC_TYPE_SUBTITLE:
795 if(prog->sid == -2 && priv->avfc->streams[program->stream_index[i]]->codec->codec_id == CODEC_ID_TEXT)
796 prog->sid = program->stream_index[i];
797 break;
800 if(prog->progid == -1 && prog->vid == -2 && prog->aid == -2)
802 p = (p + 1) % priv->avfc->nb_programs;
803 if (p == start)
804 return DEMUXER_CTRL_DONTKNOW;
805 goto redo;
807 priv->cur_program = prog->progid = program->id;
808 return DEMUXER_CTRL_OK;
810 default:
811 return DEMUXER_CTRL_NOTIMPL;
815 static void demux_close_lavf(demuxer_t *demuxer)
817 lavf_priv_t* priv = demuxer->priv;
818 if (priv){
819 if(priv->avfc)
821 av_freep(&priv->avfc->key);
822 av_close_input_stream(priv->avfc);
824 av_freep(&priv->pb);
825 free(priv); demuxer->priv= NULL;
830 const demuxer_desc_t demuxer_desc_lavf = {
831 "libavformat demuxer",
832 "lavf",
833 "libavformat",
834 "Michael Niedermayer",
835 "supports many formats, requires libavformat",
836 DEMUXER_TYPE_LAVF,
837 0, // Check after other demuxer
838 lavf_check_file,
839 demux_lavf_fill_buffer,
840 demux_open_lavf,
841 demux_close_lavf,
842 demux_seek_lavf,
843 demux_lavf_control
846 const demuxer_desc_t demuxer_desc_lavf_preferred = {
847 "libavformat preferred demuxer",
848 "lavfpref",
849 "libavformat",
850 "Michael Niedermayer",
851 "supports many formats, requires libavformat",
852 DEMUXER_TYPE_LAVF_PREFERRED,
854 lavf_check_preferred_file,
855 demux_lavf_fill_buffer,
856 demux_open_lavf,
857 demux_close_lavf,
858 demux_seek_lavf,
859 demux_lavf_control