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