2
* FFM (avserver live feed) muxer
3
* Copyright (c) 2001 Fabrice Bellard
5
* This file is part of Libav.
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.
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.
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
24
#include "libavutil/intreadwrite.h"
25
#include "libavutil/intfloat.h"
30
static void flush_packet(AVFormatContext *s)
32
FFMContext *ffm = s->priv_data;
34
AVIOContext *pb = s->pb;
36
fill_size = ffm->packet_end - ffm->packet_ptr;
37
memset(ffm->packet_ptr, 0, fill_size);
39
assert(avio_tell(pb) % ffm->packet_size == 0);
42
avio_wb16(pb, PACKET_ID);
43
avio_wb16(pb, fill_size);
44
avio_wb64(pb, ffm->dts);
45
h = ffm->frame_offset;
46
if (ffm->first_packet)
49
avio_write(pb, ffm->packet, ffm->packet_end - ffm->packet);
52
/* prepare next packet */
53
ffm->frame_offset = 0; /* no key frame */
54
ffm->packet_ptr = ffm->packet;
55
ffm->first_packet = 0;
58
/* 'first' is true if first data of a frame */
59
static void ffm_write_data(AVFormatContext *s,
60
const uint8_t *buf, int size,
61
int64_t dts, int header)
63
FFMContext *ffm = s->priv_data;
66
if (header && ffm->frame_offset == 0) {
67
ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE;
71
/* write as many packets as needed */
73
len = ffm->packet_end - ffm->packet_ptr;
76
memcpy(ffm->packet_ptr, buf, len);
78
ffm->packet_ptr += len;
81
if (ffm->packet_ptr >= ffm->packet_end)
86
static int ffm_write_header(AVFormatContext *s)
88
FFMContext *ffm = s->priv_data;
90
AVIOContext *pb = s->pb;
91
AVCodecContext *codec;
94
ffm->packet_size = FFM_PACKET_SIZE;
97
avio_wl32(pb, MKTAG('F', 'F', 'M', '1'));
98
avio_wb32(pb, ffm->packet_size);
99
avio_wb64(pb, 0); /* current write position */
101
avio_wb32(pb, s->nb_streams);
103
for(i=0;i<s->nb_streams;i++) {
105
bit_rate += st->codec->bit_rate;
107
avio_wb32(pb, bit_rate);
109
/* list of streams */
110
for(i=0;i<s->nb_streams;i++) {
112
avpriv_set_pts_info(st, 64, 1, 1000000);
116
avio_wb32(pb, codec->codec_id);
117
avio_w8(pb, codec->codec_type);
118
avio_wb32(pb, codec->bit_rate);
119
avio_wb32(pb, codec->flags);
120
avio_wb32(pb, codec->flags2);
121
avio_wb32(pb, codec->debug);
123
switch(codec->codec_type) {
124
case AVMEDIA_TYPE_VIDEO:
125
avio_wb32(pb, codec->time_base.num);
126
avio_wb32(pb, codec->time_base.den);
127
avio_wb16(pb, codec->width);
128
avio_wb16(pb, codec->height);
129
avio_wb16(pb, codec->gop_size);
130
avio_wb32(pb, codec->pix_fmt);
131
avio_w8(pb, codec->qmin);
132
avio_w8(pb, codec->qmax);
133
avio_w8(pb, codec->max_qdiff);
134
avio_wb16(pb, (int) (codec->qcompress * 10000.0));
135
avio_wb16(pb, (int) (codec->qblur * 10000.0));
136
avio_wb32(pb, codec->bit_rate_tolerance);
137
avio_put_str(pb, codec->rc_eq ? codec->rc_eq : "tex^qComp");
138
avio_wb32(pb, codec->rc_max_rate);
139
avio_wb32(pb, codec->rc_min_rate);
140
avio_wb32(pb, codec->rc_buffer_size);
141
avio_wb64(pb, av_double2int(codec->i_quant_factor));
142
avio_wb64(pb, av_double2int(codec->b_quant_factor));
143
avio_wb64(pb, av_double2int(codec->i_quant_offset));
144
avio_wb64(pb, av_double2int(codec->b_quant_offset));
145
avio_wb32(pb, codec->dct_algo);
146
avio_wb32(pb, codec->strict_std_compliance);
147
avio_wb32(pb, codec->max_b_frames);
148
avio_wb32(pb, codec->mpeg_quant);
149
avio_wb32(pb, codec->intra_dc_precision);
150
avio_wb32(pb, codec->me_method);
151
avio_wb32(pb, codec->mb_decision);
152
avio_wb32(pb, codec->nsse_weight);
153
avio_wb32(pb, codec->frame_skip_cmp);
154
avio_wb64(pb, av_double2int(codec->rc_buffer_aggressivity));
155
avio_wb32(pb, codec->codec_tag);
156
avio_w8(pb, codec->thread_count);
157
avio_wb32(pb, codec->coder_type);
158
avio_wb32(pb, codec->me_cmp);
159
avio_wb32(pb, codec->me_subpel_quality);
160
avio_wb32(pb, codec->me_range);
161
avio_wb32(pb, codec->keyint_min);
162
avio_wb32(pb, codec->scenechange_threshold);
163
avio_wb32(pb, codec->b_frame_strategy);
164
avio_wb64(pb, av_double2int(codec->qcompress));
165
avio_wb64(pb, av_double2int(codec->qblur));
166
avio_wb32(pb, codec->max_qdiff);
167
avio_wb32(pb, codec->refs);
169
case AVMEDIA_TYPE_AUDIO:
170
avio_wb32(pb, codec->sample_rate);
171
avio_wl16(pb, codec->channels);
172
avio_wl16(pb, codec->frame_size);
177
if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) {
178
avio_wb32(pb, codec->extradata_size);
179
avio_write(pb, codec->extradata, codec->extradata_size);
183
/* flush until end of block reached */
184
while ((avio_tell(pb) % ffm->packet_size) != 0)
189
/* init packet mux */
190
ffm->packet_ptr = ffm->packet;
191
ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE;
192
assert(ffm->packet_end >= ffm->packet);
193
ffm->frame_offset = 0;
195
ffm->first_packet = 1;
200
static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt)
203
uint8_t header[FRAME_HEADER_SIZE+4];
204
int header_size = FRAME_HEADER_SIZE;
207
/* packet size & key_frame */
208
header[0] = pkt->stream_index;
210
if (pkt->flags & AV_PKT_FLAG_KEY)
211
header[1] |= FLAG_KEY_FRAME;
212
AV_WB24(header+2, pkt->size);
213
AV_WB24(header+5, pkt->duration);
214
AV_WB64(header+8, pkt->pts);
215
if (pkt->pts != pkt->dts) {
216
header[1] |= FLAG_DTS;
217
AV_WB32(header+16, pkt->pts - pkt->dts);
220
ffm_write_data(s, header, header_size, dts, 1);
221
ffm_write_data(s, pkt->data, pkt->size, dts, 0);
226
static int ffm_write_trailer(AVFormatContext *s)
228
FFMContext *ffm = s->priv_data;
231
if (ffm->packet_ptr > ffm->packet)
237
AVOutputFormat ff_ffm_muxer = {
239
.long_name = NULL_IF_CONFIG_SMALL("FFM (AVserver live feed)"),
242
.priv_data_size = sizeof(FFMContext),
243
.audio_codec = AV_CODEC_ID_MP2,
244
.video_codec = AV_CODEC_ID_MPEG1VIDEO,
245
.write_header = ffm_write_header,
246
.write_packet = ffm_write_packet,
247
.write_trailer = ffm_write_trailer,
248
.flags = AVFMT_TS_NEGATIVE,