Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
ffmenc.c
Go to the documentation of this file.
1
/*
2
* FFM (avserver live feed) muxer
3
* Copyright (c) 2001 Fabrice Bellard
4
*
5
* This file is part of Libav.
6
*
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.
11
*
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.
16
*
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
20
*/
21
22
#include "
libavutil/intreadwrite.h
"
23
#include "
libavutil/intfloat.h
"
24
#include "
avformat.h
"
25
#include "
internal.h
"
26
#include "
ffm.h
"
27
28
static
void
flush_packet
(
AVFormatContext
*s)
29
{
30
FFMContext
*ffm = s->
priv_data
;
31
int
fill_size, h;
32
AVIOContext
*pb = s->
pb
;
33
34
fill_size = ffm->
packet_end
- ffm->
packet_ptr
;
35
memset(ffm->
packet_ptr
, 0, fill_size);
36
37
if
(
avio_tell
(pb) % ffm->
packet_size
)
38
av_abort
();
39
40
/* put header */
41
avio_wb16
(pb,
PACKET_ID
);
42
avio_wb16
(pb, fill_size);
43
avio_wb64
(pb, ffm->
dts
);
44
h = ffm->
frame_offset
;
45
if
(ffm->
first_packet
)
46
h |= 0x8000;
47
avio_wb16
(pb, h);
48
avio_write
(pb, ffm->
packet
, ffm->
packet_end
- ffm->
packet
);
49
avio_flush
(pb);
50
51
/* prepare next packet */
52
ffm->
frame_offset
= 0;
/* no key frame */
53
ffm->
packet_ptr
= ffm->
packet
;
54
ffm->
first_packet
= 0;
55
}
56
57
/* 'first' is true if first data of a frame */
58
static
void
ffm_write_data
(
AVFormatContext
*s,
59
const
uint8_t *buf,
int
size
,
60
int64_t dts,
int
header)
61
{
62
FFMContext
*ffm = s->
priv_data
;
63
int
len
;
64
65
if
(header && ffm->
frame_offset
== 0) {
66
ffm->
frame_offset
= ffm->
packet_ptr
- ffm->
packet
+
FFM_HEADER_SIZE
;
67
ffm->
dts
= dts;
68
}
69
70
/* write as many packets as needed */
71
while
(size > 0) {
72
len = ffm->
packet_end
- ffm->
packet_ptr
;
73
if
(len > size)
74
len =
size
;
75
memcpy(ffm->
packet_ptr
, buf, len);
76
77
ffm->
packet_ptr
+=
len
;
78
buf +=
len
;
79
size -=
len
;
80
if
(ffm->
packet_ptr
>= ffm->
packet_end
)
81
flush_packet
(s);
82
}
83
}
84
85
static
int
ffm_write_header
(
AVFormatContext
*s)
86
{
87
FFMContext
*ffm = s->
priv_data
;
88
AVStream
*st;
89
AVIOContext
*pb = s->
pb
;
90
AVCodecContext
*codec;
91
int
bit_rate, i;
92
93
ffm->
packet_size
=
FFM_PACKET_SIZE
;
94
95
/* header */
96
avio_wl32
(pb,
MKTAG
(
'F'
,
'F'
,
'M'
,
'1'
));
97
avio_wb32
(pb, ffm->
packet_size
);
98
avio_wb64
(pb, 0);
/* current write position */
99
100
avio_wb32
(pb, s->
nb_streams
);
101
bit_rate = 0;
102
for
(i=0;i<s->
nb_streams
;i++) {
103
st = s->
streams
[i];
104
bit_rate += st->
codec
->
bit_rate
;
105
}
106
avio_wb32
(pb, bit_rate);
107
108
/* list of streams */
109
for
(i=0;i<s->
nb_streams
;i++) {
110
st = s->
streams
[i];
111
avpriv_set_pts_info
(st, 64, 1, 1000000);
112
113
codec = st->
codec
;
114
/* generic info */
115
avio_wb32
(pb, codec->
codec_id
);
116
avio_w8
(pb, codec->
codec_type
);
117
avio_wb32
(pb, codec->
bit_rate
);
118
avio_wb32
(pb, codec->
flags
);
119
avio_wb32
(pb, codec->
flags2
);
120
avio_wb32
(pb, codec->
debug
);
121
/* specific info */
122
switch
(codec->
codec_type
) {
123
case
AVMEDIA_TYPE_VIDEO
:
124
avio_wb32
(pb, codec->
time_base
.
num
);
125
avio_wb32
(pb, codec->
time_base
.
den
);
126
avio_wb16
(pb, codec->
width
);
127
avio_wb16
(pb, codec->
height
);
128
avio_wb16
(pb, codec->
gop_size
);
129
avio_wb32
(pb, codec->
pix_fmt
);
130
avio_w8
(pb, codec->
qmin
);
131
avio_w8
(pb, codec->
qmax
);
132
avio_w8
(pb, codec->
max_qdiff
);
133
avio_wb16
(pb, (
int
) (codec->
qcompress
* 10000.0));
134
avio_wb16
(pb, (
int
) (codec->
qblur
* 10000.0));
135
avio_wb32
(pb, codec->
bit_rate_tolerance
);
136
avio_put_str
(pb, codec->
rc_eq
? codec->
rc_eq
:
"tex^qComp"
);
137
avio_wb32
(pb, codec->
rc_max_rate
);
138
avio_wb32
(pb, codec->
rc_min_rate
);
139
avio_wb32
(pb, codec->
rc_buffer_size
);
140
avio_wb64
(pb,
av_double2int
(codec->
i_quant_factor
));
141
avio_wb64
(pb,
av_double2int
(codec->
b_quant_factor
));
142
avio_wb64
(pb,
av_double2int
(codec->
i_quant_offset
));
143
avio_wb64
(pb,
av_double2int
(codec->
b_quant_offset
));
144
avio_wb32
(pb, codec->
dct_algo
);
145
avio_wb32
(pb, codec->
strict_std_compliance
);
146
avio_wb32
(pb, codec->
max_b_frames
);
147
avio_wb32
(pb, codec->
luma_elim_threshold
);
148
avio_wb32
(pb, codec->
chroma_elim_threshold
);
149
avio_wb32
(pb, codec->
mpeg_quant
);
150
avio_wb32
(pb, codec->
intra_dc_precision
);
151
avio_wb32
(pb, codec->
me_method
);
152
avio_wb32
(pb, codec->
mb_decision
);
153
avio_wb32
(pb, codec->
nsse_weight
);
154
avio_wb32
(pb, codec->
frame_skip_cmp
);
155
avio_wb64
(pb,
av_double2int
(codec->
rc_buffer_aggressivity
));
156
avio_wb32
(pb, codec->
codec_tag
);
157
avio_w8
(pb, codec->
thread_count
);
158
avio_wb32
(pb, codec->
coder_type
);
159
avio_wb32
(pb, codec->
me_cmp
);
160
avio_wb32
(pb, codec->
me_subpel_quality
);
161
avio_wb32
(pb, codec->
me_range
);
162
avio_wb32
(pb, codec->
keyint_min
);
163
avio_wb32
(pb, codec->
scenechange_threshold
);
164
avio_wb32
(pb, codec->
b_frame_strategy
);
165
avio_wb64
(pb,
av_double2int
(codec->
qcompress
));
166
avio_wb64
(pb,
av_double2int
(codec->
qblur
));
167
avio_wb32
(pb, codec->
max_qdiff
);
168
avio_wb32
(pb, codec->
refs
);
169
break
;
170
case
AVMEDIA_TYPE_AUDIO
:
171
avio_wb32
(pb, codec->
sample_rate
);
172
avio_wl16
(pb, codec->
channels
);
173
avio_wl16
(pb, codec->
frame_size
);
174
avio_wl16
(pb, codec->
sample_fmt
);
175
break
;
176
default
:
177
return
-1;
178
}
179
if
(codec->
flags
&
CODEC_FLAG_GLOBAL_HEADER
) {
180
avio_wb32
(pb, codec->
extradata_size
);
181
avio_write
(pb, codec->
extradata
, codec->
extradata_size
);
182
}
183
}
184
185
/* flush until end of block reached */
186
while
((
avio_tell
(pb) % ffm->
packet_size
) != 0)
187
avio_w8
(pb, 0);
188
189
avio_flush
(pb);
190
191
/* init packet mux */
192
ffm->
packet_ptr
= ffm->
packet
;
193
ffm->
packet_end
= ffm->
packet
+ ffm->
packet_size
-
FFM_HEADER_SIZE
;
194
assert(ffm->
packet_end
>= ffm->
packet
);
195
ffm->
frame_offset
= 0;
196
ffm->
dts
= 0;
197
ffm->
first_packet
= 1;
198
199
return
0;
200
}
201
202
static
int
ffm_write_packet
(
AVFormatContext
*s,
AVPacket
*pkt)
203
{
204
int64_t dts;
205
uint8_t header[
FRAME_HEADER_SIZE
+4];
206
int
header_size =
FRAME_HEADER_SIZE
;
207
208
dts = pkt->
dts
;
209
/* packet size & key_frame */
210
header[0] = pkt->
stream_index
;
211
header[1] = 0;
212
if
(pkt->
flags
&
AV_PKT_FLAG_KEY
)
213
header[1] |=
FLAG_KEY_FRAME
;
214
AV_WB24
(header+2, pkt->
size
);
215
AV_WB24
(header+5, pkt->
duration
);
216
AV_WB64
(header+8, pkt->
pts
);
217
if
(pkt->
pts
!= pkt->
dts
) {
218
header[1] |=
FLAG_DTS
;
219
AV_WB32
(header+16, pkt->
pts
- pkt->
dts
);
220
header_size += 4;
221
}
222
ffm_write_data
(s, header, header_size, dts, 1);
223
ffm_write_data
(s, pkt->
data
, pkt->
size
, dts, 0);
224
225
return
0;
226
}
227
228
static
int
ffm_write_trailer
(
AVFormatContext
*s)
229
{
230
AVIOContext
*pb = s->
pb
;
231
FFMContext
*ffm = s->
priv_data
;
232
233
/* flush packets */
234
if
(ffm->
packet_ptr
> ffm->
packet
)
235
flush_packet
(s);
236
237
avio_flush
(pb);
238
239
return
0;
240
}
241
242
AVOutputFormat
ff_ffm_muxer
= {
243
.
name
=
"ffm"
,
244
.long_name =
NULL_IF_CONFIG_SMALL
(
"FFM (AVserver live feed) format"
),
245
.mime_type =
""
,
246
.extensions =
"ffm"
,
247
.priv_data_size =
sizeof
(
FFMContext
),
248
.audio_codec =
CODEC_ID_MP2
,
249
.video_codec =
CODEC_ID_MPEG1VIDEO
,
250
.
write_header
=
ffm_write_header
,
251
.
write_packet
=
ffm_write_packet
,
252
.
write_trailer
=
ffm_write_trailer
,
253
};