FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
ffmenc.c
Go to the documentation of this file.
1
/*
2
* FFM (ffserver live feed) muxer
3
* Copyright (c) 2001 Fabrice Bellard
4
*
5
* This file is part of FFmpeg.
6
*
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.
11
*
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.
16
*
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
20
*/
21
22
#include "
libavutil/intreadwrite.h
"
23
#include "
libavutil/intfloat.h
"
24
#include "
libavutil/avassert.h
"
25
#include "
libavutil/parseutils.h
"
26
#include "
libavutil/opt.h
"
27
#include "
avformat.h
"
28
#include "
internal.h
"
29
#include "
ffm.h
"
30
31
static
void
flush_packet
(
AVFormatContext
*
s
)
32
{
33
FFMContext
*ffm = s->
priv_data
;
34
int
fill_size, h;
35
AVIOContext
*pb = s->
pb
;
36
37
fill_size = ffm->
packet_end
- ffm->
packet_ptr
;
38
memset(ffm->
packet_ptr
, 0, fill_size);
39
40
av_assert1
(
avio_tell
(pb) % ffm->
packet_size
== 0);
41
42
/* put header */
43
avio_wb16
(pb,
PACKET_ID
);
44
avio_wb16
(pb, fill_size);
45
avio_wb64
(pb, ffm->
dts
);
46
h = ffm->
frame_offset
;
47
if
(ffm->
first_packet
)
48
h |= 0x8000;
49
avio_wb16
(pb, h);
50
avio_write
(pb, ffm->
packet
, ffm->
packet_end
- ffm->
packet
);
51
avio_flush
(pb);
52
53
/* prepare next packet */
54
ffm->
frame_offset
= 0;
/* no key frame */
55
ffm->
packet_ptr
= ffm->
packet
;
56
ffm->
first_packet
= 0;
57
}
58
59
/* 'first' is true if first data of a frame */
60
static
void
ffm_write_data
(
AVFormatContext
*
s
,
61
const
uint8_t
*
buf
,
int
size
,
62
int64_t dts,
int
header
)
63
{
64
FFMContext
*ffm = s->
priv_data
;
65
int
len
;
66
67
if
(header && ffm->
frame_offset
== 0) {
68
ffm->
frame_offset
= ffm->
packet_ptr
- ffm->
packet
+
FFM_HEADER_SIZE
;
69
ffm->
dts
= dts;
70
}
71
72
/* write as many packets as needed */
73
while
(size > 0) {
74
len = ffm->
packet_end
- ffm->
packet_ptr
;
75
if
(len > size)
76
len =
size
;
77
memcpy(ffm->
packet_ptr
, buf, len);
78
79
ffm->
packet_ptr
+=
len
;
80
buf +=
len
;
81
size -=
len
;
82
if
(ffm->
packet_ptr
>= ffm->
packet_end
)
83
flush_packet
(s);
84
}
85
}
86
87
static
void
write_header_chunk
(
AVIOContext
*pb,
AVIOContext
*dpb,
unsigned
id
)
88
{
89
uint8_t
*dyn_buf;
90
int
dyn_size=
avio_close_dyn_buf
(dpb, &dyn_buf);
91
avio_wb32
(pb,
id
);
92
avio_wb32
(pb, dyn_size);
93
avio_write
(pb, dyn_buf, dyn_size);
94
av_free
(dyn_buf);
95
}
96
97
static
int
ffm_write_header_codec_private_ctx
(
AVIOContext
*pb,
AVCodecContext
*ctx,
int
type
)
98
{
99
AVIOContext
*tmp;
100
char
*
buf
= NULL;
101
int
ret
;
102
const
AVCodec
*enc = ctx->
codec
? ctx->
codec
:
avcodec_find_encoder
(ctx->
codec_id
);
103
104
if
(!enc)
105
return
AVERROR
(EINVAL);
106
if
(ctx->
priv_data
&& enc->
priv_class
&& enc->
priv_data_size
) {
107
if
((ret =
av_opt_serialize
(ctx->
priv_data
,
AV_OPT_FLAG_ENCODING_PARAM
| type,
108
AV_OPT_SERIALIZE_SKIP_DEFAULTS
, &buf,
'='
,
','
)) < 0)
109
return
ret
;
110
if
(buf && strlen(buf)) {
111
if
(
avio_open_dyn_buf
(&tmp) < 0) {
112
av_free
(buf);
113
return
AVERROR
(ENOMEM);
114
}
115
avio_put_str
(tmp, buf);
116
write_header_chunk
(pb, tmp,
MKBETAG
(
'C'
,
'P'
,
'R'
,
'V'
));
117
}
118
av_free
(buf);
119
}
120
return
0;
121
}
122
123
static
int
ffm_write_header_codec_ctx
(
AVIOContext
*pb,
AVCodecContext
*ctx,
unsigned
tag
,
int
type
)
124
{
125
AVIOContext
*tmp;
126
char
*
buf
= NULL;
127
uint8_t
*p = NULL;
128
int
ret
, need_coma = 0;
129
130
#define SKIP_DEFAULTS AV_OPT_SERIALIZE_SKIP_DEFAULTS
131
#define OPT_FLAGS_EXACT AV_OPT_SERIALIZE_OPT_FLAGS_EXACT
132
#define ENC AV_OPT_FLAG_ENCODING_PARAM
133
134
if
(
avio_open_dyn_buf
(&tmp) < 0)
135
return
AVERROR
(ENOMEM);
136
if
((ret =
av_opt_serialize
(ctx,
ENC
| type,
SKIP_DEFAULTS
, &buf,
'='
,
','
)) < 0)
137
goto
fail;
138
if
(buf && strlen(buf)) {
139
avio_write
(tmp, buf, strlen(buf));
140
av_free
(buf);
141
need_coma = 1;
142
}
143
if
((ret =
av_opt_serialize
(ctx, 0,
SKIP_DEFAULTS
|
OPT_FLAGS_EXACT
, &buf,
'='
,
','
)) < 0)
144
goto
fail;
145
if
(buf && strlen(buf)) {
146
if
(need_coma)
147
avio_w8
(tmp,
','
);
148
avio_write
(tmp, buf, strlen(buf));
149
av_free
(buf);
150
}
151
avio_w8
(tmp, 0);
152
write_header_chunk
(pb, tmp, tag);
153
return
0;
154
fail:
155
av_free
(buf);
156
avio_close_dyn_buf
(tmp, &p);
157
av_free
(p);
158
return
ret
;
159
160
#undef SKIP_DEFAULTS
161
#undef OPT_FLAGS_EXACT
162
#undef ENC
163
}
164
165
static
int
ffm_write_recommended_config
(
AVIOContext
*pb,
AVCodecContext
*ctx,
unsigned
tag
,
166
const
char
*configuration)
167
{
168
int
ret
;
169
const
AVCodec
*enc = ctx->
codec
? ctx->
codec
:
avcodec_find_encoder
(ctx->
codec_id
);
170
AVIOContext
*tmp;
171
AVDictionaryEntry
*t = NULL;
172
AVDictionary
*all = NULL, *comm = NULL, *prv = NULL;
173
char
*
buf
= NULL;
174
175
if
(!enc || !enc->
priv_class
|| !enc->
priv_data_size
) {
176
/* codec is not known/has no private options, so save everything as common options */
177
if
(
avio_open_dyn_buf
(&tmp) < 0)
178
return
AVERROR
(ENOMEM);
179
avio_put_str
(tmp, configuration);
180
write_header_chunk
(pb, tmp, tag);
181
return
0;
182
}
183
184
if
((ret =
av_dict_parse_string
(&all, configuration,
"="
,
","
, 0)) < 0)
185
return
ret
;
186
187
while
((t =
av_dict_get
(all,
""
, t,
AV_DICT_IGNORE_SUFFIX
))) {
188
if
(
av_opt_find
((
void
*)&enc->
priv_class
, t->
key
, NULL, 0,
AV_OPT_SEARCH_FAKE_OBJ
)) {
189
if
((ret =
av_dict_set
(&prv, t->
key
, t->
value
, 0)) < 0)
190
goto
fail;
191
}
else
if
((ret =
av_dict_set
(&comm, t->
key
, t->
value
, 0)) < 0)
192
goto
fail;
193
}
194
195
if
(comm) {
196
if
((ret =
av_dict_get_string
(comm, &buf,
'='
,
','
)) < 0 ||
197
(ret =
avio_open_dyn_buf
(&tmp)) < 0)
198
goto
fail;
199
avio_put_str
(tmp, buf);
200
av_freep
(&buf);
201
write_header_chunk
(pb, tmp, tag);
202
}
203
if
(prv) {
204
if
((ret =
av_dict_get_string
(prv, &buf,
'='
,
','
)) < 0 ||
205
(ret =
avio_open_dyn_buf
(&tmp)) < 0)
206
goto
fail;
207
avio_put_str
(tmp, buf);
208
write_header_chunk
(pb, tmp,
MKBETAG
(
'C'
,
'P'
,
'R'
,
'V'
));
209
}
210
211
fail:
212
av_free
(buf);
213
av_dict_free
(&all);
214
av_dict_free
(&comm);
215
av_dict_free
(&prv);
216
return
ret
;
217
}
218
219
static
int
ffm_write_header
(
AVFormatContext
*
s
)
220
{
221
FFMContext
*ffm = s->
priv_data
;
222
AVDictionaryEntry
*t;
223
AVStream
*st;
224
AVIOContext
*pb = s->
pb
;
225
AVCodecContext
*codec;
226
int
bit_rate, i,
ret
;
227
228
if
(t =
av_dict_get
(s->
metadata
,
"creation_time"
, NULL, 0)) {
229
ret =
av_parse_time
(&ffm->
start_time
, t->
value
, 0);
230
if
(ret < 0)
231
return
ret
;
232
}
233
234
ffm->
packet_size
=
FFM_PACKET_SIZE
;
235
236
/* header */
237
avio_wl32
(pb,
MKTAG
(
'F'
,
'F'
,
'M'
,
'2'
));
238
avio_wb32
(pb, ffm->
packet_size
);
239
avio_wb64
(pb, 0);
/* current write position */
240
241
if
(
avio_open_dyn_buf
(&pb) < 0)
242
return
AVERROR
(ENOMEM);
243
244
avio_wb32
(pb, s->
nb_streams
);
245
bit_rate = 0;
246
for
(i=0;i<s->
nb_streams
;i++) {
247
st = s->
streams
[i];
248
bit_rate += st->
codec
->
bit_rate
;
249
}
250
avio_wb32
(pb, bit_rate);
251
252
write_header_chunk
(s->
pb
, pb,
MKBETAG
(
'M'
,
'A'
,
'I'
,
'N'
));
253
254
/* list of streams */
255
for
(i=0;i<s->
nb_streams
;i++) {
256
st = s->
streams
[i];
257
avpriv_set_pts_info
(st, 64, 1, 1000000);
258
if
(
avio_open_dyn_buf
(&pb) < 0)
259
return
AVERROR
(ENOMEM);
260
261
codec = st->
codec
;
262
/* generic info */
263
avio_wb32
(pb, codec->
codec_id
);
264
avio_w8
(pb, codec->
codec_type
);
265
avio_wb32
(pb, codec->
bit_rate
);
266
avio_wb32
(pb, codec->
flags
);
267
avio_wb32
(pb, codec->
flags2
);
268
avio_wb32
(pb, codec->
debug
);
269
if
(codec->
flags
&
CODEC_FLAG_GLOBAL_HEADER
) {
270
avio_wb32
(pb, codec->
extradata_size
);
271
avio_write
(pb, codec->
extradata
, codec->
extradata_size
);
272
}
273
write_header_chunk
(s->
pb
, pb,
MKBETAG
(
'C'
,
'O'
,
'M'
,
'M'
));
274
/* specific info */
275
switch
(codec->
codec_type
) {
276
case
AVMEDIA_TYPE_VIDEO
:
277
if
(st->
recommended_encoder_configuration
) {
278
av_log
(NULL,
AV_LOG_DEBUG
,
"writing recommended configuration: %s\n"
,
279
st->
recommended_encoder_configuration
);
280
if
((ret =
ffm_write_recommended_config
(s->
pb
, codec,
MKBETAG
(
'S'
,
'2'
,
'V'
,
'I'
),
281
st->
recommended_encoder_configuration
)) < 0)
282
return
ret
;
283
}
else
if
((ret =
ffm_write_header_codec_ctx
(s->
pb
, codec,
MKBETAG
(
'S'
,
'2'
,
'V'
,
'I'
),
AV_OPT_FLAG_VIDEO_PARAM
)) < 0 ||
284
(ret =
ffm_write_header_codec_private_ctx
(s->
pb
, codec,
AV_OPT_FLAG_VIDEO_PARAM
)) < 0)
285
return
ret
;
286
break
;
287
case
AVMEDIA_TYPE_AUDIO
:
288
if
(st->
recommended_encoder_configuration
) {
289
av_log
(NULL,
AV_LOG_DEBUG
,
"writing recommended configuration: %s\n"
,
290
st->
recommended_encoder_configuration
);
291
if
((ret =
ffm_write_recommended_config
(s->
pb
, codec,
MKBETAG
(
'S'
,
'2'
,
'A'
,
'U'
),
292
st->
recommended_encoder_configuration
)) < 0)
293
return
ret
;
294
}
else
if
((ret =
ffm_write_header_codec_ctx
(s->
pb
, codec,
MKBETAG
(
'S'
,
'2'
,
'A'
,
'U'
),
AV_OPT_FLAG_AUDIO_PARAM
)) < 0 ||
295
(ret =
ffm_write_header_codec_private_ctx
(s->
pb
, codec,
AV_OPT_FLAG_AUDIO_PARAM
)) < 0)
296
return
ret
;
297
break
;
298
default
:
299
return
-1;
300
}
301
}
302
pb = s->
pb
;
303
304
avio_wb64
(pb, 0);
// end of header
305
306
/* flush until end of block reached */
307
while
((
avio_tell
(pb) % ffm->
packet_size
) != 0)
308
avio_w8
(pb, 0);
309
310
avio_flush
(pb);
311
312
/* init packet mux */
313
ffm->
packet_ptr
= ffm->
packet
;
314
ffm->
packet_end
= ffm->
packet
+ ffm->
packet_size
-
FFM_HEADER_SIZE
;
315
av_assert0
(ffm->
packet_end
>= ffm->
packet
);
316
ffm->
frame_offset
= 0;
317
ffm->
dts
= 0;
318
ffm->
first_packet
= 1;
319
320
return
0;
321
}
322
323
static
int
ffm_write_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
324
{
325
FFMContext
*ffm = s->
priv_data
;
326
int64_t dts;
327
uint8_t
header
[
FRAME_HEADER_SIZE
+4];
328
int
header_size =
FRAME_HEADER_SIZE
;
329
330
dts = ffm->
start_time
+ pkt->
dts
;
331
/* packet size & key_frame */
332
header[0] = pkt->
stream_index
;
333
header[1] = 0;
334
if
(pkt->
flags
&
AV_PKT_FLAG_KEY
)
335
header[1] |=
FLAG_KEY_FRAME
;
336
AV_WB24
(header+2, pkt->
size
);
337
AV_WB24
(header+5, pkt->
duration
);
338
AV_WB64
(header+8, ffm->
start_time
+ pkt->
pts
);
339
if
(pkt->
pts
!= pkt->
dts
) {
340
header[1] |=
FLAG_DTS
;
341
AV_WB32
(header+16, pkt->
pts
- pkt->
dts
);
342
header_size += 4;
343
}
344
ffm_write_data
(s, header, header_size, dts, 1);
345
ffm_write_data
(s, pkt->
data
, pkt->
size
, dts, 0);
346
347
return
0;
348
}
349
350
static
int
ffm_write_trailer
(
AVFormatContext
*
s
)
351
{
352
FFMContext
*ffm = s->
priv_data
;
353
354
/* flush packets */
355
if
(ffm->
packet_ptr
> ffm->
packet
)
356
flush_packet
(s);
357
358
return
0;
359
}
360
361
AVOutputFormat
ff_ffm_muxer
= {
362
.
name
=
"ffm"
,
363
.long_name =
NULL_IF_CONFIG_SMALL
(
"FFM (FFserver live feed)"
),
364
.extensions =
"ffm"
,
365
.priv_data_size =
sizeof
(
FFMContext
),
366
.audio_codec =
AV_CODEC_ID_MP2
,
367
.video_codec =
AV_CODEC_ID_MPEG1VIDEO
,
368
.
write_header
=
ffm_write_header
,
369
.
write_packet
=
ffm_write_packet
,
370
.
write_trailer
=
ffm_write_trailer
,
371
.
flags
=
AVFMT_TS_NEGATIVE
,
372
};
Generated on Fri Dec 5 2014 04:42:11 for FFmpeg by
1.8.2