2 * FFM (ffserver live feed) muxer
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
22 #include "libavutil/intreadwrite.h"
26 static void flush_packet(AVFormatContext
*s
)
28 FFMContext
*ffm
= s
->priv_data
;
30 ByteIOContext
*pb
= s
->pb
;
32 fill_size
= ffm
->packet_end
- ffm
->packet_ptr
;
33 memset(ffm
->packet_ptr
, 0, fill_size
);
35 if (url_ftell(pb
) % ffm
->packet_size
)
39 put_be16(pb
, PACKET_ID
);
40 put_be16(pb
, fill_size
);
41 put_be64(pb
, ffm
->dts
);
42 h
= ffm
->frame_offset
;
43 if (ffm
->first_packet
)
46 put_buffer(pb
, ffm
->packet
, ffm
->packet_end
- ffm
->packet
);
49 /* prepare next packet */
50 ffm
->frame_offset
= 0; /* no key frame */
51 ffm
->packet_ptr
= ffm
->packet
;
52 ffm
->first_packet
= 0;
55 /* 'first' is true if first data of a frame */
56 static void ffm_write_data(AVFormatContext
*s
,
57 const uint8_t *buf
, int size
,
58 int64_t dts
, int header
)
60 FFMContext
*ffm
= s
->priv_data
;
63 if (header
&& ffm
->frame_offset
== 0) {
64 ffm
->frame_offset
= ffm
->packet_ptr
- ffm
->packet
+ FFM_HEADER_SIZE
;
68 /* write as many packets as needed */
70 len
= ffm
->packet_end
- ffm
->packet_ptr
;
73 memcpy(ffm
->packet_ptr
, buf
, len
);
75 ffm
->packet_ptr
+= len
;
78 if (ffm
->packet_ptr
>= ffm
->packet_end
)
83 static int ffm_write_header(AVFormatContext
*s
)
85 FFMContext
*ffm
= s
->priv_data
;
87 ByteIOContext
*pb
= s
->pb
;
88 AVCodecContext
*codec
;
91 ffm
->packet_size
= FFM_PACKET_SIZE
;
94 put_le32(pb
, MKTAG('F', 'F', 'M', '1'));
95 put_be32(pb
, ffm
->packet_size
);
96 /* XXX: store write position in other file ? */
97 put_be64(pb
, ffm
->packet_size
); /* current write position */
99 put_be32(pb
, s
->nb_streams
);
101 for(i
=0;i
<s
->nb_streams
;i
++) {
103 bit_rate
+= st
->codec
->bit_rate
;
105 put_be32(pb
, bit_rate
);
107 /* list of streams */
108 for(i
=0;i
<s
->nb_streams
;i
++) {
110 av_set_pts_info(st
, 64, 1, 1000000);
114 put_be32(pb
, codec
->codec_id
);
115 put_byte(pb
, codec
->codec_type
);
116 put_be32(pb
, codec
->bit_rate
);
117 put_be32(pb
, st
->quality
);
118 put_be32(pb
, codec
->flags
);
119 put_be32(pb
, codec
->flags2
);
120 put_be32(pb
, codec
->debug
);
122 switch(codec
->codec_type
) {
123 case CODEC_TYPE_VIDEO
:
124 put_be32(pb
, codec
->time_base
.num
);
125 put_be32(pb
, codec
->time_base
.den
);
126 put_be16(pb
, codec
->width
);
127 put_be16(pb
, codec
->height
);
128 put_be16(pb
, codec
->gop_size
);
129 put_be32(pb
, codec
->pix_fmt
);
130 put_byte(pb
, codec
->qmin
);
131 put_byte(pb
, codec
->qmax
);
132 put_byte(pb
, codec
->max_qdiff
);
133 put_be16(pb
, (int) (codec
->qcompress
* 10000.0));
134 put_be16(pb
, (int) (codec
->qblur
* 10000.0));
135 put_be32(pb
, codec
->bit_rate_tolerance
);
136 put_strz(pb
, codec
->rc_eq
? codec
->rc_eq
: "tex^qComp");
137 put_be32(pb
, codec
->rc_max_rate
);
138 put_be32(pb
, codec
->rc_min_rate
);
139 put_be32(pb
, codec
->rc_buffer_size
);
140 put_be64(pb
, av_dbl2int(codec
->i_quant_factor
));
141 put_be64(pb
, av_dbl2int(codec
->b_quant_factor
));
142 put_be64(pb
, av_dbl2int(codec
->i_quant_offset
));
143 put_be64(pb
, av_dbl2int(codec
->b_quant_offset
));
144 put_be32(pb
, codec
->dct_algo
);
145 put_be32(pb
, codec
->strict_std_compliance
);
146 put_be32(pb
, codec
->max_b_frames
);
147 put_be32(pb
, codec
->luma_elim_threshold
);
148 put_be32(pb
, codec
->chroma_elim_threshold
);
149 put_be32(pb
, codec
->mpeg_quant
);
150 put_be32(pb
, codec
->intra_dc_precision
);
151 put_be32(pb
, codec
->me_method
);
152 put_be32(pb
, codec
->mb_decision
);
153 put_be32(pb
, codec
->nsse_weight
);
154 put_be32(pb
, codec
->frame_skip_cmp
);
155 put_be64(pb
, av_dbl2int(codec
->rc_buffer_aggressivity
));
156 put_be32(pb
, codec
->codec_tag
);
157 put_byte(pb
, codec
->thread_count
);
159 case CODEC_TYPE_AUDIO
:
160 put_be32(pb
, codec
->sample_rate
);
161 put_le16(pb
, codec
->channels
);
162 put_le16(pb
, codec
->frame_size
);
167 if (codec
->flags
& CODEC_FLAG_GLOBAL_HEADER
) {
168 put_be32(pb
, codec
->extradata_size
);
169 put_buffer(pb
, codec
->extradata
, codec
->extradata_size
);
173 /* flush until end of block reached */
174 while ((url_ftell(pb
) % ffm
->packet_size
) != 0)
177 put_flush_packet(pb
);
179 /* init packet mux */
180 ffm
->packet_ptr
= ffm
->packet
;
181 ffm
->packet_end
= ffm
->packet
+ ffm
->packet_size
- FFM_HEADER_SIZE
;
182 assert(ffm
->packet_end
>= ffm
->packet
);
183 ffm
->frame_offset
= 0;
185 ffm
->first_packet
= 1;
190 static int ffm_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
193 uint8_t header
[FRAME_HEADER_SIZE
+4];
194 int header_size
= FRAME_HEADER_SIZE
;
196 dts
= s
->timestamp
+ pkt
->dts
;
197 /* packet size & key_frame */
198 header
[0] = pkt
->stream_index
;
200 if (pkt
->flags
& PKT_FLAG_KEY
)
201 header
[1] |= FLAG_KEY_FRAME
;
202 AV_WB24(header
+2, pkt
->size
);
203 AV_WB24(header
+5, pkt
->duration
);
204 AV_WB64(header
+8, s
->timestamp
+ pkt
->pts
);
205 if (pkt
->pts
!= pkt
->dts
) {
206 header
[1] |= FLAG_DTS
;
207 AV_WB32(header
+16, pkt
->pts
- pkt
->dts
);
210 ffm_write_data(s
, header
, header_size
, dts
, 1);
211 ffm_write_data(s
, pkt
->data
, pkt
->size
, dts
, 0);
216 static int ffm_write_trailer(AVFormatContext
*s
)
218 ByteIOContext
*pb
= s
->pb
;
219 FFMContext
*ffm
= s
->priv_data
;
222 if (ffm
->packet_ptr
> ffm
->packet
)
225 put_flush_packet(pb
);
227 if (!url_is_streamed(pb
)) {
229 /* update the write offset */
230 size
= url_ftell(pb
);
231 url_fseek(pb
, 8, SEEK_SET
);
233 put_flush_packet(pb
);
239 AVOutputFormat ffm_muxer
= {
241 NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"),
245 /* not really used */