diff options
author | Måns Rullgård <mans@mansr.com> | 2005-05-13 18:10:23 +0000 |
---|---|---|
committer | Måns Rullgård <mans@mansr.com> | 2005-05-13 18:10:23 +0000 |
commit | ad2b531d3ffbcb074a81f8e6a35f500519b6909a (patch) | |
tree | 5ce84049af3d414a4aeb1964123fceeda12b7cc2 /libavcodec | |
parent | e817a73daa7e6f473cd793d8c84424536282b163 (diff) | |
download | ffmpeg-ad2b531d3ffbcb074a81f8e6a35f500519b6909a.tar.gz |
change extradata format for vorbis
Originally committed as revision 4235 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/avcodec.h | 2 | ||||
-rw-r--r-- | libavcodec/oggvorbis.c | 81 | ||||
-rw-r--r-- | libavcodec/utils.c | 14 |
3 files changed, 74 insertions, 23 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index bb84d158a3..b9fccc4cff 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2357,6 +2357,8 @@ extern void av_log_set_callback(void (*)(void*, int, const char*, va_list)); ((uint8_t*)(x))[0]) #endif +extern unsigned int av_xiphlacing(unsigned char *s, unsigned int v); + #ifdef __cplusplus } #endif 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; } diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 3eea9a962f..16d00bc33a 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1015,3 +1015,17 @@ int avcodec_thread_init(AVCodecContext *s, int thread_count){ return -1; } #endif + +unsigned int av_xiphlacing(unsigned char *s, unsigned int v) +{ + unsigned int n = 0; + + while(v >= 0xff) { + *s++ = 0xff; + v -= 0xff; + n++; + } + *s = v; + n++; + return n; +} |