Mercurial > mplayer.hg
annotate libmpdemux/demux_lavf.c @ 14217:5b5ebf93ec16
Adds support for LADSPA (Linux Audio Developer's Simple Plugin API) plugins.
Compilation is optional and can be controled by configure. You need to
have the LADSPA SDK installed in order to have it autodetected by configure.
Manual page is updated.
author | ivo |
---|---|
date | Thu, 23 Dec 2004 02:09:52 +0000 |
parents | dd7199cfb8e4 |
children | 0c4a7d871288 |
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 | |
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
17 */ | |
18 | |
19 // #include <stdio.h> | |
20 #include <stdlib.h> | |
21 // #include <unistd.h> | |
22 | |
23 #include "config.h" | |
24 #include "mp_msg.h" | |
25 // #include "help_mp.h" | |
26 | |
27 #include "stream.h" | |
28 #include "demuxer.h" | |
29 #include "stheader.h" | |
30 | |
31 #ifdef USE_LIBAVFORMAT | |
32 | |
33 #include "avformat.h" | |
34 #include "avi.h" | |
35 | |
36 #define PROBE_BUF_SIZE 2048 | |
37 | |
38 typedef struct lavf_priv_t{ | |
39 AVInputFormat *avif; | |
40 AVFormatContext *avfc; | |
41 ByteIOContext pb; | |
42 int audio_streams; | |
43 int video_streams; | |
12168 | 44 int64_t last_pts; |
12164 | 45 }lavf_priv_t; |
46 | |
47 extern void print_wave_header(WAVEFORMATEX *h); | |
48 extern void print_video_header(BITMAPINFOHEADER *h); | |
49 | |
50 static int mp_open(URLContext *h, const char *filename, int flags){ | |
51 return 0; | |
52 } | |
53 | |
54 static int mp_read(URLContext *h, unsigned char *buf, int size){ | |
55 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
|
56 int ret; |
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
57 |
12164 | 58 if(stream_eof(stream)) //needed? |
59 return -1; | |
12165
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
60 ret=stream_read(stream, buf, size); |
12166 | 61 |
12165
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
62 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
|
63 return ret; |
12164 | 64 } |
65 | |
66 static int mp_write(URLContext *h, unsigned char *buf, int size){ | |
67 return -1; | |
68 } | |
69 | |
70 static offset_t mp_seek(URLContext *h, offset_t pos, int whence){ | |
71 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
|
72 |
6ae21c78ed8d
libavformat really doesnt like it that the streams get stuck if the end is reached
michael
parents:
12164
diff
changeset
|
73 mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %d, %d)\n", h, (int)pos, whence); |
12164 | 74 if(whence == SEEK_CUR) |
75 pos +=stream_tell(stream); | |
76 else if(whence == SEEK_END) | |
77 pos += stream->end_pos; | |
78 else if(whence != SEEK_SET) | |
79 return -1; | |
80 | |
12167 | 81 if(pos<stream->end_pos && stream->eof) |
12166 | 82 stream_reset(stream); |
12164 | 83 if(stream_seek(stream, pos)==0) |
84 return -1; | |
12166 | 85 |
12164 | 86 return pos; |
87 } | |
88 | |
89 static int mp_close(URLContext *h){ | |
90 return 0; | |
91 } | |
92 | |
93 static URLProtocol mp_protocol = { | |
94 "mp", | |
95 mp_open, | |
96 mp_read, | |
97 mp_write, | |
98 mp_seek, | |
99 mp_close, | |
100 }; | |
101 | |
102 int lavf_check_file(demuxer_t *demuxer){ | |
103 AVProbeData avpd; | |
104 uint8_t buf[PROBE_BUF_SIZE]; | |
105 lavf_priv_t *priv; | |
106 | |
107 if(!demuxer->priv) | |
108 demuxer->priv=calloc(sizeof(lavf_priv_t),1); | |
109 priv= demuxer->priv; | |
110 | |
111 av_register_all(); | |
112 | |
113 stream_read(demuxer->stream, buf, PROBE_BUF_SIZE); | |
114 avpd.filename= demuxer->stream->url; | |
115 avpd.buf= buf; | |
116 avpd.buf_size= PROBE_BUF_SIZE; | |
117 | |
118 priv->avif= av_probe_input_format(&avpd, 1); | |
119 if(!priv->avif){ | |
120 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: no clue about this gibberish!\n"); | |
121 return 0; | |
122 }else | |
123 mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name); | |
124 | |
125 return 1; | |
126 } | |
127 | |
128 int demux_open_lavf(demuxer_t *demuxer){ | |
129 AVFormatContext *avfc; | |
130 AVFormatParameters ap; | |
131 lavf_priv_t *priv= demuxer->priv; | |
132 int i; | |
133 char mp_filename[256]="mp:"; | |
134 | |
135 memset(&ap, 0, sizeof(AVFormatParameters)); | |
136 | |
137 stream_seek(demuxer->stream, 0); | |
138 | |
139 register_protocol(&mp_protocol); | |
140 | |
12463 | 141 if(demuxer->stream->url) |
142 strncpy(mp_filename + 3, demuxer->stream->url, sizeof(mp_filename)-3); | |
143 else | |
144 strncpy(mp_filename + 3, "foobar.dummy", sizeof(mp_filename)-3); | |
12164 | 145 |
146 url_fopen(&priv->pb, mp_filename, URL_RDONLY); | |
147 | |
148 ((URLContext*)(priv->pb.opaque))->priv_data= demuxer->stream; | |
149 | |
150 if(av_open_input_stream(&avfc, &priv->pb, mp_filename, priv->avif, &ap)<0){ | |
151 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n"); | |
152 return 0; | |
153 } | |
154 | |
155 priv->avfc= avfc; | |
156 | |
157 if(av_find_stream_info(avfc) < 0){ | |
158 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n"); | |
159 return 0; | |
160 } | |
161 | |
12167 | 162 if(avfc->title [0]) demux_info_add(demuxer, "name" , avfc->title ); |
163 if(avfc->author [0]) demux_info_add(demuxer, "author" , avfc->author ); | |
164 if(avfc->copyright[0]) demux_info_add(demuxer, "copyright", avfc->copyright); | |
165 if(avfc->comment [0]) demux_info_add(demuxer, "comments" , avfc->comment ); | |
166 if(avfc->album [0]) demux_info_add(demuxer, "album" , avfc->album ); | |
167 // if(avfc->year ) demux_info_add(demuxer, "year" , avfc->year ); | |
168 // if(avfc->track ) demux_info_add(demuxer, "track" , avfc->track ); | |
169 if(avfc->genre [0]) demux_info_add(demuxer, "genre" , avfc->genre ); | |
12164 | 170 |
171 for(i=0; i<avfc->nb_streams; i++){ | |
172 AVStream *st= avfc->streams[i]; | |
173 AVCodecContext *codec= &st->codec; | |
174 | |
175 switch(codec->codec_type){ | |
176 case CODEC_TYPE_AUDIO:{ | |
177 WAVEFORMATEX *wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1); | |
178 sh_audio_t* sh_audio=new_sh_audio(demuxer, i); | |
179 priv->audio_streams++; | |
180 if(!codec->codec_tag) | |
181 codec->codec_tag= codec_get_wav_tag(codec->codec_id); | |
182 wf->wFormatTag= codec->codec_tag; | |
183 wf->nChannels= codec->channels; | |
184 wf->nSamplesPerSec= codec->sample_rate; | |
185 wf->nAvgBytesPerSec= codec->bit_rate/8; | |
186 wf->nBlockAlign= codec->block_align; | |
187 wf->wBitsPerSample= codec->bits_per_sample; | |
188 wf->cbSize= codec->extradata_size; | |
189 if(codec->extradata_size){ | |
190 memcpy( | |
191 wf + 1, | |
192 codec->extradata, | |
193 codec->extradata_size); | |
194 } | |
195 sh_audio->wf= wf; | |
196 sh_audio->ds= demuxer->audio; | |
197 sh_audio->format= codec->codec_tag; | |
198 sh_audio->channels= codec->channels; | |
199 sh_audio->samplerate= codec->sample_rate; | |
200 if(verbose>=1) print_wave_header(sh_audio->wf); | |
201 demuxer->audio->id=i; | |
202 demuxer->audio->sh= demuxer->a_streams[i]; | |
203 break;} | |
204 case CODEC_TYPE_VIDEO:{ | |
205 BITMAPINFOHEADER *bih=calloc(sizeof(BITMAPINFOHEADER) + codec->extradata_size,1); | |
206 sh_video_t* sh_video=new_sh_video(demuxer, i); | |
207 | |
208 priv->video_streams++; | |
209 if(!codec->codec_tag) | |
210 codec->codec_tag= codec_get_bmp_tag(codec->codec_id); | |
211 bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size; | |
212 bih->biWidth= codec->width; | |
213 bih->biHeight= codec->height; | |
214 bih->biBitCount= codec->bits_per_sample; | |
215 bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8; | |
216 bih->biCompression= codec->codec_tag; | |
217 sh_video->bih= bih; | |
218 sh_video->disp_w= codec->width; | |
219 sh_video->disp_h= codec->height; | |
220 sh_video->video.dwRate= codec->frame_rate; | |
221 sh_video->video.dwScale= codec->frame_rate_base; | |
222 sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; | |
223 sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; | |
224 sh_video->format = bih->biCompression; | |
12167 | 225 sh_video->aspect= codec->width * codec->sample_aspect_ratio.num |
226 / (float)(codec->height * codec->sample_aspect_ratio.den); | |
227 mp_msg(MSGT_DEMUX,MSGL_DBG2,"aspect= %d*%d/(%d*%d)\n", | |
228 codec->width, codec->sample_aspect_ratio.num, | |
229 codec->height, codec->sample_aspect_ratio.den); | |
230 | |
12164 | 231 sh_video->ds= demuxer->video; |
232 if(codec->extradata_size) | |
233 memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size); | |
234 if(verbose>=1) print_video_header(sh_video->bih); | |
235 /* short biPlanes; | |
236 int biXPelsPerMeter; | |
237 int biYPelsPerMeter; | |
238 int biClrUsed; | |
239 int biClrImportant;*/ | |
240 demuxer->video->id=i; | |
241 demuxer->video->sh= demuxer->v_streams[i]; | |
242 break;} | |
243 } | |
244 } | |
245 | |
246 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: %d audio and %d video streams found\n",priv->audio_streams,priv->video_streams); | |
13749 | 247 mp_msg(MSGT_HEADER,MSGL_V,"LAVF: build %d\n", LIBAVFORMAT_BUILD); |
12164 | 248 if(!priv->audio_streams) demuxer->audio->id=-2; // nosound |
249 // else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio; | |
250 if(!priv->video_streams){ | |
251 if(!priv->audio_streams){ | |
252 mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF: no audio or video headers found - broken file?\n"); | |
253 return 0; | |
254 } | |
255 demuxer->video->id=-2; // audio-only | |
256 } //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video; | |
257 | |
258 return 1; | |
259 } | |
260 | |
261 int demux_lavf_fill_buffer(demuxer_t *demux){ | |
262 lavf_priv_t *priv= demux->priv; | |
263 AVPacket pkt; | |
264 demux_packet_t *dp; | |
265 demux_stream_t *ds; | |
266 int id; | |
267 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_lavf_fill_buffer()\n"); | |
268 | |
269 demux->filepos=stream_tell(demux->stream); | |
270 | |
271 if(stream_eof(demux->stream)){ | |
272 // demuxre->stream->eof=1; | |
273 return 0; | |
274 } | |
275 | |
276 if(av_read_frame(priv->avfc, &pkt) < 0) | |
277 return 0; | |
278 | |
279 id= pkt.stream_index; | |
280 | |
281 if(id==demux->audio->id){ | |
282 // audio | |
283 ds=demux->audio; | |
284 if(!ds->sh){ | |
285 ds->sh=demux->a_streams[id]; | |
286 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id); | |
287 } | |
288 } else if(id==demux->video->id){ | |
289 // video | |
290 ds=demux->video; | |
291 if(!ds->sh){ | |
292 ds->sh=demux->v_streams[id]; | |
293 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id); | |
294 } | |
295 } else | |
296 ds= NULL; | |
297 | |
298 if(0/*pkt.destruct == av_destruct_packet*/){ | |
299 //ok kids, dont try this at home :) | |
300 dp=(demux_packet_t*)malloc(sizeof(demux_packet_t)); | |
301 dp->len=pkt.size; | |
302 dp->next=NULL; | |
303 dp->refcount=1; | |
304 dp->master=NULL; | |
305 dp->buffer=pkt.data; | |
306 pkt.destruct= NULL; | |
307 }else{ | |
308 dp=new_demux_packet(pkt.size); | |
309 memcpy(dp->buffer, pkt.data, pkt.size); | |
310 av_free_packet(&pkt); | |
311 } | |
312 | |
13747 | 313 if(pkt.pts != AV_NOPTS_VALUE){ |
314 priv->last_pts= pkt.pts; | |
315 dp->pts=pkt.pts / (float)AV_TIME_BASE; | |
316 } | |
12164 | 317 dp->pos=demux->filepos; |
318 dp->flags= !!(pkt.flags&PKT_FLAG_KEY); | |
319 // append packet to DS stream: | |
320 ds_add_packet(ds,dp); | |
321 return 1; | |
322 } | |
323 | |
324 void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, int flags){ | |
12168 | 325 lavf_priv_t *priv = demuxer->priv; |
326 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %d)\n", demuxer, rel_seek_secs, flags); | |
327 | |
13607 | 328 #if LIBAVFORMAT_BUILD < 4619 |
12168 | 329 av_seek_frame(priv->avfc, -1, priv->last_pts + rel_seek_secs*AV_TIME_BASE); |
13607 | 330 #else |
331 av_seek_frame(priv->avfc, -1, priv->last_pts + rel_seek_secs*AV_TIME_BASE, rel_seek_secs < 0 ? AVSEEK_FLAG_BACKWARD : 0); | |
332 #endif | |
12164 | 333 } |
334 | |
335 int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg) | |
336 { | |
337 lavf_priv_t *priv = demuxer->priv; | |
338 | |
339 switch (cmd) { | |
12168 | 340 case DEMUXER_CTRL_GET_TIME_LENGTH: |
341 if (priv->avfc->duration == 0) | |
12164 | 342 return DEMUXER_CTRL_DONTKNOW; |
343 | |
12168 | 344 *((unsigned long *)arg) = priv->avfc->duration / AV_TIME_BASE; |
12164 | 345 return DEMUXER_CTRL_OK; |
346 | |
347 case DEMUXER_CTRL_GET_PERCENT_POS: | |
12168 | 348 if (priv->avfc->duration == 0) |
12164 | 349 return DEMUXER_CTRL_DONTKNOW; |
350 | |
12168 | 351 *((int *)arg) = (int)(priv->last_pts*100 / priv->avfc->duration); |
352 return DEMUXER_CTRL_OK; | |
12164 | 353 |
354 default: | |
355 return DEMUXER_CTRL_NOTIMPL; | |
356 } | |
357 } | |
358 | |
359 void demux_close_lavf(demuxer_t *demuxer) | |
360 { | |
361 lavf_priv_t* priv = demuxer->priv; | |
362 if (priv){ | |
12304
434242b0706c
fix possible segfault on lavf demuxer patch by (adland <adland123 at yahoo dot com>)
michael
parents:
12168
diff
changeset
|
363 if(priv->avfc) |
434242b0706c
fix possible segfault on lavf demuxer patch by (adland <adland123 at yahoo dot com>)
michael
parents:
12168
diff
changeset
|
364 { |
434242b0706c
fix possible segfault on lavf demuxer patch by (adland <adland123 at yahoo dot com>)
michael
parents:
12168
diff
changeset
|
365 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
|
366 } |
12164 | 367 free(priv); demuxer->priv= NULL; |
368 } | |
369 } | |
370 | |
371 #endif // USE_LIBAVFORMAT |