Mercurial > libavcodec.hg
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 } ; |