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
25 static void flush_packet(AVFormatContext
*s
)
27 FFMContext
*ffm
= s
->priv_data
;
29 ByteIOContext
*pb
= s
->pb
;
31 fill_size
= ffm
->packet_end
- ffm
->packet_ptr
;
32 memset(ffm
->packet_ptr
, 0, fill_size
);
34 if (url_ftell(pb
) % ffm
->packet_size
)
38 put_be16(pb
, PACKET_ID
);
39 put_be16(pb
, fill_size
);
40 put_be64(pb
, ffm
->pts
);
41 h
= ffm
->frame_offset
;
42 if (ffm
->first_packet
)
45 put_buffer(pb
, ffm
->packet
, ffm
->packet_end
- ffm
->packet
);
48 /* prepare next packet */
49 ffm
->frame_offset
= 0; /* no key frame */
50 ffm
->pts
= 0; /* no pts */
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 pts
, 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
;
65 if (header
&& ffm
->pts
== 0)
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
) {
79 /* special case : no pts in packet : we leave the current one */
88 static int ffm_write_header(AVFormatContext
*s
)
90 FFMContext
*ffm
= s
->priv_data
;
92 ByteIOContext
*pb
= s
->pb
;
93 AVCodecContext
*codec
;
96 ffm
->packet_size
= FFM_PACKET_SIZE
;
99 put_le32(pb
, MKTAG('F', 'F', 'M', '1'));
100 put_be32(pb
, ffm
->packet_size
);
101 /* XXX: store write position in other file ? */
102 put_be64(pb
, ffm
->packet_size
); /* current write position */
104 put_be32(pb
, s
->nb_streams
);
106 for(i
=0;i
<s
->nb_streams
;i
++) {
108 bit_rate
+= st
->codec
->bit_rate
;
110 put_be32(pb
, bit_rate
);
112 /* list of streams */
113 for(i
=0;i
<s
->nb_streams
;i
++) {
115 av_set_pts_info(st
, 64, 1, 1000000);
119 put_be32(pb
, codec
->codec_id
);
120 put_byte(pb
, codec
->codec_type
);
121 put_be32(pb
, codec
->bit_rate
);
122 put_be32(pb
, st
->quality
);
123 put_be32(pb
, codec
->flags
);
124 put_be32(pb
, codec
->flags2
);
125 put_be32(pb
, codec
->debug
);
127 switch(codec
->codec_type
) {
128 case CODEC_TYPE_VIDEO
:
129 put_be32(pb
, codec
->time_base
.num
);
130 put_be32(pb
, codec
->time_base
.den
);
131 put_be16(pb
, codec
->width
);
132 put_be16(pb
, codec
->height
);
133 put_be16(pb
, codec
->gop_size
);
134 put_be32(pb
, codec
->pix_fmt
);
135 put_byte(pb
, codec
->qmin
);
136 put_byte(pb
, codec
->qmax
);
137 put_byte(pb
, codec
->max_qdiff
);
138 put_be16(pb
, (int) (codec
->qcompress
* 10000.0));
139 put_be16(pb
, (int) (codec
->qblur
* 10000.0));
140 put_be32(pb
, codec
->bit_rate_tolerance
);
141 put_strz(pb
, codec
->rc_eq
);
142 put_be32(pb
, codec
->rc_max_rate
);
143 put_be32(pb
, codec
->rc_min_rate
);
144 put_be32(pb
, codec
->rc_buffer_size
);
145 put_be64(pb
, av_dbl2int(codec
->i_quant_factor
));
146 put_be64(pb
, av_dbl2int(codec
->b_quant_factor
));
147 put_be64(pb
, av_dbl2int(codec
->i_quant_offset
));
148 put_be64(pb
, av_dbl2int(codec
->b_quant_offset
));
149 put_be32(pb
, codec
->dct_algo
);
150 put_be32(pb
, codec
->strict_std_compliance
);
151 put_be32(pb
, codec
->max_b_frames
);
152 put_be32(pb
, codec
->luma_elim_threshold
);
153 put_be32(pb
, codec
->chroma_elim_threshold
);
154 put_be32(pb
, codec
->mpeg_quant
);
155 put_be32(pb
, codec
->intra_dc_precision
);
156 put_be32(pb
, codec
->me_method
);
157 put_be32(pb
, codec
->mb_decision
);
158 put_be32(pb
, codec
->nsse_weight
);
159 put_be32(pb
, codec
->frame_skip_cmp
);
160 put_be64(pb
, av_dbl2int(codec
->rc_buffer_aggressivity
));
161 put_be32(pb
, codec
->codec_tag
);
163 case CODEC_TYPE_AUDIO
:
164 put_be32(pb
, codec
->sample_rate
);
165 put_le16(pb
, codec
->channels
);
166 put_le16(pb
, codec
->frame_size
);
171 if (codec
->flags
& CODEC_FLAG_GLOBAL_HEADER
) {
172 put_be32(pb
, codec
->extradata_size
);
173 put_buffer(pb
, codec
->extradata
, codec
->extradata_size
);
177 /* flush until end of block reached */
178 while ((url_ftell(pb
) % ffm
->packet_size
) != 0)
181 put_flush_packet(pb
);
183 /* init packet mux */
184 ffm
->packet_ptr
= ffm
->packet
;
185 ffm
->packet_end
= ffm
->packet
+ ffm
->packet_size
- FFM_HEADER_SIZE
;
186 assert(ffm
->packet_end
>= ffm
->packet
);
187 ffm
->frame_offset
= 0;
189 ffm
->first_packet
= 1;
194 static int ffm_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
197 uint8_t header
[FRAME_HEADER_SIZE
];
198 int header_size
= FRAME_HEADER_SIZE
;
200 pts
= s
->timestamp
+ pkt
->pts
;
201 /* packet size & key_frame */
202 header
[0] = pkt
->stream_index
;
204 if (pkt
->flags
& PKT_FLAG_KEY
)
205 header
[1] |= FLAG_KEY_FRAME
;
206 AV_WB24(header
+2, pkt
->size
);
207 AV_WB24(header
+5, pkt
->duration
);
208 AV_WB64(header
+8, pts
);
209 if (pkt
->pts
!= pkt
->dts
) {
210 header
[1] |= FLAG_DTS
;
211 AV_WB32(header
+16, pkt
->pts
- pkt
->dts
);
214 ffm_write_data(s
, header
, header_size
, pts
, 1);
215 ffm_write_data(s
, pkt
->data
, pkt
->size
, pts
, 0);
220 static int ffm_write_trailer(AVFormatContext
*s
)
222 ByteIOContext
*pb
= s
->pb
;
223 FFMContext
*ffm
= s
->priv_data
;
226 if (ffm
->packet_ptr
> ffm
->packet
)
229 put_flush_packet(pb
);
231 if (!url_is_streamed(pb
)) {
233 /* update the write offset */
234 size
= url_ftell(pb
);
235 url_fseek(pb
, 8, SEEK_SET
);
237 put_flush_packet(pb
);
243 AVOutputFormat ffm_muxer
= {
245 NULL_IF_CONFIG_SMALL("ffm format"),
249 /* not really used */