Mercurial > libavcodec.hg
annotate oggvorbis.c @ 2956:5f51b1e0bed6 libavcodec
Cook compatibe decoder, patch by Benjamin Larsson
Add cook demucing, change rm demuxer so that it reorders audio packets
before sending them to the decoder, and send minimum decodeable sized
packets; pass only real codec extradata fo the decoder
Fix 28_8 decoder for the new demuxer strategy
author | rtognimp |
---|---|
date | Fri, 09 Dec 2005 16:08:18 +0000 |
parents | 6f8bcb169256 |
children | ef2149182f1c |
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) { |
934
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
32 |
2850
c553a407b1b6
fixed quality / vbr encoding patch by (Justin Ruggles, jruggle, earthlink net)
michael
parents:
2716
diff
changeset
|
33 if(avccontext->flags & CODEC_FLAG_QSCALE) { |
c553a407b1b6
fixed quality / vbr encoding patch by (Justin Ruggles, jruggle, earthlink net)
michael
parents:
2716
diff
changeset
|
34 return vorbis_encode_init_vbr(vi, avccontext->channels, |
c553a407b1b6
fixed quality / vbr encoding patch by (Justin Ruggles, jruggle, earthlink net)
michael
parents:
2716
diff
changeset
|
35 avccontext->sample_rate, |
c553a407b1b6
fixed quality / vbr encoding patch by (Justin Ruggles, jruggle, earthlink net)
michael
parents:
2716
diff
changeset
|
36 avccontext->global_quality / (float)FF_QP2LAMBDA); |
c553a407b1b6
fixed quality / vbr encoding patch by (Justin Ruggles, jruggle, earthlink net)
michael
parents:
2716
diff
changeset
|
37 } |
934
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
38 #ifdef OGGVORBIS_VBR_BY_ESTIMATE |
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
39 /* variable bitrate by estimate */ |
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
40 |
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
41 return (vorbis_encode_setup_managed(vi, avccontext->channels, |
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
42 avccontext->sample_rate, -1, avccontext->bit_rate, -1) || |
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
43 vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE_AVG, NULL) || |
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
44 vorbis_encode_setup_init(vi)) ; |
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
45 #else |
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
46 /* constant bitrate */ |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
47 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
48 return vorbis_encode_init(vi, avccontext->channels, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
49 avccontext->sample_rate, -1, avccontext->bit_rate, -1) ; |
934
159333d9297e
fixes crash patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
925
diff
changeset
|
50 #endif |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
51 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
52 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
53 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
|
54 OggVorbisContext *context = avccontext->priv_data ; |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
55 ogg_packet header, header_comm, header_code; |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
56 uint8_t *p; |
2676 | 57 unsigned int offset, len; |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
58 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
59 vorbis_info_init(&context->vi) ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
60 if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) { |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1106
diff
changeset
|
61 av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed") ; |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
62 return -1 ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
63 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
64 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
|
65 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
|
66 |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
67 vorbis_comment_init(&context->vc); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
68 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
|
69 |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
70 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
|
71 &header_comm, &header_code); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
72 |
2676 | 73 len = header.bytes + header_comm.bytes + header_code.bytes; |
74 avccontext->extradata_size= 64 + len + len/255; | |
75 p = avccontext->extradata= av_mallocz(avccontext->extradata_size); | |
76 p[0] = 2; | |
77 offset = 1; | |
78 offset += av_xiphlacing(&p[offset], header.bytes); | |
79 offset += av_xiphlacing(&p[offset], header_comm.bytes); | |
80 memcpy(&p[offset], header.packet, header.bytes); | |
81 offset += header.bytes; | |
82 memcpy(&p[offset], header_comm.packet, header_comm.bytes); | |
83 offset += header_comm.bytes; | |
84 memcpy(&p[offset], header_code.packet, header_code.bytes); | |
85 offset += header_code.bytes; | |
86 avccontext->extradata_size = offset; | |
87 avccontext->extradata= av_realloc(avccontext->extradata, avccontext->extradata_size); | |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
88 |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
89 /* vorbis_block_clear(&context->vb); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
90 vorbis_dsp_clear(&context->vd); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
91 vorbis_info_clear(&context->vi);*/ |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
92 vorbis_comment_clear(&context->vc); |
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
93 |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
94 avccontext->frame_size = OGGVORBIS_FRAME_SIZE ; |
925 | 95 |
96 avccontext->coded_frame= avcodec_alloc_frame(); | |
97 avccontext->coded_frame->key_frame= 1; | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
98 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
99 return 0 ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
100 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
101 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
102 |
883 | 103 static int oggvorbis_encode_frame(AVCodecContext *avccontext, |
104 unsigned char *packets, | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
105 int buf_size, void *data) |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
106 { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
107 OggVorbisContext *context = avccontext->priv_data ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
108 float **buffer ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
109 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
|
110 signed short *audio = data ; |
2091 | 111 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
|
112 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
113 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
|
114 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
115 if(context->vi.channels == 1) { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
116 for(l = 0 ; l < samples ; l++) |
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
|
117 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
|
118 } else { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
119 for(l = 0 ; l < samples ; l++){ |
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 buffer[0][l]=audio[l*2]/32768.f; |
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
|
121 buffer[1][l]=audio[l*2+1]/32768.f; |
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 } |
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 vorbis_analysis_wrote(&context->vd, samples) ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
126 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
127 while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
128 vorbis_analysis(&context->vb, NULL); |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
129 vorbis_bitrate_addblock(&context->vb) ; |
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 while(vorbis_bitrate_flushpacket(&context->vd, &op)) { |
2091 | 132 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 |
133 continue; | |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
134 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
|
135 context->buffer_index += sizeof(ogg_packet); |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
136 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
|
137 context->buffer_index += op.bytes; |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
138 // av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes); |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
139 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
140 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
141 |
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
142 l=0; |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
143 if(context->buffer_index){ |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
144 ogg_packet *op2= (ogg_packet*)context->buffer; |
1922
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
145 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
|
146 |
2091 | 147 l= op2->bytes; |
2857 | 148 avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base); |
2858 | 149 //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
|
150 |
2091 | 151 memcpy(packets, op2->packet, l); |
152 context->buffer_index -= l + sizeof(ogg_packet); | |
153 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
|
154 // 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
|
155 } |
0ed2d7ecd1e9
fix obnoxious ogg_packet passing from encoder to muxer
michael
parents:
1920
diff
changeset
|
156 |
1924
d9f751c0f488
pts hack (correct solution would be to pass the pts from the encoder to the muxer)
michael
parents:
1923
diff
changeset
|
157 return l; |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
158 } |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
159 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
160 |
883 | 161 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
|
162 OggVorbisContext *context = avccontext->priv_data ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
163 /* ogg_packet op ; */ |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
164 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
165 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
|
166 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
167 vorbis_block_clear(&context->vb); |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
168 vorbis_dsp_clear(&context->vd); |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
169 vorbis_info_clear(&context->vi); |
925 | 170 |
171 av_freep(&avccontext->coded_frame); | |
1923
04f93474b3bb
remove function call from muxer->encoder and cleanly pass global headers
michael
parents:
1922
diff
changeset
|
172 av_freep(&avccontext->extradata); |
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 return 0 ; |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
175 } |
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 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
178 AVCodec oggvorbis_encoder = { |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
179 "vorbis", |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
180 CODEC_TYPE_AUDIO, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
181 CODEC_ID_VORBIS, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
182 sizeof(OggVorbisContext), |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
183 oggvorbis_encode_init, |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
184 oggvorbis_encode_frame, |
2091 | 185 oggvorbis_encode_close, |
186 .capabilities= CODEC_CAP_DELAY, | |
883 | 187 } ; |
188 | |
189 static int oggvorbis_decode_init(AVCodecContext *avccontext) { | |
190 OggVorbisContext *context = avccontext->priv_data ; | |
1925 | 191 uint8_t *p= avccontext->extradata; |
2676 | 192 int i, hsizes[3]; |
193 unsigned char *headers[3], *extradata = avccontext->extradata; | |
883 | 194 |
195 vorbis_info_init(&context->vi) ; | |
196 vorbis_comment_init(&context->vc) ; | |
1925 | 197 |
2676 | 198 if(! avccontext->extradata_size || ! p) { |
199 av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n"); | |
200 return -1; | |
201 } | |
2716 | 202 |
203 if(p[0] == 0 && p[1] == 30) { | |
204 for(i = 0; i < 3; i++){ | |
205 hsizes[i] = *p++ << 8; | |
206 hsizes[i] += *p++; | |
207 headers[i] = p; | |
208 p += hsizes[i]; | |
209 } | |
210 } else if(*p == 2) { | |
211 unsigned int offset = 1; | |
212 p++; | |
213 for(i=0; i<2; i++) { | |
214 hsizes[i] = 0; | |
215 while((*p == 0xFF) && (offset < avccontext->extradata_size)) { | |
216 hsizes[i] += 0xFF; | |
217 offset++; | |
218 p++; | |
219 } | |
220 if(offset >= avccontext->extradata_size - 1) { | |
221 av_log(avccontext, AV_LOG_ERROR, | |
222 "vorbis header sizes damaged\n"); | |
223 return -1; | |
224 } | |
225 hsizes[i] += *p; | |
226 offset++; | |
227 p++; | |
228 } | |
229 hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset; | |
230 #if 0 | |
231 av_log(avccontext, AV_LOG_DEBUG, | |
232 "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n", | |
233 hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size); | |
234 #endif | |
235 headers[0] = extradata + offset; | |
236 headers[1] = extradata + offset + hsizes[0]; | |
237 headers[2] = extradata + offset + hsizes[0] + hsizes[1]; | |
238 } else { | |
2676 | 239 av_log(avccontext, AV_LOG_ERROR, |
240 "vorbis initial header len is wrong: %d\n", *p); | |
241 return -1; | |
242 } | |
243 | |
1925 | 244 for(i=0; i<3; i++){ |
245 context->op.b_o_s= i==0; | |
2676 | 246 context->op.bytes = hsizes[i]; |
247 context->op.packet = headers[i]; | |
248 if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){ | |
1925 | 249 av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1); |
250 return -1; | |
251 } | |
252 } | |
2716 | 253 |
1925 | 254 avccontext->channels = context->vi.channels; |
255 avccontext->sample_rate = context->vi.rate; | |
2637 | 256 avccontext->time_base= (AVRational){1, avccontext->sample_rate}; |
1925 | 257 |
258 vorbis_synthesis_init(&context->vd, &context->vi); | |
259 vorbis_block_init(&context->vd, &context->vb); | |
883 | 260 |
261 return 0 ; | |
262 } | |
636
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
263 |
57b9a37546a0
oggvorbis support patch by (Mark Hills <mark at pogo dot org dot uk>)
michaelni
parents:
diff
changeset
|
264 |
883 | 265 static inline int conv(int samples, float **pcm, char *buf, int channels) { |
266 int i, j, val ; | |
267 ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ; | |
268 float *mono ; | |
269 | |
270 for(i = 0 ; i < channels ; i++){ | |
271 ptr = &data[i]; | |
272 mono = pcm[i] ; | |
273 | |
274 for(j = 0 ; j < samples ; j++) { | |
275 | |
276 val = mono[j] * 32767.f; | |
277 | |
278 if(val > 32767) val = 32767 ; | |
279 if(val < -32768) val = -32768 ; | |
280 | |
281 *ptr = val ; | |
282 ptr += channels; | |
283 } | |
284 } | |
285 | |
286 return 0 ; | |
287 } | |
288 | |
289 | |
290 static int oggvorbis_decode_frame(AVCodecContext *avccontext, | |
291 void *data, int *data_size, | |
1064 | 292 uint8_t *buf, int buf_size) |
883 | 293 { |
294 OggVorbisContext *context = avccontext->priv_data ; | |
295 float **pcm ; | |
1920
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
296 ogg_packet *op= &context->op; |
2893 | 297 int samples, total_samples, total_bytes; |
883 | 298 |
1919 | 299 if(!buf_size){ |
300 //FIXME flush | |
301 return 0; | |
302 } | |
303 | |
1920
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
304 op->packet = buf; |
9b87ed973dda
kill obnoxious ogg_packet passing from demuxer to decoder
michael
parents:
1919
diff
changeset
|
305 op->bytes = buf_size; |
883 | 306 |
1919 | 307 // 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); |
308 | |
309 /* for(i=0; i<op->bytes; i++) | |
310 av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]); | |
311 av_log(avccontext, AV_LOG_DEBUG, "\n");*/ | |
883 | 312 |
313 if(vorbis_synthesis(&context->vb, op) == 0) | |
314 vorbis_synthesis_blockin(&context->vd, &context->vb) ; | |
315 | |
316 total_samples = 0 ; | |
317 total_bytes = 0 ; | |
318 | |
319 while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) { | |
320 conv(samples, pcm, (char*)data + total_bytes, context->vi.channels) ; | |
321 total_bytes += samples * 2 * context->vi.channels ; | |
322 total_samples += samples ; | |
323 vorbis_synthesis_read(&context->vd, samples) ; | |
324 } | |
325 | |
326 *data_size = total_bytes ; | |
327 return buf_size ; | |
328 } | |
329 | |
330 | |
331 static int oggvorbis_decode_close(AVCodecContext *avccontext) { | |
332 OggVorbisContext *context = avccontext->priv_data ; | |
333 | |
334 vorbis_info_clear(&context->vi) ; | |
335 vorbis_comment_clear(&context->vc) ; | |
336 | |
337 return 0 ; | |
338 } | |
339 | |
340 | |
341 AVCodec oggvorbis_decoder = { | |
342 "vorbis", | |
343 CODEC_TYPE_AUDIO, | |
344 CODEC_ID_VORBIS, | |
345 sizeof(OggVorbisContext), | |
346 oggvorbis_decode_init, | |
347 NULL, | |
348 oggvorbis_decode_close, | |
349 oggvorbis_decode_frame, | |
2091 | 350 .capabilities= CODEC_CAP_DELAY, |
883 | 351 } ; |