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
|
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>
|
21995
|
35 #include <ffmpeg/avutil.h>
|
19598
|
36 #include <ffmpeg/opt.h>
|
17354
|
37 #else
|
12164
|
38 #include "avformat.h"
|
21995
|
39 #include "avutil.h"
|
12164
|
40 #include "avi.h"
|
19598
|
41 #include "opt.h"
|
17354
|
42 #endif
|
21822
|
43 #include "riff.h"
|
12164
|
44
|
|
45 #define PROBE_BUF_SIZE 2048
|
|
46
|
18775
|
47 extern char *audio_lang;
|
19598
|
48 static unsigned int opt_probesize = 0;
|
22150
|
49 static char *opt_format;
|
19598
|
50
|
|
51 m_option_t lavfdopts_conf[] = {
|
|
52 {"probesize", &(opt_probesize), CONF_TYPE_INT, CONF_RANGE, 32, INT_MAX, NULL},
|
22150
|
53 {"format", &(opt_format), CONF_TYPE_STRING, 0, 0, 0, NULL},
|
19598
|
54 {NULL, NULL, 0, 0, 0, 0, NULL}
|
|
55 };
|
|
56
|
18775
|
57
|
12164
|
58 typedef struct lavf_priv_t{
|
|
59 AVInputFormat *avif;
|
|
60 AVFormatContext *avfc;
|
|
61 ByteIOContext pb;
|
|
62 int audio_streams;
|
|
63 int video_streams;
|
12168
|
64 int64_t last_pts;
|
18762
|
65 int astreams[MAX_A_STREAMS];
|
21100
|
66 int vstreams[MAX_V_STREAMS];
|
12164
|
67 }lavf_priv_t;
|
|
68
|
17977
|
69 extern void print_wave_header(WAVEFORMATEX *h, int verbose_level);
|
|
70 extern void print_video_header(BITMAPINFOHEADER *h, int verbose_level);
|
12164
|
71
|
21966
|
72 static const AVCodecTag mp_wav_tags[] = {
|
20944
|
73 { CODEC_ID_ADPCM_4XM, MKTAG('4', 'X', 'M', 'A')},
|
|
74 { CODEC_ID_ADPCM_EA, MKTAG('A', 'D', 'E', 'A')},
|
|
75 { CODEC_ID_ADPCM_IMA_WS, MKTAG('A', 'I', 'W', 'S')},
|
21779
|
76 { CODEC_ID_AMR_NB, MKTAG('n', 'b', 0, 0)},
|
20944
|
77 { CODEC_ID_DSICINAUDIO, MKTAG('D', 'C', 'I', 'A')},
|
|
78 { CODEC_ID_INTERPLAY_DPCM, MKTAG('I', 'N', 'P', 'A')},
|
21763
|
79 { CODEC_ID_MUSEPACK7, MKTAG('M', 'P', 'C', ' ')},
|
20944
|
80 { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4')},
|
22058
|
81 { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's')},
|
20944
|
82 { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's')},
|
|
83 { CODEC_ID_ROQ_DPCM, MKTAG('R', 'o', 'Q', 'A')},
|
|
84 { CODEC_ID_SHORTEN, MKTAG('s', 'h', 'r', 'n')},
|
|
85 { CODEC_ID_TTA, MKTAG('T', 'T', 'A', '1')},
|
|
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
|
89 { 0, 0 },
|
|
90 };
|
|
91
|
21966
|
92 const struct AVCodecTag *mp_wav_taglists[] = {codec_wav_tags, mp_wav_tags, 0};
|
|
93
|
|
94 static const AVCodecTag mp_bmp_tags[] = {
|
20940
|
95 { CODEC_ID_DSICINVIDEO, MKTAG('D', 'C', 'I', 'V')},
|
20963
|
96 { CODEC_ID_FLIC, MKTAG('F', 'L', 'I', 'C')},
|
20980
|
97 { CODEC_ID_IDCIN, MKTAG('I', 'D', 'C', 'I')},
|
|
98 { CODEC_ID_INTERPLAY_VIDEO, MKTAG('I', 'N', 'P', 'V')},
|
20942
|
99 { CODEC_ID_ROQ, MKTAG('R', 'o', 'Q', 'V')},
|
20933
|
100 { CODEC_ID_TIERTEXSEQVIDEO, MKTAG('T', 'S', 'E', 'Q')},
|
20935
|
101 { CODEC_ID_VMDVIDEO, MKTAG('V', 'M', 'D', 'V')},
|
20980
|
102 { CODEC_ID_WS_VQA, MKTAG('V', 'Q', 'A', 'V')},
|
20935
|
103 { CODEC_ID_XAN_WC3, MKTAG('W', 'C', '3', 'V')},
|
20733
|
104 { 0, 0 },
|
|
105 };
|
|
106
|
21966
|
107 const struct AVCodecTag *mp_bmp_taglists[] = {codec_bmp_tags, mp_bmp_tags, 0};
|
|
108
|
12164
|
109 static int mp_open(URLContext *h, const char *filename, int flags){
|
|
110 return 0;
|
|
111 }
|
|
112
|
|
113 static int mp_read(URLContext *h, unsigned char *buf, int size){
|
|
114 stream_t *stream = (stream_t*)h->priv_data;
|
12165
|
115 int ret;
|
|
116
|
12164
|
117 if(stream_eof(stream)) //needed?
|
|
118 return -1;
|
12165
|
119 ret=stream_read(stream, buf, size);
|
12166
|
120
|
12165
|
121 mp_msg(MSGT_HEADER,MSGL_DBG2,"%d=mp_read(%p, %p, %d), eof:%d\n", ret, h, buf, size, stream->eof);
|
|
122 return ret;
|
12164
|
123 }
|
|
124
|
|
125 static int mp_write(URLContext *h, unsigned char *buf, int size){
|
|
126 return -1;
|
|
127 }
|
|
128
|
|
129 static offset_t mp_seek(URLContext *h, offset_t pos, int whence){
|
|
130 stream_t *stream = (stream_t*)h->priv_data;
|
12165
|
131
|
|
132 mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %d, %d)\n", h, (int)pos, whence);
|
12164
|
133 if(whence == SEEK_CUR)
|
|
134 pos +=stream_tell(stream);
|
|
135 else if(whence == SEEK_END)
|
|
136 pos += stream->end_pos;
|
|
137 else if(whence != SEEK_SET)
|
|
138 return -1;
|
|
139
|
12167
|
140 if(pos<stream->end_pos && stream->eof)
|
12166
|
141 stream_reset(stream);
|
12164
|
142 if(stream_seek(stream, pos)==0)
|
|
143 return -1;
|
12166
|
144
|
12164
|
145 return pos;
|
|
146 }
|
|
147
|
|
148 static int mp_close(URLContext *h){
|
|
149 return 0;
|
|
150 }
|
|
151
|
|
152 static URLProtocol mp_protocol = {
|
|
153 "mp",
|
|
154 mp_open,
|
|
155 mp_read,
|
|
156 mp_write,
|
|
157 mp_seek,
|
|
158 mp_close,
|
|
159 };
|
|
160
|
22150
|
161 static void list_formats(void) {
|
|
162 AVInputFormat *fmt;
|
|
163 mp_msg(MSGT_DEMUX, MSGL_INFO, "Available lavf input formats:\n");
|
|
164 for (fmt = first_iformat; fmt; fmt = fmt->next)
|
|
165 mp_msg(MSGT_DEMUX, MSGL_INFO, "%15s : %s\n", fmt->name, fmt->long_name);
|
|
166 }
|
|
167
|
16175
|
168 static int lavf_check_file(demuxer_t *demuxer){
|
12164
|
169 AVProbeData avpd;
|
|
170 uint8_t buf[PROBE_BUF_SIZE];
|
|
171 lavf_priv_t *priv;
|
|
172
|
|
173 if(!demuxer->priv)
|
|
174 demuxer->priv=calloc(sizeof(lavf_priv_t),1);
|
|
175 priv= demuxer->priv;
|
|
176
|
|
177 av_register_all();
|
|
178
|
15819
|
179 if(stream_read(demuxer->stream, buf, PROBE_BUF_SIZE)!=PROBE_BUF_SIZE)
|
|
180 return 0;
|
12164
|
181 avpd.filename= demuxer->stream->url;
|
|
182 avpd.buf= buf;
|
|
183 avpd.buf_size= PROBE_BUF_SIZE;
|
|
184
|
22150
|
185 if (opt_format) {
|
|
186 if (strcmp(opt_format, "help") == 0) {
|
|
187 list_formats();
|
|
188 return 0;
|
|
189 }
|
|
190 priv->avif= av_find_input_format(opt_format);
|
|
191 if (!priv->avif) {
|
|
192 mp_msg(MSGT_DEMUX,MSGL_FATAL,"Unknown lavf format %s\n", opt_format);
|
|
193 return 0;
|
|
194 }
|
|
195 mp_msg(MSGT_DEMUX,MSGL_INFO,"Forced lavf %s demuxer\n", priv->avif->long_name);
|
|
196 return DEMUXER_TYPE_LAVF;
|
|
197 }
|
12164
|
198 priv->avif= av_probe_input_format(&avpd, 1);
|
|
199 if(!priv->avif){
|
|
200 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: no clue about this gibberish!\n");
|
|
201 return 0;
|
|
202 }else
|
|
203 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name);
|
|
204
|
16175
|
205 return DEMUXER_TYPE_LAVF;
|
12164
|
206 }
|
|
207
|
16175
|
208 static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
|
12164
|
209 AVFormatContext *avfc;
|
|
210 AVFormatParameters ap;
|
19598
|
211 AVOption *opt;
|
12164
|
212 lavf_priv_t *priv= demuxer->priv;
|
15011
|
213 int i,g;
|
12164
|
214 char mp_filename[256]="mp:";
|
|
215
|
|
216 memset(&ap, 0, sizeof(AVFormatParameters));
|
|
217
|
|
218 stream_seek(demuxer->stream, 0);
|
|
219
|
|
220 register_protocol(&mp_protocol);
|
|
221
|
19598
|
222 avfc = av_alloc_format_context();
|
21548
|
223
|
|
224 if (correct_pts)
|
|
225 avfc->flags |= AVFMT_FLAG_GENPTS;
|
21568
|
226 if (index_mode == 0)
|
|
227 avfc->flags |= AVFMT_FLAG_IGNIDX;
|
21548
|
228
|
19598
|
229 ap.prealloced_context = 1;
|
|
230 if(opt_probesize) {
|
|
231 double d = (double) opt_probesize;
|
|
232 opt = av_set_double(avfc, "probesize", opt_probesize);
|
|
233 if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %.3f\r\n", d);
|
|
234 }
|
|
235
|
12463
|
236 if(demuxer->stream->url)
|
|
237 strncpy(mp_filename + 3, demuxer->stream->url, sizeof(mp_filename)-3);
|
|
238 else
|
|
239 strncpy(mp_filename + 3, "foobar.dummy", sizeof(mp_filename)-3);
|
12164
|
240
|
|
241 url_fopen(&priv->pb, mp_filename, URL_RDONLY);
|
|
242
|
|
243 ((URLContext*)(priv->pb.opaque))->priv_data= demuxer->stream;
|
|
244
|
|
245 if(av_open_input_stream(&avfc, &priv->pb, mp_filename, priv->avif, &ap)<0){
|
|
246 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n");
|
16175
|
247 return NULL;
|
12164
|
248 }
|
|
249
|
|
250 priv->avfc= avfc;
|
|
251
|
|
252 if(av_find_stream_info(avfc) < 0){
|
|
253 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n");
|
16175
|
254 return NULL;
|
12164
|
255 }
|
|
256
|
12167
|
257 if(avfc->title [0]) demux_info_add(demuxer, "name" , avfc->title );
|
|
258 if(avfc->author [0]) demux_info_add(demuxer, "author" , avfc->author );
|
|
259 if(avfc->copyright[0]) demux_info_add(demuxer, "copyright", avfc->copyright);
|
|
260 if(avfc->comment [0]) demux_info_add(demuxer, "comments" , avfc->comment );
|
|
261 if(avfc->album [0]) demux_info_add(demuxer, "album" , avfc->album );
|
|
262 // if(avfc->year ) demux_info_add(demuxer, "year" , avfc->year );
|
|
263 // if(avfc->track ) demux_info_add(demuxer, "track" , avfc->track );
|
|
264 if(avfc->genre [0]) demux_info_add(demuxer, "genre" , avfc->genre );
|
12164
|
265
|
|
266 for(i=0; i<avfc->nb_streams; i++){
|
|
267 AVStream *st= avfc->streams[i];
|
16000
|
268 AVCodecContext *codec= st->codec;
|
19073
|
269
|
12164
|
270 switch(codec->codec_type){
|
|
271 case CODEC_TYPE_AUDIO:{
|
|
272 WAVEFORMATEX *wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1);
|
18985
|
273 sh_audio_t* sh_audio;
|
18762
|
274 if(priv->audio_streams >= MAX_A_STREAMS)
|
|
275 break;
|
18985
|
276 sh_audio=new_sh_audio(demuxer, i);
|
18762
|
277 if(!sh_audio)
|
|
278 break;
|
|
279 priv->astreams[priv->audio_streams] = i;
|
12164
|
280 priv->audio_streams++;
|
|
281 if(!codec->codec_tag)
|
21966
|
282 codec->codec_tag= av_codec_get_tag(mp_wav_taglists, codec->codec_id);
|
12164
|
283 wf->wFormatTag= codec->codec_tag;
|
|
284 wf->nChannels= codec->channels;
|
|
285 wf->nSamplesPerSec= codec->sample_rate;
|
|
286 wf->nAvgBytesPerSec= codec->bit_rate/8;
|
|
287 wf->nBlockAlign= codec->block_align;
|
|
288 wf->wBitsPerSample= codec->bits_per_sample;
|
|
289 wf->cbSize= codec->extradata_size;
|
|
290 if(codec->extradata_size){
|
|
291 memcpy(
|
|
292 wf + 1,
|
|
293 codec->extradata,
|
|
294 codec->extradata_size);
|
|
295 }
|
|
296 sh_audio->wf= wf;
|
15011
|
297 sh_audio->audio.dwSampleSize= codec->block_align;
|
|
298 if(codec->frame_size && codec->sample_rate){
|
|
299 sh_audio->audio.dwScale=codec->frame_size;
|
|
300 sh_audio->audio.dwRate= codec->sample_rate;
|
|
301 }else{
|
|
302 sh_audio->audio.dwScale= codec->block_align ? codec->block_align*8 : 8;
|
|
303 sh_audio->audio.dwRate = codec->bit_rate;
|
|
304 }
|
|
305 g= ff_gcd(sh_audio->audio.dwScale, sh_audio->audio.dwRate);
|
|
306 sh_audio->audio.dwScale /= g;
|
|
307 sh_audio->audio.dwRate /= g;
|
|
308 // 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
|
309 sh_audio->ds= demuxer->audio;
|
|
310 sh_audio->format= codec->codec_tag;
|
|
311 sh_audio->channels= codec->channels;
|
|
312 sh_audio->samplerate= codec->sample_rate;
|
15007
|
313 sh_audio->i_bps= codec->bit_rate/8;
|
16134
|
314 switch (codec->codec_id) {
|
|
315 case CODEC_ID_PCM_S8:
|
|
316 case CODEC_ID_PCM_U8:
|
|
317 sh_audio->samplesize = 1;
|
16135
|
318 break;
|
16134
|
319 case CODEC_ID_PCM_S16LE:
|
|
320 case CODEC_ID_PCM_S16BE:
|
|
321 case CODEC_ID_PCM_U16LE:
|
|
322 case CODEC_ID_PCM_U16BE:
|
|
323 sh_audio->samplesize = 2;
|
16135
|
324 break;
|
|
325 case CODEC_ID_PCM_ALAW:
|
|
326 sh_audio->format = 0x6;
|
|
327 break;
|
|
328 case CODEC_ID_PCM_MULAW:
|
|
329 sh_audio->format = 0x7;
|
|
330 break;
|
16134
|
331 }
|
17977
|
332 if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_wave_header(sh_audio->wf, MSGL_V);
|
18775
|
333 if((audio_lang && st->language[0] && !strncmp(audio_lang, st->language, 3))
|
|
334 || (demuxer->audio->id == i || demuxer->audio->id == -1)
|
|
335 ) {
|
|
336 demuxer->audio->id = i;
|
|
337 demuxer->audio->sh= demuxer->a_streams[i];
|
|
338 }
|
|
339 else
|
15004
|
340 st->discard= AVDISCARD_ALL;
|
12164
|
341 break;}
|
|
342 case CODEC_TYPE_VIDEO:{
|
21100
|
343 sh_video_t* sh_video;
|
|
344 BITMAPINFOHEADER *bih;
|
|
345 if(priv->video_streams >= MAX_V_STREAMS)
|
|
346 break;
|
|
347 sh_video=new_sh_video(demuxer, i);
|
|
348 if(!sh_video) break;
|
|
349 priv->vstreams[priv->video_streams] = i;
|
|
350 priv->video_streams++;
|
|
351 bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1);
|
12164
|
352
|
|
353 if(!codec->codec_tag)
|
21966
|
354 codec->codec_tag= av_codec_get_tag(mp_bmp_taglists, codec->codec_id);
|
12164
|
355 bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size;
|
|
356 bih->biWidth= codec->width;
|
|
357 bih->biHeight= codec->height;
|
|
358 bih->biBitCount= codec->bits_per_sample;
|
|
359 bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;
|
|
360 bih->biCompression= codec->codec_tag;
|
|
361 sh_video->bih= bih;
|
|
362 sh_video->disp_w= codec->width;
|
|
363 sh_video->disp_h= codec->height;
|
16718
|
364 if (st->time_base.den) { /* if container has time_base, use that */
|
|
365 sh_video->video.dwRate= st->time_base.den;
|
|
366 sh_video->video.dwScale= st->time_base.num;
|
|
367 } else {
|
15308
|
368 sh_video->video.dwRate= codec->time_base.den;
|
|
369 sh_video->video.dwScale= codec->time_base.num;
|
16718
|
370 }
|
17556
|
371 sh_video->fps=av_q2d(st->r_frame_rate);
|
|
372 sh_video->frametime=1/av_q2d(st->r_frame_rate);
|
12164
|
373 sh_video->format = bih->biCompression;
|
12167
|
374 sh_video->aspect= codec->width * codec->sample_aspect_ratio.num
|
|
375 / (float)(codec->height * codec->sample_aspect_ratio.den);
|
15007
|
376 sh_video->i_bps= codec->bit_rate/8;
|
12167
|
377 mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n",
|
|
378 codec->width, codec->sample_aspect_ratio.num,
|
|
379 codec->height, codec->sample_aspect_ratio.den);
|
|
380
|
12164
|
381 sh_video->ds= demuxer->video;
|
|
382 if(codec->extradata_size)
|
|
383 memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size);
|
17977
|
384 if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
|
12164
|
385 /* short biPlanes;
|
|
386 int biXPelsPerMeter;
|
|
387 int biYPelsPerMeter;
|
|
388 int biClrUsed;
|
|
389 int biClrImportant;*/
|
15004
|
390 if(demuxer->video->id != i && demuxer->video->id != -1)
|
|
391 st->discard= AVDISCARD_ALL;
|
|
392 else{
|
|
393 demuxer->video->id = i;
|
|
394 demuxer->video->sh= demuxer->v_streams[i];
|
|
395 }
|
12164
|
396 break;}
|
15004
|
397 default:
|
|
398 st->discard= AVDISCARD_ALL;
|
12164
|
399 }
|
|
400 }
|
|
401
|
|
402 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams);
|
13749
|
403 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD);
|
12164
|
404 if(!priv->audio_streams) demuxer->audio->id=-2; // nosound
|
|
405 // else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio;
|
|
406 if(!priv->video_streams){
|
|
407 if(!priv->audio_streams){
|
|
408 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n");
|
16175
|
409 return NULL;
|
12164
|
410 }
|
|
411 demuxer->video->id=-2; // audio-only
|
|
412 } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;
|
|
413
|
16175
|
414 return demuxer;
|
12164
|
415 }
|
|
416
|
16175
|
417 static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
|
12164
|
418 lavf_priv_t *priv= demux->priv;
|
|
419 AVPacket pkt;
|
|
420 demux_packet_t *dp;
|
|
421 demux_stream_t *ds;
|
|
422 int id;
|
|
423 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_lavf_fill_buffer()\n");
|
|
424
|
|
425 demux->filepos=stream_tell(demux->stream);
|
|
426
|
|
427 if(av_read_frame(priv->avfc, &pkt) < 0)
|
|
428 return 0;
|
|
429
|
|
430 id= pkt.stream_index;
|
|
431
|
|
432 if(id==demux->audio->id){
|
|
433 // audio
|
|
434 ds=demux->audio;
|
|
435 if(!ds->sh){
|
|
436 ds->sh=demux->a_streams[id];
|
|
437 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id);
|
|
438 }
|
|
439 } else if(id==demux->video->id){
|
|
440 // video
|
|
441 ds=demux->video;
|
|
442 if(!ds->sh){
|
|
443 ds->sh=demux->v_streams[id];
|
|
444 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id);
|
|
445 }
|
14611
|
446 } else {
|
|
447 av_free_packet(&pkt);
|
|
448 return 1;
|
|
449 }
|
12164
|
450
|
|
451 if(0/*pkt.destruct == av_destruct_packet*/){
|
|
452 //ok kids, dont try this at home :)
|
19062
|
453 dp=malloc(sizeof(demux_packet_t));
|
12164
|
454 dp->len=pkt.size;
|
|
455 dp->next=NULL;
|
|
456 dp->refcount=1;
|
|
457 dp->master=NULL;
|
|
458 dp->buffer=pkt.data;
|
|
459 pkt.destruct= NULL;
|
|
460 }else{
|
|
461 dp=new_demux_packet(pkt.size);
|
|
462 memcpy(dp->buffer, pkt.data, pkt.size);
|
|
463 av_free_packet(&pkt);
|
|
464 }
|
|
465
|
13747
|
466 if(pkt.pts != AV_NOPTS_VALUE){
|
15308
|
467 dp->pts=pkt.pts * av_q2d(priv->avfc->streams[id]->time_base);
|
|
468 priv->last_pts= dp->pts * AV_TIME_BASE;
|
13747
|
469 }
|
12164
|
470 dp->pos=demux->filepos;
|
|
471 dp->flags= !!(pkt.flags&PKT_FLAG_KEY);
|
|
472 // append packet to DS stream:
|
|
473 ds_add_packet(ds,dp);
|
|
474 return 1;
|
|
475 }
|
|
476
|
17636
|
477 static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags){
|
12168
|
478 lavf_priv_t *priv = demuxer->priv;
|
20070
|
479 int avsflags = 0;
|
17636
|
480 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %f, %d)\n", demuxer, rel_seek_secs, audio_delay, flags);
|
19073
|
481
|
20070
|
482 if (flags & 1) // absolute seek
|
|
483 priv->last_pts = priv->avfc->start_time;
|
|
484 if (flags & 2) { // percent seek
|
|
485 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
|
|
486 return;
|
|
487 priv->last_pts += rel_seek_secs * priv->avfc->duration;
|
|
488 } else {
|
|
489 priv->last_pts += rel_seek_secs * AV_TIME_BASE;
|
|
490 if (rel_seek_secs < 0) avsflags = AVSEEK_FLAG_BACKWARD;
|
|
491 }
|
|
492 av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
|
12164
|
493 }
|
|
494
|
16175
|
495 static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
|
12164
|
496 {
|
|
497 lavf_priv_t *priv = demuxer->priv;
|
|
498
|
|
499 switch (cmd) {
|
12168
|
500 case DEMUXER_CTRL_GET_TIME_LENGTH:
|
19207
|
501 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
|
12164
|
502 return DEMUXER_CTRL_DONTKNOW;
|
|
503
|
16346
|
504 *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
|
12164
|
505 return DEMUXER_CTRL_OK;
|
|
506
|
|
507 case DEMUXER_CTRL_GET_PERCENT_POS:
|
19207
|
508 if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
|
12164
|
509 return DEMUXER_CTRL_DONTKNOW;
|
|
510
|
19160
|
511 *((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time)*100 / priv->avfc->duration);
|
12168
|
512 return DEMUXER_CTRL_OK;
|
18762
|
513 case DEMUXER_CTRL_SWITCH_AUDIO:
|
21100
|
514 case DEMUXER_CTRL_SWITCH_VIDEO:
|
18762
|
515 {
|
|
516 int id = *((int*)arg);
|
|
517 int newid = -2;
|
|
518 int i, curridx = -2;
|
21100
|
519 int nstreams, *pstreams;
|
|
520 demux_stream_t *ds;
|
18762
|
521
|
21100
|
522 if(cmd == DEMUXER_CTRL_SWITCH_VIDEO)
|
|
523 {
|
|
524 ds = demuxer->video;
|
|
525 nstreams = priv->video_streams;
|
|
526 pstreams = priv->vstreams;
|
|
527 }
|
|
528 else
|
|
529 {
|
|
530 ds = demuxer->audio;
|
|
531 nstreams = priv->audio_streams;
|
|
532 pstreams = priv->astreams;
|
|
533 }
|
|
534 if(ds->id == -2)
|
18762
|
535 return DEMUXER_CTRL_NOTIMPL;
|
21100
|
536 for(i = 0; i < nstreams; i++)
|
18762
|
537 {
|
21100
|
538 if(pstreams[i] == ds->id) //current stream id
|
18762
|
539 {
|
|
540 curridx = i;
|
|
541 break;
|
|
542 }
|
|
543 }
|
|
544
|
|
545 if(id < 0)
|
|
546 {
|
21100
|
547 i = (curridx + 1) % nstreams;
|
|
548 newid = pstreams[i];
|
18762
|
549 }
|
|
550 else
|
|
551 {
|
21100
|
552 for(i = 0; i < nstreams; i++)
|
18762
|
553 {
|
21100
|
554 if(pstreams[i] == id)
|
18762
|
555 {
|
|
556 newid = id;
|
|
557 break;
|
|
558 }
|
|
559 }
|
|
560 }
|
|
561 if(newid == -2 || i == curridx)
|
|
562 return DEMUXER_CTRL_NOTIMPL;
|
|
563 else
|
|
564 {
|
21100
|
565 ds_free_packs(ds);
|
|
566 priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
|
|
567 *((int*)arg) = ds->id = newid;
|
18762
|
568 priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
|
|
569 return DEMUXER_CTRL_OK;
|
|
570 }
|
|
571 }
|
12164
|
572 default:
|
|
573 return DEMUXER_CTRL_NOTIMPL;
|
|
574 }
|
|
575 }
|
|
576
|
16175
|
577 static void demux_close_lavf(demuxer_t *demuxer)
|
12164
|
578 {
|
|
579 lavf_priv_t* priv = demuxer->priv;
|
|
580 if (priv){
|
12304
|
581 if(priv->avfc)
|
|
582 {
|
|
583 av_close_input_file(priv->avfc); priv->avfc= NULL;
|
|
584 }
|
12164
|
585 free(priv); demuxer->priv= NULL;
|
|
586 }
|
|
587 }
|
|
588
|
16175
|
589
|
|
590 demuxer_desc_t demuxer_desc_lavf = {
|
|
591 "libavformat demuxer",
|
|
592 "lavf",
|
|
593 "libavformat",
|
|
594 "Michael Niedermayer",
|
|
595 "supports many formats, requires libavformat",
|
|
596 DEMUXER_TYPE_LAVF,
|
|
597 0, // Check after other demuxer
|
|
598 lavf_check_file,
|
|
599 demux_lavf_fill_buffer,
|
|
600 demux_open_lavf,
|
|
601 demux_close_lavf,
|
|
602 demux_seek_lavf,
|
|
603 demux_lavf_control
|
|
604 };
|
|
605
|