]> git.sesse.net Git - vlc/blob - modules/demux/mp4/mp4.h
* ./configure.ac.in: removed -W in favour of -Wtraditional.
[vlc] / modules / demux / mp4 / mp4.h
1 /*****************************************************************************
2  * mp4.h : MP4 file input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: mp4.h,v 1.5 2002/12/06 16:34:06 sam Exp $
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *
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.
12  *
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.
17  *
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  *****************************************************************************/
22
23
24
25 /*****************************************************************************
26  * Structure needed for decoder
27  *****************************************************************************/
28 typedef struct bitmapinfoheader_s
29 {
30     uint32_t i_size; /* size of header 40 + size of data follwoing this header */
31     uint32_t i_width;
32     uint32_t i_height;
33     uint16_t i_planes;
34     uint16_t i_bitcount;
35     uint32_t i_compression;
36     uint32_t i_sizeimage;
37     uint32_t i_xpelspermeter;
38     uint32_t i_ypelspermeter;
39     uint32_t i_clrused;
40     uint32_t i_clrimportant;
41 } bitmapinfoheader_t;
42
43 typedef struct waveformatex_s
44 {
45     uint16_t i_format;
46     uint16_t i_channels;
47     uint32_t i_samplepersec;
48     uint32_t i_avgbytespersec;
49     uint16_t i_blockalign;
50     uint16_t i_bitspersample;
51     uint16_t i_size;          /* This give size of data
52                             imediatly following this header. */
53 } waveformatex_t;
54
55 /*****************************************************************************
56  * Contain all information about a chunk
57  *****************************************************************************/
58 typedef struct chunk_data_mp4_s
59 {
60     uint64_t     i_offset; /* absolute position of this chunk in the file */
61     uint32_t     i_sample_description_index; /* index for SampleEntry to use */
62     uint32_t     i_sample_count; /* how many samples in this chunk */
63     uint32_t     i_sample_first; /* index of the first sample in this chunk */
64
65     /* now provide way to calculate pts, dts, and offset without to
66         much memory and with fast acces */
67
68     /* with this we can calculate dts/pts without waste memory */
69     uint64_t     i_first_dts;
70     uint32_t     *p_sample_count_dts;
71     uint32_t     *p_sample_delta_dts; /* dts delta */
72
73     /* TODO if needed add pts
74         but quickly *add* support for edts and seeking */
75
76 } chunk_data_mp4_t;
77
78
79 /*****************************************************************************
80  * Contain all needed information for read all track with vlc
81  *****************************************************************************/
82 typedef struct track_data_mp4_s
83 {
84     int b_ok;           /* The track is usable */
85     int i_track_ID;     /* this should be unique */
86     int b_enable;       /* is the trak enable by default */
87     int b_selected;     /* is the trak being played */
88     int i_cat;          /* Type of the track, VIDEO_ES, AUDIO_ES, UNKNOWN_ES  ... */
89     char        i_language[3];
90
91     /* display size only ! */
92     int         i_width;
93     int         i_height;
94
95     /* more internal data */
96     uint64_t         i_timescale;  /* time scale for this track only */
97
98     /* give the next sample to read, i_chunk is to find quickly where
99       the sample is located */
100     uint32_t         i_sample;       /* next sample to read */
101     uint32_t         i_chunk;        /* chunk where next sample is stored */
102     /* total count of chunk and sample */
103     uint32_t         i_chunk_count;
104     uint32_t         i_sample_count;
105
106     chunk_data_mp4_t    *chunk; /* always defined  for each chunk */
107
108     /* sample size, p_sample_size defined only if i_sample_size == 0
109         else i_sample_size is size for all sample */
110     uint32_t         i_sample_size;
111     uint32_t         *p_sample_size; /* XXX perhaps add file offset if take
112                                     too much time to do sumations each time*/
113
114     es_descriptor_t *p_es; /* vlc es for this track */
115
116     MP4_Box_t *p_stbl;  /* will contain all timing information */
117     MP4_Box_t *p_stsd;  /* will contain all data to initialize decoder */
118
119     MP4_Box_t *p_sample; /* actual SampleEntry to make life simpler */
120 } track_data_mp4_t;
121
122
123 /*****************************************************************************
124  *
125  *****************************************************************************/
126 struct demux_sys_t
127 {
128     MP4_Box_t   box_root;      /* container for the whole file */
129
130     mtime_t      i_pcr;
131
132     uint64_t     i_time;        /* time position of the presentation
133                                  * in movie timescale */
134     uint64_t     i_timescale;   /* movie time scale */
135     uint64_t     i_duration;    /* movie duration */
136     unsigned int i_tracks;      /* number of tracks */
137     track_data_mp4_t *track;    /* array of track */
138 };
139
140 static inline uint64_t MP4_GetTrackPos( track_data_mp4_t *p_track )
141 {
142     unsigned int i_sample;
143     uint64_t i_pos;
144
145
146     i_pos = p_track->chunk[p_track->i_chunk].i_offset;
147
148     if( p_track->i_sample_size )
149     {
150         i_pos += ( p_track->i_sample -
151                         p_track->chunk[p_track->i_chunk].i_sample_first ) *
152                                 p_track->i_sample_size;
153     }
154     else
155     {
156         for( i_sample = p_track->chunk[p_track->i_chunk].i_sample_first;
157                 i_sample < p_track->i_sample; i_sample++ )
158         {
159             i_pos += p_track->p_sample_size[i_sample];
160         }
161
162     }
163     return( i_pos );
164 }
165
166 /* Return time in µs of a track */
167 static inline mtime_t MP4_GetTrackPTS( track_data_mp4_t *p_track )
168 {
169     unsigned int i_sample;
170     unsigned int i_index;
171     uint64_t i_dts;
172
173     i_sample = p_track->i_sample - p_track->chunk[p_track->i_chunk].i_sample_first;
174     i_dts = p_track->chunk[p_track->i_chunk].i_first_dts;
175     i_index = 0;
176     while( i_sample > 0 )
177     {
178         if( i_sample > p_track->chunk[p_track->i_chunk].p_sample_count_dts[i_index] )
179         {
180             i_dts += p_track->chunk[p_track->i_chunk].p_sample_count_dts[i_index] *
181                         p_track->chunk[p_track->i_chunk].p_sample_delta_dts[i_index];
182             i_sample -= p_track->chunk[p_track->i_chunk].p_sample_count_dts[i_index];
183             i_index++;
184         }
185         else
186         {
187             i_dts += i_sample *
188                         p_track->chunk[p_track->i_chunk].p_sample_delta_dts[i_index];
189             i_sample = 0;
190             break;
191         }
192     }
193     return( (mtime_t)(
194                 (mtime_t)1000000 *
195                 (mtime_t)i_dts /
196                 (mtime_t)p_track->i_timescale ) );
197 }
198
199 static inline mtime_t MP4_GetMoviePTS(demux_sys_t *p_demux )
200 {
201     return( (mtime_t)(
202                 (mtime_t)1000000 *
203                 (mtime_t)p_demux->i_time /
204                 (mtime_t)p_demux->i_timescale )
205           );
206 }