2 * FFM (ffserver live feed) muxer and demuxer
3 * Copyright (c) 2001 Fabrice Bellard.
5 * This file is part of FFmpeg.
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.
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.
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
24 /* The FFM file is made of blocks of fixed size */
25 #define FFM_HEADER_SIZE 14
26 #define PACKET_ID 0x666d
28 /* each packet contains frames (which can span several packets */
29 #define FRAME_HEADER_SIZE 8
30 #define FLAG_KEY_FRAME 0x01
32 typedef struct FFMStream
{
41 typedef struct FFMContext
{
42 /* only reading mode */
43 offset_t write_index
, file_size
;
45 uint8_t header
[FRAME_HEADER_SIZE
];
48 int first_packet
; /* true if first packet, needed to set the discontinuity tag */
49 int first_frame_in_packet
; /* true if first frame in packet, needed to know if PTS information is valid */
53 uint8_t *packet_ptr
, *packet_end
;
54 uint8_t packet
[FFM_PACKET_SIZE
];
57 static int64_t get_pts(AVFormatContext
*s
, offset_t pos
);
59 /* disable pts hack for testing */
63 static void flush_packet(AVFormatContext
*s
)
65 FFMContext
*ffm
= s
->priv_data
;
67 ByteIOContext
*pb
= s
->pb
;
69 fill_size
= ffm
->packet_end
- ffm
->packet_ptr
;
70 memset(ffm
->packet_ptr
, 0, fill_size
);
72 if (url_ftell(pb
) % ffm
->packet_size
)
76 put_be16(pb
, PACKET_ID
);
77 put_be16(pb
, fill_size
);
78 put_be64(pb
, ffm
->pts
);
79 h
= ffm
->frame_offset
;
80 if (ffm
->first_packet
)
83 put_buffer(pb
, ffm
->packet
, ffm
->packet_end
- ffm
->packet
);
86 /* prepare next packet */
87 ffm
->frame_offset
= 0; /* no key frame */
88 ffm
->pts
= 0; /* no pts */
89 ffm
->packet_ptr
= ffm
->packet
;
90 ffm
->first_packet
= 0;
93 /* 'first' is true if first data of a frame */
94 static void ffm_write_data(AVFormatContext
*s
,
95 const uint8_t *buf
, int size
,
96 int64_t pts
, int first
)
98 FFMContext
*ffm
= s
->priv_data
;
101 if (first
&& ffm
->frame_offset
== 0)
102 ffm
->frame_offset
= ffm
->packet_ptr
- ffm
->packet
+ FFM_HEADER_SIZE
;
103 if (first
&& ffm
->pts
== 0)
106 /* write as many packets as needed */
108 len
= ffm
->packet_end
- ffm
->packet_ptr
;
111 memcpy(ffm
->packet_ptr
, buf
, len
);
113 ffm
->packet_ptr
+= len
;
116 if (ffm
->packet_ptr
>= ffm
->packet_end
) {
117 /* special case : no pts in packet : we leave the current one */
126 static int ffm_write_header(AVFormatContext
*s
)
128 FFMContext
*ffm
= s
->priv_data
;
131 ByteIOContext
*pb
= s
->pb
;
132 AVCodecContext
*codec
;
135 ffm
->packet_size
= FFM_PACKET_SIZE
;
138 put_le32(pb
, MKTAG('F', 'F', 'M', '1'));
139 put_be32(pb
, ffm
->packet_size
);
140 /* XXX: store write position in other file ? */
141 put_be64(pb
, ffm
->packet_size
); /* current write position */
143 put_be32(pb
, s
->nb_streams
);
145 for(i
=0;i
<s
->nb_streams
;i
++) {
147 bit_rate
+= st
->codec
->bit_rate
;
149 put_be32(pb
, bit_rate
);
151 /* list of streams */
152 for(i
=0;i
<s
->nb_streams
;i
++) {
154 fst
= av_mallocz(sizeof(FFMStream
));
157 av_set_pts_info(st
, 64, 1, 1000000);
162 put_be32(pb
, codec
->codec_id
);
163 put_byte(pb
, codec
->codec_type
);
164 put_be32(pb
, codec
->bit_rate
);
165 put_be32(pb
, st
->quality
);
166 put_be32(pb
, codec
->flags
);
167 put_be32(pb
, codec
->flags2
);
168 put_be32(pb
, codec
->debug
);
170 switch(codec
->codec_type
) {
171 case CODEC_TYPE_VIDEO
:
172 put_be32(pb
, codec
->time_base
.num
);
173 put_be32(pb
, codec
->time_base
.den
);
174 put_be16(pb
, codec
->width
);
175 put_be16(pb
, codec
->height
);
176 put_be16(pb
, codec
->gop_size
);
177 put_be32(pb
, codec
->pix_fmt
);
178 put_byte(pb
, codec
->qmin
);
179 put_byte(pb
, codec
->qmax
);
180 put_byte(pb
, codec
->max_qdiff
);
181 put_be16(pb
, (int) (codec
->qcompress
* 10000.0));
182 put_be16(pb
, (int) (codec
->qblur
* 10000.0));
183 put_be32(pb
, codec
->bit_rate_tolerance
);
184 put_strz(pb
, codec
->rc_eq
);
185 put_be32(pb
, codec
->rc_max_rate
);
186 put_be32(pb
, codec
->rc_min_rate
);
187 put_be32(pb
, codec
->rc_buffer_size
);
188 put_be64(pb
, av_dbl2int(codec
->i_quant_factor
));
189 put_be64(pb
, av_dbl2int(codec
->b_quant_factor
));
190 put_be64(pb
, av_dbl2int(codec
->i_quant_offset
));
191 put_be64(pb
, av_dbl2int(codec
->b_quant_offset
));
192 put_be32(pb
, codec
->dct_algo
);
193 put_be32(pb
, codec
->strict_std_compliance
);
194 put_be32(pb
, codec
->max_b_frames
);
195 put_be32(pb
, codec
->luma_elim_threshold
);
196 put_be32(pb
, codec
->chroma_elim_threshold
);
197 put_be32(pb
, codec
->mpeg_quant
);
198 put_be32(pb
, codec
->intra_dc_precision
);
199 put_be32(pb
, codec
->me_method
);
200 put_be32(pb
, codec
->mb_decision
);
201 put_be32(pb
, codec
->nsse_weight
);
202 put_be32(pb
, codec
->frame_skip_cmp
);
203 put_be64(pb
, av_dbl2int(codec
->rc_buffer_aggressivity
));
204 put_be32(pb
, codec
->codec_tag
);
206 case CODEC_TYPE_AUDIO
:
207 put_be32(pb
, codec
->sample_rate
);
208 put_le16(pb
, codec
->channels
);
209 put_le16(pb
, codec
->frame_size
);
214 /* hack to have real time */
218 fst
->pts
= av_gettime();
221 /* flush until end of block reached */
222 while ((url_ftell(pb
) % ffm
->packet_size
) != 0)
225 put_flush_packet(pb
);
227 /* init packet mux */
228 ffm
->packet_ptr
= ffm
->packet
;
229 ffm
->packet_end
= ffm
->packet
+ ffm
->packet_size
- FFM_HEADER_SIZE
;
230 assert(ffm
->packet_end
>= ffm
->packet
);
231 ffm
->frame_offset
= 0;
233 ffm
->first_packet
= 1;
237 for(i
=0;i
<s
->nb_streams
;i
++) {
239 av_freep(&st
->priv_data
);
244 static int ffm_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
246 AVStream
*st
= s
->streams
[pkt
->stream_index
];
247 FFMStream
*fst
= st
->priv_data
;
249 uint8_t header
[FRAME_HEADER_SIZE
];
253 //XXX/FIXME use duration from pkt
254 if (st
->codec
->codec_type
== CODEC_TYPE_AUDIO
) {
255 duration
= ((float)st
->codec
->frame_size
/ st
->codec
->sample_rate
* 1000000.0);
257 duration
= (1000000.0 * st
->codec
->time_base
.num
/ (float)st
->codec
->time_base
.den
);
261 /* packet size & key_frame */
262 header
[0] = pkt
->stream_index
;
264 if (pkt
->flags
& PKT_FLAG_KEY
)
265 header
[1] |= FLAG_KEY_FRAME
;
266 header
[2] = (size
>> 16) & 0xff;
267 header
[3] = (size
>> 8) & 0xff;
268 header
[4] = size
& 0xff;
269 header
[5] = (duration
>> 16) & 0xff;
270 header
[6] = (duration
>> 8) & 0xff;
271 header
[7] = duration
& 0xff;
272 ffm_write_data(s
, header
, FRAME_HEADER_SIZE
, pts
, 1);
273 ffm_write_data(s
, pkt
->data
, size
, pts
, 0);
275 fst
->pts
+= duration
;
279 static int ffm_write_trailer(AVFormatContext
*s
)
281 ByteIOContext
*pb
= s
->pb
;
282 FFMContext
*ffm
= s
->priv_data
;
285 if (ffm
->packet_ptr
> ffm
->packet
)
288 put_flush_packet(pb
);
290 if (!url_is_streamed(pb
)) {
292 /* update the write offset */
293 size
= url_ftell(pb
);
294 url_fseek(pb
, 8, SEEK_SET
);
296 put_flush_packet(pb
);
301 #endif //CONFIG_MUXERS
305 static int ffm_is_avail_data(AVFormatContext
*s
, int size
)
307 FFMContext
*ffm
= s
->priv_data
;
308 offset_t pos
, avail_size
;
311 len
= ffm
->packet_end
- ffm
->packet_ptr
;
313 /* XXX: I don't understand this test, so I disabled it for testing */
317 pos
= url_ftell(s
->pb
);
318 if (pos
== ffm
->write_index
) {
319 /* exactly at the end of stream */
321 } else if (pos
< ffm
->write_index
) {
322 avail_size
= ffm
->write_index
- pos
;
324 avail_size
= (ffm
->file_size
- pos
) + (ffm
->write_index
- FFM_PACKET_SIZE
);
326 avail_size
= (avail_size
/ ffm
->packet_size
) * (ffm
->packet_size
- FFM_HEADER_SIZE
) + len
;
327 if (size
<= avail_size
)
333 /* first is true if we read the frame header */
334 static int ffm_read_data(AVFormatContext
*s
,
335 uint8_t *buf
, int size
, int first
)
337 FFMContext
*ffm
= s
->priv_data
;
338 ByteIOContext
*pb
= s
->pb
;
339 int len
, fill_size
, size1
, frame_offset
;
344 len
= ffm
->packet_end
- ffm
->packet_ptr
;
348 if (url_ftell(pb
) == ffm
->file_size
)
349 url_fseek(pb
, ffm
->packet_size
, SEEK_SET
);
351 get_be16(pb
); /* PACKET_ID */
352 fill_size
= get_be16(pb
);
353 ffm
->pts
= get_be64(pb
);
354 ffm
->first_frame_in_packet
= 1;
355 frame_offset
= get_be16(pb
);
356 get_buffer(pb
, ffm
->packet
, ffm
->packet_size
- FFM_HEADER_SIZE
);
357 ffm
->packet_end
= ffm
->packet
+ (ffm
->packet_size
- FFM_HEADER_SIZE
- fill_size
);
358 if (ffm
->packet_end
< ffm
->packet
)
360 /* if first packet or resynchronization packet, we must
361 handle it specifically */
362 if (ffm
->first_packet
|| (frame_offset
& 0x8000)) {
364 /* This packet has no frame headers in it */
365 if (url_ftell(pb
) >= ffm
->packet_size
* 3) {
366 url_fseek(pb
, -ffm
->packet_size
* 2, SEEK_CUR
);
369 /* This is bad, we cannot find a valid frame header */
372 ffm
->first_packet
= 0;
373 if ((frame_offset
& 0x7ffff) < FFM_HEADER_SIZE
)
375 ffm
->packet_ptr
= ffm
->packet
+ (frame_offset
& 0x7fff) - FFM_HEADER_SIZE
;
379 ffm
->packet_ptr
= ffm
->packet
;
383 memcpy(buf
, ffm
->packet_ptr
, len
);
385 ffm
->packet_ptr
+= len
;
393 static void adjust_write_index(AVFormatContext
*s
)
395 FFMContext
*ffm
= s
->priv_data
;
396 ByteIOContext
*pb
= s
->pb
;
398 //offset_t orig_write_index = ffm->write_index;
399 offset_t pos_min
, pos_max
;
401 offset_t ptr
= url_ftell(pb
);
405 pos_max
= ffm
->file_size
- 2 * FFM_PACKET_SIZE
;
407 pts_start
= get_pts(s
, pos_min
);
409 pts
= get_pts(s
, pos_max
);
411 if (pts
- 100000 > pts_start
)
414 ffm
->write_index
= FFM_PACKET_SIZE
;
416 pts_start
= get_pts(s
, pos_min
);
418 pts
= get_pts(s
, pos_max
);
420 if (pts
- 100000 <= pts_start
) {
425 newpos
= ((pos_max
+ pos_min
) / (2 * FFM_PACKET_SIZE
)) * FFM_PACKET_SIZE
;
427 if (newpos
== pos_min
)
430 newpts
= get_pts(s
, newpos
);
432 if (newpts
- 100000 <= pts
) {
439 ffm
->write_index
+= pos_max
;
442 //printf("Adjusted write index from %"PRId64" to %"PRId64": pts=%0.6f\n", orig_write_index, ffm->write_index, pts / 1000000.);
443 //printf("pts range %0.6f - %0.6f\n", get_pts(s, 0) / 1000000. , get_pts(s, ffm->file_size - 2 * FFM_PACKET_SIZE) / 1000000. );
446 url_fseek(pb
, ptr
, SEEK_SET
);
450 static int ffm_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
452 FFMContext
*ffm
= s
->priv_data
;
455 ByteIOContext
*pb
= s
->pb
;
456 AVCodecContext
*codec
;
462 if (tag
!= MKTAG('F', 'F', 'M', '1'))
464 ffm
->packet_size
= get_be32(pb
);
465 if (ffm
->packet_size
!= FFM_PACKET_SIZE
)
467 ffm
->write_index
= get_be64(pb
);
468 /* get also filesize */
469 if (!url_is_streamed(pb
)) {
470 ffm
->file_size
= url_fsize(pb
);
471 adjust_write_index(s
);
473 ffm
->file_size
= (UINT64_C(1) << 63) - 1;
476 nb_streams
= get_be32(pb
);
477 get_be32(pb
); /* total bitrate */
478 /* read each stream */
479 for(i
=0;i
<nb_streams
;i
++) {
482 st
= av_new_stream(s
, 0);
485 fst
= av_mallocz(sizeof(FFMStream
));
490 av_set_pts_info(st
, 64, 1, 1000000);
496 codec
->codec_id
= get_be32(pb
);
497 codec
->codec_type
= get_byte(pb
); /* codec_type */
498 codec
->bit_rate
= get_be32(pb
);
499 st
->quality
= get_be32(pb
);
500 codec
->flags
= get_be32(pb
);
501 codec
->flags2
= get_be32(pb
);
502 codec
->debug
= get_be32(pb
);
504 switch(codec
->codec_type
) {
505 case CODEC_TYPE_VIDEO
:
506 codec
->time_base
.num
= get_be32(pb
);
507 codec
->time_base
.den
= get_be32(pb
);
508 codec
->width
= get_be16(pb
);
509 codec
->height
= get_be16(pb
);
510 codec
->gop_size
= get_be16(pb
);
511 codec
->pix_fmt
= get_be32(pb
);
512 codec
->qmin
= get_byte(pb
);
513 codec
->qmax
= get_byte(pb
);
514 codec
->max_qdiff
= get_byte(pb
);
515 codec
->qcompress
= get_be16(pb
) / 10000.0;
516 codec
->qblur
= get_be16(pb
) / 10000.0;
517 codec
->bit_rate_tolerance
= get_be32(pb
);
518 codec
->rc_eq
= av_strdup(get_strz(pb
, rc_eq_buf
, sizeof(rc_eq_buf
)));
519 codec
->rc_max_rate
= get_be32(pb
);
520 codec
->rc_min_rate
= get_be32(pb
);
521 codec
->rc_buffer_size
= get_be32(pb
);
522 codec
->i_quant_factor
= av_int2dbl(get_be64(pb
));
523 codec
->b_quant_factor
= av_int2dbl(get_be64(pb
));
524 codec
->i_quant_offset
= av_int2dbl(get_be64(pb
));
525 codec
->b_quant_offset
= av_int2dbl(get_be64(pb
));
526 codec
->dct_algo
= get_be32(pb
);
527 codec
->strict_std_compliance
= get_be32(pb
);
528 codec
->max_b_frames
= get_be32(pb
);
529 codec
->luma_elim_threshold
= get_be32(pb
);
530 codec
->chroma_elim_threshold
= get_be32(pb
);
531 codec
->mpeg_quant
= get_be32(pb
);
532 codec
->intra_dc_precision
= get_be32(pb
);
533 codec
->me_method
= get_be32(pb
);
534 codec
->mb_decision
= get_be32(pb
);
535 codec
->nsse_weight
= get_be32(pb
);
536 codec
->frame_skip_cmp
= get_be32(pb
);
537 codec
->rc_buffer_aggressivity
= av_int2dbl(get_be64(pb
));
538 codec
->codec_tag
= get_be32(pb
);
540 case CODEC_TYPE_AUDIO
:
541 codec
->sample_rate
= get_be32(pb
);
542 codec
->channels
= get_le16(pb
);
543 codec
->frame_size
= get_le16(pb
);
551 /* get until end of block reached */
552 while ((url_ftell(pb
) % ffm
->packet_size
) != 0)
555 /* init packet demux */
556 ffm
->packet_ptr
= ffm
->packet
;
557 ffm
->packet_end
= ffm
->packet
;
558 ffm
->frame_offset
= 0;
560 ffm
->read_state
= READ_HEADER
;
561 ffm
->first_packet
= 1;
564 for(i
=0;i
<s
->nb_streams
;i
++) {
567 av_freep(&st
->priv_data
);
574 /* return < 0 if eof */
575 static int ffm_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
578 FFMContext
*ffm
= s
->priv_data
;
581 switch(ffm
->read_state
) {
583 if (!ffm_is_avail_data(s
, FRAME_HEADER_SIZE
)) {
584 return AVERROR(EAGAIN
);
587 printf("pos=%08"PRIx64
" spos=%"PRIx64
", write_index=%"PRIx64
" size=%"PRIx64
"\n",
588 url_ftell(s
->pb
), s
->pb
.pos
, ffm
->write_index
, ffm
->file_size
);
590 if (ffm_read_data(s
, ffm
->header
, FRAME_HEADER_SIZE
, 1) !=
592 return AVERROR(EAGAIN
);
596 for(i
=0;i
<FRAME_HEADER_SIZE
;i
++)
597 printf("%02x ", ffm
->header
[i
]);
601 ffm
->read_state
= READ_DATA
;
604 size
= AV_RB24(ffm
->header
+ 2);
605 if (!ffm_is_avail_data(s
, size
)) {
606 return AVERROR(EAGAIN
);
609 duration
= AV_RB24(ffm
->header
+ 5);
611 av_new_packet(pkt
, size
);
612 pkt
->stream_index
= ffm
->header
[0];
613 pkt
->pos
= url_ftell(s
->pb
);
614 if (ffm
->header
[1] & FLAG_KEY_FRAME
)
615 pkt
->flags
|= PKT_FLAG_KEY
;
617 ffm
->read_state
= READ_HEADER
;
618 if (ffm_read_data(s
, pkt
->data
, size
, 0) != size
) {
619 /* bad case: desynchronized packet. we cancel all the packet loading */
621 return AVERROR(EAGAIN
);
623 if (ffm
->first_frame_in_packet
)
626 ffm
->first_frame_in_packet
= 0;
628 pkt
->duration
= duration
;
636 /* pos is between 0 and file_size - FFM_PACKET_SIZE. It is translated
637 by the write position inside this function */
638 static void ffm_seek1(AVFormatContext
*s
, offset_t pos1
)
640 FFMContext
*ffm
= s
->priv_data
;
641 ByteIOContext
*pb
= s
->pb
;
644 pos
= pos1
+ ffm
->write_index
;
645 if (pos
>= ffm
->file_size
)
646 pos
-= (ffm
->file_size
- FFM_PACKET_SIZE
);
648 printf("seek to %"PRIx64
" -> %"PRIx64
"\n", pos1
, pos
);
650 url_fseek(pb
, pos
, SEEK_SET
);
653 static int64_t get_pts(AVFormatContext
*s
, offset_t pos
)
655 ByteIOContext
*pb
= s
->pb
;
662 printf("pts=%0.6f\n", pts
/ 1000000.0);
667 /* seek to a given time in the file. The file read pointer is
668 positioned at or before pts. XXX: the following code is quite
670 static int ffm_seek(AVFormatContext
*s
, int stream_index
, int64_t wanted_pts
, int flags
)
672 FFMContext
*ffm
= s
->priv_data
;
673 offset_t pos_min
, pos_max
, pos
;
674 int64_t pts_min
, pts_max
, pts
;
678 printf("wanted_pts=%0.6f\n", wanted_pts
/ 1000000.0);
680 /* find the position using linear interpolation (better than
681 dichotomy in typical cases) */
683 pos_max
= ffm
->file_size
- 2 * FFM_PACKET_SIZE
;
684 while (pos_min
<= pos_max
) {
685 pts_min
= get_pts(s
, pos_min
);
686 pts_max
= get_pts(s
, pos_max
);
687 /* linear interpolation */
688 pos1
= (double)(pos_max
- pos_min
) * (double)(wanted_pts
- pts_min
) /
689 (double)(pts_max
- pts_min
);
690 pos
= (((int64_t)pos1
) / FFM_PACKET_SIZE
) * FFM_PACKET_SIZE
;
693 else if (pos
>= pos_max
)
695 pts
= get_pts(s
, pos
);
696 /* check if we are lucky */
697 if (pts
== wanted_pts
) {
699 } else if (pts
> wanted_pts
) {
700 pos_max
= pos
- FFM_PACKET_SIZE
;
702 pos_min
= pos
+ FFM_PACKET_SIZE
;
705 pos
= (flags
& AVSEEK_FLAG_BACKWARD
) ? pos_min
: pos_max
;
707 pos
-= FFM_PACKET_SIZE
;
713 #ifdef CONFIG_FFSERVER
714 offset_t
ffm_read_write_index(int fd
)
718 lseek(fd
, 8, SEEK_SET
);
723 void ffm_write_write_index(int fd
, offset_t pos
)
729 buf
[i
] = (pos
>> (56 - i
* 8)) & 0xff;
730 lseek(fd
, 8, SEEK_SET
);
734 void ffm_set_write_index(AVFormatContext
*s
, offset_t pos
, offset_t file_size
)
736 FFMContext
*ffm
= s
->priv_data
;
737 ffm
->write_index
= pos
;
738 ffm
->file_size
= file_size
;
740 #endif // CONFIG_FFSERVER
742 static int ffm_read_close(AVFormatContext
*s
)
747 for(i
=0;i
<s
->nb_streams
;i
++) {
749 av_freep(&st
->priv_data
);
754 static int ffm_probe(AVProbeData
*p
)
757 p
->buf
[0] == 'F' && p
->buf
[1] == 'F' && p
->buf
[2] == 'M' &&
759 return AVPROBE_SCORE_MAX
+ 1;
763 #ifdef CONFIG_FFM_DEMUXER
764 AVInputFormat ffm_demuxer
= {
775 #ifdef CONFIG_FFM_MUXER
776 AVOutputFormat ffm_muxer
= {
782 /* not really used */
789 #endif //CONFIG_FFM_MUXER