ba4fa7c0b7b1f91b21085ef8ba50235537d4bfd3
[ffmpeg.git] / libavformat / ffmenc.c
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 "avformat.h"
23 #include "ffm.h"
24 #include <unistd.h>
25
26 /* disable pts hack for testing */
27 int ffm_nopts = 0;
28
29 static void flush_packet(AVFormatContext *s)
30 {
31     FFMContext *ffm = s->priv_data;
32     int fill_size, h;
33     ByteIOContext *pb = s->pb;
34
35     fill_size = ffm->packet_end - ffm->packet_ptr;
36     memset(ffm->packet_ptr, 0, fill_size);
37
38     if (url_ftell(pb) % ffm->packet_size)
39         av_abort();
40
41     /* put header */
42     put_be16(pb, PACKET_ID);
43     put_be16(pb, fill_size);
44     put_be64(pb, ffm->pts);
45     h = ffm->frame_offset;
46     if (ffm->first_packet)
47         h |= 0x8000;
48     put_be16(pb, h);
49     put_buffer(pb, ffm->packet, ffm->packet_end - ffm->packet);
50     put_flush_packet(pb);
51
52     /* prepare next packet */
53     ffm->frame_offset = 0; /* no key frame */
54     ffm->pts = 0; /* no pts */
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 pts, int first)
63 {
64     FFMContext *ffm = s->priv_data;
65     int len;
66
67     if (first && ffm->frame_offset == 0)
68         ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE;
69     if (first && ffm->pts == 0)
70         ffm->pts = pts;
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             /* special case : no pts in packet : we leave the current one */
84             if (ffm->pts == 0)
85                 ffm->pts = pts;
86
87             flush_packet(s);
88         }
89     }
90 }
91
92 static int ffm_write_header(AVFormatContext *s)
93 {
94     FFMContext *ffm = s->priv_data;
95     AVStream *st;
96     FFMStream *fst;
97     ByteIOContext *pb = s->pb;
98     AVCodecContext *codec;
99     int bit_rate, i;
100
101     ffm->packet_size = FFM_PACKET_SIZE;
102
103     /* header */
104     put_le32(pb, MKTAG('F', 'F', 'M', '1'));
105     put_be32(pb, ffm->packet_size);
106     /* XXX: store write position in other file ? */
107     put_be64(pb, ffm->packet_size); /* current write position */
108
109     put_be32(pb, s->nb_streams);
110     bit_rate = 0;
111     for(i=0;i<s->nb_streams;i++) {
112         st = s->streams[i];
113         bit_rate += st->codec->bit_rate;
114     }
115     put_be32(pb, bit_rate);
116
117     /* list of streams */
118     for(i=0;i<s->nb_streams;i++) {
119         st = s->streams[i];
120         fst = av_mallocz(sizeof(FFMStream));
121         if (!fst)
122             goto fail;
123         av_set_pts_info(st, 64, 1, 1000000);
124         st->priv_data = fst;
125
126         codec = st->codec;
127         /* generic info */
128         put_be32(pb, codec->codec_id);
129         put_byte(pb, codec->codec_type);
130         put_be32(pb, codec->bit_rate);
131         put_be32(pb, st->quality);
132         put_be32(pb, codec->flags);
133         put_be32(pb, codec->flags2);
134         put_be32(pb, codec->debug);
135         /* specific info */
136         switch(codec->codec_type) {
137         case CODEC_TYPE_VIDEO:
138             put_be32(pb, codec->time_base.num);
139             put_be32(pb, codec->time_base.den);
140             put_be16(pb, codec->width);
141             put_be16(pb, codec->height);
142             put_be16(pb, codec->gop_size);
143             put_be32(pb, codec->pix_fmt);
144             put_byte(pb, codec->qmin);
145             put_byte(pb, codec->qmax);
146             put_byte(pb, codec->max_qdiff);
147             put_be16(pb, (int) (codec->qcompress * 10000.0));
148             put_be16(pb, (int) (codec->qblur * 10000.0));
149             put_be32(pb, codec->bit_rate_tolerance);
150             put_strz(pb, codec->rc_eq);
151             put_be32(pb, codec->rc_max_rate);
152             put_be32(pb, codec->rc_min_rate);
153             put_be32(pb, codec->rc_buffer_size);
154             put_be64(pb, av_dbl2int(codec->i_quant_factor));
155             put_be64(pb, av_dbl2int(codec->b_quant_factor));
156             put_be64(pb, av_dbl2int(codec->i_quant_offset));
157             put_be64(pb, av_dbl2int(codec->b_quant_offset));
158             put_be32(pb, codec->dct_algo);
159             put_be32(pb, codec->strict_std_compliance);
160             put_be32(pb, codec->max_b_frames);
161             put_be32(pb, codec->luma_elim_threshold);
162             put_be32(pb, codec->chroma_elim_threshold);
163             put_be32(pb, codec->mpeg_quant);
164             put_be32(pb, codec->intra_dc_precision);
165             put_be32(pb, codec->me_method);
166             put_be32(pb, codec->mb_decision);
167             put_be32(pb, codec->nsse_weight);
168             put_be32(pb, codec->frame_skip_cmp);
169             put_be64(pb, av_dbl2int(codec->rc_buffer_aggressivity));
170             put_be32(pb, codec->codec_tag);
171             break;
172         case CODEC_TYPE_AUDIO:
173             put_be32(pb, codec->sample_rate);
174             put_le16(pb, codec->channels);
175             put_le16(pb, codec->frame_size);
176             break;
177         default:
178             return -1;
179         }
180         /* hack to have real time */
181         if (ffm_nopts)
182             fst->pts = 0;
183         else
184             fst->pts = av_gettime();
185     }
186
187     /* flush until end of block reached */
188     while ((url_ftell(pb) % ffm->packet_size) != 0)
189         put_byte(pb, 0);
190
191     put_flush_packet(pb);
192
193     /* init packet mux */
194     ffm->packet_ptr = ffm->packet;
195     ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE;
196     assert(ffm->packet_end >= ffm->packet);
197     ffm->frame_offset = 0;
198     ffm->pts = 0;
199     ffm->first_packet = 1;
200
201     return 0;
202  fail:
203     for(i=0;i<s->nb_streams;i++) {
204         st = s->streams[i];
205         av_freep(&st->priv_data);
206     }
207     return -1;
208 }
209
210 static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt)
211 {
212     AVStream *st = s->streams[pkt->stream_index];
213     FFMStream *fst = st->priv_data;
214     int64_t pts;
215     uint8_t header[FRAME_HEADER_SIZE];
216
217     pts = fst->pts;
218     /* packet size & key_frame */
219     header[0] = pkt->stream_index;
220     header[1] = 0;
221     if (pkt->flags & PKT_FLAG_KEY)
222         header[1] |= FLAG_KEY_FRAME;
223     AV_WB24(header+2, pkt->size);
224     AV_WB24(header+5, pkt->duration);
225     ffm_write_data(s, header, FRAME_HEADER_SIZE, pts, 1);
226     ffm_write_data(s, pkt->data, pkt->size, pts, 0);
227
228     fst->pts += pkt->duration;
229     return 0;
230 }
231
232 static int ffm_write_trailer(AVFormatContext *s)
233 {
234     ByteIOContext *pb = s->pb;
235     FFMContext *ffm = s->priv_data;
236
237     /* flush packets */
238     if (ffm->packet_ptr > ffm->packet)
239         flush_packet(s);
240
241     put_flush_packet(pb);
242
243     if (!url_is_streamed(pb)) {
244         int64_t size;
245         /* update the write offset */
246         size = url_ftell(pb);
247         url_fseek(pb, 8, SEEK_SET);
248         put_be64(pb, size);
249         put_flush_packet(pb);
250     }
251
252     return 0;
253 }
254
255 AVOutputFormat ffm_muxer = {
256     "ffm",
257     "ffm format",
258     "",
259     "ffm",
260     sizeof(FFMContext),
261     /* not really used */
262     CODEC_ID_MP2,
263     CODEC_ID_MPEG1VIDEO,
264     ffm_write_header,
265     ffm_write_packet,
266     ffm_write_trailer,
267 };