Mercurial > libavformat.hg
annotate ffmenc.c @ 3754:8d267b43eaba libavformat
Move malloc() down until after all initializations, so that the resource is
only allocated if initialization worked. This means that on failure, we
don't have to deallocate it.
author | rbultje |
---|---|
date | Sat, 23 Aug 2008 18:46:30 +0000 |
parents | d8d0fc55a7b8 |
children | 7d2f3f1b68d8 |
rev | line source |
---|---|
0 | 1 /* |
3348 | 2 * FFM (ffserver live feed) muxer |
0 | 3 * Copyright (c) 2001 Fabrice Bellard. |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 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 | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
887
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
3348 | 21 |
0 | 22 #include "avformat.h" |
3348 | 23 #include "ffm.h" |
0 | 24 |
25 static void flush_packet(AVFormatContext *s) | |
26 { | |
27 FFMContext *ffm = s->priv_data; | |
28 int fill_size, h; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2222
diff
changeset
|
29 ByteIOContext *pb = s->pb; |
0 | 30 |
31 fill_size = ffm->packet_end - ffm->packet_ptr; | |
32 memset(ffm->packet_ptr, 0, fill_size); | |
33 | |
885 | 34 if (url_ftell(pb) % ffm->packet_size) |
318
54e915169d48
Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents:
277
diff
changeset
|
35 av_abort(); |
54e915169d48
Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents:
277
diff
changeset
|
36 |
0 | 37 /* put header */ |
38 put_be16(pb, PACKET_ID); | |
39 put_be16(pb, fill_size); | |
3492 | 40 put_be64(pb, ffm->dts); |
0 | 41 h = ffm->frame_offset; |
42 if (ffm->first_packet) | |
43 h |= 0x8000; | |
44 put_be16(pb, h); | |
45 put_buffer(pb, ffm->packet, ffm->packet_end - ffm->packet); | |
751
dcb459ca11eb
Flush the ffm packet to the wire (or file) whenever we flush the ffm packet.
philipjsg
parents:
744
diff
changeset
|
46 put_flush_packet(pb); |
0 | 47 |
48 /* prepare next packet */ | |
49 ffm->frame_offset = 0; /* no key frame */ | |
50 ffm->packet_ptr = ffm->packet; | |
51 ffm->first_packet = 0; | |
52 } | |
53 | |
54 /* 'first' is true if first data of a frame */ | |
55 static void ffm_write_data(AVFormatContext *s, | |
241 | 56 const uint8_t *buf, int size, |
3492 | 57 int64_t dts, int header) |
0 | 58 { |
59 FFMContext *ffm = s->priv_data; | |
60 int len; | |
61 | |
3488
222810cefa11
do not reset ffm pts, this avoids setting last pts to 0 and screwing up seeking
bcoudurier
parents:
3443
diff
changeset
|
62 if (header && ffm->frame_offset == 0) { |
0 | 63 ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE; |
3492 | 64 ffm->dts = dts; |
3488
222810cefa11
do not reset ffm pts, this avoids setting last pts to 0 and screwing up seeking
bcoudurier
parents:
3443
diff
changeset
|
65 } |
0 | 66 |
67 /* write as many packets as needed */ | |
68 while (size > 0) { | |
69 len = ffm->packet_end - ffm->packet_ptr; | |
70 if (len > size) | |
71 len = size; | |
72 memcpy(ffm->packet_ptr, buf, len); | |
73 | |
74 ffm->packet_ptr += len; | |
75 buf += len; | |
76 size -= len; | |
3490 | 77 if (ffm->packet_ptr >= ffm->packet_end) |
0 | 78 flush_packet(s); |
79 } | |
80 } | |
81 | |
82 static int ffm_write_header(AVFormatContext *s) | |
83 { | |
84 FFMContext *ffm = s->priv_data; | |
85 AVStream *st; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2222
diff
changeset
|
86 ByteIOContext *pb = s->pb; |
0 | 87 AVCodecContext *codec; |
88 int bit_rate, i; | |
89 | |
90 ffm->packet_size = FFM_PACKET_SIZE; | |
91 | |
92 /* header */ | |
862
aa0abab5e320
fix feed read_header, avoid using put_tag in write_header, to be consistent with read_header, also some minor cosmetics
alex
parents:
858
diff
changeset
|
93 put_le32(pb, MKTAG('F', 'F', 'M', '1')); |
0 | 94 put_be32(pb, ffm->packet_size); |
95 /* XXX: store write position in other file ? */ | |
96 put_be64(pb, ffm->packet_size); /* current write position */ | |
97 | |
98 put_be32(pb, s->nb_streams); | |
99 bit_rate = 0; | |
100 for(i=0;i<s->nb_streams;i++) { | |
101 st = s->streams[i]; | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
102 bit_rate += st->codec->bit_rate; |
0 | 103 } |
104 put_be32(pb, bit_rate); | |
105 | |
106 /* list of streams */ | |
107 for(i=0;i<s->nb_streams;i++) { | |
108 st = s->streams[i]; | |
502
813b0119a98e
ffserver fixes by (Koos Vriezen <koos.vriezen at xs4all dot nl>)
michael
parents:
468
diff
changeset
|
109 av_set_pts_info(st, 64, 1, 1000000); |
0 | 110 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
111 codec = st->codec; |
0 | 112 /* generic info */ |
113 put_be32(pb, codec->codec_id); | |
114 put_byte(pb, codec->codec_type); | |
115 put_be32(pb, codec->bit_rate); | |
887 | 116 put_be32(pb, st->quality); |
0 | 117 put_be32(pb, codec->flags); |
744
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
118 put_be32(pb, codec->flags2); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
119 put_be32(pb, codec->debug); |
0 | 120 /* specific info */ |
121 switch(codec->codec_type) { | |
122 case CODEC_TYPE_VIDEO: | |
743 | 123 put_be32(pb, codec->time_base.num); |
124 put_be32(pb, codec->time_base.den); | |
0 | 125 put_be16(pb, codec->width); |
126 put_be16(pb, codec->height); | |
127 put_be16(pb, codec->gop_size); | |
744
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
128 put_be32(pb, codec->pix_fmt); |
0 | 129 put_byte(pb, codec->qmin); |
130 put_byte(pb, codec->qmax); | |
131 put_byte(pb, codec->max_qdiff); | |
132 put_be16(pb, (int) (codec->qcompress * 10000.0)); | |
133 put_be16(pb, (int) (codec->qblur * 10000.0)); | |
134 put_be32(pb, codec->bit_rate_tolerance); | |
3731 | 135 put_strz(pb, codec->rc_eq ? codec->rc_eq : "tex^qComp"); |
0 | 136 put_be32(pb, codec->rc_max_rate); |
137 put_be32(pb, codec->rc_min_rate); | |
138 put_be32(pb, codec->rc_buffer_size); | |
823 | 139 put_be64(pb, av_dbl2int(codec->i_quant_factor)); |
140 put_be64(pb, av_dbl2int(codec->b_quant_factor)); | |
141 put_be64(pb, av_dbl2int(codec->i_quant_offset)); | |
142 put_be64(pb, av_dbl2int(codec->b_quant_offset)); | |
0 | 143 put_be32(pb, codec->dct_algo); |
744
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
144 put_be32(pb, codec->strict_std_compliance); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
145 put_be32(pb, codec->max_b_frames); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
146 put_be32(pb, codec->luma_elim_threshold); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
147 put_be32(pb, codec->chroma_elim_threshold); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
148 put_be32(pb, codec->mpeg_quant); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
149 put_be32(pb, codec->intra_dc_precision); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
150 put_be32(pb, codec->me_method); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
151 put_be32(pb, codec->mb_decision); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
152 put_be32(pb, codec->nsse_weight); |
da5b3b9e898e
Add in many fields that have been added to the Codec structure. This means
philipjsg
parents:
743
diff
changeset
|
153 put_be32(pb, codec->frame_skip_cmp); |
823 | 154 put_be64(pb, av_dbl2int(codec->rc_buffer_aggressivity)); |
1809
491581a2b9a7
codec_tag settable via VideoTag, and transmit codec_tag in ffm
alex
parents:
1787
diff
changeset
|
155 put_be32(pb, codec->codec_tag); |
3489 | 156 put_byte(pb, codec->thread_count); |
0 | 157 break; |
158 case CODEC_TYPE_AUDIO: | |
159 put_be32(pb, codec->sample_rate); | |
160 put_le16(pb, codec->channels); | |
161 put_le16(pb, codec->frame_size); | |
162 break; | |
163 default: | |
537 | 164 return -1; |
0 | 165 } |
3441 | 166 if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { |
167 put_be32(pb, codec->extradata_size); | |
168 put_buffer(pb, codec->extradata, codec->extradata_size); | |
169 } | |
0 | 170 } |
171 | |
172 /* flush until end of block reached */ | |
173 while ((url_ftell(pb) % ffm->packet_size) != 0) | |
174 put_byte(pb, 0); | |
175 | |
176 put_flush_packet(pb); | |
177 | |
178 /* init packet mux */ | |
179 ffm->packet_ptr = ffm->packet; | |
180 ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE; | |
537 | 181 assert(ffm->packet_end >= ffm->packet); |
0 | 182 ffm->frame_offset = 0; |
3492 | 183 ffm->dts = 0; |
0 | 184 ffm->first_packet = 1; |
185 | |
186 return 0; | |
187 } | |
188 | |
468 | 189 static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt) |
0 | 190 { |
3491 | 191 int64_t dts; |
3527 | 192 uint8_t header[FRAME_HEADER_SIZE+4]; |
3442
a6f4d53b738d
pass dts and pts through ffm, should fix streaming b frames
bcoudurier
parents:
3441
diff
changeset
|
193 int header_size = FRAME_HEADER_SIZE; |
0 | 194 |
3491 | 195 dts = s->timestamp + pkt->dts; |
0 | 196 /* packet size & key_frame */ |
468 | 197 header[0] = pkt->stream_index; |
0 | 198 header[1] = 0; |
468 | 199 if (pkt->flags & PKT_FLAG_KEY) |
0 | 200 header[1] |= FLAG_KEY_FRAME; |
3312 | 201 AV_WB24(header+2, pkt->size); |
3310 | 202 AV_WB24(header+5, pkt->duration); |
3491 | 203 AV_WB64(header+8, s->timestamp + pkt->pts); |
3442
a6f4d53b738d
pass dts and pts through ffm, should fix streaming b frames
bcoudurier
parents:
3441
diff
changeset
|
204 if (pkt->pts != pkt->dts) { |
a6f4d53b738d
pass dts and pts through ffm, should fix streaming b frames
bcoudurier
parents:
3441
diff
changeset
|
205 header[1] |= FLAG_DTS; |
a6f4d53b738d
pass dts and pts through ffm, should fix streaming b frames
bcoudurier
parents:
3441
diff
changeset
|
206 AV_WB32(header+16, pkt->pts - pkt->dts); |
a6f4d53b738d
pass dts and pts through ffm, should fix streaming b frames
bcoudurier
parents:
3441
diff
changeset
|
207 header_size += 4; |
a6f4d53b738d
pass dts and pts through ffm, should fix streaming b frames
bcoudurier
parents:
3441
diff
changeset
|
208 } |
3491 | 209 ffm_write_data(s, header, header_size, dts, 1); |
210 ffm_write_data(s, pkt->data, pkt->size, dts, 0); | |
0 | 211 |
212 return 0; | |
213 } | |
214 | |
215 static int ffm_write_trailer(AVFormatContext *s) | |
216 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2222
diff
changeset
|
217 ByteIOContext *pb = s->pb; |
0 | 218 FFMContext *ffm = s->priv_data; |
219 | |
220 /* flush packets */ | |
221 if (ffm->packet_ptr > ffm->packet) | |
222 flush_packet(s); | |
223 | |
224 put_flush_packet(pb); | |
225 | |
226 if (!url_is_streamed(pb)) { | |
65 | 227 int64_t size; |
0 | 228 /* update the write offset */ |
229 size = url_ftell(pb); | |
230 url_fseek(pb, 8, SEEK_SET); | |
231 put_be64(pb, size); | |
232 put_flush_packet(pb); | |
233 } | |
234 | |
235 return 0; | |
236 } | |
237 | |
1169 | 238 AVOutputFormat ffm_muxer = { |
0 | 239 "ffm", |
3603 | 240 NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"), |
0 | 241 "", |
242 "ffm", | |
243 sizeof(FFMContext), | |
244 /* not really used */ | |
245 CODEC_ID_MP2, | |
246 CODEC_ID_MPEG1VIDEO, | |
247 ffm_write_header, | |
248 ffm_write_packet, | |
249 ffm_write_trailer, | |
250 }; |