]> git.sesse.net Git - ffmpeg/blob - libavformat/ffmdec.c
asfdec: cosmetics, reformat ff_asf_parse_packet()
[ffmpeg] / libavformat / ffmdec.c
1 /*
2  * FFM (avserver live feed) demuxer
3  * Copyright (c) 2001 Fabrice Bellard
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/intfloat.h"
24 #include "avformat.h"
25 #include "internal.h"
26 #include "ffm.h"
27
28 static int ffm_is_avail_data(AVFormatContext *s, int size)
29 {
30     FFMContext *ffm = s->priv_data;
31     int64_t pos, avail_size;
32     int len;
33
34     len = ffm->packet_end - ffm->packet_ptr;
35     if (size <= len)
36         return 1;
37     pos = avio_tell(s->pb);
38     if (!ffm->write_index) {
39         if (pos == ffm->file_size)
40             return AVERROR_EOF;
41         avail_size = ffm->file_size - pos;
42     } else {
43     if (pos == ffm->write_index) {
44         /* exactly at the end of stream */
45         return AVERROR(EAGAIN);
46     } else if (pos < ffm->write_index) {
47         avail_size = ffm->write_index - pos;
48     } else {
49         avail_size = (ffm->file_size - pos) + (ffm->write_index - FFM_PACKET_SIZE);
50     }
51     }
52     avail_size = (avail_size / ffm->packet_size) * (ffm->packet_size - FFM_HEADER_SIZE) + len;
53     if (size <= avail_size)
54         return 1;
55     else
56         return AVERROR(EAGAIN);
57 }
58
59 static int ffm_resync(AVFormatContext *s, int state)
60 {
61     av_log(s, AV_LOG_ERROR, "resyncing\n");
62     while (state != PACKET_ID) {
63         if (s->pb->eof_reached) {
64             av_log(s, AV_LOG_ERROR, "cannot find FFM syncword\n");
65             return -1;
66         }
67         state = (state << 8) | avio_r8(s->pb);
68     }
69     return 0;
70 }
71
72 /* first is true if we read the frame header */
73 static int ffm_read_data(AVFormatContext *s,
74                          uint8_t *buf, int size, int header)
75 {
76     FFMContext *ffm = s->priv_data;
77     AVIOContext *pb = s->pb;
78     int len, fill_size, size1, frame_offset, id;
79
80     size1 = size;
81     while (size > 0) {
82     redo:
83         len = ffm->packet_end - ffm->packet_ptr;
84         if (len < 0)
85             return -1;
86         if (len > size)
87             len = size;
88         if (len == 0) {
89             if (avio_tell(pb) == ffm->file_size)
90                 avio_seek(pb, ffm->packet_size, SEEK_SET);
91     retry_read:
92             id = avio_rb16(pb); /* PACKET_ID */
93             if (id != PACKET_ID)
94                 if (ffm_resync(s, id) < 0)
95                     return -1;
96             fill_size = avio_rb16(pb);
97             ffm->dts = avio_rb64(pb);
98             frame_offset = avio_rb16(pb);
99             avio_read(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE);
100             ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size);
101             if (ffm->packet_end < ffm->packet || frame_offset < 0)
102                 return -1;
103             /* if first packet or resynchronization packet, we must
104                handle it specifically */
105             if (ffm->first_packet || (frame_offset & 0x8000)) {
106                 if (!frame_offset) {
107                     /* This packet has no frame headers in it */
108                     if (avio_tell(pb) >= ffm->packet_size * 3) {
109                         avio_seek(pb, -ffm->packet_size * 2, SEEK_CUR);
110                         goto retry_read;
111                     }
112                     /* This is bad, we cannot find a valid frame header */
113                     return 0;
114                 }
115                 ffm->first_packet = 0;
116                 if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE)
117                     return -1;
118                 ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE;
119                 if (!header)
120                     break;
121             } else {
122                 ffm->packet_ptr = ffm->packet;
123             }
124             goto redo;
125         }
126         memcpy(buf, ffm->packet_ptr, len);
127         buf += len;
128         ffm->packet_ptr += len;
129         size -= len;
130         header = 0;
131     }
132     return size1 - size;
133 }
134
135 /* ensure that acutal seeking happens between FFM_PACKET_SIZE
136    and file_size - FFM_PACKET_SIZE */
137 static int64_t ffm_seek1(AVFormatContext *s, int64_t pos1)
138 {
139     FFMContext *ffm = s->priv_data;
140     AVIOContext *pb = s->pb;
141     int64_t pos;
142
143     pos = FFMIN(pos1, ffm->file_size - FFM_PACKET_SIZE);
144     pos = FFMAX(pos, FFM_PACKET_SIZE);
145     av_dlog(s, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos);
146     return avio_seek(pb, pos, SEEK_SET);
147 }
148
149 static int64_t get_dts(AVFormatContext *s, int64_t pos)
150 {
151     AVIOContext *pb = s->pb;
152     int64_t dts;
153
154     ffm_seek1(s, pos);
155     avio_skip(pb, 4);
156     dts = avio_rb64(pb);
157     av_dlog(s, "dts=%0.6f\n", dts / 1000000.0);
158     return dts;
159 }
160
161 static void adjust_write_index(AVFormatContext *s)
162 {
163     FFMContext *ffm = s->priv_data;
164     AVIOContext *pb = s->pb;
165     int64_t pts;
166     //int64_t orig_write_index = ffm->write_index;
167     int64_t pos_min, pos_max;
168     int64_t pts_start;
169     int64_t ptr = avio_tell(pb);
170
171
172     pos_min = 0;
173     pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE;
174
175     pts_start = get_dts(s, pos_min);
176
177     pts = get_dts(s, pos_max);
178
179     if (pts - 100000 > pts_start)
180         goto end;
181
182     ffm->write_index = FFM_PACKET_SIZE;
183
184     pts_start = get_dts(s, pos_min);
185
186     pts = get_dts(s, pos_max);
187
188     if (pts - 100000 <= pts_start) {
189         while (1) {
190             int64_t newpos;
191             int64_t newpts;
192
193             newpos = ((pos_max + pos_min) / (2 * FFM_PACKET_SIZE)) * FFM_PACKET_SIZE;
194
195             if (newpos == pos_min)
196                 break;
197
198             newpts = get_dts(s, newpos);
199
200             if (newpts - 100000 <= pts) {
201                 pos_max = newpos;
202                 pts = newpts;
203             } else {
204                 pos_min = newpos;
205             }
206         }
207         ffm->write_index += pos_max;
208     }
209
210  end:
211     avio_seek(pb, ptr, SEEK_SET);
212 }
213
214
215 static int ffm_close(AVFormatContext *s)
216 {
217     int i;
218
219     for (i = 0; i < s->nb_streams; i++)
220         av_freep(&s->streams[i]->codec->rc_eq);
221
222     return 0;
223 }
224
225
226 static int ffm_read_header(AVFormatContext *s)
227 {
228     FFMContext *ffm = s->priv_data;
229     AVStream *st;
230     AVIOContext *pb = s->pb;
231     AVCodecContext *codec;
232     int i, nb_streams;
233     uint32_t tag;
234
235     /* header */
236     tag = avio_rl32(pb);
237     if (tag != MKTAG('F', 'F', 'M', '1'))
238         goto fail;
239     ffm->packet_size = avio_rb32(pb);
240     if (ffm->packet_size != FFM_PACKET_SIZE)
241         goto fail;
242     ffm->write_index = avio_rb64(pb);
243     /* get also filesize */
244     if (pb->seekable) {
245         ffm->file_size = avio_size(pb);
246         if (ffm->write_index)
247             adjust_write_index(s);
248     } else {
249         ffm->file_size = (UINT64_C(1) << 63) - 1;
250     }
251
252     nb_streams = avio_rb32(pb);
253     avio_rb32(pb); /* total bitrate */
254     /* read each stream */
255     for(i=0;i<nb_streams;i++) {
256         char rc_eq_buf[128];
257
258         st = avformat_new_stream(s, NULL);
259         if (!st)
260             goto fail;
261
262         avpriv_set_pts_info(st, 64, 1, 1000000);
263
264         codec = st->codec;
265         /* generic info */
266         codec->codec_id = avio_rb32(pb);
267         codec->codec_type = avio_r8(pb); /* codec_type */
268         codec->bit_rate = avio_rb32(pb);
269         codec->flags = avio_rb32(pb);
270         codec->flags2 = avio_rb32(pb);
271         codec->debug = avio_rb32(pb);
272         /* specific info */
273         switch(codec->codec_type) {
274         case AVMEDIA_TYPE_VIDEO:
275             codec->time_base.num = avio_rb32(pb);
276             codec->time_base.den = avio_rb32(pb);
277             codec->width = avio_rb16(pb);
278             codec->height = avio_rb16(pb);
279             codec->gop_size = avio_rb16(pb);
280             codec->pix_fmt = avio_rb32(pb);
281             codec->qmin = avio_r8(pb);
282             codec->qmax = avio_r8(pb);
283             codec->max_qdiff = avio_r8(pb);
284             codec->qcompress = avio_rb16(pb) / 10000.0;
285             codec->qblur = avio_rb16(pb) / 10000.0;
286             codec->bit_rate_tolerance = avio_rb32(pb);
287             avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));
288             codec->rc_eq = av_strdup(rc_eq_buf);
289             codec->rc_max_rate = avio_rb32(pb);
290             codec->rc_min_rate = avio_rb32(pb);
291             codec->rc_buffer_size = avio_rb32(pb);
292             codec->i_quant_factor = av_int2double(avio_rb64(pb));
293             codec->b_quant_factor = av_int2double(avio_rb64(pb));
294             codec->i_quant_offset = av_int2double(avio_rb64(pb));
295             codec->b_quant_offset = av_int2double(avio_rb64(pb));
296             codec->dct_algo = avio_rb32(pb);
297             codec->strict_std_compliance = avio_rb32(pb);
298             codec->max_b_frames = avio_rb32(pb);
299             codec->mpeg_quant = avio_rb32(pb);
300             codec->intra_dc_precision = avio_rb32(pb);
301             codec->me_method = avio_rb32(pb);
302             codec->mb_decision = avio_rb32(pb);
303             codec->nsse_weight = avio_rb32(pb);
304             codec->frame_skip_cmp = avio_rb32(pb);
305             codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb));
306             codec->codec_tag = avio_rb32(pb);
307             codec->thread_count = avio_r8(pb);
308             codec->coder_type = avio_rb32(pb);
309             codec->me_cmp = avio_rb32(pb);
310             codec->me_subpel_quality = avio_rb32(pb);
311             codec->me_range = avio_rb32(pb);
312             codec->keyint_min = avio_rb32(pb);
313             codec->scenechange_threshold = avio_rb32(pb);
314             codec->b_frame_strategy = avio_rb32(pb);
315             codec->qcompress = av_int2double(avio_rb64(pb));
316             codec->qblur = av_int2double(avio_rb64(pb));
317             codec->max_qdiff = avio_rb32(pb);
318             codec->refs = avio_rb32(pb);
319             break;
320         case AVMEDIA_TYPE_AUDIO:
321             codec->sample_rate = avio_rb32(pb);
322             codec->channels = avio_rl16(pb);
323             codec->frame_size = avio_rl16(pb);
324             break;
325         default:
326             goto fail;
327         }
328         if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) {
329             codec->extradata_size = avio_rb32(pb);
330             codec->extradata = av_malloc(codec->extradata_size);
331             if (!codec->extradata)
332                 return AVERROR(ENOMEM);
333             avio_read(pb, codec->extradata, codec->extradata_size);
334         }
335     }
336
337     /* get until end of block reached */
338     while ((avio_tell(pb) % ffm->packet_size) != 0)
339         avio_r8(pb);
340
341     /* init packet demux */
342     ffm->packet_ptr = ffm->packet;
343     ffm->packet_end = ffm->packet;
344     ffm->frame_offset = 0;
345     ffm->dts = 0;
346     ffm->read_state = READ_HEADER;
347     ffm->first_packet = 1;
348     return 0;
349  fail:
350     ffm_close(s);
351     return -1;
352 }
353
354 /* return < 0 if eof */
355 static int ffm_read_packet(AVFormatContext *s, AVPacket *pkt)
356 {
357     int size;
358     FFMContext *ffm = s->priv_data;
359     int duration, ret;
360
361     switch(ffm->read_state) {
362     case READ_HEADER:
363         if ((ret = ffm_is_avail_data(s, FRAME_HEADER_SIZE+4)) < 0)
364             return ret;
365
366         av_dlog(s, "pos=%08"PRIx64" spos=%"PRIx64", write_index=%"PRIx64" size=%"PRIx64"\n",
367                avio_tell(s->pb), s->pb->pos, ffm->write_index, ffm->file_size);
368         if (ffm_read_data(s, ffm->header, FRAME_HEADER_SIZE, 1) !=
369             FRAME_HEADER_SIZE)
370             return -1;
371         if (ffm->header[1] & FLAG_DTS)
372             if (ffm_read_data(s, ffm->header+16, 4, 1) != 4)
373                 return -1;
374         ffm->read_state = READ_DATA;
375         /* fall thru */
376     case READ_DATA:
377         size = AV_RB24(ffm->header + 2);
378         if ((ret = ffm_is_avail_data(s, size)) < 0)
379             return ret;
380
381         duration = AV_RB24(ffm->header + 5);
382
383         av_new_packet(pkt, size);
384         pkt->stream_index = ffm->header[0];
385         if ((unsigned)pkt->stream_index >= s->nb_streams) {
386             av_log(s, AV_LOG_ERROR, "invalid stream index %d\n", pkt->stream_index);
387             av_free_packet(pkt);
388             ffm->read_state = READ_HEADER;
389             return -1;
390         }
391         pkt->pos = avio_tell(s->pb);
392         if (ffm->header[1] & FLAG_KEY_FRAME)
393             pkt->flags |= AV_PKT_FLAG_KEY;
394
395         ffm->read_state = READ_HEADER;
396         if (ffm_read_data(s, pkt->data, size, 0) != size) {
397             /* bad case: desynchronized packet. we cancel all the packet loading */
398             av_free_packet(pkt);
399             return -1;
400         }
401         pkt->pts = AV_RB64(ffm->header+8);
402         if (ffm->header[1] & FLAG_DTS)
403             pkt->dts = pkt->pts - AV_RB32(ffm->header+16);
404         else
405             pkt->dts = pkt->pts;
406         pkt->duration = duration;
407         break;
408     }
409     return 0;
410 }
411
412 /* seek to a given time in the file. The file read pointer is
413    positioned at or before pts. XXX: the following code is quite
414    approximative */
415 static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, int flags)
416 {
417     FFMContext *ffm = s->priv_data;
418     int64_t pos_min, pos_max, pos;
419     int64_t pts_min, pts_max, pts;
420     double pos1;
421
422     av_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
423     /* find the position using linear interpolation (better than
424        dichotomy in typical cases) */
425     pos_min = FFM_PACKET_SIZE;
426     pos_max = ffm->file_size - FFM_PACKET_SIZE;
427     while (pos_min <= pos_max) {
428         pts_min = get_dts(s, pos_min);
429         pts_max = get_dts(s, pos_max);
430         /* linear interpolation */
431         pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) /
432             (double)(pts_max - pts_min);
433         pos = (((int64_t)pos1) / FFM_PACKET_SIZE) * FFM_PACKET_SIZE;
434         if (pos <= pos_min)
435             pos = pos_min;
436         else if (pos >= pos_max)
437             pos = pos_max;
438         pts = get_dts(s, pos);
439         /* check if we are lucky */
440         if (pts == wanted_pts) {
441             goto found;
442         } else if (pts > wanted_pts) {
443             pos_max = pos - FFM_PACKET_SIZE;
444         } else {
445             pos_min = pos + FFM_PACKET_SIZE;
446         }
447     }
448     pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
449
450  found:
451     if (ffm_seek1(s, pos) < 0)
452         return -1;
453
454     /* reset read state */
455     ffm->read_state = READ_HEADER;
456     ffm->packet_ptr = ffm->packet;
457     ffm->packet_end = ffm->packet;
458     ffm->first_packet = 1;
459
460     return 0;
461 }
462
463 static int ffm_probe(AVProbeData *p)
464 {
465     if (
466         p->buf[0] == 'F' && p->buf[1] == 'F' && p->buf[2] == 'M' &&
467         p->buf[3] == '1')
468         return AVPROBE_SCORE_MAX + 1;
469     return 0;
470 }
471
472 AVInputFormat ff_ffm_demuxer = {
473     .name           = "ffm",
474     .long_name      = NULL_IF_CONFIG_SMALL("FFM (AVserver live feed)"),
475     .priv_data_size = sizeof(FFMContext),
476     .read_probe     = ffm_probe,
477     .read_header    = ffm_read_header,
478     .read_packet    = ffm_read_packet,
479     .read_close     = ffm_close,
480     .read_seek      = ffm_seek,
481 };