00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 #include <vorbis/vorbisenc.h>
00028
00029 #include "avcodec.h"
00030 #include "bytestream.h"
00031
00032 #undef NDEBUG
00033 #include <assert.h>
00034
00035 #define OGGVORBIS_FRAME_SIZE 64
00036
00037 #define BUFFER_SIZE (1024*64)
00038
00039 typedef struct OggVorbisContext {
00040 vorbis_info vi ;
00041 vorbis_dsp_state vd ;
00042 vorbis_block vb ;
00043 uint8_t buffer[BUFFER_SIZE];
00044 int buffer_index;
00045
00046
00047 vorbis_comment vc ;
00048 ogg_packet op;
00049 } OggVorbisContext ;
00050
00051
00052 static int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext) {
00053 double cfreq;
00054
00055 if(avccontext->flags & CODEC_FLAG_QSCALE) {
00056
00057 if(vorbis_encode_setup_vbr(vi, avccontext->channels,
00058 avccontext->sample_rate,
00059 avccontext->global_quality / (float)FF_QP2LAMBDA))
00060 return -1;
00061 } else {
00062
00063 if(vorbis_encode_setup_managed(vi, avccontext->channels,
00064 avccontext->sample_rate, -1, avccontext->bit_rate, -1))
00065 return -1;
00066
00067 #ifdef OGGVORBIS_VBR_BY_ESTIMATE
00068
00069 if(vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE_AVG, NULL))
00070 return -1;
00071 #endif
00072 }
00073
00074
00075 if(avccontext->cutoff > 0) {
00076 cfreq = avccontext->cutoff / 1000.0;
00077 if(vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq))
00078 return -1;
00079 }
00080
00081 return vorbis_encode_setup_init(vi);
00082 }
00083
00084 static int oggvorbis_encode_init(AVCodecContext *avccontext) {
00085 OggVorbisContext *context = avccontext->priv_data ;
00086 ogg_packet header, header_comm, header_code;
00087 uint8_t *p;
00088 unsigned int offset, len;
00089
00090 vorbis_info_init(&context->vi) ;
00091 if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) {
00092 av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed") ;
00093 return -1 ;
00094 }
00095 vorbis_analysis_init(&context->vd, &context->vi) ;
00096 vorbis_block_init(&context->vd, &context->vb) ;
00097
00098 vorbis_comment_init(&context->vc);
00099 vorbis_comment_add_tag(&context->vc, "encoder", LIBAVCODEC_IDENT) ;
00100
00101 vorbis_analysis_headerout(&context->vd, &context->vc, &header,
00102 &header_comm, &header_code);
00103
00104 len = header.bytes + header_comm.bytes + header_code.bytes;
00105 avccontext->extradata_size= 64 + len + len/255;
00106 p = avccontext->extradata= av_mallocz(avccontext->extradata_size);
00107 p[0] = 2;
00108 offset = 1;
00109 offset += av_xiphlacing(&p[offset], header.bytes);
00110 offset += av_xiphlacing(&p[offset], header_comm.bytes);
00111 memcpy(&p[offset], header.packet, header.bytes);
00112 offset += header.bytes;
00113 memcpy(&p[offset], header_comm.packet, header_comm.bytes);
00114 offset += header_comm.bytes;
00115 memcpy(&p[offset], header_code.packet, header_code.bytes);
00116 offset += header_code.bytes;
00117 avccontext->extradata_size = offset;
00118 avccontext->extradata= av_realloc(avccontext->extradata, avccontext->extradata_size);
00119
00120
00121
00122
00123 vorbis_comment_clear(&context->vc);
00124
00125 avccontext->frame_size = OGGVORBIS_FRAME_SIZE ;
00126
00127 avccontext->coded_frame= avcodec_alloc_frame();
00128 avccontext->coded_frame->key_frame= 1;
00129
00130 return 0 ;
00131 }
00132
00133
00134 static int oggvorbis_encode_frame(AVCodecContext *avccontext,
00135 unsigned char *packets,
00136 int buf_size, void *data)
00137 {
00138 OggVorbisContext *context = avccontext->priv_data ;
00139 float **buffer ;
00140 ogg_packet op ;
00141 signed short *audio = data ;
00142 int l, samples = data ? OGGVORBIS_FRAME_SIZE : 0;
00143
00144 buffer = vorbis_analysis_buffer(&context->vd, samples) ;
00145
00146 if(context->vi.channels == 1) {
00147 for(l = 0 ; l < samples ; l++)
00148 buffer[0][l]=audio[l]/32768.f;
00149 } else {
00150 for(l = 0 ; l < samples ; l++){
00151 buffer[0][l]=audio[l*2]/32768.f;
00152 buffer[1][l]=audio[l*2+1]/32768.f;
00153 }
00154 }
00155
00156 vorbis_analysis_wrote(&context->vd, samples) ;
00157
00158 while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) {
00159 vorbis_analysis(&context->vb, NULL);
00160 vorbis_bitrate_addblock(&context->vb) ;
00161
00162 while(vorbis_bitrate_flushpacket(&context->vd, &op)) {
00163
00164
00165 if(op.bytes==1)
00166 continue;
00167 memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet));
00168 context->buffer_index += sizeof(ogg_packet);
00169 memcpy(context->buffer + context->buffer_index, op.packet, op.bytes);
00170 context->buffer_index += op.bytes;
00171
00172 }
00173 }
00174
00175 l=0;
00176 if(context->buffer_index){
00177 ogg_packet *op2= (ogg_packet*)context->buffer;
00178 op2->packet = context->buffer + sizeof(ogg_packet);
00179
00180 l= op2->bytes;
00181 avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base);
00182
00183
00184 memcpy(packets, op2->packet, l);
00185 context->buffer_index -= l + sizeof(ogg_packet);
00186 memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index);
00187
00188 }
00189
00190 return l;
00191 }
00192
00193
00194 static int oggvorbis_encode_close(AVCodecContext *avccontext) {
00195 OggVorbisContext *context = avccontext->priv_data ;
00196
00197
00198 vorbis_analysis_wrote(&context->vd, 0) ;
00199
00200 vorbis_block_clear(&context->vb);
00201 vorbis_dsp_clear(&context->vd);
00202 vorbis_info_clear(&context->vi);
00203
00204 av_freep(&avccontext->coded_frame);
00205 av_freep(&avccontext->extradata);
00206
00207 return 0 ;
00208 }
00209
00210
00211 AVCodec libvorbis_encoder = {
00212 "libvorbis",
00213 CODEC_TYPE_AUDIO,
00214 CODEC_ID_VORBIS,
00215 sizeof(OggVorbisContext),
00216 oggvorbis_encode_init,
00217 oggvorbis_encode_frame,
00218 oggvorbis_encode_close,
00219 .capabilities= CODEC_CAP_DELAY,
00220 } ;