comparison oggvorbis.c @ 2091:02a4fd7c606c libavcodec

flush audio encoder buffers at the end fix vorbis in nut again
author michael
date Tue, 22 Jun 2004 21:14:01 +0000
parents 141a9539e270
children 0433866b1075
comparison
equal deleted inserted replaced
2090:869805505b30 2091:02a4fd7c606c
19 vorbis_info vi ; 19 vorbis_info vi ;
20 vorbis_dsp_state vd ; 20 vorbis_dsp_state vd ;
21 vorbis_block vb ; 21 vorbis_block vb ;
22 uint8_t buffer[BUFFER_SIZE]; 22 uint8_t buffer[BUFFER_SIZE];
23 int buffer_index; 23 int buffer_index;
24 int64_t fake_pts; //pts which libavformat will guess, HACK FIXME
25 24
26 /* decoder */ 25 /* decoder */
27 vorbis_comment vc ; 26 vorbis_comment vc ;
28 ogg_packet op; 27 ogg_packet op;
29 } OggVorbisContext ; 28 } OggVorbisContext ;
102 { 101 {
103 OggVorbisContext *context = avccontext->priv_data ; 102 OggVorbisContext *context = avccontext->priv_data ;
104 float **buffer ; 103 float **buffer ;
105 ogg_packet op ; 104 ogg_packet op ;
106 signed char *audio = data ; 105 signed char *audio = data ;
107 int l, samples = OGGVORBIS_FRAME_SIZE ; 106 int l, samples = data ? OGGVORBIS_FRAME_SIZE : 0;
108 107
109 buffer = vorbis_analysis_buffer(&context->vd, samples) ; 108 buffer = vorbis_analysis_buffer(&context->vd, samples) ;
110 109
111 if(context->vi.channels == 1) { 110 if(context->vi.channels == 1) {
112 for(l = 0 ; l < samples ; l++) 111 for(l = 0 ; l < samples ; l++)
123 while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) { 122 while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) {
124 vorbis_analysis(&context->vb, NULL); 123 vorbis_analysis(&context->vb, NULL);
125 vorbis_bitrate_addblock(&context->vb) ; 124 vorbis_bitrate_addblock(&context->vb) ;
126 125
127 while(vorbis_bitrate_flushpacket(&context->vd, &op)) { 126 while(vorbis_bitrate_flushpacket(&context->vd, &op)) {
127 if(op.bytes==1) //id love to say this is a hack, bad sadly its not, appearently the end of stream decission is in libogg
128 continue;
128 memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet)); 129 memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet));
129 context->buffer_index += sizeof(ogg_packet); 130 context->buffer_index += sizeof(ogg_packet);
130 memcpy(context->buffer + context->buffer_index, op.packet, op.bytes); 131 memcpy(context->buffer + context->buffer_index, op.packet, op.bytes);
131 context->buffer_index += op.bytes; 132 context->buffer_index += op.bytes;
132 // av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes); 133 // av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes);
136 l=0; 137 l=0;
137 if(context->buffer_index){ 138 if(context->buffer_index){
138 ogg_packet *op2= (ogg_packet*)context->buffer; 139 ogg_packet *op2= (ogg_packet*)context->buffer;
139 op2->packet = context->buffer + sizeof(ogg_packet); 140 op2->packet = context->buffer + sizeof(ogg_packet);
140 141
141 if(op2->granulepos <= context->fake_pts /*&& (context->fake_pts || context->buffer_index > 4*1024)*/){ 142 l= op2->bytes;
142 assert(op2->granulepos == context->fake_pts); 143 avccontext->coded_frame->pts= av_rescale(op2->granulepos, AV_TIME_BASE, avccontext->sample_rate);
143 l= op2->bytes; 144
144 145 memcpy(packets, op2->packet, l);
145 memcpy(packets, op2->packet, l); 146 context->buffer_index -= l + sizeof(ogg_packet);
146 context->buffer_index -= l + sizeof(ogg_packet); 147 memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index);
147 memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index);
148 }
149 // av_log(avccontext, AV_LOG_DEBUG, "E%d\n", l); 148 // av_log(avccontext, AV_LOG_DEBUG, "E%d\n", l);
150 } 149 }
151 150
152 if(l || context->fake_pts){
153 context->fake_pts += avccontext->frame_size;
154 }
155
156 return l; 151 return l;
157 } 152 }
158 153
159 154
160 static int oggvorbis_encode_close(AVCodecContext *avccontext) { 155 static int oggvorbis_encode_close(AVCodecContext *avccontext) {
161 OggVorbisContext *context = avccontext->priv_data ; 156 OggVorbisContext *context = avccontext->priv_data ;
162 /* ogg_packet op ; */ 157 /* ogg_packet op ; */
163 158
164 vorbis_analysis_wrote(&context->vd, 0) ; /* notify vorbisenc this is EOF */ 159 vorbis_analysis_wrote(&context->vd, 0) ; /* notify vorbisenc this is EOF */
165
166 /* We need to write all the remaining packets into the stream
167 * on closing */
168
169 av_log(avccontext, AV_LOG_ERROR, "fixme: not all packets written on oggvorbis_encode_close()\n") ;
170
171 /*
172 while(vorbis_bitrate_flushpacket(&context->vd, &op)) {
173 memcpy(packets + l, &op, sizeof(ogg_packet)) ;
174 memcpy(packets + l + sizeof(ogg_packet), op.packet, op.bytes) ;
175 l += sizeof(ogg_packet) + op.bytes ;
176 }
177 */
178 160
179 vorbis_block_clear(&context->vb); 161 vorbis_block_clear(&context->vb);
180 vorbis_dsp_clear(&context->vd); 162 vorbis_dsp_clear(&context->vd);
181 vorbis_info_clear(&context->vi); 163 vorbis_info_clear(&context->vi);
182 164
192 CODEC_TYPE_AUDIO, 174 CODEC_TYPE_AUDIO,
193 CODEC_ID_VORBIS, 175 CODEC_ID_VORBIS,
194 sizeof(OggVorbisContext), 176 sizeof(OggVorbisContext),
195 oggvorbis_encode_init, 177 oggvorbis_encode_init,
196 oggvorbis_encode_frame, 178 oggvorbis_encode_frame,
197 oggvorbis_encode_close 179 oggvorbis_encode_close,
180 .capabilities= CODEC_CAP_DELAY,
198 } ; 181 } ;
199 182
200 183
201 static int oggvorbis_decode_init(AVCodecContext *avccontext) { 184 static int oggvorbis_decode_init(AVCodecContext *avccontext) {
202 OggVorbisContext *context = avccontext->priv_data ; 185 OggVorbisContext *context = avccontext->priv_data ;
311 sizeof(OggVorbisContext), 294 sizeof(OggVorbisContext),
312 oggvorbis_decode_init, 295 oggvorbis_decode_init,
313 NULL, 296 NULL,
314 oggvorbis_decode_close, 297 oggvorbis_decode_close,
315 oggvorbis_decode_frame, 298 oggvorbis_decode_frame,
299 .capabilities= CODEC_CAP_DELAY,
316 } ; 300 } ;