Mercurial > libavcodec.hg
annotate libvorbis.c @ 5319:40af705cef7e libavcodec
AC-3 decoder, soc revision 69, Aug 31 07:12:56 2006 UTC by cloud9
Fix the bugs:
1. The quality of output because of incorrect windowing coefficients.
New code for window generation.
2. Dynrng values were reset where dynrng value is present in the first block,
but not in the subsequent block.
| author | jbr |
|---|---|
| date | Sat, 14 Jul 2007 16:03:14 +0000 |
| parents | 2b72f9bc4f06 |
| children | c2ab2ac31edb |
| rev | line source |
|---|---|
|
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
1 /* |
|
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
2 * copyright (c) 2002 Mark Hills <mark@pogo.org.uk> |
|
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
3 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
4 * This file is part of FFmpeg. |
|
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
5 * |
|
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
6 * FFmpeg is free software; you can redistribute it and/or |
|
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
7 * modify it under the terms of the GNU Lesser General Public |
|
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
8 * License as published by the Free Software Foundation; either |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
9 * version 2.1 of the License, or (at your option) any later version. |
|
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
10 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
11 * FFmpeg is distributed in the hope that it will be useful, |
|
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
14 * Lesser General Public License for more details. |
|
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
15 * |
|
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
16 * You should have received a copy of the GNU Lesser General Public |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
17 * License along with FFmpeg; if not, write to the Free Software |
| 5215 | 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
19 */ |
|
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
20 |
| 1106 | 21 /** |
| 22 * @file oggvorbis.c | |
| 23 * Ogg Vorbis codec support via libvorbisenc. | |
| 24 * @author Mark Hills <mark@pogo.org.uk> | |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
25 */ |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
26 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
27 #include <vorbis/vorbisenc.h> |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
28 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
29 #include "avcodec.h" |
| 5089 | 30 #include "bytestream.h" |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
31 |
|
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
32 #undef NDEBUG |
|
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
33 #include <assert.h> |
|
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
34 |
|
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
35 #define OGGVORBIS_FRAME_SIZE 64 |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
36 |
|
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
37 #define BUFFER_SIZE (1024*64) |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
38 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
39 typedef struct OggVorbisContext { |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
40 vorbis_info vi ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
41 vorbis_dsp_state vd ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
42 vorbis_block vb ; |
|
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
43 uint8_t buffer[BUFFER_SIZE]; |
|
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
44 int buffer_index; |
| 883 | 45 |
| 46 /* decoder */ | |
| 47 vorbis_comment vc ; | |
|
1920
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
48 ogg_packet op; |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
49 } OggVorbisContext ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
50 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
51 |
|
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
52 static int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext) { |
|
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
53 double cfreq; |
|
934
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
54 |
|
2850
c553a407b1b6
fixed quality / vbr encoding patch by (Justin Ruggles, jruggle, earthlink net)
michael
parents:
2716
diff
changeset
|
55 if(avccontext->flags & CODEC_FLAG_QSCALE) { |
|
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
56 /* variable bitrate */ |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
57 if(vorbis_encode_setup_vbr(vi, avccontext->channels, |
|
2850
c553a407b1b6
fixed quality / vbr encoding patch by (Justin Ruggles, jruggle, earthlink net)
michael
parents:
2716
diff
changeset
|
58 avccontext->sample_rate, |
|
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
59 avccontext->global_quality / (float)FF_QP2LAMBDA)) |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
60 return -1; |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
61 } else { |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
62 /* constant bitrate */ |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
63 if(vorbis_encode_setup_managed(vi, avccontext->channels, |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
64 avccontext->sample_rate, -1, avccontext->bit_rate, -1)) |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
65 return -1; |
|
934
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
66 |
|
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
67 #ifdef OGGVORBIS_VBR_BY_ESTIMATE |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
68 /* variable bitrate by estimate */ |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
69 if(vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE_AVG, NULL)) |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
70 return -1; |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
71 #endif |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
72 } |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
73 |
|
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
74 /* cutoff frequency */ |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
75 if(avccontext->cutoff > 0) { |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
76 cfreq = avccontext->cutoff / 1000.0; |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
77 if(vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq)) |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
78 return -1; |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
79 } |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
80 |
|
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
81 return vorbis_encode_setup_init(vi); |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
82 } |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
83 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
84 static int oggvorbis_encode_init(AVCodecContext *avccontext) { |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
85 OggVorbisContext *context = avccontext->priv_data ; |
|
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
86 ogg_packet header, header_comm, header_code; |
|
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
87 uint8_t *p; |
| 2676 | 88 unsigned int offset, len; |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
89 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
90 vorbis_info_init(&context->vi) ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
91 if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) { |
| 2979 | 92 av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed") ; |
| 93 return -1 ; | |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
94 } |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
95 vorbis_analysis_init(&context->vd, &context->vi) ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
96 vorbis_block_init(&context->vd, &context->vb) ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
97 |
|
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
98 vorbis_comment_init(&context->vc); |
|
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
99 vorbis_comment_add_tag(&context->vc, "encoder", LIBAVCODEC_IDENT) ; |
|
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
100 |
|
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
101 vorbis_analysis_headerout(&context->vd, &context->vc, &header, |
|
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
102 &header_comm, &header_code); |
| 2967 | 103 |
| 2676 | 104 len = header.bytes + header_comm.bytes + header_code.bytes; |
| 105 avccontext->extradata_size= 64 + len + len/255; | |
| 106 p = avccontext->extradata= av_mallocz(avccontext->extradata_size); | |
| 107 p[0] = 2; | |
| 108 offset = 1; | |
| 109 offset += av_xiphlacing(&p[offset], header.bytes); | |
| 110 offset += av_xiphlacing(&p[offset], header_comm.bytes); | |
| 111 memcpy(&p[offset], header.packet, header.bytes); | |
| 112 offset += header.bytes; | |
| 113 memcpy(&p[offset], header_comm.packet, header_comm.bytes); | |
| 114 offset += header_comm.bytes; | |
| 115 memcpy(&p[offset], header_code.packet, header_code.bytes); | |
| 116 offset += header_code.bytes; | |
| 117 avccontext->extradata_size = offset; | |
| 118 avccontext->extradata= av_realloc(avccontext->extradata, avccontext->extradata_size); | |
| 2967 | 119 |
|
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
120 /* vorbis_block_clear(&context->vb); |
|
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
121 vorbis_dsp_clear(&context->vd); |
|
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
122 vorbis_info_clear(&context->vi);*/ |
|
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
123 vorbis_comment_clear(&context->vc); |
| 2967 | 124 |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
125 avccontext->frame_size = OGGVORBIS_FRAME_SIZE ; |
| 2967 | 126 |
| 925 | 127 avccontext->coded_frame= avcodec_alloc_frame(); |
| 128 avccontext->coded_frame->key_frame= 1; | |
| 2967 | 129 |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
130 return 0 ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
131 } |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
132 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
133 |
| 883 | 134 static int oggvorbis_encode_frame(AVCodecContext *avccontext, |
| 2979 | 135 unsigned char *packets, |
| 136 int buf_size, void *data) | |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
137 { |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
138 OggVorbisContext *context = avccontext->priv_data ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
139 float **buffer ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
140 ogg_packet op ; |
|
2393
0433866b1075
fixes transcoding to vorbis with ffmpeg on big endian machines patch by (Sigbj?rn Skj?ret {sskjer-1 broadpark no})
michael
parents:
2091
diff
changeset
|
141 signed short *audio = data ; |
| 2091 | 142 int l, samples = data ? OGGVORBIS_FRAME_SIZE : 0; |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
143 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
144 buffer = vorbis_analysis_buffer(&context->vd, samples) ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
145 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
146 if(context->vi.channels == 1) { |
| 2979 | 147 for(l = 0 ; l < samples ; l++) |
| 148 buffer[0][l]=audio[l]/32768.f; | |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
149 } else { |
| 2979 | 150 for(l = 0 ; l < samples ; l++){ |
| 151 buffer[0][l]=audio[l*2]/32768.f; | |
| 152 buffer[1][l]=audio[l*2+1]/32768.f; | |
| 153 } | |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
154 } |
| 2967 | 155 |
| 156 vorbis_analysis_wrote(&context->vd, samples) ; | |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
157 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
158 while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) { |
| 2979 | 159 vorbis_analysis(&context->vb, NULL); |
| 160 vorbis_bitrate_addblock(&context->vb) ; | |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
161 |
| 2979 | 162 while(vorbis_bitrate_flushpacket(&context->vd, &op)) { |
|
4553
1a714d3f0233
cosmetics: Fix a common typo, sepErate --> sepArate.
diego
parents:
4122
diff
changeset
|
163 /* i'd love to say the following line is a hack, but sadly it's |
|
1a714d3f0233
cosmetics: Fix a common typo, sepErate --> sepArate.
diego
parents:
4122
diff
changeset
|
164 * not, apparently the end of stream decision is in libogg. */ |
|
1a714d3f0233
cosmetics: Fix a common typo, sepErate --> sepArate.
diego
parents:
4122
diff
changeset
|
165 if(op.bytes==1) |
| 2091 | 166 continue; |
|
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
167 memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet)); |
|
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
168 context->buffer_index += sizeof(ogg_packet); |
|
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
169 memcpy(context->buffer + context->buffer_index, op.packet, op.bytes); |
|
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
170 context->buffer_index += op.bytes; |
|
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
171 // av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes); |
| 2979 | 172 } |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
173 } |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
174 |
|
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
175 l=0; |
|
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
176 if(context->buffer_index){ |
|
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
177 ogg_packet *op2= (ogg_packet*)context->buffer; |
|
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
178 op2->packet = context->buffer + sizeof(ogg_packet); |
|
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
179 |
| 2091 | 180 l= op2->bytes; |
| 2857 | 181 avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base); |
| 2858 | 182 //FIXME we should reorder the user supplied pts and not assume that they are spaced by 1/sample_rate |
|
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
183 |
| 2091 | 184 memcpy(packets, op2->packet, l); |
| 185 context->buffer_index -= l + sizeof(ogg_packet); | |
| 186 memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index); | |
|
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
187 // av_log(avccontext, AV_LOG_DEBUG, "E%d\n", l); |
|
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
188 } |
|
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
189 |
|
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
190 return l; |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
191 } |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
192 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
193 |
| 883 | 194 static int oggvorbis_encode_close(AVCodecContext *avccontext) { |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
195 OggVorbisContext *context = avccontext->priv_data ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
196 /* ogg_packet op ; */ |
| 2967 | 197 |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
198 vorbis_analysis_wrote(&context->vd, 0) ; /* notify vorbisenc this is EOF */ |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
199 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
200 vorbis_block_clear(&context->vb); |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
201 vorbis_dsp_clear(&context->vd); |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
202 vorbis_info_clear(&context->vi); |
| 925 | 203 |
| 204 av_freep(&avccontext->coded_frame); | |
|
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
205 av_freep(&avccontext->extradata); |
| 2967 | 206 |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
207 return 0 ; |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
208 } |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
209 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
210 |
| 5058 | 211 AVCodec libvorbis_encoder = { |
| 212 "libvorbis", | |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
213 CODEC_TYPE_AUDIO, |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
214 CODEC_ID_VORBIS, |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
215 sizeof(OggVorbisContext), |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
216 oggvorbis_encode_init, |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
217 oggvorbis_encode_frame, |
| 2091 | 218 oggvorbis_encode_close, |
| 219 .capabilities= CODEC_CAP_DELAY, | |
| 883 | 220 } ; |
| 221 | |
| 222 static int oggvorbis_decode_init(AVCodecContext *avccontext) { | |
| 223 OggVorbisContext *context = avccontext->priv_data ; | |
| 1925 | 224 uint8_t *p= avccontext->extradata; |
| 2676 | 225 int i, hsizes[3]; |
| 226 unsigned char *headers[3], *extradata = avccontext->extradata; | |
| 883 | 227 |
| 228 vorbis_info_init(&context->vi) ; | |
| 229 vorbis_comment_init(&context->vc) ; | |
| 1925 | 230 |
| 2676 | 231 if(! avccontext->extradata_size || ! p) { |
| 232 av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n"); | |
| 233 return -1; | |
| 234 } | |
| 2716 | 235 |
| 236 if(p[0] == 0 && p[1] == 30) { | |
| 237 for(i = 0; i < 3; i++){ | |
| 5089 | 238 hsizes[i] = bytestream_get_be16(&p); |
| 2716 | 239 headers[i] = p; |
| 240 p += hsizes[i]; | |
| 241 } | |
| 242 } else if(*p == 2) { | |
| 243 unsigned int offset = 1; | |
| 244 p++; | |
| 245 for(i=0; i<2; i++) { | |
| 246 hsizes[i] = 0; | |
| 247 while((*p == 0xFF) && (offset < avccontext->extradata_size)) { | |
| 248 hsizes[i] += 0xFF; | |
| 249 offset++; | |
| 250 p++; | |
| 251 } | |
| 252 if(offset >= avccontext->extradata_size - 1) { | |
| 253 av_log(avccontext, AV_LOG_ERROR, | |
| 254 "vorbis header sizes damaged\n"); | |
| 255 return -1; | |
| 256 } | |
| 257 hsizes[i] += *p; | |
| 258 offset++; | |
| 259 p++; | |
| 260 } | |
| 261 hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset; | |
| 262 #if 0 | |
| 263 av_log(avccontext, AV_LOG_DEBUG, | |
| 264 "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n", | |
| 265 hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size); | |
| 266 #endif | |
| 267 headers[0] = extradata + offset; | |
| 268 headers[1] = extradata + offset + hsizes[0]; | |
| 269 headers[2] = extradata + offset + hsizes[0] + hsizes[1]; | |
| 270 } else { | |
| 2676 | 271 av_log(avccontext, AV_LOG_ERROR, |
| 272 "vorbis initial header len is wrong: %d\n", *p); | |
| 273 return -1; | |
| 274 } | |
| 275 | |
| 1925 | 276 for(i=0; i<3; i++){ |
| 277 context->op.b_o_s= i==0; | |
| 2676 | 278 context->op.bytes = hsizes[i]; |
| 279 context->op.packet = headers[i]; | |
| 280 if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){ | |
| 1925 | 281 av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1); |
| 282 return -1; | |
| 283 } | |
| 284 } | |
| 2716 | 285 |
| 1925 | 286 avccontext->channels = context->vi.channels; |
| 287 avccontext->sample_rate = context->vi.rate; | |
| 2637 | 288 avccontext->time_base= (AVRational){1, avccontext->sample_rate}; |
| 1925 | 289 |
| 290 vorbis_synthesis_init(&context->vd, &context->vi); | |
| 2967 | 291 vorbis_block_init(&context->vd, &context->vb); |
| 883 | 292 |
| 293 return 0 ; | |
| 294 } | |
|
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
295 |
|
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
296 |
| 883 | 297 static inline int conv(int samples, float **pcm, char *buf, int channels) { |
| 298 int i, j, val ; | |
| 299 ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ; | |
| 300 float *mono ; | |
| 2967 | 301 |
| 883 | 302 for(i = 0 ; i < channels ; i++){ |
| 2979 | 303 ptr = &data[i]; |
| 304 mono = pcm[i] ; | |
| 2967 | 305 |
| 2979 | 306 for(j = 0 ; j < samples ; j++) { |
| 2967 | 307 |
| 2979 | 308 val = mono[j] * 32767.f; |
| 2967 | 309 |
| 2979 | 310 if(val > 32767) val = 32767 ; |
| 311 if(val < -32768) val = -32768 ; | |
| 2967 | 312 |
| 2979 | 313 *ptr = val ; |
| 314 ptr += channels; | |
| 315 } | |
| 883 | 316 } |
| 2967 | 317 |
| 883 | 318 return 0 ; |
| 319 } | |
| 2967 | 320 |
| 321 | |
| 883 | 322 static int oggvorbis_decode_frame(AVCodecContext *avccontext, |
| 323 void *data, int *data_size, | |
| 1064 | 324 uint8_t *buf, int buf_size) |
| 883 | 325 { |
| 326 OggVorbisContext *context = avccontext->priv_data ; | |
| 327 float **pcm ; | |
| 2967 | 328 ogg_packet *op= &context->op; |
| 2893 | 329 int samples, total_samples, total_bytes; |
| 2967 | 330 |
| 1919 | 331 if(!buf_size){ |
| 332 //FIXME flush | |
| 333 return 0; | |
| 334 } | |
| 2967 | 335 |
|
1920
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
336 op->packet = buf; |
|
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
337 op->bytes = buf_size; |
| 883 | 338 |
|
4122
daae66c03857
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
3947
diff
changeset
|
339 // av_log(avccontext, AV_LOG_DEBUG, "%d %d %d %"PRId64" %"PRId64" %d %d\n", op->bytes, op->b_o_s, op->e_o_s, op->granulepos, op->packetno, buf_size, context->vi.rate); |
| 2967 | 340 |
| 1919 | 341 /* for(i=0; i<op->bytes; i++) |
| 342 av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]); | |
| 343 av_log(avccontext, AV_LOG_DEBUG, "\n");*/ | |
| 883 | 344 |
| 345 if(vorbis_synthesis(&context->vb, op) == 0) | |
| 2979 | 346 vorbis_synthesis_blockin(&context->vd, &context->vb) ; |
| 2967 | 347 |
| 883 | 348 total_samples = 0 ; |
| 349 total_bytes = 0 ; | |
| 350 | |
| 351 while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) { | |
| 2979 | 352 conv(samples, pcm, (char*)data + total_bytes, context->vi.channels) ; |
| 353 total_bytes += samples * 2 * context->vi.channels ; | |
| 354 total_samples += samples ; | |
| 883 | 355 vorbis_synthesis_read(&context->vd, samples) ; |
| 356 } | |
| 357 | |
| 2967 | 358 *data_size = total_bytes ; |
| 883 | 359 return buf_size ; |
| 360 } | |
| 361 | |
| 362 | |
| 363 static int oggvorbis_decode_close(AVCodecContext *avccontext) { | |
| 364 OggVorbisContext *context = avccontext->priv_data ; | |
| 2967 | 365 |
| 883 | 366 vorbis_info_clear(&context->vi) ; |
| 367 vorbis_comment_clear(&context->vc) ; | |
| 368 | |
| 369 return 0 ; | |
| 370 } | |
| 371 | |
| 372 | |
| 4901 | 373 AVCodec libvorbis_decoder = { |
| 374 "libvorbis", | |
| 883 | 375 CODEC_TYPE_AUDIO, |
| 376 CODEC_ID_VORBIS, | |
| 377 sizeof(OggVorbisContext), | |
| 378 oggvorbis_decode_init, | |
| 379 NULL, | |
| 380 oggvorbis_decode_close, | |
| 381 oggvorbis_decode_frame, | |
| 2091 | 382 .capabilities= CODEC_CAP_DELAY, |
| 883 | 383 } ; |
