changeset 18667:495142cba779

support for vorbis in mp4/mov
author nicodvb
date Fri, 09 Jun 2006 21:30:06 +0000
parents 492c6d674c3e
children 5a77f8808432
files libmpdemux/demux_mov.c libmpdemux/demux_ogg.c
diffstat 2 files changed, 61 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_mov.c	Fri Jun 09 21:29:18 2006 +0000
+++ b/libmpdemux/demux_mov.c	Fri Jun 09 21:30:06 2006 +0000
@@ -544,6 +544,7 @@
 static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id,
                            off_t pos, off_t len, mov_track_t* trak);
 
+extern unsigned int store_ughvlc(unsigned char *s, unsigned int v);
 static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak){
     mov_priv_t* priv=demuxer->priv;
 //    printf("lschunks (level=%d,endpos=%x)\n", level, endpos);
@@ -618,6 +619,7 @@
 		} my_stdata;		  
 #endif		
 		int version, adjust;
+		int is_vorbis = 0;
 		sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db);
 		sh->format=trak->fourcc;
 
@@ -780,7 +782,54 @@
 			if(atom_len > 8) {
 			  esds_t esds; 				  
 			  if(!mp4_parse_esds(&trak->stdata[36+adjust], atom_len-8, &esds)) {
-			    
+			    if(sh->format==0x6134706D && esds.decoderConfigLen > 8)
+				{
+					//vorbis audio
+					unsigned char *buf[3];
+					unsigned short sizes[3];
+					int offset, len, k;
+					unsigned char *ptr = esds.decoderConfig;
+
+					if(ptr[0] != 0 || ptr[1] != 30) goto quit_vorbis_block; //wrong extradata layout
+
+					offset = len = 0;
+					for(k = 0; k < 3; k++)
+					{
+						sizes[k] = (ptr[offset]<<8) | ptr[offset+1];
+						len += sizes[k];
+						offset += 2;
+						if(offset + sizes[k] > esds.decoderConfigLen)
+						{
+							mp_msg(MSGT_DEMUX, MSGL_FATAL, "MOV: ERROR!, not enough vorbis extradata to read: offset = %d, k=%d, size=%d, len: %d\n", offset, k, sizes[k], esds.decoderConfigLen);
+							goto quit_vorbis_block;
+						}
+						buf[k] = malloc(sizes[k]);
+						if(!buf[k]) goto quit_vorbis_block;
+						memcpy(buf[k], &ptr[offset], sizes[k]);
+						offset += sizes[k];
+					}
+
+					sh->codecdata_len = len + len/255 + 64;
+					sh->codecdata = malloc(sh->codecdata_len);
+					ptr = sh->codecdata;
+					
+					ptr[0] = 2;
+					offset = 1;
+					offset += store_ughvlc(&ptr[offset], sizes[0]);
+					offset += store_ughvlc(&ptr[offset], sizes[1]);
+					for(k = 0; k < 3; k++) 
+					{
+						memcpy(&ptr[offset], buf[k], sizes[k]);
+						offset += sizes[k];
+					}
+
+					sh->codecdata_len = offset;
+					sh->codecdata = realloc(sh->codecdata, offset);
+					mp_msg(MSGT_DEMUX,MSGL_V, "demux_mov, vorbis extradata size: %d\n", offset);
+					is_vorbis = 1;
+quit_vorbis_block:
+					sh->format = mmioFOURCC('v', 'r', 'b', 's');
+				}
 			    sh->i_bps = esds.avgBitrate/8; 
 
 //			    printf("######## audio format = %d ########\n",esds.objectTypeId);
@@ -791,10 +840,13 @@
 			    if(esds.decoderConfigLen){
 			    if( (esds.decoderConfig[0]>>3) == 29 )
 			    	sh->format = 0x1d61346d; // request multi-channel mp3 decoder
+			    if(!is_vorbis)
+			    {
 			    sh->codecdata_len = esds.decoderConfigLen;
 			    sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);
 			    memcpy(sh->codecdata, esds.decoderConfig, sh->codecdata_len);
 			    }
+			    }
 			  }
 			  mp4_free_esds(&esds); // freeup esds mem
 #if 0
@@ -837,7 +889,7 @@
 		  fclose(f); }
 #endif
 		// Emulate WAVEFORMATEX struct:
-		sh->wf=malloc(sizeof(WAVEFORMATEX));
+		sh->wf=malloc(sizeof(WAVEFORMATEX) + (is_vorbis ? sh->codecdata_len : 0));
 		memset(sh->wf,0,sizeof(WAVEFORMATEX));
 		sh->wf->nChannels=sh->channels;
 		sh->wf->wBitsPerSample=(trak->stdata[18]<<8)+trak->stdata[19];
@@ -855,6 +907,12 @@
 		  if (sh->format == 0x1100736d && trak->stdata_len >= 36)
 		      sh->wf->nBlockAlign=char2int(trak->stdata,36);
 		}
+
+		if(is_vorbis && sh->codecdata_len)
+		{
+			memcpy(sh->wf+1, sh->codecdata, sh->codecdata_len);
+			sh->wf->cbSize = sh->codecdata_len;
+		}
 		// Selection:
 //		if(demuxer->audio->id==-1 || demuxer->audio->id==priv->track_db){
 //		    // (auto)selected audio track:
--- a/libmpdemux/demux_ogg.c	Fri Jun 09 21:29:18 2006 +0000
+++ b/libmpdemux/demux_ogg.c	Fri Jun 09 21:30:06 2006 +0000
@@ -763,7 +763,7 @@
 
 static void demux_close_ogg(demuxer_t* demuxer);
 
-static inline unsigned int store_ughvlc(unsigned char *s, unsigned int v)
+unsigned int store_ughvlc(unsigned char *s, unsigned int v)
 {
   unsigned int n = 0;