Mercurial > libavcodec.hg
annotate oggvorbis.c @ 4166:eced83504436 libavcodec
mp3 header (de)compression bitstream filter
this will make mp3 frames 4 bytes smaller, it will not give you binary identical mp3 files, but it will give you mp3 files which decode to binary identical output
this will only work in containers providing at least packet size, sample_rate and number of channels
bugreports about mp3 files for which this fails are welcome
and this is experimental (dont expect compatibility and dont even expect to be able to decompress what you compressed, hell dont even expect this to work without editing the source a little)
author | michael |
---|---|
date | Fri, 10 Nov 2006 01:41:53 +0000 |
parents | daae66c03857 |
children | 1a714d3f0233 |
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 |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3058
diff
changeset
|
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
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" |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
30 |
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
31 #undef NDEBUG |
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
32 #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
|
33 |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
34 #define OGGVORBIS_FRAME_SIZE 64 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
35 |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
36 #define BUFFER_SIZE (1024*64) |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
37 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
38 typedef struct OggVorbisContext { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
39 vorbis_info vi ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
40 vorbis_dsp_state vd ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
41 vorbis_block vb ; |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
42 uint8_t buffer[BUFFER_SIZE]; |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
43 int buffer_index; |
883 | 44 |
45 /* decoder */ | |
46 vorbis_comment vc ; | |
1920
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
47 ogg_packet op; |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
48 } OggVorbisContext ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
49 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
50 |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
51 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
|
52 double cfreq; |
934
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
53 |
2850
c553a407b1b6
fixed quality / vbr encoding patch by (Justin Ruggles, jruggle, earthlink net)
michael
parents:
2716
diff
changeset
|
54 if(avccontext->flags & CODEC_FLAG_QSCALE) { |
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
55 /* variable bitrate */ |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
56 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
|
57 avccontext->sample_rate, |
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
58 avccontext->global_quality / (float)FF_QP2LAMBDA)) |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
59 return -1; |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
60 } else { |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
61 /* constant bitrate */ |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
62 if(vorbis_encode_setup_managed(vi, avccontext->channels, |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
63 avccontext->sample_rate, -1, avccontext->bit_rate, -1)) |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
64 return -1; |
934
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
65 |
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
66 #ifdef OGGVORBIS_VBR_BY_ESTIMATE |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
67 /* variable bitrate by estimate */ |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
68 if(vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE_AVG, NULL)) |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
69 return -1; |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
70 #endif |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
71 } |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
72 |
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
73 /* cutoff frequency */ |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
74 if(avccontext->cutoff > 0) { |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
75 cfreq = avccontext->cutoff / 1000.0; |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
76 if(vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq)) |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
77 return -1; |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
78 } |
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 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
|
81 } |
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 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
|
84 OggVorbisContext *context = avccontext->priv_data ; |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
85 ogg_packet header, header_comm, header_code; |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
86 uint8_t *p; |
2676 | 87 unsigned int offset, len; |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
88 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
89 vorbis_info_init(&context->vi) ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
90 if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) { |
2979 | 91 av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed") ; |
92 return -1 ; | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
93 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
94 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
|
95 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
|
96 |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
97 vorbis_comment_init(&context->vc); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
98 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
|
99 |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
100 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
|
101 &header_comm, &header_code); |
2967 | 102 |
2676 | 103 len = header.bytes + header_comm.bytes + header_code.bytes; |
104 avccontext->extradata_size= 64 + len + len/255; | |
105 p = avccontext->extradata= av_mallocz(avccontext->extradata_size); | |
106 p[0] = 2; | |
107 offset = 1; | |
108 offset += av_xiphlacing(&p[offset], header.bytes); | |
109 offset += av_xiphlacing(&p[offset], header_comm.bytes); | |
110 memcpy(&p[offset], header.packet, header.bytes); | |
111 offset += header.bytes; | |
112 memcpy(&p[offset], header_comm.packet, header_comm.bytes); | |
113 offset += header_comm.bytes; | |
114 memcpy(&p[offset], header_code.packet, header_code.bytes); | |
115 offset += header_code.bytes; | |
116 avccontext->extradata_size = offset; | |
117 avccontext->extradata= av_realloc(avccontext->extradata, avccontext->extradata_size); | |
2967 | 118 |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
119 /* vorbis_block_clear(&context->vb); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
120 vorbis_dsp_clear(&context->vd); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
121 vorbis_info_clear(&context->vi);*/ |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
122 vorbis_comment_clear(&context->vc); |
2967 | 123 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
124 avccontext->frame_size = OGGVORBIS_FRAME_SIZE ; |
2967 | 125 |
925 | 126 avccontext->coded_frame= avcodec_alloc_frame(); |
127 avccontext->coded_frame->key_frame= 1; | |
2967 | 128 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
129 return 0 ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
130 } |
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 |
883 | 133 static int oggvorbis_encode_frame(AVCodecContext *avccontext, |
2979 | 134 unsigned char *packets, |
135 int buf_size, void *data) | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
136 { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
137 OggVorbisContext *context = avccontext->priv_data ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
138 float **buffer ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
139 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
|
140 signed short *audio = data ; |
2091 | 141 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
|
142 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
143 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
|
144 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
145 if(context->vi.channels == 1) { |
2979 | 146 for(l = 0 ; l < samples ; l++) |
147 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
|
148 } else { |
2979 | 149 for(l = 0 ; l < samples ; l++){ |
150 buffer[0][l]=audio[l*2]/32768.f; | |
151 buffer[1][l]=audio[l*2+1]/32768.f; | |
152 } | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
153 } |
2967 | 154 |
155 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
|
156 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
157 while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) { |
2979 | 158 vorbis_analysis(&context->vb, NULL); |
159 vorbis_bitrate_addblock(&context->vb) ; | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
160 |
2979 | 161 while(vorbis_bitrate_flushpacket(&context->vd, &op)) { |
2091 | 162 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 |
163 continue; | |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
164 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
|
165 context->buffer_index += sizeof(ogg_packet); |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
166 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
|
167 context->buffer_index += op.bytes; |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
168 // av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes); |
2979 | 169 } |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
170 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
171 |
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
172 l=0; |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
173 if(context->buffer_index){ |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
174 ogg_packet *op2= (ogg_packet*)context->buffer; |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
175 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
|
176 |
2091 | 177 l= op2->bytes; |
2857 | 178 avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base); |
2858 | 179 //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
|
180 |
2091 | 181 memcpy(packets, op2->packet, l); |
182 context->buffer_index -= l + sizeof(ogg_packet); | |
183 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
|
184 // 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
|
185 } |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
186 |
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
187 return l; |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
188 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
189 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
190 |
883 | 191 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
|
192 OggVorbisContext *context = avccontext->priv_data ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
193 /* ogg_packet op ; */ |
2967 | 194 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
195 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
|
196 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
197 vorbis_block_clear(&context->vb); |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
198 vorbis_dsp_clear(&context->vd); |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
199 vorbis_info_clear(&context->vi); |
925 | 200 |
201 av_freep(&avccontext->coded_frame); | |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
202 av_freep(&avccontext->extradata); |
2967 | 203 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
204 return 0 ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
205 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
206 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
207 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
208 AVCodec oggvorbis_encoder = { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
209 "vorbis", |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
210 CODEC_TYPE_AUDIO, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
211 CODEC_ID_VORBIS, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
212 sizeof(OggVorbisContext), |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
213 oggvorbis_encode_init, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
214 oggvorbis_encode_frame, |
2091 | 215 oggvorbis_encode_close, |
216 .capabilities= CODEC_CAP_DELAY, | |
883 | 217 } ; |
218 | |
219 static int oggvorbis_decode_init(AVCodecContext *avccontext) { | |
220 OggVorbisContext *context = avccontext->priv_data ; | |
1925 | 221 uint8_t *p= avccontext->extradata; |
2676 | 222 int i, hsizes[3]; |
223 unsigned char *headers[3], *extradata = avccontext->extradata; | |
883 | 224 |
225 vorbis_info_init(&context->vi) ; | |
226 vorbis_comment_init(&context->vc) ; | |
1925 | 227 |
2676 | 228 if(! avccontext->extradata_size || ! p) { |
229 av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n"); | |
230 return -1; | |
231 } | |
2716 | 232 |
233 if(p[0] == 0 && p[1] == 30) { | |
234 for(i = 0; i < 3; i++){ | |
235 hsizes[i] = *p++ << 8; | |
236 hsizes[i] += *p++; | |
237 headers[i] = p; | |
238 p += hsizes[i]; | |
239 } | |
240 } else if(*p == 2) { | |
241 unsigned int offset = 1; | |
242 p++; | |
243 for(i=0; i<2; i++) { | |
244 hsizes[i] = 0; | |
245 while((*p == 0xFF) && (offset < avccontext->extradata_size)) { | |
246 hsizes[i] += 0xFF; | |
247 offset++; | |
248 p++; | |
249 } | |
250 if(offset >= avccontext->extradata_size - 1) { | |
251 av_log(avccontext, AV_LOG_ERROR, | |
252 "vorbis header sizes damaged\n"); | |
253 return -1; | |
254 } | |
255 hsizes[i] += *p; | |
256 offset++; | |
257 p++; | |
258 } | |
259 hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset; | |
260 #if 0 | |
261 av_log(avccontext, AV_LOG_DEBUG, | |
262 "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n", | |
263 hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size); | |
264 #endif | |
265 headers[0] = extradata + offset; | |
266 headers[1] = extradata + offset + hsizes[0]; | |
267 headers[2] = extradata + offset + hsizes[0] + hsizes[1]; | |
268 } else { | |
2676 | 269 av_log(avccontext, AV_LOG_ERROR, |
270 "vorbis initial header len is wrong: %d\n", *p); | |
271 return -1; | |
272 } | |
273 | |
1925 | 274 for(i=0; i<3; i++){ |
275 context->op.b_o_s= i==0; | |
2676 | 276 context->op.bytes = hsizes[i]; |
277 context->op.packet = headers[i]; | |
278 if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){ | |
1925 | 279 av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1); |
280 return -1; | |
281 } | |
282 } | |
2716 | 283 |
1925 | 284 avccontext->channels = context->vi.channels; |
285 avccontext->sample_rate = context->vi.rate; | |
2637 | 286 avccontext->time_base= (AVRational){1, avccontext->sample_rate}; |
1925 | 287 |
288 vorbis_synthesis_init(&context->vd, &context->vi); | |
2967 | 289 vorbis_block_init(&context->vd, &context->vb); |
883 | 290 |
291 return 0 ; | |
292 } | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
293 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
294 |
883 | 295 static inline int conv(int samples, float **pcm, char *buf, int channels) { |
296 int i, j, val ; | |
297 ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ; | |
298 float *mono ; | |
2967 | 299 |
883 | 300 for(i = 0 ; i < channels ; i++){ |
2979 | 301 ptr = &data[i]; |
302 mono = pcm[i] ; | |
2967 | 303 |
2979 | 304 for(j = 0 ; j < samples ; j++) { |
2967 | 305 |
2979 | 306 val = mono[j] * 32767.f; |
2967 | 307 |
2979 | 308 if(val > 32767) val = 32767 ; |
309 if(val < -32768) val = -32768 ; | |
2967 | 310 |
2979 | 311 *ptr = val ; |
312 ptr += channels; | |
313 } | |
883 | 314 } |
2967 | 315 |
883 | 316 return 0 ; |
317 } | |
2967 | 318 |
319 | |
883 | 320 static int oggvorbis_decode_frame(AVCodecContext *avccontext, |
321 void *data, int *data_size, | |
1064 | 322 uint8_t *buf, int buf_size) |
883 | 323 { |
324 OggVorbisContext *context = avccontext->priv_data ; | |
325 float **pcm ; | |
2967 | 326 ogg_packet *op= &context->op; |
2893 | 327 int samples, total_samples, total_bytes; |
2967 | 328 |
1919 | 329 if(!buf_size){ |
330 //FIXME flush | |
331 return 0; | |
332 } | |
2967 | 333 |
1920
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
334 op->packet = buf; |
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
335 op->bytes = buf_size; |
883 | 336 |
4122
daae66c03857
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
3947
diff
changeset
|
337 // 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 | 338 |
1919 | 339 /* for(i=0; i<op->bytes; i++) |
340 av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]); | |
341 av_log(avccontext, AV_LOG_DEBUG, "\n");*/ | |
883 | 342 |
343 if(vorbis_synthesis(&context->vb, op) == 0) | |
2979 | 344 vorbis_synthesis_blockin(&context->vd, &context->vb) ; |
2967 | 345 |
883 | 346 total_samples = 0 ; |
347 total_bytes = 0 ; | |
348 | |
349 while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) { | |
2979 | 350 conv(samples, pcm, (char*)data + total_bytes, context->vi.channels) ; |
351 total_bytes += samples * 2 * context->vi.channels ; | |
352 total_samples += samples ; | |
883 | 353 vorbis_synthesis_read(&context->vd, samples) ; |
354 } | |
355 | |
2967 | 356 *data_size = total_bytes ; |
883 | 357 return buf_size ; |
358 } | |
359 | |
360 | |
361 static int oggvorbis_decode_close(AVCodecContext *avccontext) { | |
362 OggVorbisContext *context = avccontext->priv_data ; | |
2967 | 363 |
883 | 364 vorbis_info_clear(&context->vi) ; |
365 vorbis_comment_clear(&context->vc) ; | |
366 | |
367 return 0 ; | |
368 } | |
369 | |
370 | |
371 AVCodec oggvorbis_decoder = { | |
372 "vorbis", | |
373 CODEC_TYPE_AUDIO, | |
374 CODEC_ID_VORBIS, | |
375 sizeof(OggVorbisContext), | |
376 oggvorbis_decode_init, | |
377 NULL, | |
378 oggvorbis_decode_close, | |
379 oggvorbis_decode_frame, | |
2091 | 380 .capabilities= CODEC_CAP_DELAY, |
883 | 381 } ; |