Mercurial > libavformat.hg
annotate ffmenc.c @ 6142:bd851edc58ac libavformat
RTMP: Return from rtmp_read as soon as some data is available
Earlier, the function only returned when the enough data to fill the
requested buffer was available. This lead to high latency when receiving
low-bandwidth streams.
author | mstorsjo |
---|---|
date | Fri, 18 Jun 2010 12:02:51 +0000 |
parents | 11bb10c37225 |
children |
rev | line source |
---|---|
0 | 1 /* |
3348 | 2 * FFM (ffserver live feed) muxer |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4201
diff
changeset
|
3 * Copyright (c) 2001 Fabrice Bellard |
0 | 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 |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
3731
diff
changeset
|
22 #include "libavutil/intreadwrite.h" |
0 | 23 #include "avformat.h" |
3348 | 24 #include "ffm.h" |
0 | 25 |
26 static void flush_packet(AVFormatContext *s) | |
27 { | |
28 FFMContext *ffm = s->priv_data; | |
29 int fill_size, h; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2222
diff
changeset
|
30 ByteIOContext *pb = s->pb; |
0 | 31 |
32 fill_size = ffm->packet_end - ffm->packet_ptr; | |
33 memset(ffm->packet_ptr, 0, fill_size); | |
34 | |
885 | 35 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
|
36 av_abort(); |
54e915169d48
Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents:
277
diff
changeset
|
37 |
0 | 38 /* put header */ |
39 put_be16(pb, PACKET_ID); | |
40 put_be16(pb, fill_size); | |
3492 | 41 put_be64(pb, ffm->dts); |
0 | 42 h = ffm->frame_offset; |
43 if (ffm->first_packet) | |
44 h |= 0x8000; | |
45 put_be16(pb, h); | |
46 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
|
47 put_flush_packet(pb); |
0 | 48 |
49 /* prepare next packet */ | |
50 ffm->frame_offset = 0; /* no key frame */ | |
51 ffm->packet_ptr = ffm->packet; | |
52 ffm->first_packet = 0; | |
53 } | |
54 | |
55 /* 'first' is true if first data of a frame */ | |
56 static void ffm_write_data(AVFormatContext *s, | |
241 | 57 const uint8_t *buf, int size, |
3492 | 58 int64_t dts, int header) |
0 | 59 { |
60 FFMContext *ffm = s->priv_data; | |
61 int len; | |
62 | |
3488
222810cefa11
do not reset ffm pts, this avoids setting last pts to 0 and screwing up seeking
bcoudurier
parents:
3443
diff
changeset
|
63 if (header && ffm->frame_offset == 0) { |
0 | 64 ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE; |
3492 | 65 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
|
66 } |
0 | 67 |
68 /* write as many packets as needed */ | |
69 while (size > 0) { | |
70 len = ffm->packet_end - ffm->packet_ptr; | |
71 if (len > size) | |
72 len = size; | |
73 memcpy(ffm->packet_ptr, buf, len); | |
74 | |
75 ffm->packet_ptr += len; | |
76 buf += len; | |
77 size -= len; | |
3490 | 78 if (ffm->packet_ptr >= ffm->packet_end) |
0 | 79 flush_packet(s); |
80 } | |
81 } | |
82 | |
83 static int ffm_write_header(AVFormatContext *s) | |
84 { | |
85 FFMContext *ffm = s->priv_data; | |
86 AVStream *st; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2222
diff
changeset
|
87 ByteIOContext *pb = s->pb; |
0 | 88 AVCodecContext *codec; |
89 int bit_rate, i; | |
90 | |
91 ffm->packet_size = FFM_PACKET_SIZE; | |
92 | |
93 /* 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
|
94 put_le32(pb, MKTAG('F', 'F', 'M', '1')); |
0 | 95 put_be32(pb, ffm->packet_size); |
4756
d426504e401b
do not write ffm write index by default, detect if file is being written and return EOF
bcoudurier
parents:
4251
diff
changeset
|
96 put_be64(pb, 0); /* current write position */ |
0 | 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) { | |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5463
diff
changeset
|
122 case AVMEDIA_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); |
5385
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
157 put_be32(pb, codec->coder_type); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
158 put_be32(pb, codec->me_cmp); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
159 put_be32(pb, codec->partitions); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
160 put_be32(pb, codec->me_subpel_quality); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
161 put_be32(pb, codec->me_range); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
162 put_be32(pb, codec->keyint_min); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
163 put_be32(pb, codec->scenechange_threshold); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
164 put_be32(pb, codec->b_frame_strategy); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
165 put_be64(pb, av_dbl2int(codec->qcompress)); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
166 put_be64(pb, av_dbl2int(codec->qblur)); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
167 put_be32(pb, codec->max_qdiff); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
168 put_be32(pb, codec->refs); |
de6eb16c2b5b
Update ffserver to include all basic x264 parameters in .ffm files.
darkshikari
parents:
4756
diff
changeset
|
169 put_be32(pb, codec->directpred); |
0 | 170 break; |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5463
diff
changeset
|
171 case AVMEDIA_TYPE_AUDIO: |
0 | 172 put_be32(pb, codec->sample_rate); |
173 put_le16(pb, codec->channels); | |
174 put_le16(pb, codec->frame_size); | |
5463
08abadf5350b
Fix breakage introduced by setting the sample_fmt to SAMPLE_FMT_NONE (r20623). This makes
banan
parents:
5385
diff
changeset
|
175 put_le16(pb, codec->sample_fmt); |
0 | 176 break; |
177 default: | |
537 | 178 return -1; |
0 | 179 } |
3441 | 180 if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { |
181 put_be32(pb, codec->extradata_size); | |
182 put_buffer(pb, codec->extradata, codec->extradata_size); | |
183 } | |
0 | 184 } |
185 | |
186 /* flush until end of block reached */ | |
187 while ((url_ftell(pb) % ffm->packet_size) != 0) | |
188 put_byte(pb, 0); | |
189 | |
190 put_flush_packet(pb); | |
191 | |
192 /* init packet mux */ | |
193 ffm->packet_ptr = ffm->packet; | |
194 ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE; | |
537 | 195 assert(ffm->packet_end >= ffm->packet); |
0 | 196 ffm->frame_offset = 0; |
3492 | 197 ffm->dts = 0; |
0 | 198 ffm->first_packet = 1; |
199 | |
200 return 0; | |
201 } | |
202 | |
468 | 203 static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt) |
0 | 204 { |
3491 | 205 int64_t dts; |
3527 | 206 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
|
207 int header_size = FRAME_HEADER_SIZE; |
0 | 208 |
3491 | 209 dts = s->timestamp + pkt->dts; |
0 | 210 /* packet size & key_frame */ |
468 | 211 header[0] = pkt->stream_index; |
0 | 212 header[1] = 0; |
5913
11bb10c37225
Replace all occurences of PKT_FLAG_KEY with AV_PKT_FLAG_KEY.
cehoyos
parents:
5910
diff
changeset
|
213 if (pkt->flags & AV_PKT_FLAG_KEY) |
0 | 214 header[1] |= FLAG_KEY_FRAME; |
3312 | 215 AV_WB24(header+2, pkt->size); |
3310 | 216 AV_WB24(header+5, pkt->duration); |
3491 | 217 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
|
218 if (pkt->pts != pkt->dts) { |
a6f4d53b738d
pass dts and pts through ffm, should fix streaming b frames
bcoudurier
parents:
3441
diff
changeset
|
219 header[1] |= FLAG_DTS; |
a6f4d53b738d
pass dts and pts through ffm, should fix streaming b frames
bcoudurier
parents:
3441
diff
changeset
|
220 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
|
221 header_size += 4; |
a6f4d53b738d
pass dts and pts through ffm, should fix streaming b frames
bcoudurier
parents:
3441
diff
changeset
|
222 } |
3491 | 223 ffm_write_data(s, header, header_size, dts, 1); |
224 ffm_write_data(s, pkt->data, pkt->size, dts, 0); | |
0 | 225 |
226 return 0; | |
227 } | |
228 | |
229 static int ffm_write_trailer(AVFormatContext *s) | |
230 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2222
diff
changeset
|
231 ByteIOContext *pb = s->pb; |
0 | 232 FFMContext *ffm = s->priv_data; |
233 | |
234 /* flush packets */ | |
235 if (ffm->packet_ptr > ffm->packet) | |
236 flush_packet(s); | |
237 | |
238 put_flush_packet(pb); | |
239 | |
240 return 0; | |
241 } | |
242 | |
1169 | 243 AVOutputFormat ffm_muxer = { |
0 | 244 "ffm", |
3603 | 245 NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"), |
0 | 246 "", |
247 "ffm", | |
248 sizeof(FFMContext), | |
249 /* not really used */ | |
250 CODEC_ID_MP2, | |
251 CODEC_ID_MPEG1VIDEO, | |
252 ffm_write_header, | |
253 ffm_write_packet, | |
254 ffm_write_trailer, | |
255 }; |