Mercurial > mplayer.hg
comparison libmpdemux/demux_mov.c @ 24182:8d6ad131c010
Split lschunks function further, it is simply too huge to do any useful changes (e.g. for
more proper support for multi-codec tracks).
author | reimar |
---|---|
date | Sat, 25 Aug 2007 18:09:00 +0000 |
parents | fd31150fe5b8 |
children | 7e5e6eff5a4f |
comparison
equal
deleted
inserted
replaced
24181:fe3fd951b8cc | 24182:8d6ad131c010 |
---|---|
576 } | 576 } |
577 | 577 |
578 static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, | 578 static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id, |
579 off_t pos, off_t len, mov_track_t* trak); | 579 off_t pos, off_t len, mov_track_t* trak); |
580 | 580 |
581 static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak){ | 581 static int gen_sh_audio(sh_audio_t* sh, mov_track_t* trak, int timescale) { |
582 mov_priv_t* priv=demuxer->priv; | |
583 // printf("lschunks (level=%d,endpos=%x)\n", level, endpos); | |
584 while(1){ | |
585 off_t pos; | |
586 off_t len; | |
587 unsigned int id; | |
588 // | |
589 pos=stream_tell(demuxer->stream); | |
590 // printf("stream_tell==%d\n",pos); | |
591 if(pos>=endpos) return; // END | |
592 len=stream_read_dword(demuxer->stream); | |
593 // printf("len==%d\n",len); | |
594 if(len<8) return; // error | |
595 len-=8; | |
596 id=stream_read_dword(demuxer->stream); | |
597 // | |
598 mp_msg(MSGT_DEMUX,MSGL_DBG2,"lschunks %.4s %d\n",(char *)&id,(int)len); | |
599 // | |
600 if(trak){ | |
601 if (lschunks_intrak(demuxer, level, id, pos, len, trak) < 0) | |
602 return; | |
603 } else { /* not in track */ | |
604 switch(id) { | |
605 case MOV_FOURCC('m','v','h','d'): { | |
606 int version = stream_read_char(demuxer->stream); | |
607 stream_skip(demuxer->stream, (version == 1) ? 19 : 11); | |
608 priv->timescale=stream_read_dword(demuxer->stream); | |
609 if (version == 1) | |
610 priv->duration=stream_read_qword(demuxer->stream); | |
611 else | |
612 priv->duration=stream_read_dword(demuxer->stream); | |
613 mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*sMovie header (%d bytes): tscale=%d dur=%d\n",level,"",(int)len, | |
614 (int)priv->timescale,(int)priv->duration); | |
615 break; | |
616 } | |
617 case MOV_FOURCC('t','r','a','k'): { | |
618 // if(trak) printf("MOV: Warning! trak in trak?\n"); | |
619 if(priv->track_db>=MOV_MAX_TRACKS){ | |
620 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_MOVtooManyTrk); | |
621 return; | |
622 } | |
623 if(!priv->track_db) mp_msg(MSGT_DEMUX, MSGL_V, "--------------\n"); | |
624 trak=malloc(sizeof(mov_track_t)); | |
625 memset(trak,0,sizeof(mov_track_t)); | |
626 mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Track #%d:\n",priv->track_db); | |
627 trak->id=priv->track_db; | |
628 priv->tracks[priv->track_db]=trak; | |
629 lschunks(demuxer,level+1,pos+len,trak); | |
630 mov_build_index(trak,priv->timescale); | |
631 switch(trak->type){ | |
632 case MOV_TRAK_AUDIO: { | |
633 #if 0 | 582 #if 0 |
634 struct { | 583 struct { |
635 int16_t version; // 0 or 1 (version 1 is qt3.0+) | 584 int16_t version; // 0 or 1 (version 1 is qt3.0+) |
636 int16_t revision; // 0 | 585 int16_t revision; // 0 |
637 int32_t vendor_id; // 0 | 586 int32_t vendor_id; // 0 |
655 // ([int32_t size,int32_t type,some data ],repeat) | 604 // ([int32_t size,int32_t type,some data ],repeat) |
656 } my_stdata; | 605 } my_stdata; |
657 #endif | 606 #endif |
658 int version, adjust; | 607 int version, adjust; |
659 int is_vorbis = 0; | 608 int is_vorbis = 0; |
660 sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db); | |
661 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "mov", priv->track_db); | |
662 sh->format=trak->fourcc; | 609 sh->format=trak->fourcc; |
663 | 610 |
664 // crude audio delay from editlist0 hack ::atm | 611 // crude audio delay from editlist0 hack ::atm |
665 if(trak->editlist_size>=1) { | 612 if(trak->editlist_size>=1) { |
666 if(trak->editlist[0].pos == -1) { | 613 if(trak->editlist[0].pos == -1) { |
667 sh->stream_delay = (float)trak->editlist[0].dur/(float)priv->timescale; | 614 sh->stream_delay = (float)trak->editlist[0].dur/(float)timescale; |
668 mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Initial Audio-Delay: %.3f sec\n", sh->stream_delay); | 615 mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Initial Audio-Delay: %.3f sec\n", sh->stream_delay); |
669 } | 616 } |
670 } | 617 } |
671 | 618 |
672 | 619 |
972 // if(demuxer->audio->id==-1 || demuxer->audio->id==priv->track_db){ | 919 // if(demuxer->audio->id==-1 || demuxer->audio->id==priv->track_db){ |
973 // // (auto)selected audio track: | 920 // // (auto)selected audio track: |
974 // demuxer->audio->id=priv->track_db; | 921 // demuxer->audio->id=priv->track_db; |
975 // demuxer->audio->sh=sh; sh->ds=demuxer->audio; | 922 // demuxer->audio->sh=sh; sh->ds=demuxer->audio; |
976 // } | 923 // } |
977 break; | 924 return 1; |
978 } | 925 } |
979 case MOV_TRAK_VIDEO: { | 926 |
927 static int gen_sh_video(sh_video_t* sh, mov_track_t* trak, int timescale) { | |
980 int depth, i, entry; | 928 int depth, i, entry; |
981 int flag, start, count_flag, end, palette_count, gray; | 929 int flag, start, count_flag, end, palette_count, gray; |
982 int hdr_ptr = 76; // the byte just after depth | 930 int hdr_ptr = 76; // the byte just after depth |
983 unsigned char *palette_map; | 931 unsigned char *palette_map; |
984 sh_video_t* sh=new_sh_video(demuxer,priv->track_db); | |
985 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "mov", priv->track_db); | |
986 sh->format=trak->fourcc; | 932 sh->format=trak->fourcc; |
987 | 933 |
988 // crude video delay from editlist0 hack ::atm | 934 // crude video delay from editlist0 hack ::atm |
989 if(trak->editlist_size>=1) { | 935 if(trak->editlist_size>=1) { |
990 if(trak->editlist[0].pos == -1) { | 936 if(trak->editlist[0].pos == -1) { |
991 sh->stream_delay = (float)trak->editlist[0].dur/(float)priv->timescale; | 937 sh->stream_delay = (float)trak->editlist[0].dur/(float)timescale; |
992 mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Initial Video-Delay: %.3f sec\n", sh->stream_delay); | 938 mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Initial Video-Delay: %.3f sec\n", sh->stream_delay); |
993 } | 939 } |
994 } | 940 } |
995 | 941 |
996 | 942 |
997 if (trak->stdata_len < 78) { | 943 if (trak->stdata_len < 78) { |
998 mp_msg(MSGT_DEMUXER, MSGL_WARN, | 944 mp_msg(MSGT_DEMUXER, MSGL_WARN, |
999 "MOV: Invalid (%d bytes instead of >= 78) video trak desc\n", | 945 "MOV: Invalid (%d bytes instead of >= 78) video trak desc\n", |
1000 trak->stdata_len); | 946 trak->stdata_len); |
1001 break; | 947 return 0; |
1002 } | 948 } |
1003 depth = trak->stdata[75] | (trak->stdata[74] << 8); | 949 depth = trak->stdata[75] | (trak->stdata[74] << 8); |
1004 // stdata[]: | 950 // stdata[]: |
1005 // 8 short version | 951 // 8 short version |
1006 // 10 short revision | 952 // 10 short revision |
1302 // if(demuxer->video->id==-1 || demuxer->video->id==priv->track_db){ | 1248 // if(demuxer->video->id==-1 || demuxer->video->id==priv->track_db){ |
1303 // // (auto)selected video track: | 1249 // // (auto)selected video track: |
1304 // demuxer->video->id=priv->track_db; | 1250 // demuxer->video->id=priv->track_db; |
1305 // demuxer->video->sh=sh; sh->ds=demuxer->video; | 1251 // demuxer->video->sh=sh; sh->ds=demuxer->video; |
1306 // } | 1252 // } |
1253 return 1; | |
1254 } | |
1255 | |
1256 static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak){ | |
1257 mov_priv_t* priv=demuxer->priv; | |
1258 // printf("lschunks (level=%d,endpos=%x)\n", level, endpos); | |
1259 while(1){ | |
1260 off_t pos; | |
1261 off_t len; | |
1262 unsigned int id; | |
1263 // | |
1264 pos=stream_tell(demuxer->stream); | |
1265 // printf("stream_tell==%d\n",pos); | |
1266 if(pos>=endpos) return; // END | |
1267 len=stream_read_dword(demuxer->stream); | |
1268 // printf("len==%d\n",len); | |
1269 if(len<8) return; // error | |
1270 len-=8; | |
1271 id=stream_read_dword(demuxer->stream); | |
1272 // | |
1273 mp_msg(MSGT_DEMUX,MSGL_DBG2,"lschunks %.4s %d\n",(char *)&id,(int)len); | |
1274 // | |
1275 if(trak){ | |
1276 if (lschunks_intrak(demuxer, level, id, pos, len, trak) < 0) | |
1277 return; | |
1278 } else { /* not in track */ | |
1279 switch(id) { | |
1280 case MOV_FOURCC('m','v','h','d'): { | |
1281 int version = stream_read_char(demuxer->stream); | |
1282 stream_skip(demuxer->stream, (version == 1) ? 19 : 11); | |
1283 priv->timescale=stream_read_dword(demuxer->stream); | |
1284 if (version == 1) | |
1285 priv->duration=stream_read_qword(demuxer->stream); | |
1286 else | |
1287 priv->duration=stream_read_dword(demuxer->stream); | |
1288 mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*sMovie header (%d bytes): tscale=%d dur=%d\n",level,"",(int)len, | |
1289 (int)priv->timescale,(int)priv->duration); | |
1290 break; | |
1291 } | |
1292 case MOV_FOURCC('t','r','a','k'): { | |
1293 // if(trak) printf("MOV: Warning! trak in trak?\n"); | |
1294 if(priv->track_db>=MOV_MAX_TRACKS){ | |
1295 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_MOVtooManyTrk); | |
1296 return; | |
1297 } | |
1298 if(!priv->track_db) mp_msg(MSGT_DEMUX, MSGL_V, "--------------\n"); | |
1299 trak=malloc(sizeof(mov_track_t)); | |
1300 memset(trak,0,sizeof(mov_track_t)); | |
1301 mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Track #%d:\n",priv->track_db); | |
1302 trak->id=priv->track_db; | |
1303 priv->tracks[priv->track_db]=trak; | |
1304 lschunks(demuxer,level+1,pos+len,trak); | |
1305 mov_build_index(trak,priv->timescale); | |
1306 switch(trak->type){ | |
1307 case MOV_TRAK_AUDIO: { | |
1308 sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db); | |
1309 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "mov", priv->track_db); | |
1310 gen_sh_audio(sh, trak, priv->timescale); | |
1311 break; | |
1312 } | |
1313 case MOV_TRAK_VIDEO: { | |
1314 sh_video_t* sh=new_sh_video(demuxer,priv->track_db); | |
1315 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "mov", priv->track_db); | |
1316 gen_sh_video(sh, trak, priv->timescale); | |
1307 break; | 1317 break; |
1308 } | 1318 } |
1309 case MOV_TRAK_GENERIC: | 1319 case MOV_TRAK_GENERIC: |
1310 if (trak->fourcc == mmioFOURCC('m','p','4','s') || | 1320 if (trak->fourcc == mmioFOURCC('m','p','4','s') || |
1311 trak->fourcc == mmioFOURCC('t','x','3','g') || | 1321 trak->fourcc == mmioFOURCC('t','x','3','g') || |