disable encoders where appropriate (patch courtesy of BERO
[ffmpeg.git] / libavformat / ffm.c
1 /*
2  * FFM (ffserver live feed) encoder and decoder
3  * Copyright (c) 2001 Fabrice Bellard.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include "avformat.h"
20 #include <unistd.h>
21
22 /* The FFM file is made of blocks of fixed size */
23 #define FFM_HEADER_SIZE 14
24 #define PACKET_ID       0x666d
25
26 /* each packet contains frames (which can span several packets */
27 #define FRAME_HEADER_SIZE    8
28 #define FLAG_KEY_FRAME       0x01
29
30 typedef struct FFMStream {
31     int64_t pts;
32 } FFMStream;
33
34 enum {
35     READ_HEADER,
36     READ_DATA,
37 };
38
39 typedef struct FFMContext {
40     /* only reading mode */
41     offset_t write_index, file_size;
42     int read_state;
43     uint8_t header[FRAME_HEADER_SIZE];
44
45     /* read and write */
46     int first_packet; /* true if first packet, needed to set the discontinuity tag */
47     int packet_size;
48     int frame_offset;
49     int64_t pts;
50     uint8_t *packet_ptr, *packet_end;
51     uint8_t packet[FFM_PACKET_SIZE];
52 } FFMContext;
53
54 /* disable pts hack for testing */
55 int ffm_nopts = 0;
56
57 #ifdef CONFIG_ENCODERS
58 static void flush_packet(AVFormatContext *s)
59 {
60     FFMContext *ffm = s->priv_data;
61     int fill_size, h;
62     ByteIOContext *pb = &s->pb;
63
64     fill_size = ffm->packet_end - ffm->packet_ptr;
65     memset(ffm->packet_ptr, 0, fill_size);
66
67     /* put header */
68     put_be16(pb, PACKET_ID);
69     put_be16(pb, fill_size);
70     put_be64(pb, ffm->pts);
71     h = ffm->frame_offset;
72     if (ffm->first_packet)
73         h |= 0x8000;
74     put_be16(pb, h);
75     put_buffer(pb, ffm->packet, ffm->packet_end - ffm->packet);
76
77     /* prepare next packet */
78     ffm->frame_offset = 0; /* no key frame */
79     ffm->pts = 0; /* no pts */
80     ffm->packet_ptr = ffm->packet;
81     ffm->first_packet = 0;
82 }
83
84 /* 'first' is true if first data of a frame */
85 static void ffm_write_data(AVFormatContext *s,
86                            const uint8_t *buf, int size,
87                            int64_t pts, int first)
88 {
89     FFMContext *ffm = s->priv_data;
90     int len;
91
92     if (first && ffm->frame_offset == 0)
93         ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE;
94     if (first && ffm->pts == 0)
95         ffm->pts = pts;
96
97     /* write as many packets as needed */
98     while (size > 0) {
99         len = ffm->packet_end - ffm->packet_ptr;
100         if (len > size)
101             len = size;
102         memcpy(ffm->packet_ptr, buf, len);
103
104         ffm->packet_ptr += len;
105         buf += len;
106         size -= len;
107         if (ffm->packet_ptr >= ffm->packet_end) {
108             /* special case : no pts in packet : we leave the current one */
109             if (ffm->pts == 0)
110                 ffm->pts = pts;
111
112             flush_packet(s);
113         }
114     }
115 }
116
117 static int ffm_write_header(AVFormatContext *s)
118 {
119     FFMContext *ffm = s->priv_data;
120     AVStream *st;
121     FFMStream *fst;
122     ByteIOContext *pb = &s->pb;
123     AVCodecContext *codec;
124     int bit_rate, i;
125
126     ffm->packet_size = FFM_PACKET_SIZE;
127
128     /* header */
129     put_tag(pb, "FFM1");
130     put_be32(pb, ffm->packet_size);
131     /* XXX: store write position in other file ? */
132     put_be64(pb, ffm->packet_size); /* current write position */
133
134     put_be32(pb, s->nb_streams);
135     bit_rate = 0;
136     for(i=0;i<s->nb_streams;i++) {
137         st = s->streams[i];
138         bit_rate += st->codec.bit_rate;
139     }
140     put_be32(pb, bit_rate);
141
142     /* list of streams */
143     for(i=0;i<s->nb_streams;i++) {
144         st = s->streams[i];
145         fst = av_mallocz(sizeof(FFMStream));
146         if (!fst)
147             goto fail;
148         st->priv_data = fst;
149
150         codec = &st->codec;
151         /* generic info */
152         put_be32(pb, codec->codec_id);
153         put_byte(pb, codec->codec_type);
154         put_be32(pb, codec->bit_rate);
155         put_be32(pb, st->quality);
156         put_be32(pb, codec->flags);
157         /* specific info */
158         switch(codec->codec_type) {
159         case CODEC_TYPE_VIDEO:
160             put_be32(pb, codec->frame_rate_base);
161             put_be32(pb, codec->frame_rate);
162             put_be16(pb, codec->width);
163             put_be16(pb, codec->height);
164             put_be16(pb, codec->gop_size);
165             put_byte(pb, codec->qmin);
166             put_byte(pb, codec->qmax);
167             put_byte(pb, codec->max_qdiff);
168             put_be16(pb, (int) (codec->qcompress * 10000.0));
169             put_be16(pb, (int) (codec->qblur * 10000.0));
170             put_be32(pb, codec->bit_rate_tolerance);
171             put_strz(pb, codec->rc_eq);
172             put_be32(pb, codec->rc_max_rate);
173             put_be32(pb, codec->rc_min_rate);
174             put_be32(pb, codec->rc_buffer_size);
175             put_be64_double(pb, codec->i_quant_factor);
176             put_be64_double(pb, codec->b_quant_factor);
177             put_be64_double(pb, codec->i_quant_offset);
178             put_be64_double(pb, codec->b_quant_offset);
179             put_be32(pb, codec->dct_algo);
180             break;
181         case CODEC_TYPE_AUDIO:
182             put_be32(pb, codec->sample_rate);
183             put_le16(pb, codec->channels);
184             put_le16(pb, codec->frame_size);
185             break;
186         default:
187             av_abort();
188         }
189         /* hack to have real time */
190         if (ffm_nopts)
191             fst->pts = 0;
192         else
193             fst->pts = av_gettime();
194     }
195
196     /* flush until end of block reached */
197     while ((url_ftell(pb) % ffm->packet_size) != 0)
198         put_byte(pb, 0);
199
200     put_flush_packet(pb);
201
202     /* init packet mux */
203     ffm->packet_ptr = ffm->packet;
204     ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE;
205     ffm->frame_offset = 0;
206     ffm->pts = 0;
207     ffm->first_packet = 1;
208
209     return 0;
210  fail:
211     for(i=0;i<s->nb_streams;i++) {
212         st = s->streams[i];
213         av_freep(&st->priv_data);
214     }
215     return -1;
216 }
217
218 static int ffm_write_packet(AVFormatContext *s, int stream_index,
219                             const uint8_t *buf, int size, int64_t force_pts)
220 {
221     AVStream *st = s->streams[stream_index];
222     FFMStream *fst = st->priv_data;
223     int64_t pts;
224     uint8_t header[FRAME_HEADER_SIZE];
225     int duration;
226
227     if (st->codec.codec_type == CODEC_TYPE_AUDIO) {
228         duration = ((float)st->codec.frame_size / st->codec.sample_rate * 1000000.0);
229     } else {
230         duration = (1000000.0 * st->codec.frame_rate_base / (float)st->codec.frame_rate);
231     }
232
233     pts = fst->pts;
234     /* packet size & key_frame */
235     header[0] = stream_index;
236     header[1] = 0;
237     if (st->codec.coded_frame->key_frame) //if st->codec.coded_frame==NULL then there is a bug somewhere else
238         header[1] |= FLAG_KEY_FRAME;
239     header[2] = (size >> 16) & 0xff;
240     header[3] = (size >> 8) & 0xff;
241     header[4] = size & 0xff;
242     header[5] = (duration >> 16) & 0xff;
243     header[6] = (duration >> 8) & 0xff;
244     header[7] = duration & 0xff;
245     ffm_write_data(s, header, FRAME_HEADER_SIZE, pts, 1);
246     ffm_write_data(s, buf, size, pts, 0);
247
248     fst->pts += duration;
249     return 0;
250 }
251
252 static int ffm_write_trailer(AVFormatContext *s)
253 {
254     ByteIOContext *pb = &s->pb;
255     FFMContext *ffm = s->priv_data;
256     int i;
257
258     /* flush packets */
259     if (ffm->packet_ptr > ffm->packet)
260         flush_packet(s);
261
262     put_flush_packet(pb);
263
264     if (!url_is_streamed(pb)) {
265         int64_t size;
266         /* update the write offset */
267         size = url_ftell(pb);
268         url_fseek(pb, 8, SEEK_SET);
269         put_be64(pb, size);
270         put_flush_packet(pb);
271     }
272
273     for(i=0;i<s->nb_streams;i++)
274         av_freep(&s->streams[i]->priv_data);
275     return 0;
276 }
277 #endif //CONFIG_ENCODERS
278
279 /* ffm demux */
280
281 static int ffm_is_avail_data(AVFormatContext *s, int size)
282 {
283     FFMContext *ffm = s->priv_data;
284     offset_t pos, avail_size;
285     int len;
286
287     len = ffm->packet_end - ffm->packet_ptr;
288     if (!ffm_nopts) {
289         /* XXX: I don't understand this test, so I disabled it for testing */
290         if (size <= len)
291             return 1;
292     }
293     pos = url_ftell(&s->pb);
294     if (pos == ffm->write_index) {
295         /* exactly at the end of stream */
296         return 0;
297     } else if (pos < ffm->write_index) {
298         avail_size = ffm->write_index - pos;
299     } else {
300         avail_size = (ffm->file_size - pos) + (ffm->write_index - FFM_PACKET_SIZE);
301     }
302     avail_size = (avail_size / ffm->packet_size) * (ffm->packet_size - FFM_HEADER_SIZE) + len;
303     if (size <= avail_size)
304         return 1;
305     else
306         return 0;
307 }
308
309 /* first is true if we read the frame header */
310 static int ffm_read_data(AVFormatContext *s,
311                          uint8_t *buf, int size, int first)
312 {
313     FFMContext *ffm = s->priv_data;
314     ByteIOContext *pb = &s->pb;
315     int len, fill_size, size1, frame_offset;
316
317     size1 = size;
318     while (size > 0) {
319     redo:
320         len = ffm->packet_end - ffm->packet_ptr;
321         if (len > size)
322             len = size;
323         if (len == 0) {
324             if (url_ftell(pb) == ffm->file_size)
325                 url_fseek(pb, ffm->packet_size, SEEK_SET);
326     retry_read:
327             get_be16(pb); /* PACKET_ID */
328             fill_size = get_be16(pb);
329             ffm->pts = get_be64(pb);
330             frame_offset = get_be16(pb);
331             get_buffer(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE);
332             ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size);
333             /* if first packet or resynchronization packet, we must
334                handle it specifically */
335             if (ffm->first_packet || (frame_offset & 0x8000)) {
336                 if (!frame_offset) {
337                     /* This packet has no frame headers in it */
338                     if (url_ftell(pb) >= ffm->packet_size * 3) {
339                         url_fseek(pb, -ffm->packet_size * 2, SEEK_CUR);
340                         goto retry_read;
341                     }
342                     /* This is bad, we cannot find a valid frame header */
343                     return 0;
344                 }
345                 ffm->first_packet = 0;
346                 if ((frame_offset & 0x7ffff) < FFM_HEADER_SIZE)
347                     av_abort();
348                 ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE;
349                 if (!first)
350                     break;
351             } else {
352                 ffm->packet_ptr = ffm->packet;
353             }
354             goto redo;
355         }
356         memcpy(buf, ffm->packet_ptr, len);
357         buf += len;
358         ffm->packet_ptr += len;
359         size -= len;
360         first = 0;
361     }
362     return size1 - size;
363 }
364
365
366 static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
367 {
368     FFMContext *ffm = s->priv_data;
369     AVStream *st;
370     FFMStream *fst;
371     ByteIOContext *pb = &s->pb;
372     AVCodecContext *codec;
373     int i, nb_streams;
374     uint32_t tag;
375
376     /* header */
377     tag = get_le32(pb);
378     if (tag != MKTAG('F', 'F', 'M', '1'))
379         goto fail;
380     ffm->packet_size = get_be32(pb);
381     if (ffm->packet_size != FFM_PACKET_SIZE)
382         goto fail;
383     ffm->write_index = get_be64(pb);
384     /* get also filesize */
385     if (!url_is_streamed(pb)) {
386         ffm->file_size = url_filesize(url_fileno(pb));
387     } else {
388         ffm->file_size = (uint64_t_C(1) << 63) - 1;
389     }
390
391     nb_streams = get_be32(pb);
392     get_be32(pb); /* total bitrate */
393     /* read each stream */
394     for(i=0;i<nb_streams;i++) {
395         char rc_eq_buf[128];
396
397         st = av_new_stream(s, 0);
398         if (!st)
399             goto fail;
400         fst = av_mallocz(sizeof(FFMStream));
401         if (!fst)
402             goto fail;
403         st->priv_data = fst;
404
405         codec = &st->codec;
406         /* generic info */
407         st->codec.codec_id = get_be32(pb);
408         st->codec.codec_type = get_byte(pb); /* codec_type */
409         codec->bit_rate = get_be32(pb);
410         st->quality = get_be32(pb);
411         codec->flags = get_be32(pb);
412         /* specific info */
413         switch(codec->codec_type) {
414         case CODEC_TYPE_VIDEO:
415             codec->frame_rate_base = get_be32(pb);
416             codec->frame_rate = get_be32(pb);
417             codec->width = get_be16(pb);
418             codec->height = get_be16(pb);
419             codec->gop_size = get_be16(pb);
420             codec->qmin = get_byte(pb);
421             codec->qmax = get_byte(pb);
422             codec->max_qdiff = get_byte(pb);
423             codec->qcompress = get_be16(pb) / 10000.0;
424             codec->qblur = get_be16(pb) / 10000.0;
425             codec->bit_rate_tolerance = get_be32(pb);
426             codec->rc_eq = av_strdup(get_strz(pb, rc_eq_buf, sizeof(rc_eq_buf)));
427             codec->rc_max_rate = get_be32(pb);
428             codec->rc_min_rate = get_be32(pb);
429             codec->rc_buffer_size = get_be32(pb);
430             codec->i_quant_factor = get_be64_double(pb);
431             codec->b_quant_factor = get_be64_double(pb);
432             codec->i_quant_offset = get_be64_double(pb);
433             codec->b_quant_offset = get_be64_double(pb);
434             codec->dct_algo = get_be32(pb);
435             break;
436         case CODEC_TYPE_AUDIO:
437             codec->sample_rate = get_be32(pb);
438             codec->channels = get_le16(pb);
439             codec->frame_size = get_le16(pb);
440             break;
441         default:
442             goto fail;
443         }
444
445     }
446
447     /* get until end of block reached */
448     while ((url_ftell(pb) % ffm->packet_size) != 0)
449         get_byte(pb);
450
451     /* init packet demux */
452     ffm->packet_ptr = ffm->packet;
453     ffm->packet_end = ffm->packet;
454     ffm->frame_offset = 0;
455     ffm->pts = 0;
456     ffm->read_state = READ_HEADER;
457     ffm->first_packet = 1;
458     return 0;
459  fail:
460     for(i=0;i<s->nb_streams;i++) {
461         st = s->streams[i];
462         if (st) {
463             av_freep(&st->priv_data);
464             av_free(st);
465         }
466     }
467     return -1;
468 }
469
470 /* return < 0 if eof */
471 static int ffm_read_packet(AVFormatContext *s, AVPacket *pkt)
472 {
473     int size;
474     FFMContext *ffm = s->priv_data;
475     int duration;
476
477     switch(ffm->read_state) {
478     case READ_HEADER:
479         if (!ffm_is_avail_data(s, FRAME_HEADER_SIZE)) {
480             return -EAGAIN;
481         }
482 #if 0
483         printf("pos=%08Lx spos=%Lx, write_index=%Lx size=%Lx\n",
484                url_ftell(&s->pb), s->pb.pos, ffm->write_index, ffm->file_size);
485 #endif
486         if (ffm_read_data(s, ffm->header, FRAME_HEADER_SIZE, 1) != 
487             FRAME_HEADER_SIZE)
488             return -EAGAIN;
489 #if 0
490         {
491             int i;
492             for(i=0;i<FRAME_HEADER_SIZE;i++)
493                 printf("%02x ", ffm->header[i]);
494             printf("\n");
495         }
496 #endif
497         ffm->read_state = READ_DATA;
498         /* fall thru */
499     case READ_DATA:
500         size = (ffm->header[2] << 16) | (ffm->header[3] << 8) | ffm->header[4];
501         if (!ffm_is_avail_data(s, size)) {
502             return -EAGAIN;
503         }
504
505         duration = (ffm->header[5] << 16) | (ffm->header[6] << 8) | ffm->header[7];
506
507         av_new_packet(pkt, size);
508         pkt->stream_index = ffm->header[0];
509         if (ffm->header[1] & FLAG_KEY_FRAME)
510             pkt->flags |= PKT_FLAG_KEY;
511
512         ffm->read_state = READ_HEADER;
513         if (ffm_read_data(s, pkt->data, size, 0) != size) {
514             /* bad case: desynchronized packet. we cancel all the packet loading */
515             av_free_packet(pkt);
516             return -EAGAIN;
517         }
518         pkt->pts = ffm->pts;
519         pkt->duration = duration;
520         break;
521     }
522     return 0;
523 }
524
525 //#define DEBUG_SEEK
526
527 /* pos is between 0 and file_size - FFM_PACKET_SIZE. It is translated
528    by the write position inside this function */
529 static void ffm_seek1(AVFormatContext *s, offset_t pos1)
530 {
531     FFMContext *ffm = s->priv_data;
532     ByteIOContext *pb = &s->pb;
533     offset_t pos;
534
535     pos = pos1 + ffm->write_index;
536     if (pos >= ffm->file_size)
537         pos -= (ffm->file_size - FFM_PACKET_SIZE);
538 #ifdef DEBUG_SEEK
539     printf("seek to %Lx -> %Lx\n", pos1, pos);
540 #endif
541     url_fseek(pb, pos, SEEK_SET);
542 }
543
544 static int64_t get_pts(AVFormatContext *s, offset_t pos)
545 {
546     ByteIOContext *pb = &s->pb;
547     int64_t pts;
548
549     ffm_seek1(s, pos);
550     url_fskip(pb, 4);
551     pts = get_be64(pb);
552 #ifdef DEBUG_SEEK
553     printf("pts=%0.6f\n", pts / 1000000.0);
554 #endif
555     return pts;
556 }
557
558 /* seek to a given time in the file. The file read pointer is
559    positionned at or before pts. XXX: the following code is quite
560    approximative */
561 static int ffm_seek(AVFormatContext *s, int64_t wanted_pts)
562 {
563     FFMContext *ffm = s->priv_data;
564     offset_t pos_min, pos_max, pos;
565     int64_t pts_min, pts_max, pts;
566     double pos1;
567
568 #ifdef DEBUG_SEEK
569     printf("wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
570 #endif
571     /* find the position using linear interpolation (better than
572        dichotomy in typical cases) */
573     pos_min = 0;
574     pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE;
575     while (pos_min <= pos_max) {
576         pts_min = get_pts(s, pos_min);
577         pts_max = get_pts(s, pos_max);
578         /* linear interpolation */
579         pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) /
580             (double)(pts_max - pts_min);
581         pos = (((int64_t)pos1) / FFM_PACKET_SIZE) * FFM_PACKET_SIZE;
582         if (pos <= pos_min)
583             pos = pos_min;
584         else if (pos >= pos_max)
585             pos = pos_max;
586         pts = get_pts(s, pos);
587         /* check if we are lucky */
588         if (pts == wanted_pts) {
589             goto found;
590         } else if (pts > wanted_pts) {
591             pos_max = pos - FFM_PACKET_SIZE;
592         } else {
593             pos_min = pos + FFM_PACKET_SIZE;
594         }
595     }
596     pos = pos_min;
597     if (pos > 0)
598         pos -= FFM_PACKET_SIZE;
599  found:
600     ffm_seek1(s, pos);
601     return 0;
602 }
603
604 offset_t ffm_read_write_index(int fd)
605 {
606     uint8_t buf[8];
607     offset_t pos;
608     int i;
609
610     lseek(fd, 8, SEEK_SET);
611     read(fd, buf, 8);
612     pos = 0;
613     for(i=0;i<8;i++)
614         pos |= (int64_t)buf[i] << (56 - i * 8);
615     return pos;
616 }
617
618 void ffm_write_write_index(int fd, offset_t pos)
619 {
620     uint8_t buf[8];
621     int i;
622
623     for(i=0;i<8;i++)
624         buf[i] = (pos >> (56 - i * 8)) & 0xff;
625     lseek(fd, 8, SEEK_SET);
626     write(fd, buf, 8);
627 }
628
629 void ffm_set_write_index(AVFormatContext *s, offset_t pos, offset_t file_size)
630 {
631     FFMContext *ffm = s->priv_data;
632     ffm->write_index = pos;
633     ffm->file_size = file_size;
634 }
635
636 static int ffm_read_close(AVFormatContext *s)
637 {
638     AVStream *st;
639     int i;
640
641     for(i=0;i<s->nb_streams;i++) {
642         st = s->streams[i];
643         av_freep(&st->priv_data);
644     }
645     return 0;
646 }
647
648 static int ffm_probe(AVProbeData *p)
649 {
650     if (p->buf_size >= 4 &&
651         p->buf[0] == 'F' && p->buf[1] == 'F' && p->buf[2] == 'M' && 
652         p->buf[3] == '1')
653         return AVPROBE_SCORE_MAX + 1;
654     return 0;
655 }
656
657 static AVInputFormat ffm_iformat = {
658     "ffm",
659     "ffm format",
660     sizeof(FFMContext),
661     ffm_probe,
662     ffm_read_header,
663     ffm_read_packet,
664     ffm_read_close,
665     ffm_seek,
666 };
667
668 #ifdef CONFIG_ENCODERS
669 static AVOutputFormat ffm_oformat = {
670     "ffm",
671     "ffm format",
672     "",
673     "ffm",
674     sizeof(FFMContext),
675     /* not really used */
676     CODEC_ID_MP2,
677     CODEC_ID_MPEG1VIDEO,
678     ffm_write_header,
679     ffm_write_packet,
680     ffm_write_trailer,
681 };
682 #endif //CONFIG_ENCODERS
683
684 int ffm_init(void)
685 {
686     av_register_input_format(&ffm_iformat);
687 #ifdef CONFIG_ENCODERS
688     av_register_output_format(&ffm_oformat);
689 #endif //CONFIG_ENCODERS
690     return 0;
691 }