Mercurial > mplayer.hg
annotate libmpdemux/demux_lavf.c @ 21548:bf65ffcf0cdb
Set AVFMT_FLAG_GENPTS if -correct-pts is used.
This should allow using -correct-pts (and thus filters which adjust pts
or add frames) with dvd or other mpeg container files by specifying
"-correct-pts -demuxer lavf -vc ffmpeg12". Might work with libmpeg2
decoder too but certainly not with internal demuxer.
Using this flag isn't quite optimal as it can cause extra buffering of
demuxed frames, but at least it's better than just failing until a more
complex solution is implemented.
author | uau |
---|---|
date | Sun, 10 Dec 2006 00:50:38 +0000 |
parents | 76f120c4e0f1 |
children | 51a7cbc52102 |
rev | line source |
---|---|
12164 | 1 /* |
2 Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> | |
3 | |
4 This program is free software; you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 2 of the License, or | |
7 (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
15 along with this program; if not, write to the Free Software | |
17367
401b440a6d76
Update licensing information: The FSF changed postal address.
diego
parents:
17354
diff
changeset
|
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
12164 | 17 */ |
18 | |
19 // #include <stdio.h> | |
20 #include <stdlib.h> | |
21 // #include <unistd.h> | |
19611 | 22 #include <limits.h> |
12164 | 23 |
24 #include "config.h" | |
25 #include "mp_msg.h" | |
26 // #include "help_mp.h" | |
27 | |
28 #include "stream.h" | |
29 #include "demuxer.h" | |
30 #include "stheader.h" | |
19598 | 31 #include "m_option.h" |
12164 | 32 |
17354 | 33 #ifdef USE_LIBAVFORMAT_SO |
34 #include <ffmpeg/avformat.h> | |
19598 | 35 #include <ffmpeg/opt.h> |
20733
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
36 typedef struct CodecTag { |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
37 int id; |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
38 unsigned int tag; |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
39 unsigned int invalid_asf : 1; |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
40 } CodecTag; |
17354 | 41 #else |
12164 | 42 #include "avformat.h" |
20733
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
43 #include "riff.h" |
12164 | 44 #include "avi.h" |
19598 | 45 #include "opt.h" |
17354 | 46 #endif |
12164 | 47 |
48 #define PROBE_BUF_SIZE 2048 | |
49 | |
18775 | 50 extern char *audio_lang; |
19598 | 51 static unsigned int opt_probesize = 0; |
52 | |
53 m_option_t lavfdopts_conf[] = { | |
54 {"probesize", &(opt_probesize), CONF_TYPE_INT, CONF_RANGE, 32, INT_MAX, NULL}, | |
55 {NULL, NULL, 0, 0, 0, 0, NULL} | |
56 }; | |
57 | |
18775 | 58 |
12164 | 59 typedef struct lavf_priv_t{ |
60 AVInputFormat *avif; | |
61 AVFormatContext *avfc; | |
62 ByteIOContext pb; | |
63 int audio_streams; | |
64 int video_streams; | |
12168 | 65 int64_t last_pts; |
18762 | 66 int astreams[MAX_A_STREAMS]; |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
67 int vstreams[MAX_V_STREAMS]; |
12164 | 68 }lavf_priv_t; |
69 | |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
70 extern void print_wave_header(WAVEFORMATEX *h, int verbose_level); |
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
71 extern void print_video_header(BITMAPINFOHEADER *h, int verbose_level); |
12164 | 72 |
15011 | 73 int64_t ff_gcd(int64_t a, int64_t b); |
74 | |
20733
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
75 const CodecTag mp_wav_tags[] = { |
20944
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
76 { CODEC_ID_ADPCM_4XM, MKTAG('4', 'X', 'M', 'A')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
77 { CODEC_ID_ADPCM_EA, MKTAG('A', 'D', 'E', 'A')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
78 { CODEC_ID_ADPCM_IMA_WS, MKTAG('A', 'I', 'W', 'S')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
79 { CODEC_ID_DSICINAUDIO, MKTAG('D', 'C', 'I', 'A')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
80 { CODEC_ID_INTERPLAY_DPCM, MKTAG('I', 'N', 'P', 'A')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
81 { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
82 { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
83 { CODEC_ID_ROQ_DPCM, MKTAG('R', 'o', 'Q', 'A')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
84 { CODEC_ID_SHORTEN, MKTAG('s', 'h', 'r', 'n')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
85 { CODEC_ID_TTA, MKTAG('T', 'T', 'A', '1')}, |
20910582789d
cosmetics: Restore alphabetical order, align both tables.
diego
parents:
20942
diff
changeset
|
86 { CODEC_ID_WAVPACK, MKTAG('W', 'V', 'P', 'K')}, |
21362 | 87 { CODEC_ID_WESTWOOD_SND1, MKTAG('S', 'N', 'D', '1')}, |
20990 | 88 { CODEC_ID_XAN_DPCM, MKTAG('A', 'x', 'a', 'n')}, |
20733
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
89 { 0, 0 }, |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
90 }; |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
91 |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
92 const CodecTag mp_bmp_tags[] = { |
20940 | 93 { CODEC_ID_DSICINVIDEO, MKTAG('D', 'C', 'I', 'V')}, |
20963 | 94 { CODEC_ID_FLIC, MKTAG('F', 'L', 'I', 'C')}, |
20980
70ca50bcc4a8
support for some more fringe formats, still buggy ..
diego
parents:
20963
diff
changeset
|
95 { CODEC_ID_IDCIN, MKTAG('I', 'D', 'C', 'I')}, |
70ca50bcc4a8
support for some more fringe formats, still buggy ..
diego
parents:
20963
diff
changeset
|
96 { CODEC_ID_INTERPLAY_VIDEO, MKTAG('I', 'N', 'P', 'V')}, |
20942
2093d87ed14b
support for RoQ video and audio through libavformat
diego
parents:
20941
diff
changeset
|
97 { CODEC_ID_ROQ, MKTAG('R', 'o', 'Q', 'V')}, |
20933 | 98 { CODEC_ID_TIERTEXSEQVIDEO, MKTAG('T', 'S', 'E', 'Q')}, |
20935
4a8c67e44c7f
cosmetics: alphabetical order and prettyprinting for the CodecTag table
diego
parents:
20934
diff
changeset
|
99 { CODEC_ID_VMDVIDEO, MKTAG('V', 'M', 'D', 'V')}, |
20980
70ca50bcc4a8
support for some more fringe formats, still buggy ..
diego
parents:
20963
diff
changeset
|
100 { CODEC_ID_WS_VQA, MKTAG('V', 'Q', 'A', 'V')}, |
20935
4a8c67e44c7f
cosmetics: alphabetical order and prettyprinting for the CodecTag table
diego
parents:
20934
diff
changeset
|
101 { CODEC_ID_XAN_WC3, MKTAG('W', 'C', '3', 'V')}, |
20733
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
102 { 0, 0 }, |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
103 }; |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
104 |
12164 | 105 static int mp_open(URLContext *h, const char *filename, int flags){ |
106 return 0; | |
107 } | |
108 | |
109 static int mp_read(URLContext *h, unsigned char *buf, int size){ | |
110 stream_t *stream = (stream_t*)h->priv_data; | |
12165
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
111 int ret; |
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
112 |
12164 | 113 if(stream_eof(stream)) //needed? |
114 return -1; | |
12165
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
115 ret=stream_read(stream, buf, size); |
12166 | 116 |
12165
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
117 mp_msg(MSGT_HEADER,MSGL_DBG2,"%d=mp_read(%p, %p, %d), eof:%d\n", ret, h, buf, size, stream->eof); |
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
118 return ret; |
12164 | 119 } |
120 | |
121 static int mp_write(URLContext *h, unsigned char *buf, int size){ | |
122 return -1; | |
123 } | |
124 | |
125 static offset_t mp_seek(URLContext *h, offset_t pos, int whence){ | |
126 stream_t *stream = (stream_t*)h->priv_data; | |
12165
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
127 |
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
128 mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %d, %d)\n", h, (int)pos, whence); |
12164 | 129 if(whence == SEEK_CUR) |
130 pos +=stream_tell(stream); | |
131 else if(whence == SEEK_END) | |
132 pos += stream->end_pos; | |
133 else if(whence != SEEK_SET) | |
134 return -1; | |
135 | |
12167 | 136 if(pos<stream->end_pos && stream->eof) |
12166 | 137 stream_reset(stream); |
12164 | 138 if(stream_seek(stream, pos)==0) |
139 return -1; | |
12166 | 140 |
12164 | 141 return pos; |
142 } | |
143 | |
144 static int mp_close(URLContext *h){ | |
145 return 0; | |
146 } | |
147 | |
148 static URLProtocol mp_protocol = { | |
149 "mp", | |
150 mp_open, | |
151 mp_read, | |
152 mp_write, | |
153 mp_seek, | |
154 mp_close, | |
155 }; | |
156 | |
16175 | 157 static int lavf_check_file(demuxer_t *demuxer){ |
12164 | 158 AVProbeData avpd; |
159 uint8_t buf[PROBE_BUF_SIZE]; | |
160 lavf_priv_t *priv; | |
161 | |
162 if(!demuxer->priv) | |
163 demuxer->priv=calloc(sizeof(lavf_priv_t),1); | |
164 priv= demuxer->priv; | |
165 | |
166 av_register_all(); | |
167 | |
15819 | 168 if(stream_read(demuxer->stream, buf, PROBE_BUF_SIZE)!=PROBE_BUF_SIZE) |
169 return 0; | |
12164 | 170 avpd.filename= demuxer->stream->url; |
171 avpd.buf= buf; | |
172 avpd.buf_size= PROBE_BUF_SIZE; | |
173 | |
174 priv->avif= av_probe_input_format(&avpd, 1); | |
175 if(!priv->avif){ | |
176 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: no clue about this gibberish!\n"); | |
177 return 0; | |
178 }else | |
179 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name); | |
180 | |
16175 | 181 return DEMUXER_TYPE_LAVF; |
12164 | 182 } |
183 | |
16175 | 184 static demuxer_t* demux_open_lavf(demuxer_t *demuxer){ |
12164 | 185 AVFormatContext *avfc; |
186 AVFormatParameters ap; | |
19598 | 187 AVOption *opt; |
12164 | 188 lavf_priv_t *priv= demuxer->priv; |
15011 | 189 int i,g; |
12164 | 190 char mp_filename[256]="mp:"; |
191 | |
192 memset(&ap, 0, sizeof(AVFormatParameters)); | |
193 | |
194 stream_seek(demuxer->stream, 0); | |
195 | |
196 register_protocol(&mp_protocol); | |
197 | |
19598 | 198 avfc = av_alloc_format_context(); |
21548 | 199 |
200 if (correct_pts) | |
201 avfc->flags |= AVFMT_FLAG_GENPTS; | |
202 | |
19598 | 203 ap.prealloced_context = 1; |
204 if(opt_probesize) { | |
205 double d = (double) opt_probesize; | |
206 opt = av_set_double(avfc, "probesize", opt_probesize); | |
207 if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %.3f\r\n", d); | |
208 } | |
209 | |
12463 | 210 if(demuxer->stream->url) |
211 strncpy(mp_filename + 3, demuxer->stream->url, sizeof(mp_filename)-3); | |
212 else | |
213 strncpy(mp_filename + 3, "foobar.dummy", sizeof(mp_filename)-3); | |
12164 | 214 |
215 url_fopen(&priv->pb, mp_filename, URL_RDONLY); | |
216 | |
217 ((URLContext*)(priv->pb.opaque))->priv_data= demuxer->stream; | |
218 | |
219 if(av_open_input_stream(&avfc, &priv->pb, mp_filename, priv->avif, &ap)<0){ | |
220 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n"); | |
16175 | 221 return NULL; |
12164 | 222 } |
223 | |
224 priv->avfc= avfc; | |
225 | |
226 if(av_find_stream_info(avfc) < 0){ | |
227 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n"); | |
16175 | 228 return NULL; |
12164 | 229 } |
230 | |
12167 | 231 if(avfc->title [0]) demux_info_add(demuxer, "name" , avfc->title ); |
232 if(avfc->author [0]) demux_info_add(demuxer, "author" , avfc->author ); | |
233 if(avfc->copyright[0]) demux_info_add(demuxer, "copyright", avfc->copyright); | |
234 if(avfc->comment [0]) demux_info_add(demuxer, "comments" , avfc->comment ); | |
235 if(avfc->album [0]) demux_info_add(demuxer, "album" , avfc->album ); | |
236 // if(avfc->year ) demux_info_add(demuxer, "year" , avfc->year ); | |
237 // if(avfc->track ) demux_info_add(demuxer, "track" , avfc->track ); | |
238 if(avfc->genre [0]) demux_info_add(demuxer, "genre" , avfc->genre ); | |
12164 | 239 |
240 for(i=0; i<avfc->nb_streams; i++){ | |
241 AVStream *st= avfc->streams[i]; | |
16000 | 242 AVCodecContext *codec= st->codec; |
19073
8b52dad54b1d
Remove #if LIBAVCODEC_BUILD >= XXX and #if LIBAVFORMAT_BUILD >= XXX jungle.
diego
parents:
19062
diff
changeset
|
243 |
12164 | 244 switch(codec->codec_type){ |
245 case CODEC_TYPE_AUDIO:{ | |
246 WAVEFORMATEX *wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1); | |
18985 | 247 sh_audio_t* sh_audio; |
18762 | 248 if(priv->audio_streams >= MAX_A_STREAMS) |
249 break; | |
18985 | 250 sh_audio=new_sh_audio(demuxer, i); |
18762 | 251 if(!sh_audio) |
252 break; | |
253 priv->astreams[priv->audio_streams] = i; | |
12164 | 254 priv->audio_streams++; |
255 if(!codec->codec_tag) | |
256 codec->codec_tag= codec_get_wav_tag(codec->codec_id); | |
20733
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
257 if(!codec->codec_tag) |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
258 codec->codec_tag= codec_get_tag(mp_wav_tags, codec->codec_id); |
12164 | 259 wf->wFormatTag= codec->codec_tag; |
260 wf->nChannels= codec->channels; | |
261 wf->nSamplesPerSec= codec->sample_rate; | |
262 wf->nAvgBytesPerSec= codec->bit_rate/8; | |
263 wf->nBlockAlign= codec->block_align; | |
264 wf->wBitsPerSample= codec->bits_per_sample; | |
265 wf->cbSize= codec->extradata_size; | |
266 if(codec->extradata_size){ | |
267 memcpy( | |
268 wf + 1, | |
269 codec->extradata, | |
270 codec->extradata_size); | |
271 } | |
272 sh_audio->wf= wf; | |
15011 | 273 sh_audio->audio.dwSampleSize= codec->block_align; |
274 if(codec->frame_size && codec->sample_rate){ | |
275 sh_audio->audio.dwScale=codec->frame_size; | |
276 sh_audio->audio.dwRate= codec->sample_rate; | |
277 }else{ | |
278 sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8; | |
279 sh_audio->audio.dwRate = codec->bit_rate; | |
280 } | |
281 g= ff_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate); | |
282 sh_audio->audio.dwScale /= g; | |
283 sh_audio->audio.dwRate /= g; | |
284 // 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); | |
12164 | 285 sh_audio->ds= demuxer->audio; |
286 sh_audio->format= codec->codec_tag; | |
287 sh_audio->channels= codec->channels; | |
288 sh_audio->samplerate= codec->sample_rate; | |
15007 | 289 sh_audio->i_bps= codec->bit_rate/8; |
16134
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
290 switch (codec->codec_id) { |
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
291 case CODEC_ID_PCM_S8: |
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
292 case CODEC_ID_PCM_U8: |
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
293 sh_audio->samplesize = 1; |
16135 | 294 break; |
16134
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
295 case CODEC_ID_PCM_S16LE: |
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
296 case CODEC_ID_PCM_S16BE: |
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
297 case CODEC_ID_PCM_U16LE: |
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
298 case CODEC_ID_PCM_U16BE: |
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
299 sh_audio->samplesize = 2; |
16135 | 300 break; |
301 case CODEC_ID_PCM_ALAW: | |
302 sh_audio->format = 0x6; | |
303 break; | |
304 case CODEC_ID_PCM_MULAW: | |
305 sh_audio->format = 0x7; | |
306 break; | |
16134
a1fd1a7eeb35
lavf demuxer with raw PCM fix (and a related hang)
reimar
parents:
16000
diff
changeset
|
307 } |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
308 if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V); |
18775 | 309 if((audio_lang && st->language[0] && !strncmp(audio_lang, st->language, 3)) |
310 || (demuxer->audio->id == i || demuxer->audio->id == -1) | |
311 ) { | |
312 demuxer->audio->id = i; | |
313 demuxer->audio->sh= demuxer->a_streams[i]; | |
314 } | |
315 else | |
15004 | 316 st->discard= AVDISCARD_ALL; |
12164 | 317 break;} |
318 case CODEC_TYPE_VIDEO:{ | |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
319 sh_video_t* sh_video; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
320 BITMAPINFOHEADER *bih; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
321 if(priv->video_streams >= MAX_V_STREAMS) |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
322 break; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
323 sh_video=new_sh_video(demuxer, i); |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
324 if(!sh_video) break; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
325 priv->vstreams[priv->video_streams] = i; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
326 priv->video_streams++; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
327 bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1); |
12164 | 328 |
329 if(!codec->codec_tag) | |
330 codec->codec_tag= codec_get_bmp_tag(codec->codec_id); | |
20733
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
331 if(!codec->codec_tag) |
404fb439acba
Add our own CODEC_ID -> fourcc translation tables so we do not need
reimar
parents:
20070
diff
changeset
|
332 codec->codec_tag= codec_get_tag(mp_bmp_tags, codec->codec_id); |
12164 | 333 bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size; |
334 bih->biWidth= codec->width; | |
335 bih->biHeight= codec->height; | |
336 bih->biBitCount= codec->bits_per_sample; | |
337 bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8; | |
338 bih->biCompression= codec->codec_tag; | |
339 sh_video->bih= bih; | |
340 sh_video->disp_w= codec->width; | |
341 sh_video->disp_h= codec->height; | |
16718
044260623695
makes demux_lavf (-demuxer 35) use the framerate specified in the container
gpoirier
parents:
16346
diff
changeset
|
342 if (st->time_base.den) { /* if container has time_base, use that */ |
044260623695
makes demux_lavf (-demuxer 35) use the framerate specified in the container
gpoirier
parents:
16346
diff
changeset
|
343 sh_video->video.dwRate= st->time_base.den; |
044260623695
makes demux_lavf (-demuxer 35) use the framerate specified in the container
gpoirier
parents:
16346
diff
changeset
|
344 sh_video->video.dwScale= st->time_base.num; |
044260623695
makes demux_lavf (-demuxer 35) use the framerate specified in the container
gpoirier
parents:
16346
diff
changeset
|
345 } else { |
15308 | 346 sh_video->video.dwRate= codec->time_base.den; |
347 sh_video->video.dwScale= codec->time_base.num; | |
16718
044260623695
makes demux_lavf (-demuxer 35) use the framerate specified in the container
gpoirier
parents:
16346
diff
changeset
|
348 } |
17556 | 349 sh_video->fps=av_q2d(st->r_frame_rate); |
350 sh_video->frametime=1/av_q2d(st->r_frame_rate); | |
12164 | 351 sh_video->format = bih->biCompression; |
12167 | 352 sh_video->aspect= codec->width * codec->sample_aspect_ratio.num |
353 / (float)(codec->height * codec->sample_aspect_ratio.den); | |
15007 | 354 sh_video->i_bps= codec->bit_rate/8; |
12167 | 355 mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n", |
356 codec->width, codec->sample_aspect_ratio.num, | |
357 codec->height, codec->sample_aspect_ratio.den); | |
358 | |
12164 | 359 sh_video->ds= demuxer->video; |
360 if(codec->extradata_size) | |
361 memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size); | |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
362 if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V); |
12164 | 363 /* short biPlanes; |
364 int biXPelsPerMeter; | |
365 int biYPelsPerMeter; | |
366 int biClrUsed; | |
367 int biClrImportant;*/ | |
15004 | 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]; | |
373 } | |
12164 | 374 break;} |
15004 | 375 default: |
376 st->discard= AVDISCARD_ALL; | |
12164 | 377 } |
378 } | |
379 | |
380 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams); | |
13749 | 381 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD); |
12164 | 382 if(!priv->audio_streams) demuxer->audio->id=-2; // nosound |
383 // else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio; | |
384 if(!priv->video_streams){ | |
385 if(!priv->audio_streams){ | |
386 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n"); | |
16175 | 387 return NULL; |
12164 | 388 } |
389 demuxer->video->id=-2; // audio-only | |
390 } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video; | |
391 | |
16175 | 392 return demuxer; |
12164 | 393 } |
394 | |
16175 | 395 static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){ |
12164 | 396 lavf_priv_t *priv= demux->priv; |
397 AVPacket pkt; | |
398 demux_packet_t *dp; | |
399 demux_stream_t *ds; | |
400 int id; | |
401 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_lavf_fill_buffer()\n"); | |
402 | |
403 demux->filepos=stream_tell(demux->stream); | |
404 | |
405 if(av_read_frame(priv->avfc, &pkt) < 0) | |
406 return 0; | |
407 | |
408 id= pkt.stream_index; | |
409 | |
410 if(id==demux->audio->id){ | |
411 // audio | |
412 ds=demux->audio; | |
413 if(!ds->sh){ | |
414 ds->sh=demux->a_streams[id]; | |
415 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id); | |
416 } | |
417 } else if(id==demux->video->id){ | |
418 // video | |
419 ds=demux->video; | |
420 if(!ds->sh){ | |
421 ds->sh=demux->v_streams[id]; | |
422 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id); | |
423 } | |
14611 | 424 } else { |
425 av_free_packet(&pkt); | |
426 return 1; | |
427 } | |
12164 | 428 |
429 if(0/*pkt.destruct == av_destruct_packet*/){ | |
430 //ok kids, dont try this at home :) | |
19062
83c3afeab35d
drops casts from void * on malloc/calloc from libmpdemux code
reynaldo
parents:
18985
diff
changeset
|
431 dp=malloc(sizeof(demux_packet_t)); |
12164 | 432 dp->len=pkt.size; |
433 dp->next=NULL; | |
434 dp->refcount=1; | |
435 dp->master=NULL; | |
436 dp->buffer=pkt.data; | |
437 pkt.destruct= NULL; | |
438 }else{ | |
439 dp=new_demux_packet(pkt.size); | |
440 memcpy(dp->buffer, pkt.data, pkt.size); | |
441 av_free_packet(&pkt); | |
442 } | |
443 | |
13747 | 444 if(pkt.pts != AV_NOPTS_VALUE){ |
15308 | 445 dp->pts=pkt.pts * av_q2d(priv->avfc->streams[id]->time_base); |
446 priv->last_pts= dp->pts * AV_TIME_BASE; | |
13747 | 447 } |
12164 | 448 dp->pos=demux->filepos; |
449 dp->flags= !!(pkt.flags&PKT_FLAG_KEY); | |
450 // append packet to DS stream: | |
451 ds_add_packet(ds,dp); | |
452 return 1; | |
453 } | |
454 | |
17636 | 455 static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags){ |
12168 | 456 lavf_priv_t *priv = demuxer->priv; |
20070 | 457 int avsflags = 0; |
17636 | 458 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %f, %d)\n", demuxer, rel_seek_secs, audio_delay, flags); |
19073
8b52dad54b1d
Remove #if LIBAVCODEC_BUILD >= XXX and #if LIBAVFORMAT_BUILD >= XXX jungle.
diego
parents:
19062
diff
changeset
|
459 |
20070 | 460 if (flags & 1) // absolute seek |
461 priv->last_pts = priv->avfc->start_time; | |
462 if (flags & 2) { // percent seek | |
463 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE) | |
464 return; | |
465 priv->last_pts += rel_seek_secs * priv->avfc->duration; | |
466 } else { | |
467 priv->last_pts += rel_seek_secs * AV_TIME_BASE; | |
468 if (rel_seek_secs < 0) avsflags = AVSEEK_FLAG_BACKWARD; | |
469 } | |
470 av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags); | |
12164 | 471 } |
472 | |
16175 | 473 static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg) |
12164 | 474 { |
475 lavf_priv_t *priv = demuxer->priv; | |
476 | |
477 switch (cmd) { | |
12168 | 478 case DEMUXER_CTRL_GET_TIME_LENGTH: |
19207
c636a4e9565a
Do not treat AV_NOPTS_VALUE as a valid duration value.
reimar
parents:
19160
diff
changeset
|
479 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE) |
12164 | 480 return DEMUXER_CTRL_DONTKNOW; |
481 | |
16346
6ff303d2876b
Make -identify's 'ID_LENGTH=' print a float and not an integer.. The
ods15
parents:
16175
diff
changeset
|
482 *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE; |
12164 | 483 return DEMUXER_CTRL_OK; |
484 | |
485 case DEMUXER_CTRL_GET_PERCENT_POS: | |
19207
c636a4e9565a
Do not treat AV_NOPTS_VALUE as a valid duration value.
reimar
parents:
19160
diff
changeset
|
486 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE) |
12164 | 487 return DEMUXER_CTRL_DONTKNOW; |
488 | |
19160
ccb42ce33c23
Take start time into consideration when calculation percentage position
reimar
parents:
19073
diff
changeset
|
489 *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration); |
12168 | 490 return DEMUXER_CTRL_OK; |
18762 | 491 case DEMUXER_CTRL_SWITCH_AUDIO: |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
492 case DEMUXER_CTRL_SWITCH_VIDEO: |
18762 | 493 { |
494 int id = *((int*)arg); | |
495 int newid = -2; | |
496 int i, curridx = -2; | |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
497 int nstreams, *pstreams; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
498 demux_stream_t *ds; |
18762 | 499 |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
500 if(cmd == DEMUXER_CTRL_SWITCH_VIDEO) |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
501 { |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
502 ds = demuxer->video; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
503 nstreams = priv->video_streams; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
504 pstreams = priv->vstreams; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
505 } |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
506 else |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
507 { |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
508 ds = demuxer->audio; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
509 nstreams = priv->audio_streams; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
510 pstreams = priv->astreams; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
511 } |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
512 if(ds->id == -2) |
18762 | 513 return DEMUXER_CTRL_NOTIMPL; |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
514 for(i = 0; i < nstreams; i++) |
18762 | 515 { |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
516 if(pstreams[i] == ds->id) //current stream id |
18762 | 517 { |
518 curridx = i; | |
519 break; | |
520 } | |
521 } | |
522 | |
523 if(id < 0) | |
524 { | |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
525 i = (curridx + 1) % nstreams; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
526 newid = pstreams[i]; |
18762 | 527 } |
528 else | |
529 { | |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
530 for(i = 0; i < nstreams; i++) |
18762 | 531 { |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
532 if(pstreams[i] == id) |
18762 | 533 { |
534 newid = id; | |
535 break; | |
536 } | |
537 } | |
538 } | |
539 if(newid == -2 || i == curridx) | |
540 return DEMUXER_CTRL_NOTIMPL; | |
541 else | |
542 { | |
21100
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
543 ds_free_packs(ds); |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
544 priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL; |
6bc989360c8b
check we aren't short of sh_videos before allocating another one
nicodvb
parents:
20990
diff
changeset
|
545 *((int*)arg) = ds->id = newid; |
18762 | 546 priv->avfc->streams[newid]->discard = AVDISCARD_NONE; |
547 return DEMUXER_CTRL_OK; | |
548 } | |
549 } | |
12164 | 550 default: |
551 return DEMUXER_CTRL_NOTIMPL; | |
552 } | |
553 } | |
554 | |
16175 | 555 static void demux_close_lavf(demuxer_t *demuxer) |
12164 | 556 { |
557 lavf_priv_t* priv = demuxer->priv; | |
558 if (priv){ | |
12304
434242b0706c
fix possible segfault on lavf demuxer patch by (adland <adland123 at yahoo dot com>)
michael
parents:
12168
diff
changeset
|
559 if(priv->avfc) |
434242b0706c
fix possible segfault on lavf demuxer patch by (adland <adland123 at yahoo dot com>)
michael
parents:
12168
diff
changeset
|
560 { |
434242b0706c
fix possible segfault on lavf demuxer patch by (adland <adland123 at yahoo dot com>)
michael
parents:
12168
diff
changeset
|
561 av_close_input_file(priv->avfc); priv->avfc= NULL; |
434242b0706c
fix possible segfault on lavf demuxer patch by (adland <adland123 at yahoo dot com>)
michael
parents:
12168
diff
changeset
|
562 } |
12164 | 563 free(priv); demuxer->priv= NULL; |
564 } | |
565 } | |
566 | |
16175 | 567 |
568 demuxer_desc_t demuxer_desc_lavf = { | |
569 "libavformat demuxer", | |
570 "lavf", | |
571 "libavformat", | |
572 "Michael Niedermayer", | |
573 "supports many formats, requires libavformat", | |
574 DEMUXER_TYPE_LAVF, | |
575 0, // Check after other demuxer | |
576 lavf_check_file, | |
577 demux_lavf_fill_buffer, | |
578 demux_open_lavf, | |
579 demux_close_lavf, | |
580 demux_seek_lavf, | |
581 demux_lavf_control | |
582 }; | |
583 |