Mercurial > mplayer.hg
changeset 15420:f3cf481bbcda
vorbis extradata is now passed from demuxer to decoder in matroska's way
author | nicodvb |
---|---|
date | Thu, 12 May 2005 17:35:58 +0000 |
parents | da39fe11c872 |
children | ae5e1b9e3c92 |
files | libmpcodecs/ad_libvorbis.c libmpdemux/demux_mkv.c libmpdemux/demux_ogg.c |
diffstat | 3 files changed, 146 insertions(+), 69 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpcodecs/ad_libvorbis.c Thu May 12 15:31:37 2005 +0000 +++ b/libmpcodecs/ad_libvorbis.c Thu May 12 17:35:58 2005 +0000 @@ -60,6 +60,8 @@ static int init(sh_audio_t *sh) { + unsigned int offset, i, length, hsizes[3], *headers[3]; + unsigned char* extradata; ogg_packet op; vorbis_comment vc; struct ov_struct_st *ov; @@ -69,31 +71,66 @@ free(ov); \ return 0; \ } + + if(! sh->wf) { + mp_msg(MSGT_DECAUDIO,MSGL_ERR,"ad_vorbis, extradata seems to be absent! exit\n"); + ERROR(); + } + + if(! sh->wf->cbSize) { + mp_msg(MSGT_DECAUDIO,MSGL_ERR,"ad_vorbis, extradata seems to be absent!, exit\n"); + ERROR(); + } + + mp_msg(MSGT_DECAUDIO,MSGL_V,"ad_vorbis, extradata seems is %d bytes long\n", sh->wf->cbSize); + extradata = (char*) (sh->wf+1); + if(!extradata) { + mp_msg(MSGT_DECAUDIO,MSGL_ERR,"ad_vorbis, extradata seems to be NULL!, exit\n"); + ERROR(); + } + + if(*extradata != 2) { + mp_msg (MSGT_DEMUX, MSGL_WARN, "ad_vorbis: Vorbis track does not contain valid headers.\n"); + ERROR(); + } + + offset = 1; + for (i=0; i < 2; i++) { + length = 0; + while ((extradata[offset] == (unsigned char) 0xFF) && length < sh->wf->cbSize) { + length += 255; + offset++; + } + if(offset >= (sh->wf->cbSize - 1)) { + mp_msg (MSGT_DEMUX, MSGL_WARN, "ad_vorbis: Vorbis track does not contain valid headers.\n"); + ERROR(); + } + length += extradata[offset]; + offset++; + mp_msg (MSGT_DEMUX, MSGL_V, "ad_vorbis, offset: %u, length: %u\n", offset, length); + hsizes[i] = length; + } + + headers[0] = &extradata[offset]; + headers[1] = &extradata[offset + hsizes[0]]; + headers[2] = &extradata[offset + hsizes[0] + hsizes[1]]; + hsizes[2] = sh->wf->cbSize - offset - hsizes[0] - hsizes[1]; + mp_msg (MSGT_DEMUX, MSGL_V, "ad_vorbis, header sizes: %d %d %d\n", hsizes[0], hsizes[1], hsizes[2]); + /// Init the decoder with the 3 header packets ov = (struct ov_struct_st*)malloc(sizeof(struct ov_struct_st)); vorbis_info_init(&ov->vi); vorbis_comment_init(&vc); - op.bytes = ds_get_packet(sh->ds,&op.packet); - op.b_o_s = 1; - /// Header - if(vorbis_synthesis_headerin(&ov->vi,&vc,&op) <0) { - mp_msg(MSGT_DECAUDIO,MSGL_ERR,"OggVorbis: initial (identification) header broken!\n"); - ERROR(); - } - op.bytes = ds_get_packet(sh->ds,&op.packet); - op.b_o_s = 0; - /// Comments - if(vorbis_synthesis_headerin(&ov->vi,&vc,&op) <0) { - mp_msg(MSGT_DECAUDIO,MSGL_ERR,"OggVorbis: comment header broken!\n"); - ERROR(); - } - op.bytes = ds_get_packet(sh->ds,&op.packet); - //// Codebook - if(vorbis_synthesis_headerin(&ov->vi,&vc,&op)<0) { - mp_msg(MSGT_DECAUDIO,MSGL_WARN,"OggVorbis: codebook header broken!\n"); - ERROR(); - } else { /// Print the infos - float rg_gain=0.f, rg_peak=0.f; + for(i=0; i<3; i++) { + op.bytes = hsizes[i]; + op.packet = headers[i]; + op.b_o_s = (i == 0); + if(vorbis_synthesis_headerin(&ov->vi,&vc,&op) <0) { + mp_msg(MSGT_DECAUDIO,MSGL_ERR,"OggVorbis: header n. %d broken! len=%d\n", i, op.bytes); + ERROR(); + } + if(i == 2) { + float rg_gain=0.f, rg_peak=0.f; char **ptr=vc.user_comments; while(*ptr){ mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbisComment: %s\n",*ptr); @@ -130,7 +167,9 @@ if(rg_gain || rg_peak) mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Gain = %+.2f dB, Peak = %.4f, Scale = %.2f\n", rg_gain, rg_peak, ov->rg_scale); mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Encoded by: %s\n",vc.vendor); + } } + vorbis_comment_clear(&vc); // printf("lower=%d upper=%d \n",(int)ov->vi.bitrate_lower,(int)ov->vi.bitrate_upper);
--- a/libmpdemux/demux_mkv.c Thu May 12 15:31:37 2005 +0000 +++ b/libmpdemux/demux_mkv.c Thu May 12 17:35:58 2005 +0000 @@ -1781,48 +1781,8 @@ track->a_formattag = mmioFOURCC('M', 'P', '4', 'A'); else if (!strcmp(track->codec_id, MKV_A_VORBIS)) { - unsigned char *c; - uint32_t offset, length; - if (track->private_data == NULL) return 1; - - c = (unsigned char *) track->private_data; - if (*c != 2) - { - mp_msg (MSGT_DEMUX, MSGL_WARN, "[mkv] Vorbis track does not " - "contain valid headers.\n"); - return 1; - } - - offset = 1; - for (i=0; i < 2; i++) - { - length = 0; - while (c[offset] == (unsigned char) 0xFF - && length < track->private_size) - { - length += 255; - offset++; - } - if (offset >= (track->private_size - 1)) - { - mp_msg (MSGT_DEMUX, MSGL_WARN, "[mkv] Vorbis track " - "does not contain valid headers.\n"); - return 1; - } - length += c[offset]; - offset++; - track->header_sizes[i] = length; - } - - track->headers[0] = &c[offset]; - track->headers[1] = &c[offset + track->header_sizes[0]]; - track->headers[2] = &c[offset + track->header_sizes[0] + - track->header_sizes[1]]; - track->header_sizes[2] = track->private_size - offset - - track->header_sizes[0] - track->header_sizes[1]; - track->a_formattag = mmioFOURCC('v', 'r', 'b', 's'); } else if (!strcmp(track->codec_id, MKV_A_QDMC)) @@ -1954,14 +1914,9 @@ } else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's')) /* VORBIS */ { - for (i=0; i < 3; i++) - { - dp = new_demux_packet (track->header_sizes[i]); - memcpy (dp->buffer,track->headers[i],track->header_sizes[i]); - dp->pts = 0; - dp->flags = 0; - ds_add_packet (demuxer->audio, dp); - } + sh_a->wf->cbSize = track->private_size; + sh_a->wf = (WAVEFORMATEX*)realloc(sh_a->wf, sizeof(WAVEFORMATEX) + sh_a->wf->cbSize); + memcpy((unsigned char *) (sh_a->wf+1), track->private_data, sh_a->wf->cbSize); } else if (track->private_size >= sizeof(real_audio_v4_props_t) && !strncmp (track->codec_id, MKV_A_REALATRC, 7))
--- a/libmpdemux/demux_ogg.c Thu May 12 15:31:37 2005 +0000 +++ b/libmpdemux/demux_ogg.c Thu May 12 17:35:58 2005 +0000 @@ -736,6 +736,86 @@ void demux_close_ogg(demuxer_t* demuxer); +static inline unsigned int store_ughvlc(unsigned char *s, unsigned int v) +{ + unsigned int n = 0; + + while(v >= 0xff) + { + *s++ = 0xff; + v -= 0xff; + n++; + } + *s = v; + n++; + + return n; +} + +static void fixup_vorbis_wf(sh_audio_t *sh) +{ + int i, k, offset; + ogg_packet op[3]; + unsigned char *buf[3]; + unsigned char *ptr; + + for(i = 0; i < 3; i++) { + op[i].bytes = ds_get_packet(sh->ds, &(op[i].packet)); + mp_msg(MSGT_DEMUX,MSGL_V, "fixup_vorbis_wf: i=%d, size=%d\n", i, op[i].bytes); + if(op[i].bytes < 0) { + mp_msg(MSGT_DEMUX,MSGL_ERR,"Ogg demuxer error!, fixup_vorbis_wf: bad packet n. %d\n", i); + return; + } + buf[i] = malloc(op[i].bytes); + if(!buf[i]) + return; + memcpy(buf[i], op[i].packet, op[i].bytes); + } + + sh->wf = (WAVEFORMATEX*)calloc(1, sizeof(WAVEFORMATEX) + op[0].bytes + op[1].bytes + op[2].bytes + 64); + ptr = (unsigned char*) (sh->wf+1); + + ptr[0] = 2; + offset = 1; + offset += store_ughvlc(&ptr[offset], op[0].bytes); + mp_msg(MSGT_DEMUX,MSGL_V,"demux_ogg, offset after 1st len = %d\n", offset); + offset += store_ughvlc(&ptr[offset], op[1].bytes); + mp_msg(MSGT_DEMUX,MSGL_V,"demux_ogg, offset after 2nd len = %d\n", offset); + for(i = 0; i < 3; i++) { + mp_msg(MSGT_DEMUX,MSGL_V,"demux_ogg, i=%d\n", op[i].bytes, offset, i); + memcpy(&ptr[offset], buf[i], op[i].bytes); + offset += op[i].bytes; + } + sh->wf->cbSize = offset; + mp_msg(MSGT_DEMUX,MSGL_V, "demux_ogg, extradata size: %d\n", sh->wf->cbSize); + sh->wf = (WAVEFORMATEX*)realloc(sh->wf, sizeof(WAVEFORMATEX) + sh->wf->cbSize); + + if(op[0].bytes >= 29) { + unsigned int br, nombr, minbr, maxbr; + ptr = buf[0]; + sh->channels = ptr[11]; + sh->samplerate = sh->wf->nSamplesPerSec = get_uint32(&ptr[12]); + maxbr = get_uint32(&ptr[16]); //max + nombr = get_uint32(&ptr[20]); //nominal + minbr = get_uint32(&ptr[24]); //minimum + br = maxbr / 8; + if(!br) + br = nombr / 8; + if(!br) + br = minbr / 8; + sh->wf->nAvgBytesPerSec = br; + sh->wf->wBitsPerSample = 16; + sh->samplesize = (sh->wf->wBitsPerSample+7)/8; + + mp_msg(MSGT_DEMUX,MSGL_V,"demux_ogg, vorbis stream features are: channels: %d, srate: %d, bitrate: %d, max: %u, nominal: %u, min: %u\n", + sh->channels, sh->samplerate, sh->wf->nAvgBytesPerSec, maxbr, nombr, minbr); + } + free(buf[2]); + free(buf[1]); + free(buf[0]); +} + + /// Open an ogg physical stream int demux_ogg_open(demuxer_t* demuxer) { ogg_demuxer_t* ogg_d; @@ -1107,6 +1187,9 @@ mp_msg(MSGT_DEMUX,MSGL_V,"Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",n_audio,n_audio>1?"s":"",n_video,n_video>1?"s":"",ogg_d->n_text,ogg_d->n_text>1?"s":""); + if(sh_a->format == FOURCC_VORBIS) + fixup_vorbis_wf(sh_a); + return 1; err_out: