1 /*****************************************************************************
2 * mp4.h : MP4 file input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2001 VideoLAN
5 * $Id: mp4.h,v 1.2 2002/07/21 15:13:19 fenrir Exp $
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
25 /*****************************************************************************
26 * Structure needed for ffmpeg decoder
27 *****************************************************************************/
29 typedef struct bitmapinfoheader_s
31 u32 i_size; /* size of header */
46 /*****************************************************************************
47 * Contain all information about a chunk
48 *****************************************************************************/
49 typedef struct chunk_data_mp4_s
51 u64 i_offset; /* absolute position of this chunk in the file */
52 u32 i_sample_description_index; /* index for SampleEntry to use */
53 u32 i_sample_count; /* how many samples in this chunk */
54 u32 i_sample_first; /* index of the first sample in this chunk */
56 /* now provide way to calculate pts, dts, and offset without to
57 much memory and with fast acces */
59 /* with this we can calculate dts/pts without waste memory */
61 u32 *p_sample_count_dts;
62 u32 *p_sample_delta_dts; /* dts delta */
64 /* TODO if needed add pts
65 but quickly *add* support for edts and seeking */
70 /*****************************************************************************
71 * Contain all needed information for read all track with vlc
72 *****************************************************************************/
73 typedef struct track_data_mp4_s
75 int b_ok; /* The track is usable */
76 int i_track_ID; /* this should be unique */
77 int b_enable; /* is the trak enable by default */
79 int i_cat; /* Type of the track, VIDEO_ES, AUDIO_ES, UNKNOWN_ES ... */
82 /* display size only ! */
86 /* more internal data */
87 u64 i_timescale; /* time scale for this track only */
89 /* give the next sample to read, i_chunk is to find quickly where
90 the sample is located */
91 u32 i_sample; /* next sample to read */
92 u32 i_chunk; /* chunk where next sample is stored */
93 /* total count of chunk and sample */
97 chunk_data_mp4_t *chunk; /* always defined for each chunk */
99 /* sample size, p_sample_size defined only if i_sample_size == 0
100 else i_sample_size is size for all sample */
102 u32 *p_sample_size; /* XXX perhaps add file offset if take
103 too much time to do sumations each time*/
105 es_descriptor_t *p_es; /* vlc es for this track */
106 data_packet_t *p_data_init; /* send this with the first packet,
107 and then discarded it*/
109 MP4_Box_t *p_stbl; /* will contain all timing information */
110 MP4_Box_t *p_stsd; /* will contain all data to initialize decoder */
112 MP4_Box_t *p_sample; /* actual SampleEntry to make life simpler */
116 /*****************************************************************************
118 *****************************************************************************/
119 typedef struct demux_data_mp4_s
122 MP4_Box_t box_root; /* container for the hole file */
126 u64 i_time; /* time position of the presentation in movie timescale */
127 u64 i_timescale; /* movie time scale */
129 int i_tracks; /* number of track */
130 track_data_mp4_t *track; /* array of track */
135 static inline u64 MP4_GetTrackPos( track_data_mp4_t *p_track )
141 i_pos = p_track->chunk[p_track->i_chunk].i_offset;
143 if( p_track->i_sample_size )
145 i_pos += ( p_track->i_sample -
146 p_track->chunk[p_track->i_chunk].i_sample_first ) *
147 p_track->i_sample_size;
151 for( i_sample = p_track->chunk[p_track->i_chunk].i_sample_first;
152 i_sample < p_track->i_sample; i_sample++ )
154 i_pos += p_track->p_sample_size[i_sample];
161 /* Return time in µs of a track */
162 static inline mtime_t MP4_GetTrackPTS( track_data_mp4_t *p_track )
168 i_sample = p_track->i_sample - p_track->chunk[p_track->i_chunk].i_sample_first;
169 i_dts = p_track->chunk[p_track->i_chunk].i_first_dts;
171 while( i_sample > 0 )
173 if( i_sample > p_track->chunk[p_track->i_chunk].p_sample_count_dts[i_index] )
175 i_dts += p_track->chunk[p_track->i_chunk].p_sample_count_dts[i_index] *
176 p_track->chunk[p_track->i_chunk].p_sample_delta_dts[i_index];
177 i_sample -= p_track->chunk[p_track->i_chunk].p_sample_count_dts[i_index];
183 p_track->chunk[p_track->i_chunk].p_sample_delta_dts[i_index];
191 (mtime_t)p_track->i_timescale ) );
194 static inline mtime_t MP4_GetMoviePTS(demux_data_mp4_t *p_demux )
198 (mtime_t)p_demux->i_time /
199 (mtime_t)p_demux->i_timescale )
210 { FOURCC_vide, UNKNOWN_ES, "Generic VisualSampleEntry" },
211 { FOURCC_DIVX, MPEG4_VIDEO_ES, "DIVX SampleEntry (MPEG-4)" },
212 { FOURCC_h263, H263_VIDEO_ES, "H263 SampleEntry" },
213 { FOURCC_SVQ1, SVQ1_VIDEO_ES, "SVQ1 SampleEntry (Sorenson Video v1" },
214 { FOURCC_mp4v, MPEG4_VIDEO_ES, "MP4VisualSampleEntry (MPEG-4)" },
215 { FOURCC_3IV1, UNKNOWN_ES, "3IV1 SampleEntry" },
216 { FOURCC_cvid, CINEPAK_VIDEO_ES,"cvid SampleEntry (Cinepak Video Codec)" },
219 { FOURCC_soun, UNKNOWN_ES, "Generic AudioSampleEntry" },
220 { FOURCC_mp4a, UNKNOWN_ES, "MP4AudioSampleEntry (AAC)" },
221 { FOURCC__mp3, MPEG2_AUDIO_ES, ".mp3 SampleEntry (MPEG-I/II layer 3)" },
223 /* Last entry with fourcc == 0 */
224 { 0, UNKNOWN_ES, "Unknown SampleEntry" }
227 static int MP4_GetCodec( u32 i_fourcc,
235 if( ( MP4_Codecs[i].i_fourcc == i_fourcc )||
236 ( MP4_Codecs[i].i_fourcc == 0) )
243 *pi_codec = MP4_Codecs[i].i_codec;
246 *ppsz_name = MP4_Codecs[i].psz_name;
248 return( MP4_Codecs[i].i_codec == UNKNOWN_ES ? 0 : 1 );