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