Mercurial > libavcodec.hg
annotate oggvorbis.c @ 3198:6b9f0c4fbdbe libavcodec
First part of a series of speed-enchancing patches.
This one sets up a snow.h and makes snow use the dsputil function pointer
framework to access the three functions that will be implemented in asm
in the other parts of the patchset.
Patch by Robert Edele < yartrebo AH earthlink POIS net>
Original thread:
Subject: [Ffmpeg-devel] [PATCH] Snow mmx+sse2 asm optimizations
Date: Sun, 05 Feb 2006 12:47:14 -0500
author | gpoirier |
---|---|
date | Thu, 16 Mar 2006 19:18:18 +0000 |
parents | 8936371f5a5c |
children | c537a97eec66 |
rev | line source |
---|---|
1106 | 1 /** |
2 * @file oggvorbis.c | |
3 * Ogg Vorbis codec support via libvorbisenc. | |
4 * @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
|
5 */ |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
6 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
7 #include <vorbis/vorbisenc.h> |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
8 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
9 #include "avcodec.h" |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
10 |
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
11 #undef NDEBUG |
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
12 #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
|
13 |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
14 #define OGGVORBIS_FRAME_SIZE 64 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
15 |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
16 #define BUFFER_SIZE (1024*64) |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
17 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
18 typedef struct OggVorbisContext { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
19 vorbis_info vi ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
20 vorbis_dsp_state vd ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
21 vorbis_block vb ; |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
22 uint8_t buffer[BUFFER_SIZE]; |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
23 int buffer_index; |
883 | 24 |
25 /* decoder */ | |
26 vorbis_comment vc ; | |
1920
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
27 ogg_packet op; |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
28 } OggVorbisContext ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
29 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
30 |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
31 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
|
32 double cfreq; |
934
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
33 |
2850
c553a407b1b6
fixed quality / vbr encoding patch by (Justin Ruggles, jruggle, earthlink net)
michael
parents:
2716
diff
changeset
|
34 if(avccontext->flags & CODEC_FLAG_QSCALE) { |
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
35 /* variable bitrate */ |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
36 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
|
37 avccontext->sample_rate, |
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
38 avccontext->global_quality / (float)FF_QP2LAMBDA)) |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
39 return -1; |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
40 } else { |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
41 /* constant bitrate */ |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
42 if(vorbis_encode_setup_managed(vi, avccontext->channels, |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
43 avccontext->sample_rate, -1, avccontext->bit_rate, -1)) |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
44 return -1; |
934
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
45 |
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
46 #ifdef OGGVORBIS_VBR_BY_ESTIMATE |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
47 /* variable bitrate by estimate */ |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
48 if(vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE_AVG, NULL)) |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
49 return -1; |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
50 #endif |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
51 } |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
52 |
3058
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
53 /* cutoff frequency */ |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
54 if(avccontext->cutoff > 0) { |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
55 cfreq = avccontext->cutoff / 1000.0; |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
56 if(vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq)) |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
57 return -1; |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
58 } |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
59 |
8936371f5a5c
Implement audio cutoff frequency to the vorbis encoder.
banan
parents:
2979
diff
changeset
|
60 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
|
61 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
62 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
63 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
|
64 OggVorbisContext *context = avccontext->priv_data ; |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
65 ogg_packet header, header_comm, header_code; |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
66 uint8_t *p; |
2676 | 67 unsigned int offset, len; |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
68 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
69 vorbis_info_init(&context->vi) ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
70 if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) { |
2979 | 71 av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed") ; |
72 return -1 ; | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
73 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
74 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
|
75 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
|
76 |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
77 vorbis_comment_init(&context->vc); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
78 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
|
79 |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
80 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
|
81 &header_comm, &header_code); |
2967 | 82 |
2676 | 83 len = header.bytes + header_comm.bytes + header_code.bytes; |
84 avccontext->extradata_size= 64 + len + len/255; | |
85 p = avccontext->extradata= av_mallocz(avccontext->extradata_size); | |
86 p[0] = 2; | |
87 offset = 1; | |
88 offset += av_xiphlacing(&p[offset], header.bytes); | |
89 offset += av_xiphlacing(&p[offset], header_comm.bytes); | |
90 memcpy(&p[offset], header.packet, header.bytes); | |
91 offset += header.bytes; | |
92 memcpy(&p[offset], header_comm.packet, header_comm.bytes); | |
93 offset += header_comm.bytes; | |
94 memcpy(&p[offset], header_code.packet, header_code.bytes); | |
95 offset += header_code.bytes; | |
96 avccontext->extradata_size = offset; | |
97 avccontext->extradata= av_realloc(avccontext->extradata, avccontext->extradata_size); | |
2967 | 98 |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
99 /* vorbis_block_clear(&context->vb); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
100 vorbis_dsp_clear(&context->vd); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
101 vorbis_info_clear(&context->vi);*/ |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
102 vorbis_comment_clear(&context->vc); |
2967 | 103 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
104 avccontext->frame_size = OGGVORBIS_FRAME_SIZE ; |
2967 | 105 |
925 | 106 avccontext->coded_frame= avcodec_alloc_frame(); |
107 avccontext->coded_frame->key_frame= 1; | |
2967 | 108 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
109 return 0 ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
110 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
111 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
112 |
883 | 113 static int oggvorbis_encode_frame(AVCodecContext *avccontext, |
2979 | 114 unsigned char *packets, |
115 int buf_size, void *data) | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
116 { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
117 OggVorbisContext *context = avccontext->priv_data ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
118 float **buffer ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
119 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
|
120 signed short *audio = data ; |
2091 | 121 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
|
122 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
123 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
|
124 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
125 if(context->vi.channels == 1) { |
2979 | 126 for(l = 0 ; l < samples ; l++) |
127 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
|
128 } else { |
2979 | 129 for(l = 0 ; l < samples ; l++){ |
130 buffer[0][l]=audio[l*2]/32768.f; | |
131 buffer[1][l]=audio[l*2+1]/32768.f; | |
132 } | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
133 } |
2967 | 134 |
135 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
|
136 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
137 while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) { |
2979 | 138 vorbis_analysis(&context->vb, NULL); |
139 vorbis_bitrate_addblock(&context->vb) ; | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
140 |
2979 | 141 while(vorbis_bitrate_flushpacket(&context->vd, &op)) { |
2091 | 142 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 |
143 continue; | |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
144 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
|
145 context->buffer_index += sizeof(ogg_packet); |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
146 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
|
147 context->buffer_index += op.bytes; |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
148 // av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes); |
2979 | 149 } |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
150 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
151 |
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
152 l=0; |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
153 if(context->buffer_index){ |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
154 ogg_packet *op2= (ogg_packet*)context->buffer; |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
155 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
|
156 |
2091 | 157 l= op2->bytes; |
2857 | 158 avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base); |
2858 | 159 //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
|
160 |
2091 | 161 memcpy(packets, op2->packet, l); |
162 context->buffer_index -= l + sizeof(ogg_packet); | |
163 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
|
164 // 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
|
165 } |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
166 |
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
167 return l; |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
168 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
169 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
170 |
883 | 171 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
|
172 OggVorbisContext *context = avccontext->priv_data ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
173 /* ogg_packet op ; */ |
2967 | 174 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
175 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
|
176 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
177 vorbis_block_clear(&context->vb); |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
178 vorbis_dsp_clear(&context->vd); |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
179 vorbis_info_clear(&context->vi); |
925 | 180 |
181 av_freep(&avccontext->coded_frame); | |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
182 av_freep(&avccontext->extradata); |
2967 | 183 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
184 return 0 ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
185 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
186 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
187 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
188 AVCodec oggvorbis_encoder = { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
189 "vorbis", |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
190 CODEC_TYPE_AUDIO, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
191 CODEC_ID_VORBIS, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
192 sizeof(OggVorbisContext), |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
193 oggvorbis_encode_init, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
194 oggvorbis_encode_frame, |
2091 | 195 oggvorbis_encode_close, |
196 .capabilities= CODEC_CAP_DELAY, | |
883 | 197 } ; |
198 | |
199 static int oggvorbis_decode_init(AVCodecContext *avccontext) { | |
200 OggVorbisContext *context = avccontext->priv_data ; | |
1925 | 201 uint8_t *p= avccontext->extradata; |
2676 | 202 int i, hsizes[3]; |
203 unsigned char *headers[3], *extradata = avccontext->extradata; | |
883 | 204 |
205 vorbis_info_init(&context->vi) ; | |
206 vorbis_comment_init(&context->vc) ; | |
1925 | 207 |
2676 | 208 if(! avccontext->extradata_size || ! p) { |
209 av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n"); | |
210 return -1; | |
211 } | |
2716 | 212 |
213 if(p[0] == 0 && p[1] == 30) { | |
214 for(i = 0; i < 3; i++){ | |
215 hsizes[i] = *p++ << 8; | |
216 hsizes[i] += *p++; | |
217 headers[i] = p; | |
218 p += hsizes[i]; | |
219 } | |
220 } else if(*p == 2) { | |
221 unsigned int offset = 1; | |
222 p++; | |
223 for(i=0; i<2; i++) { | |
224 hsizes[i] = 0; | |
225 while((*p == 0xFF) && (offset < avccontext->extradata_size)) { | |
226 hsizes[i] += 0xFF; | |
227 offset++; | |
228 p++; | |
229 } | |
230 if(offset >= avccontext->extradata_size - 1) { | |
231 av_log(avccontext, AV_LOG_ERROR, | |
232 "vorbis header sizes damaged\n"); | |
233 return -1; | |
234 } | |
235 hsizes[i] += *p; | |
236 offset++; | |
237 p++; | |
238 } | |
239 hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset; | |
240 #if 0 | |
241 av_log(avccontext, AV_LOG_DEBUG, | |
242 "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n", | |
243 hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size); | |
244 #endif | |
245 headers[0] = extradata + offset; | |
246 headers[1] = extradata + offset + hsizes[0]; | |
247 headers[2] = extradata + offset + hsizes[0] + hsizes[1]; | |
248 } else { | |
2676 | 249 av_log(avccontext, AV_LOG_ERROR, |
250 "vorbis initial header len is wrong: %d\n", *p); | |
251 return -1; | |
252 } | |
253 | |
1925 | 254 for(i=0; i<3; i++){ |
255 context->op.b_o_s= i==0; | |
2676 | 256 context->op.bytes = hsizes[i]; |
257 context->op.packet = headers[i]; | |
258 if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){ | |
1925 | 259 av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1); |
260 return -1; | |
261 } | |
262 } | |
2716 | 263 |
1925 | 264 avccontext->channels = context->vi.channels; |
265 avccontext->sample_rate = context->vi.rate; | |
2637 | 266 avccontext->time_base= (AVRational){1, avccontext->sample_rate}; |
1925 | 267 |
268 vorbis_synthesis_init(&context->vd, &context->vi); | |
2967 | 269 vorbis_block_init(&context->vd, &context->vb); |
883 | 270 |
271 return 0 ; | |
272 } | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
273 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
274 |
883 | 275 static inline int conv(int samples, float **pcm, char *buf, int channels) { |
276 int i, j, val ; | |
277 ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ; | |
278 float *mono ; | |
2967 | 279 |
883 | 280 for(i = 0 ; i < channels ; i++){ |
2979 | 281 ptr = &data[i]; |
282 mono = pcm[i] ; | |
2967 | 283 |
2979 | 284 for(j = 0 ; j < samples ; j++) { |
2967 | 285 |
2979 | 286 val = mono[j] * 32767.f; |
2967 | 287 |
2979 | 288 if(val > 32767) val = 32767 ; |
289 if(val < -32768) val = -32768 ; | |
2967 | 290 |
2979 | 291 *ptr = val ; |
292 ptr += channels; | |
293 } | |
883 | 294 } |
2967 | 295 |
883 | 296 return 0 ; |
297 } | |
2967 | 298 |
299 | |
883 | 300 static int oggvorbis_decode_frame(AVCodecContext *avccontext, |
301 void *data, int *data_size, | |
1064 | 302 uint8_t *buf, int buf_size) |
883 | 303 { |
304 OggVorbisContext *context = avccontext->priv_data ; | |
305 float **pcm ; | |
2967 | 306 ogg_packet *op= &context->op; |
2893 | 307 int samples, total_samples, total_bytes; |
2967 | 308 |
1919 | 309 if(!buf_size){ |
310 //FIXME flush | |
311 return 0; | |
312 } | |
2967 | 313 |
1920
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
314 op->packet = buf; |
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
315 op->bytes = buf_size; |
883 | 316 |
1919 | 317 // av_log(avccontext, AV_LOG_DEBUG, "%d %d %d %lld %lld %d %d\n", op->bytes, op->b_o_s, op->e_o_s, op->granulepos, op->packetno, buf_size, context->vi.rate); |
2967 | 318 |
1919 | 319 /* for(i=0; i<op->bytes; i++) |
320 av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]); | |
321 av_log(avccontext, AV_LOG_DEBUG, "\n");*/ | |
883 | 322 |
323 if(vorbis_synthesis(&context->vb, op) == 0) | |
2979 | 324 vorbis_synthesis_blockin(&context->vd, &context->vb) ; |
2967 | 325 |
883 | 326 total_samples = 0 ; |
327 total_bytes = 0 ; | |
328 | |
329 while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) { | |
2979 | 330 conv(samples, pcm, (char*)data + total_bytes, context->vi.channels) ; |
331 total_bytes += samples * 2 * context->vi.channels ; | |
332 total_samples += samples ; | |
883 | 333 vorbis_synthesis_read(&context->vd, samples) ; |
334 } | |
335 | |
2967 | 336 *data_size = total_bytes ; |
883 | 337 return buf_size ; |
338 } | |
339 | |
340 | |
341 static int oggvorbis_decode_close(AVCodecContext *avccontext) { | |
342 OggVorbisContext *context = avccontext->priv_data ; | |
2967 | 343 |
883 | 344 vorbis_info_clear(&context->vi) ; |
345 vorbis_comment_clear(&context->vc) ; | |
346 | |
347 return 0 ; | |
348 } | |
349 | |
350 | |
351 AVCodec oggvorbis_decoder = { | |
352 "vorbis", | |
353 CODEC_TYPE_AUDIO, | |
354 CODEC_ID_VORBIS, | |
355 sizeof(OggVorbisContext), | |
356 oggvorbis_decode_init, | |
357 NULL, | |
358 oggvorbis_decode_close, | |
359 oggvorbis_decode_frame, | |
2091 | 360 .capabilities= CODEC_CAP_DELAY, |
883 | 361 } ; |