Mercurial > audlegacy-plugins
comparison src/ffmpeg/libavformat/flvdec.c @ 808:e8776388b02a trunk
[svn] - add ffmpeg
author | nenolod |
---|---|
date | Mon, 12 Mar 2007 11:18:54 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
807:0f9c8d4d3ac4 | 808:e8776388b02a |
---|---|
1 /* | |
2 * FLV encoder. | |
3 * Copyright (c) 2003 The FFmpeg Project. | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 #include "avformat.h" | |
22 | |
23 static int flv_probe(AVProbeData *p) | |
24 { | |
25 const uint8_t *d; | |
26 | |
27 if (p->buf_size < 6) | |
28 return 0; | |
29 d = p->buf; | |
30 if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V') { | |
31 return 50; | |
32 } | |
33 return 0; | |
34 } | |
35 | |
36 static int flv_read_header(AVFormatContext *s, | |
37 AVFormatParameters *ap) | |
38 { | |
39 int offset, flags, size; | |
40 | |
41 s->ctx_flags |= AVFMTCTX_NOHEADER; //ok we have a header but theres no fps, codec type, sample_rate, ... | |
42 | |
43 url_fskip(&s->pb, 4); | |
44 flags = get_byte(&s->pb); | |
45 | |
46 offset = get_be32(&s->pb); | |
47 | |
48 if(!url_is_streamed(&s->pb)){ | |
49 const int fsize= url_fsize(&s->pb); | |
50 url_fseek(&s->pb, fsize-4, SEEK_SET); | |
51 size= get_be32(&s->pb); | |
52 url_fseek(&s->pb, fsize-3-size, SEEK_SET); | |
53 if(size == get_be24(&s->pb) + 11){ | |
54 s->duration= get_be24(&s->pb) * (int64_t)AV_TIME_BASE / 1000; | |
55 } | |
56 } | |
57 | |
58 url_fseek(&s->pb, offset, SEEK_SET); | |
59 | |
60 s->start_time = 0; | |
61 | |
62 return 0; | |
63 } | |
64 | |
65 static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) | |
66 { | |
67 int ret, i, type, size, pts, flags, is_audio, next, pos; | |
68 AVStream *st = NULL; | |
69 | |
70 for(;;){ | |
71 pos = url_ftell(&s->pb); | |
72 url_fskip(&s->pb, 4); /* size of previous packet */ | |
73 type = get_byte(&s->pb); | |
74 size = get_be24(&s->pb); | |
75 pts = get_be24(&s->pb); | |
76 // av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, pts:%d\n", type, size, pts); | |
77 if (url_feof(&s->pb)) | |
78 return AVERROR_IO; | |
79 url_fskip(&s->pb, 4); /* reserved */ | |
80 flags = 0; | |
81 | |
82 if(size == 0) | |
83 continue; | |
84 | |
85 next= size + url_ftell(&s->pb); | |
86 | |
87 if (type == 8) { | |
88 is_audio=1; | |
89 flags = get_byte(&s->pb); | |
90 } else if (type == 9) { | |
91 is_audio=0; | |
92 flags = get_byte(&s->pb); | |
93 } else if (type == 18 && size > 13+1+4) { | |
94 url_fskip(&s->pb, 13); //onMetaData blah | |
95 if(get_byte(&s->pb) == 8){ | |
96 url_fskip(&s->pb, 4); | |
97 } | |
98 while(url_ftell(&s->pb) + 5 < next){ | |
99 char tmp[128]; | |
100 int type, len; | |
101 double d= 0; | |
102 | |
103 len= get_be16(&s->pb); | |
104 if(len >= sizeof(tmp) || !len) | |
105 break; | |
106 get_buffer(&s->pb, tmp, len); | |
107 tmp[len]=0; | |
108 | |
109 type= get_byte(&s->pb); | |
110 if(type==0){ | |
111 d= av_int2dbl(get_be64(&s->pb)); | |
112 }else if(type==2){ | |
113 len= get_be16(&s->pb); | |
114 if(len >= sizeof(tmp)) | |
115 break; | |
116 url_fskip(&s->pb, len); | |
117 }else if(type==8){ | |
118 //array | |
119 break; | |
120 }else if(type==11){ | |
121 d= av_int2dbl(get_be64(&s->pb)); | |
122 get_be16(&s->pb); | |
123 } | |
124 | |
125 if(!strcmp(tmp, "duration")){ | |
126 s->duration = d*AV_TIME_BASE; | |
127 }else if(!strcmp(tmp, "videodatarate")){ | |
128 }else if(!strcmp(tmp, "audiodatarate")){ | |
129 } | |
130 } | |
131 url_fseek(&s->pb, next, SEEK_SET); | |
132 continue; | |
133 } else { | |
134 /* skip packet */ | |
135 av_log(s, AV_LOG_ERROR, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); | |
136 url_fseek(&s->pb, next, SEEK_SET); | |
137 continue; | |
138 } | |
139 | |
140 /* now find stream */ | |
141 for(i=0;i<s->nb_streams;i++) { | |
142 st = s->streams[i]; | |
143 if (st->id == is_audio) | |
144 break; | |
145 } | |
146 if(i == s->nb_streams){ | |
147 st = av_new_stream(s, is_audio); | |
148 if (!st) | |
149 return AVERROR_NOMEM; | |
150 | |
151 av_set_pts_info(st, 24, 1, 1000); /* 24 bit pts in ms */ | |
152 st->codec->time_base= (AVRational){1,1000}; | |
153 } | |
154 // av_log(NULL, AV_LOG_DEBUG, "%d %X %d \n", is_audio, flags, st->discard); | |
155 if( (st->discard >= AVDISCARD_NONKEY && !((flags >> 4)==1 || is_audio)) | |
156 ||(st->discard >= AVDISCARD_BIDIR && ((flags >> 4)==3 && !is_audio)) | |
157 || st->discard >= AVDISCARD_ALL | |
158 ){ | |
159 url_fseek(&s->pb, next, SEEK_SET); | |
160 continue; | |
161 } | |
162 if ((flags >> 4)==1) | |
163 av_add_index_entry(st, pos, pts, size, 0, AVINDEX_KEYFRAME); | |
164 break; | |
165 } | |
166 | |
167 if(is_audio){ | |
168 if(st->codec->sample_rate == 0){ | |
169 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
170 st->codec->channels = (flags&1)+1; | |
171 if((flags >> 4) == 5) | |
172 st->codec->sample_rate= 8000; | |
173 else | |
174 st->codec->sample_rate = (44100<<((flags>>2)&3))>>3; | |
175 switch(flags >> 4){/* 0: uncompressed 1: ADPCM 2: mp3 5: Nellymoser 8kHz mono 6: Nellymoser*/ | |
176 case 0: if (flags&2) st->codec->codec_id = CODEC_ID_PCM_S16BE; | |
177 else st->codec->codec_id = CODEC_ID_PCM_S8; break; | |
178 case 1: st->codec->codec_id = CODEC_ID_ADPCM_SWF; break; | |
179 case 2: st->codec->codec_id = CODEC_ID_MP3; st->need_parsing = 1; break; | |
180 // this is not listed at FLV but at SWF, strange... | |
181 case 3: if (flags&2) st->codec->codec_id = CODEC_ID_PCM_S16LE; | |
182 else st->codec->codec_id = CODEC_ID_PCM_S8; break; | |
183 default: | |
184 av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flags >> 4); | |
185 st->codec->codec_tag= (flags >> 4); | |
186 } | |
187 st->codec->bits_per_sample = (flags & 2) ? 16 : 8; | |
188 } | |
189 }else{ | |
190 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
191 switch(flags & 0xF){ | |
192 case 2: st->codec->codec_id = CODEC_ID_FLV1; break; | |
193 case 3: st->codec->codec_id = CODEC_ID_FLASHSV; break; | |
194 case 4: | |
195 st->codec->codec_id = CODEC_ID_VP6F; | |
196 get_byte(&s->pb); /* width and height adjustment */ | |
197 size--; | |
198 break; | |
199 default: | |
200 av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flags & 0xf); | |
201 st->codec->codec_tag= flags & 0xF; | |
202 } | |
203 } | |
204 | |
205 ret= av_get_packet(&s->pb, pkt, size - 1); | |
206 if (ret <= 0) { | |
207 return AVERROR_IO; | |
208 } | |
209 /* note: we need to modify the packet size here to handle the last | |
210 packet */ | |
211 pkt->size = ret; | |
212 pkt->pts = pts; | |
213 pkt->stream_index = st->index; | |
214 | |
215 if (is_audio || ((flags >> 4)==1)) | |
216 pkt->flags |= PKT_FLAG_KEY; | |
217 | |
218 return ret; | |
219 } | |
220 | |
221 static int flv_read_close(AVFormatContext *s) | |
222 { | |
223 return 0; | |
224 } | |
225 | |
226 static int flv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) | |
227 { | |
228 AVStream *st = s->streams[stream_index]; | |
229 int index = av_index_search_timestamp(st, timestamp, flags); | |
230 if (index < 0) | |
231 return -1; | |
232 url_fseek(&s->pb, st->index_entries[index].pos, SEEK_SET); | |
233 | |
234 return 0; | |
235 } | |
236 | |
237 AVInputFormat flv_demuxer = { | |
238 "flv", | |
239 "flv format", | |
240 0, | |
241 flv_probe, | |
242 flv_read_header, | |
243 flv_read_packet, | |
244 flv_read_close, | |
245 flv_read_seek, | |
246 .extensions = "flv", | |
247 .value = CODEC_ID_FLV1, | |
248 }; |