summaryrefslogtreecommitdiff
path: root/libavcodec/oggvorbis.c
diff options
context:
space:
mode:
authorMåns Rullgård <mans@mansr.com>2005-05-13 18:10:23 +0000
committerMåns Rullgård <mans@mansr.com>2005-05-13 18:10:23 +0000
commitad2b531d3ffbcb074a81f8e6a35f500519b6909a (patch)
tree5ce84049af3d414a4aeb1964123fceeda12b7cc2 /libavcodec/oggvorbis.c
parente817a73daa7e6f473cd793d8c84424536282b163 (diff)
change extradata format for vorbis
Originally committed as revision 4235 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/oggvorbis.c')
-rw-r--r--libavcodec/oggvorbis.c81
1 files changed, 58 insertions, 23 deletions
diff --git a/libavcodec/oggvorbis.c b/libavcodec/oggvorbis.c
index e5dd106424..9a47aeec97 100644
--- a/libavcodec/oggvorbis.c
+++ b/libavcodec/oggvorbis.c
@@ -49,6 +49,7 @@ static int oggvorbis_encode_init(AVCodecContext *avccontext) {
OggVorbisContext *context = avccontext->priv_data ;
ogg_packet header, header_comm, header_code;
uint8_t *p;
+ unsigned int offset, len;
vorbis_info_init(&context->vi) ;
if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) {
@@ -64,22 +65,21 @@ static int oggvorbis_encode_init(AVCodecContext *avccontext) {
vorbis_analysis_headerout(&context->vd, &context->vc, &header,
&header_comm, &header_code);
- avccontext->extradata_size= 3*2 + header.bytes + header_comm.bytes + header_code.bytes;
- p= avccontext->extradata= av_mallocz(avccontext->extradata_size);
-
- *(p++) = header.bytes>>8;
- *(p++) = header.bytes&0xFF;
- memcpy(p, header.packet, header.bytes);
- p += header.bytes;
-
- *(p++) = header_comm.bytes>>8;
- *(p++) = header_comm.bytes&0xFF;
- memcpy(p, header_comm.packet, header_comm.bytes);
- p += header_comm.bytes;
-
- *(p++) = header_code.bytes>>8;
- *(p++) = header_code.bytes&0xFF;
- memcpy(p, header_code.packet, header_code.bytes);
+ len = header.bytes + header_comm.bytes + header_code.bytes;
+ avccontext->extradata_size= 64 + len + len/255;
+ p = avccontext->extradata= av_mallocz(avccontext->extradata_size);
+ p[0] = 2;
+ offset = 1;
+ offset += av_xiphlacing(&p[offset], header.bytes);
+ offset += av_xiphlacing(&p[offset], header_comm.bytes);
+ memcpy(&p[offset], header.packet, header.bytes);
+ offset += header.bytes;
+ memcpy(&p[offset], header_comm.packet, header_comm.bytes);
+ offset += header_comm.bytes;
+ memcpy(&p[offset], header_code.packet, header_code.bytes);
+ offset += header_code.bytes;
+ avccontext->extradata_size = offset;
+ avccontext->extradata= av_realloc(avccontext->extradata, avccontext->extradata_size);
/* vorbis_block_clear(&context->vb);
vorbis_dsp_clear(&context->vd);
@@ -184,19 +184,54 @@ AVCodec oggvorbis_encoder = {
static int oggvorbis_decode_init(AVCodecContext *avccontext) {
OggVorbisContext *context = avccontext->priv_data ;
uint8_t *p= avccontext->extradata;
- int i;
+ int i, hsizes[3];
+ unsigned char *headers[3], *extradata = avccontext->extradata;
+ unsigned int offset;
vorbis_info_init(&context->vi) ;
vorbis_comment_init(&context->vc) ;
+ if(! avccontext->extradata_size || ! p) {
+ av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n");
+ return -1;
+ }
+ if(*p != 2) {
+ av_log(avccontext, AV_LOG_ERROR,
+ "vorbis initial header len is wrong: %d\n", *p);
+ return -1;
+ }
+ offset = 1;
+ p++;
+ for(i=0; i<2; i++) {
+ hsizes[i] = 0;
+ while((*p == 0xFF) && (offset < avccontext->extradata_size)) {
+ hsizes[i] += 0xFF;
+ offset++;
+ p++;
+ }
+ if(offset >= avccontext->extradata_size - 1) {
+ av_log(avccontext, AV_LOG_ERROR, "vorbis header sizes damaged\n");
+ return -1;
+ }
+ hsizes[i] += *p;
+ offset++;
+ p++;
+ }
+ hsizes[2] = avccontext->extradata_size - hsizes[0] - hsizes[1] - offset;
+#if 0
+ av_log(avccontext, AV_LOG_DEBUG,
+ "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n",
+ hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size);
+#endif
+ headers[0] = extradata + offset;
+ headers[1] = extradata + offset + hsizes[0];
+ headers[2] = extradata + offset + hsizes[0] + hsizes[1];
+
for(i=0; i<3; i++){
context->op.b_o_s= i==0;
- context->op.bytes= *(p++)<<8;
- context->op.bytes+=*(p++);
- context->op.packet= p;
- p += context->op.bytes;
-
- if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){
+ context->op.bytes = hsizes[i];
+ context->op.packet = headers[i];
+ if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){
av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1);
return -1;
}