demux: take chapter/attachment name strings without 0-termination
[mplayer/glamo.git] / libmpdemux / demux_lavf.c
blobad958889eda273844e433d4afa7e0caed6f059bd
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 "help_mp.h"
31 #include "av_opts.h"
33 #include "stream/stream.h"
34 #include "demuxer.h"
35 #include "stheader.h"
36 #include "m_option.h"
37 #include "libvo/sub.h"
39 #include "libavformat/avformat.h"
40 #include "libavformat/avio.h"
41 #include "libavutil/avutil.h"
42 #include "libavcodec/opt.h"
44 #include "mp_taglists.h"
46 #define PROBE_BUF_SIZE (32*1024)
48 static unsigned int opt_probesize = 0;
49 static unsigned int opt_analyzeduration = 0;
50 static char *opt_format;
51 static char *opt_cryptokey;
52 static char *opt_avopt = NULL;
54 const m_option_t lavfdopts_conf[] = {
55 {"probesize", &(opt_probesize), CONF_TYPE_INT, CONF_RANGE, 32, INT_MAX, NULL},
56 {"format", &(opt_format), CONF_TYPE_STRING, 0, 0, 0, NULL},
57 {"analyzeduration", &(opt_analyzeduration), CONF_TYPE_INT, CONF_RANGE, 0, INT_MAX, NULL},
58 {"cryptokey", &(opt_cryptokey), CONF_TYPE_STRING, 0, 0, 0, NULL},
59 {"o", &opt_avopt, CONF_TYPE_STRING, 0, 0, 0, NULL},
60 {NULL, NULL, 0, 0, 0, 0, NULL}
63 #define BIO_BUFFER_SIZE 32768
65 typedef struct lavf_priv_t{
66 AVInputFormat *avif;
67 AVFormatContext *avfc;
68 ByteIOContext *pb;
69 uint8_t buffer[FFMAX(BIO_BUFFER_SIZE, PROBE_BUF_SIZE)];
70 int audio_streams;
71 int video_streams;
72 int sub_streams;
73 int64_t last_pts;
74 int astreams[MAX_A_STREAMS];
75 int vstreams[MAX_V_STREAMS];
76 int sstreams[MAX_S_STREAMS];
77 int cur_program;
78 }lavf_priv_t;
80 void print_wave_header(WAVEFORMATEX *h, int verbose_level);
81 void print_video_header(BITMAPINFOHEADER *h, int verbose_level);
83 static int mp_read(void *opaque, uint8_t *buf, int size) {
84 stream_t *stream = opaque;
85 int ret;
87 if(stream_eof(stream)) //needed?
88 return -1;
89 ret=stream_read(stream, buf, size);
91 mp_msg(MSGT_HEADER,MSGL_DBG2,"%d=mp_read(%p, %p, %d), eof:%d\n", ret, stream, buf, size, stream->eof);
92 return ret;
95 static int64_t mp_seek(void *opaque, int64_t pos, int whence) {
96 stream_t *stream = opaque;
97 int64_t current_pos;
98 mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %d, %d)\n", stream, (int)pos, whence);
99 if(whence == SEEK_CUR)
100 pos +=stream_tell(stream);
101 else if(whence == SEEK_END && stream->end_pos > 0)
102 pos += stream->end_pos;
103 else if(whence == SEEK_SET)
104 pos += stream->start_pos;
105 else if(whence == AVSEEK_SIZE && stream->end_pos > 0)
106 return stream->end_pos - stream->start_pos;
107 else
108 return -1;
110 if(pos<0)
111 return -1;
112 if(pos<stream->end_pos && stream->eof)
113 stream_reset(stream);
114 current_pos = stream_tell(stream);
115 if(stream_seek(stream, pos)==0) {
116 stream_reset(stream);
117 stream_seek(stream, current_pos);
118 return -1;
121 return pos - stream->start_pos;
124 static void list_formats(void) {
125 AVInputFormat *fmt;
126 mp_msg(MSGT_DEMUX, MSGL_INFO, "Available lavf input formats:\n");
127 for (fmt = first_iformat; fmt; fmt = fmt->next)
128 mp_msg(MSGT_DEMUX, MSGL_INFO, "%15s : %s\n", fmt->name, fmt->long_name);
131 static int lavf_check_file(demuxer_t *demuxer){
132 AVProbeData avpd;
133 lavf_priv_t *priv;
134 int probe_data_size;
136 if(!demuxer->priv)
137 demuxer->priv=calloc(sizeof(lavf_priv_t),1);
138 priv= demuxer->priv;
140 av_register_all();
142 if (opt_format) {
143 if (strcmp(opt_format, "help") == 0) {
144 list_formats();
145 return 0;
147 priv->avif= av_find_input_format(opt_format);
148 if (!priv->avif) {
149 mp_msg(MSGT_DEMUX,MSGL_FATAL,"Unknown lavf format %s\n", opt_format);
150 return 0;
152 mp_msg(MSGT_DEMUX,MSGL_INFO,"Forced lavf %s demuxer\n", priv->avif->long_name);
153 return DEMUXER_TYPE_LAVF;
156 probe_data_size = stream_read(demuxer->stream, priv->buffer, PROBE_BUF_SIZE);
157 if(probe_data_size <= 0)
158 return 0;
159 avpd.filename= demuxer->stream->url;
160 avpd.buf= priv->buffer;
161 avpd.buf_size= probe_data_size;
163 priv->avif= av_probe_input_format(&avpd, 1);
164 if(!priv->avif){
165 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: no clue about this gibberish!\n");
166 return 0;
167 }else
168 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name);
170 return DEMUXER_TYPE_LAVF;
173 static const char * const preferred_list[] = {
174 "dxa",
175 "flv",
176 "gxf",
177 "nut",
178 "nuv",
179 "mov,mp4,m4a,3gp,3g2,mj2",
180 "mpc",
181 "mpc8",
182 "mxf",
183 "swf",
184 "vqf",
185 "w64",
186 "wv",
187 NULL
190 static int lavf_check_preferred_file(demuxer_t *demuxer){
191 if (lavf_check_file(demuxer)) {
192 const char * const *p = preferred_list;
193 lavf_priv_t *priv = demuxer->priv;
194 while (*p) {
195 if (strcmp(*p, priv->avif->name) == 0)
196 return DEMUXER_TYPE_LAVF_PREFERRED;
197 p++;
200 return 0;
203 static uint8_t char2int(char c) {
204 if (c >= '0' && c <= '9') return c - '0';
205 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
206 if (c >= 'A' && c <= 'F') return c - 'A' + 10;
207 return 0;
210 static void parse_cryptokey(AVFormatContext *avfc, const char *str) {
211 int len = strlen(str) / 2;
212 uint8_t *key = av_mallocz(len);
213 int i;
214 avfc->keylen = len;
215 avfc->key = key;
216 for (i = 0; i < len; i++, str += 2)
217 *key++ = (char2int(str[0]) << 4) | char2int(str[1]);
220 static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
221 lavf_priv_t *priv= demuxer->priv;
222 AVStream *st= avfc->streams[i];
223 AVCodecContext *codec= st->codec;
224 AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0);
225 int g, override_tag = mp_av_codec_get_tag(mp_codecid_override_taglists,
226 codec->codec_id);
227 // For some formats (like PCM) always trust CODEC_ID_* more than codec_tag
228 if (override_tag)
229 codec->codec_tag = override_tag;
231 switch(codec->codec_type){
232 case CODEC_TYPE_AUDIO:{
233 WAVEFORMATEX *wf;
234 sh_audio_t* sh_audio;
235 sh_audio=new_sh_audio(demuxer, i);
236 mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "lavf", i);
237 if(!sh_audio)
238 break;
239 priv->astreams[priv->audio_streams] = i;
240 priv->audio_streams++;
241 wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1);
242 // mp4a tag is used for all mp4 files no matter what they actually contain
243 if(codec->codec_tag == MKTAG('m', 'p', '4', 'a'))
244 codec->codec_tag= 0;
245 if(!codec->codec_tag)
246 codec->codec_tag= mp_av_codec_get_tag(mp_wav_taglists, codec->codec_id);
247 wf->wFormatTag= codec->codec_tag;
248 wf->nChannels= codec->channels;
249 wf->nSamplesPerSec= codec->sample_rate;
250 wf->nAvgBytesPerSec= codec->bit_rate/8;
251 wf->nBlockAlign= codec->block_align ? codec->block_align : 1;
252 wf->wBitsPerSample= codec->bits_per_coded_sample;
253 wf->cbSize= codec->extradata_size;
254 if(codec->extradata_size)
255 memcpy(wf + 1, codec->extradata, codec->extradata_size);
256 sh_audio->wf= wf;
257 sh_audio->audio.dwSampleSize= codec->block_align;
258 if(codec->frame_size && codec->sample_rate){
259 sh_audio->audio.dwScale=codec->frame_size;
260 sh_audio->audio.dwRate= codec->sample_rate;
261 }else{
262 sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8;
263 sh_audio->audio.dwRate = codec->bit_rate;
265 g= av_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate);
266 sh_audio->audio.dwScale /= g;
267 sh_audio->audio.dwRate /= g;
268 // 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);
269 sh_audio->ds= demuxer->audio;
270 sh_audio->format= codec->codec_tag;
271 sh_audio->channels= codec->channels;
272 sh_audio->samplerate= codec->sample_rate;
273 sh_audio->i_bps= codec->bit_rate/8;
274 switch (codec->codec_id) {
275 case CODEC_ID_PCM_S8:
276 case CODEC_ID_PCM_U8:
277 sh_audio->samplesize = 1;
278 break;
279 case CODEC_ID_PCM_S16LE:
280 case CODEC_ID_PCM_S16BE:
281 case CODEC_ID_PCM_U16LE:
282 case CODEC_ID_PCM_U16BE:
283 sh_audio->samplesize = 2;
284 break;
285 case CODEC_ID_PCM_ALAW:
286 sh_audio->format = 0x6;
287 break;
288 case CODEC_ID_PCM_MULAW:
289 sh_audio->format = 0x7;
290 break;
292 if (lang && lang->value) {
293 sh_audio->lang = strdup(lang->value);
294 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_LANG=%s\n", i, sh_audio->lang);
296 if (st->disposition & AV_DISPOSITION_DEFAULT)
297 sh_audio->default_track = 1;
298 if(mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V);
299 // select the first audio stream
300 if (!demuxer->audio->sh) {
301 demuxer->audio->id = i;
302 demuxer->audio->sh= demuxer->a_streams[i];
303 } else
304 st->discard= AVDISCARD_ALL;
305 break;
307 case CODEC_TYPE_VIDEO:{
308 sh_video_t* sh_video;
309 BITMAPINFOHEADER *bih;
310 sh_video=new_sh_video(demuxer, i);
311 mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Video stream found, -vid %d\n", "lavf", i);
312 if(!sh_video) break;
313 priv->vstreams[priv->video_streams] = i;
314 priv->video_streams++;
315 bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1);
317 if(codec->codec_id == CODEC_ID_RAWVIDEO) {
318 switch (codec->pix_fmt) {
319 case PIX_FMT_RGB24:
320 codec->codec_tag= MKTAG(24, 'B', 'G', 'R');
323 if(!codec->codec_tag)
324 codec->codec_tag= mp_av_codec_get_tag(mp_bmp_taglists, codec->codec_id);
325 bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size;
326 bih->biWidth= codec->width;
327 bih->biHeight= codec->height;
328 bih->biBitCount= codec->bits_per_coded_sample;
329 bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;
330 bih->biCompression= codec->codec_tag;
331 sh_video->bih= bih;
332 sh_video->disp_w= codec->width;
333 sh_video->disp_h= codec->height;
334 if (st->time_base.den) { /* if container has time_base, use that */
335 sh_video->video.dwRate= st->time_base.den;
336 sh_video->video.dwScale= st->time_base.num;
337 } else {
338 sh_video->video.dwRate= codec->time_base.den;
339 sh_video->video.dwScale= codec->time_base.num;
341 sh_video->fps=av_q2d(st->r_frame_rate);
342 sh_video->frametime=1/av_q2d(st->r_frame_rate);
343 sh_video->format=bih->biCompression;
344 if(st->sample_aspect_ratio.num)
345 sh_video->aspect = codec->width * st->sample_aspect_ratio.num
346 / (float)(codec->height * st->sample_aspect_ratio.den);
347 else
348 sh_video->aspect=codec->width * codec->sample_aspect_ratio.num
349 / (float)(codec->height * codec->sample_aspect_ratio.den);
350 sh_video->i_bps=codec->bit_rate/8;
351 mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n",
352 codec->width, codec->sample_aspect_ratio.num,
353 codec->height, codec->sample_aspect_ratio.den);
355 sh_video->ds= demuxer->video;
356 if(codec->extradata_size)
357 memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size);
358 if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
360 short biPlanes;
361 int biXPelsPerMeter;
362 int biYPelsPerMeter;
363 int biClrUsed;
364 int biClrImportant;
366 if(demuxer->video->id != i && demuxer->video->id != -1)
367 st->discard= AVDISCARD_ALL;
368 else{
369 demuxer->video->id = i;
370 demuxer->video->sh= demuxer->v_streams[i];
372 break;
374 case CODEC_TYPE_SUBTITLE:{
375 sh_sub_t* sh_sub;
376 char type;
377 /* only support text subtitles for now */
378 if(codec->codec_id == CODEC_ID_TEXT)
379 type = 't';
380 else if(codec->codec_id == CODEC_ID_MOV_TEXT)
381 type = 'm';
382 else if(codec->codec_id == CODEC_ID_SSA)
383 type = 'a';
384 else if(codec->codec_id == CODEC_ID_DVD_SUBTITLE)
385 type = 'v';
386 else if(codec->codec_id == CODEC_ID_DVB_TELETEXT)
387 type = 'd';
388 else
389 break;
390 sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams);
391 mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Subtitle stream found, -sid %d\n", "lavf", priv->sub_streams);
392 if(!sh_sub) break;
393 priv->sstreams[priv->sub_streams] = i;
394 sh_sub->type = type;
395 if (codec->extradata_size) {
396 sh_sub->extradata = malloc(codec->extradata_size);
397 memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
398 sh_sub->extradata_len = codec->extradata_size;
400 if (lang && lang->value) {
401 sh_sub->lang = strdup(lang->value);
402 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_LANG=%s\n", priv->sub_streams, sh_sub->lang);
404 if (st->disposition & AV_DISPOSITION_DEFAULT)
405 sh_sub->default_track = 1;
406 priv->sub_streams++;
407 break;
409 case CODEC_TYPE_ATTACHMENT:{
410 if (st->codec->codec_id == CODEC_ID_TTF)
411 demuxer_add_attachment(demuxer, st->filename, INT_MAX,
412 "application/x-truetype-font", INT_MAX,
413 codec->extradata, codec->extradata_size);
414 break;
416 default:
417 st->discard= AVDISCARD_ALL;
421 static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
422 struct MPOpts *opts = demuxer->opts;
423 AVFormatContext *avfc;
424 AVFormatParameters ap;
425 const AVOption *opt;
426 AVMetadataTag *t = NULL;
427 lavf_priv_t *priv= demuxer->priv;
428 int i;
429 char mp_filename[256]="mp:";
431 memset(&ap, 0, sizeof(AVFormatParameters));
433 stream_seek(demuxer->stream, 0);
435 avfc = avformat_alloc_context();
437 if (opt_cryptokey)
438 parse_cryptokey(avfc, opt_cryptokey);
439 if (opts->user_correct_pts != 0)
440 avfc->flags |= AVFMT_FLAG_GENPTS;
441 if (index_mode == 0)
442 avfc->flags |= AVFMT_FLAG_IGNIDX;
444 ap.prealloced_context = 1;
445 if(opt_probesize) {
446 opt = av_set_int(avfc, "probesize", opt_probesize);
447 if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %u\n", opt_probesize);
449 if(opt_analyzeduration) {
450 opt = av_set_int(avfc, "analyzeduration", opt_analyzeduration * AV_TIME_BASE);
451 if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option analyzeduration to %u\n", opt_analyzeduration);
454 if(opt_avopt){
455 if(parse_avopts(avfc, opt_avopt) < 0){
456 mp_msg(MSGT_HEADER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", opt_avopt);
457 return NULL;
461 if(demuxer->stream->url)
462 strncpy(mp_filename + 3, demuxer->stream->url, sizeof(mp_filename)-3);
463 else
464 strncpy(mp_filename + 3, "foobar.dummy", sizeof(mp_filename)-3);
466 priv->pb = av_alloc_put_byte(priv->buffer, BIO_BUFFER_SIZE, 0,
467 demuxer->stream, mp_read, NULL, mp_seek);
468 priv->pb->is_streamed = !demuxer->stream->end_pos || (demuxer->stream->flags & MP_STREAM_SEEK) != MP_STREAM_SEEK;
470 if(av_open_input_stream(&avfc, priv->pb, mp_filename, priv->avif, &ap)<0){
471 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n");
472 return NULL;
475 priv->avfc= avfc;
477 if(av_find_stream_info(avfc) < 0){
478 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n");
479 return NULL;
482 /* Add metadata. */
483 av_metadata_conv(avfc, NULL, avfc->iformat->metadata_conv);
484 while((t = av_metadata_get(avfc->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
485 demux_info_add(demuxer, t->key, t->value);
487 for(i=0; i < avfc->nb_chapters; i++) {
488 AVChapter *c = avfc->chapters[i];
489 uint64_t start = av_rescale_q(c->start, c->time_base, (AVRational){1,1000});
490 uint64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,1000});
491 t = av_metadata_get(c->metadata, "title", NULL, 0);
492 demuxer_add_chapter(demuxer, t ? t->value : NULL, INT_MAX, start, end);
495 for(i=0; i<avfc->nb_streams; i++)
496 handle_stream(demuxer, avfc, i);
497 if(avfc->nb_programs) {
498 int p;
499 for (p = 0; p < avfc->nb_programs; p++) {
500 AVProgram *program = avfc->programs[p];
501 t = av_metadata_get(program->metadata, "title", NULL, 0);
502 mp_msg(MSGT_HEADER,MSGL_INFO,"LAVF: Program %d %s\n", program->id, t ? t->value : "");
506 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams);
507 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD);
508 if(!priv->audio_streams) demuxer->audio->id=-2; // nosound
509 // else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
510 if(!priv->video_streams){
511 if(!priv->audio_streams){
512 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n");
513 return NULL;
515 demuxer->video->id=-2; // audio-only
516 } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;
518 demuxer->accurate_seek = true;
520 return demuxer;
523 static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
524 lavf_priv_t *priv= demux->priv;
525 AVPacket pkt;
526 demux_packet_t *dp;
527 demux_stream_t *ds;
528 int id;
529 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_lavf_fill_buffer()\n");
531 demux->filepos=stream_tell(demux->stream);
533 if(av_read_frame(priv->avfc, &pkt) < 0)
534 return 0;
536 id= pkt.stream_index;
538 if(id==demux->audio->id){
539 // audio
540 ds=demux->audio;
541 if(!ds->sh){
542 ds->sh=demux->a_streams[id];
543 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id);
545 } else if(id==demux->video->id){
546 // video
547 ds=demux->video;
548 if(!ds->sh){
549 ds->sh=demux->v_streams[id];
550 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id);
552 } else if(id==demux->sub->id){
553 // subtitle
554 ds=demux->sub;
555 sub_utf8=1;
556 } else {
557 av_free_packet(&pkt);
558 return 1;
561 if(0/*pkt.destruct == av_destruct_packet*/){
562 //ok kids, dont try this at home :)
563 dp=malloc(sizeof(demux_packet_t));
564 dp->len=pkt.size;
565 dp->next=NULL;
566 dp->refcount=1;
567 dp->master=NULL;
568 dp->buffer=pkt.data;
569 pkt.destruct= NULL;
570 }else{
571 dp=new_demux_packet(pkt.size);
572 memcpy(dp->buffer, pkt.data, pkt.size);
573 av_free_packet(&pkt);
576 if(pkt.pts != AV_NOPTS_VALUE){
577 dp->pts=pkt.pts * av_q2d(priv->avfc->streams[id]->time_base);
578 priv->last_pts= dp->pts * AV_TIME_BASE;
579 if(pkt.convergence_duration)
580 dp->endpts = dp->pts + pkt.convergence_duration * av_q2d(priv->avfc->streams[id]->time_base);
582 dp->pos=demux->filepos;
583 dp->flags= !!(pkt.flags&PKT_FLAG_KEY);
584 // append packet to DS stream:
585 ds_add_packet(ds,dp);
586 return 1;
589 static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags){
590 lavf_priv_t *priv = demuxer->priv;
591 int avsflags = 0;
592 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %f, %d)\n", demuxer, rel_seek_secs, audio_delay, flags);
594 if (flags & SEEK_ABSOLUTE) {
595 priv->last_pts = 0;
596 } else {
597 if (rel_seek_secs < 0) avsflags = AVSEEK_FLAG_BACKWARD;
599 if (flags & SEEK_FORWARD)
600 avsflags = 0;
601 else if (flags & SEEK_BACKWARD)
602 avsflags = AVSEEK_FLAG_BACKWARD;
603 if (flags & SEEK_FACTOR) {
604 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
605 return;
606 priv->last_pts += rel_seek_secs * priv->avfc->duration;
607 } else {
608 priv->last_pts += rel_seek_secs * AV_TIME_BASE;
610 if (av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags) < 0) {
611 avsflags ^= AVSEEK_FLAG_BACKWARD;
612 av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
616 static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
618 lavf_priv_t *priv = demuxer->priv;
620 switch (cmd) {
621 case DEMUXER_CTRL_CORRECT_PTS:
622 return DEMUXER_CTRL_OK;
623 case DEMUXER_CTRL_GET_TIME_LENGTH:
624 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
625 return DEMUXER_CTRL_DONTKNOW;
627 *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
628 return DEMUXER_CTRL_OK;
630 case DEMUXER_CTRL_GET_PERCENT_POS:
631 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
632 return DEMUXER_CTRL_DONTKNOW;
634 *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration);
635 return DEMUXER_CTRL_OK;
636 case DEMUXER_CTRL_SWITCH_AUDIO:
637 case DEMUXER_CTRL_SWITCH_VIDEO:
639 int id = *((int*)arg);
640 int newid = -2;
641 int i, curridx = -1;
642 int nstreams, *pstreams;
643 demux_stream_t *ds;
645 if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)
647 ds = demuxer->video;
648 nstreams = priv->video_streams;
649 pstreams = priv->vstreams;
651 else
653 ds = demuxer->audio;
654 nstreams = priv->audio_streams;
655 pstreams = priv->astreams;
657 for(i = 0; i < nstreams; i++)
659 if(pstreams[i] == ds->id) //current stream id
661 curridx = i;
662 break;
666 if(id == -2) { // no sound
667 i = -1;
668 } else if(id == -1) { // next track
669 i = (curridx + 2) % (nstreams + 1) - 1;
670 if (i >= 0)
671 newid = pstreams[i];
673 else // select track by id
675 for(i = 0; i < nstreams; i++)
677 if(pstreams[i] == id)
679 newid = id;
680 break;
684 if(i == curridx)
685 return DEMUXER_CTRL_NOTIMPL;
686 else
688 ds_free_packs(ds);
689 if(ds->id >= 0)
690 priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
691 *((int*)arg) = ds->id = newid;
692 if(newid >= 0)
693 priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
694 return DEMUXER_CTRL_OK;
697 case DEMUXER_CTRL_IDENTIFY_PROGRAM:
699 demux_program_t *prog = arg;
700 AVProgram *program;
701 int p, i;
702 int start;
704 prog->vid = prog->aid = prog->sid = -2; //no audio and no video by default
705 if(priv->avfc->nb_programs < 1)
706 return DEMUXER_CTRL_DONTKNOW;
708 if(prog->progid == -1)
710 p = 0;
711 while(p<priv->avfc->nb_programs && priv->avfc->programs[p]->id != priv->cur_program)
712 p++;
713 p = (p + 1) % priv->avfc->nb_programs;
715 else
717 for(i=0; i<priv->avfc->nb_programs; i++)
718 if(priv->avfc->programs[i]->id == prog->progid)
719 break;
720 if(i==priv->avfc->nb_programs)
721 return DEMUXER_CTRL_DONTKNOW;
722 p = i;
724 start = p;
725 redo:
726 program = priv->avfc->programs[p];
727 for(i=0; i<program->nb_stream_indexes; i++)
729 switch(priv->avfc->streams[program->stream_index[i]]->codec->codec_type)
731 case CODEC_TYPE_VIDEO:
732 if(prog->vid == -2)
733 prog->vid = program->stream_index[i];
734 break;
735 case CODEC_TYPE_AUDIO:
736 if(prog->aid == -2)
737 prog->aid = program->stream_index[i];
738 break;
739 case CODEC_TYPE_SUBTITLE:
740 if(prog->sid == -2 && priv->avfc->streams[program->stream_index[i]]->codec->codec_id == CODEC_ID_TEXT)
741 prog->sid = program->stream_index[i];
742 break;
745 if(prog->progid == -1 && prog->vid == -2 && prog->aid == -2)
747 p = (p + 1) % priv->avfc->nb_programs;
748 if (p == start)
749 return DEMUXER_CTRL_DONTKNOW;
750 goto redo;
752 priv->cur_program = prog->progid = program->id;
753 return DEMUXER_CTRL_OK;
755 default:
756 return DEMUXER_CTRL_NOTIMPL;
760 static void demux_close_lavf(demuxer_t *demuxer)
762 lavf_priv_t* priv = demuxer->priv;
763 if (priv){
764 if(priv->avfc)
766 av_freep(&priv->avfc->key);
767 av_close_input_stream(priv->avfc);
769 av_freep(&priv->pb);
770 free(priv); demuxer->priv= NULL;
775 const demuxer_desc_t demuxer_desc_lavf = {
776 "libavformat demuxer",
777 "lavf",
778 "libavformat",
779 "Michael Niedermayer",
780 "supports many formats, requires libavformat",
781 DEMUXER_TYPE_LAVF,
782 0, // Check after other demuxer
783 lavf_check_file,
784 demux_lavf_fill_buffer,
785 demux_open_lavf,
786 demux_close_lavf,
787 demux_seek_lavf,
788 demux_lavf_control
791 const demuxer_desc_t demuxer_desc_lavf_preferred = {
792 "libavformat preferred demuxer",
793 "lavfpref",
794 "libavformat",
795 "Michael Niedermayer",
796 "supports many formats, requires libavformat",
797 DEMUXER_TYPE_LAVF_PREFERRED,
799 lavf_check_preferred_file,
800 demux_lavf_fill_buffer,
801 demux_open_lavf,
802 demux_close_lavf,
803 demux_seek_lavf,
804 demux_lavf_control