Libav 0.7.1
|
00001 /* 00002 * FFM (ffserver live feed) muxer 00003 * Copyright (c) 2001 Fabrice Bellard 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "libavutil/intreadwrite.h" 00023 #include "avformat.h" 00024 #include "ffm.h" 00025 00026 static void flush_packet(AVFormatContext *s) 00027 { 00028 FFMContext *ffm = s->priv_data; 00029 int fill_size, h; 00030 AVIOContext *pb = s->pb; 00031 00032 fill_size = ffm->packet_end - ffm->packet_ptr; 00033 memset(ffm->packet_ptr, 0, fill_size); 00034 00035 if (avio_tell(pb) % ffm->packet_size) 00036 av_abort(); 00037 00038 /* put header */ 00039 avio_wb16(pb, PACKET_ID); 00040 avio_wb16(pb, fill_size); 00041 avio_wb64(pb, ffm->dts); 00042 h = ffm->frame_offset; 00043 if (ffm->first_packet) 00044 h |= 0x8000; 00045 avio_wb16(pb, h); 00046 avio_write(pb, ffm->packet, ffm->packet_end - ffm->packet); 00047 avio_flush(pb); 00048 00049 /* prepare next packet */ 00050 ffm->frame_offset = 0; /* no key frame */ 00051 ffm->packet_ptr = ffm->packet; 00052 ffm->first_packet = 0; 00053 } 00054 00055 /* 'first' is true if first data of a frame */ 00056 static void ffm_write_data(AVFormatContext *s, 00057 const uint8_t *buf, int size, 00058 int64_t dts, int header) 00059 { 00060 FFMContext *ffm = s->priv_data; 00061 int len; 00062 00063 if (header && ffm->frame_offset == 0) { 00064 ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE; 00065 ffm->dts = dts; 00066 } 00067 00068 /* write as many packets as needed */ 00069 while (size > 0) { 00070 len = ffm->packet_end - ffm->packet_ptr; 00071 if (len > size) 00072 len = size; 00073 memcpy(ffm->packet_ptr, buf, len); 00074 00075 ffm->packet_ptr += len; 00076 buf += len; 00077 size -= len; 00078 if (ffm->packet_ptr >= ffm->packet_end) 00079 flush_packet(s); 00080 } 00081 } 00082 00083 static int ffm_write_header(AVFormatContext *s) 00084 { 00085 FFMContext *ffm = s->priv_data; 00086 AVStream *st; 00087 AVIOContext *pb = s->pb; 00088 AVCodecContext *codec; 00089 int bit_rate, i; 00090 00091 ffm->packet_size = FFM_PACKET_SIZE; 00092 00093 /* header */ 00094 avio_wl32(pb, MKTAG('F', 'F', 'M', '1')); 00095 avio_wb32(pb, ffm->packet_size); 00096 avio_wb64(pb, 0); /* current write position */ 00097 00098 avio_wb32(pb, s->nb_streams); 00099 bit_rate = 0; 00100 for(i=0;i<s->nb_streams;i++) { 00101 st = s->streams[i]; 00102 bit_rate += st->codec->bit_rate; 00103 } 00104 avio_wb32(pb, bit_rate); 00105 00106 /* list of streams */ 00107 for(i=0;i<s->nb_streams;i++) { 00108 st = s->streams[i]; 00109 av_set_pts_info(st, 64, 1, 1000000); 00110 00111 codec = st->codec; 00112 /* generic info */ 00113 avio_wb32(pb, codec->codec_id); 00114 avio_w8(pb, codec->codec_type); 00115 avio_wb32(pb, codec->bit_rate); 00116 avio_wb32(pb, st->quality); 00117 avio_wb32(pb, codec->flags); 00118 avio_wb32(pb, codec->flags2); 00119 avio_wb32(pb, codec->debug); 00120 /* specific info */ 00121 switch(codec->codec_type) { 00122 case AVMEDIA_TYPE_VIDEO: 00123 avio_wb32(pb, codec->time_base.num); 00124 avio_wb32(pb, codec->time_base.den); 00125 avio_wb16(pb, codec->width); 00126 avio_wb16(pb, codec->height); 00127 avio_wb16(pb, codec->gop_size); 00128 avio_wb32(pb, codec->pix_fmt); 00129 avio_w8(pb, codec->qmin); 00130 avio_w8(pb, codec->qmax); 00131 avio_w8(pb, codec->max_qdiff); 00132 avio_wb16(pb, (int) (codec->qcompress * 10000.0)); 00133 avio_wb16(pb, (int) (codec->qblur * 10000.0)); 00134 avio_wb32(pb, codec->bit_rate_tolerance); 00135 avio_put_str(pb, codec->rc_eq ? codec->rc_eq : "tex^qComp"); 00136 avio_wb32(pb, codec->rc_max_rate); 00137 avio_wb32(pb, codec->rc_min_rate); 00138 avio_wb32(pb, codec->rc_buffer_size); 00139 avio_wb64(pb, av_dbl2int(codec->i_quant_factor)); 00140 avio_wb64(pb, av_dbl2int(codec->b_quant_factor)); 00141 avio_wb64(pb, av_dbl2int(codec->i_quant_offset)); 00142 avio_wb64(pb, av_dbl2int(codec->b_quant_offset)); 00143 avio_wb32(pb, codec->dct_algo); 00144 avio_wb32(pb, codec->strict_std_compliance); 00145 avio_wb32(pb, codec->max_b_frames); 00146 avio_wb32(pb, codec->luma_elim_threshold); 00147 avio_wb32(pb, codec->chroma_elim_threshold); 00148 avio_wb32(pb, codec->mpeg_quant); 00149 avio_wb32(pb, codec->intra_dc_precision); 00150 avio_wb32(pb, codec->me_method); 00151 avio_wb32(pb, codec->mb_decision); 00152 avio_wb32(pb, codec->nsse_weight); 00153 avio_wb32(pb, codec->frame_skip_cmp); 00154 avio_wb64(pb, av_dbl2int(codec->rc_buffer_aggressivity)); 00155 avio_wb32(pb, codec->codec_tag); 00156 avio_w8(pb, codec->thread_count); 00157 avio_wb32(pb, codec->coder_type); 00158 avio_wb32(pb, codec->me_cmp); 00159 avio_wb32(pb, codec->partitions); 00160 avio_wb32(pb, codec->me_subpel_quality); 00161 avio_wb32(pb, codec->me_range); 00162 avio_wb32(pb, codec->keyint_min); 00163 avio_wb32(pb, codec->scenechange_threshold); 00164 avio_wb32(pb, codec->b_frame_strategy); 00165 avio_wb64(pb, av_dbl2int(codec->qcompress)); 00166 avio_wb64(pb, av_dbl2int(codec->qblur)); 00167 avio_wb32(pb, codec->max_qdiff); 00168 avio_wb32(pb, codec->refs); 00169 avio_wb32(pb, codec->directpred); 00170 break; 00171 case AVMEDIA_TYPE_AUDIO: 00172 avio_wb32(pb, codec->sample_rate); 00173 avio_wl16(pb, codec->channels); 00174 avio_wl16(pb, codec->frame_size); 00175 avio_wl16(pb, codec->sample_fmt); 00176 break; 00177 default: 00178 return -1; 00179 } 00180 if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { 00181 avio_wb32(pb, codec->extradata_size); 00182 avio_write(pb, codec->extradata, codec->extradata_size); 00183 } 00184 } 00185 00186 /* flush until end of block reached */ 00187 while ((avio_tell(pb) % ffm->packet_size) != 0) 00188 avio_w8(pb, 0); 00189 00190 avio_flush(pb); 00191 00192 /* init packet mux */ 00193 ffm->packet_ptr = ffm->packet; 00194 ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE; 00195 assert(ffm->packet_end >= ffm->packet); 00196 ffm->frame_offset = 0; 00197 ffm->dts = 0; 00198 ffm->first_packet = 1; 00199 00200 return 0; 00201 } 00202 00203 static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt) 00204 { 00205 int64_t dts; 00206 uint8_t header[FRAME_HEADER_SIZE+4]; 00207 int header_size = FRAME_HEADER_SIZE; 00208 00209 dts = s->timestamp + pkt->dts; 00210 /* packet size & key_frame */ 00211 header[0] = pkt->stream_index; 00212 header[1] = 0; 00213 if (pkt->flags & AV_PKT_FLAG_KEY) 00214 header[1] |= FLAG_KEY_FRAME; 00215 AV_WB24(header+2, pkt->size); 00216 AV_WB24(header+5, pkt->duration); 00217 AV_WB64(header+8, s->timestamp + pkt->pts); 00218 if (pkt->pts != pkt->dts) { 00219 header[1] |= FLAG_DTS; 00220 AV_WB32(header+16, pkt->pts - pkt->dts); 00221 header_size += 4; 00222 } 00223 ffm_write_data(s, header, header_size, dts, 1); 00224 ffm_write_data(s, pkt->data, pkt->size, dts, 0); 00225 00226 return 0; 00227 } 00228 00229 static int ffm_write_trailer(AVFormatContext *s) 00230 { 00231 AVIOContext *pb = s->pb; 00232 FFMContext *ffm = s->priv_data; 00233 00234 /* flush packets */ 00235 if (ffm->packet_ptr > ffm->packet) 00236 flush_packet(s); 00237 00238 avio_flush(pb); 00239 00240 return 0; 00241 } 00242 00243 AVOutputFormat ff_ffm_muxer = { 00244 "ffm", 00245 NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"), 00246 "", 00247 "ffm", 00248 sizeof(FFMContext), 00249 /* not really used */ 00250 CODEC_ID_MP2, 00251 CODEC_ID_MPEG1VIDEO, 00252 ffm_write_header, 00253 ffm_write_packet, 00254 ffm_write_trailer, 00255 };