summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authornicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-06-09 21:30:06 +0000
committernicodvb <nicodvb@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-06-09 21:30:06 +0000
commitd96e0e658a049b4ff23b07383873198e5d512244 (patch)
tree44038cbdd6e7e0cfaa611c927991b483076f7f5d /libmpdemux
parent1fe2e1963e3cc067dfb147a54c316f3603ccf445 (diff)
downloadmpv-d96e0e658a049b4ff23b07383873198e5d512244.tar.bz2
mpv-d96e0e658a049b4ff23b07383873198e5d512244.tar.xz
support for vorbis in mp4/mov
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18668 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/demux_mov.c62
-rw-r--r--libmpdemux/demux_ogg.c2
2 files changed, 61 insertions, 3 deletions
diff --git a/libmpdemux/demux_mov.c b/libmpdemux/demux_mov.c
index da08cac447..6559bb777e 100644
--- a/libmpdemux/demux_mov.c
+++ b/libmpdemux/demux_mov.c
@@ -544,6 +544,7 @@ static void demux_close_mov(demuxer_t *demuxer) {
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 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
} 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 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
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 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
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 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
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 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
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:
diff --git a/libmpdemux/demux_ogg.c b/libmpdemux/demux_ogg.c
index a98aba2e33..e922e7fa8c 100644
--- a/libmpdemux/demux_ogg.c
+++ b/libmpdemux/demux_ogg.c
@@ -763,7 +763,7 @@ char *demux_ogg_sub_lang(demuxer_t *demuxer, int index) {
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;