allow ffmpeg video to resample curr_pos, add bluray format
[goodguy/history.git] / cinelerra-5.0 / quicktime / esds.c
1 #include "funcprotos.h"
2 #include "quicktime.h"
3
4
5 static int decode_length(quicktime_t *file)
6 {
7         int bytes = 0;
8         int result = 0;
9         int byte;
10         do
11         {
12                 byte = quicktime_read_char(file);
13                 result = (result << 7) + (byte & 0x7f);
14                 bytes++;
15         }while((byte & 0x80) && bytes < 4);
16         return result;
17 }
18
19 void quicktime_delete_esds(quicktime_esds_t *esds)
20 {
21         if(esds->mpeg4_header) free(esds->mpeg4_header);
22 }
23
24 void quicktime_esds_samplerate(quicktime_stsd_table_t *table, 
25         quicktime_esds_t *esds)
26 {
27 // Straight out of ffmpeg
28         if(esds->mpeg4_header_size > 1 &&
29                 quicktime_match_32(table->format, QUICKTIME_MP4A))
30         {
31                 static int samplerate_table[] = 
32                 {
33              96000, 88200, 64000, 48000, 44100, 32000, 
34              24000, 22050, 16000, 12000, 11025, 8000, 
35              7350, 0, 0, 0
36         };
37
38                 unsigned char *ptr = (unsigned char *)esds->mpeg4_header;
39                 int samplerate_index = ((ptr[0] & 7) << 1) + ((ptr[1] >> 7) & 1);
40                 table->channels = (ptr[1] >> 3) & 0xf;
41                 table->sample_rate = 
42                         samplerate_table[samplerate_index];
43 // Faad decodes 1/2 the requested samplerate if the samplerate is <= 22050.
44         }
45 }
46
47 void quicktime_read_esds(quicktime_t *file, 
48         quicktime_atom_t *parent_atom, 
49         quicktime_esds_t *esds)
50 {
51
52 // version
53         quicktime_read_char(file);
54 // flags
55         quicktime_read_int24(file);
56 // elementary stream descriptor tag
57
58         if(quicktime_read_char(file) == 0x3)
59         {
60                 decode_length(file);
61                 quicktime_read_int16(file); // elementary stream id
62                 quicktime_read_char(file); // stream priority
63 // decoder configuration descripton tab
64                 if(quicktime_read_char(file) == 0x4)
65                 {
66                         decode_length(file);
67                         quicktime_read_char(file); // object type id
68                         quicktime_read_char(file); // stream type
69                         quicktime_read_int24(file); // buffer size
70                         quicktime_read_int32(file); // max bitrate
71                         quicktime_read_int32(file); // average bitrate
72
73 // decoder specific description tag
74                         if(quicktime_read_char(file) == 0x5)
75                         {
76                                 esds->mpeg4_header_size = decode_length(file);
77                                 if(!esds->mpeg4_header_size) return;
78
79 // Need padding for FFMPEG
80                                 esds->mpeg4_header = calloc(1, 
81                                         esds->mpeg4_header_size + 1024);
82 // Get extra data for decoder
83                                 quicktime_read_data(file, 
84                                         esds->mpeg4_header, 
85                                         esds->mpeg4_header_size);
86
87 // skip rest
88                                 quicktime_atom_skip(file, parent_atom);
89                                 return;
90                         }
91                         else
92                         {
93 // error
94                                 quicktime_atom_skip(file, parent_atom);
95                                 return;
96                         }
97                 }
98                 else
99                 {
100 // error
101                         quicktime_atom_skip(file, parent_atom);
102                         return;
103                 }
104         }
105         else
106         {
107 // error
108                 quicktime_atom_skip(file, parent_atom);
109                 return;
110         }
111 }
112
113
114
115 void quicktime_write_esds(quicktime_t *file, 
116         quicktime_esds_t *esds,
117         int do_video,
118         int do_audio)
119 {
120         quicktime_atom_t atom;
121         quicktime_atom_write_header(file, &atom, "esds");
122 // version
123         quicktime_write_char(file, 0);
124 // flags
125         quicktime_write_int24(file, 0);
126
127 // elementary stream descriptor tag
128         quicktime_write_char(file, 0x3);
129
130 // length placeholder
131         int64_t length1 = quicktime_position(file);
132 //      quicktime_write_int32(file, 0x80808080);
133         quicktime_write_char(file, 0x00);
134
135 // elementary stream id
136         quicktime_write_int16(file, 0x1);
137
138 // stream priority
139 /*
140  *      if(do_video)
141  *              quicktime_write_char(file, 0x1f);
142  *      else
143  */
144                 quicktime_write_char(file, 0);
145
146
147 // decoder configuration description tab
148         quicktime_write_char(file, 0x4);
149 // length placeholder
150         int64_t length2 = quicktime_position(file);
151 //      quicktime_write_int32(file, 0x80808080);
152         quicktime_write_char(file, 0x00);
153
154 // video
155         if(do_video)
156         {
157 // object type id
158                 quicktime_write_char(file, 0x20);
159 // stream type
160                 quicktime_write_char(file, 0x11);
161 // buffer size
162 //              quicktime_write_int24(file, 0x007b00);
163                 quicktime_write_int24(file, 0x000000);
164 // max bitrate
165 //              quicktime_write_int32(file, 0x00014800);
166                 quicktime_write_int32(file, 0x000030d40);
167 // average bitrate
168 //              quicktime_write_int32(file, 0x00014800);
169                 quicktime_write_int32(file, 0x00000000);
170         }
171         else
172         {
173 // object type id
174                 quicktime_write_char(file, 0x40);
175 // stream type
176                 quicktime_write_char(file, 0x15);
177 // buffer size
178                 quicktime_write_int24(file, 0x001800);
179 // max bitrate
180                 quicktime_write_int32(file, 0x00004e20);
181 // average bitrate
182                 quicktime_write_int32(file, 0x00003e80);
183         }
184
185 // decoder specific description tag
186         quicktime_write_char(file, 0x05);
187 // length placeholder
188         int64_t length3 = quicktime_position(file);
189 //      quicktime_write_int32(file, 0x80808080);
190         quicktime_write_char(file, 0x00);
191
192 // mpeg4 sequence header
193         quicktime_write_data(file, esds->mpeg4_header, esds->mpeg4_header_size);
194
195
196         int64_t current_length2 = quicktime_position(file) - length2 - 1;
197         int64_t current_length3 = quicktime_position(file) - length3 - 1;
198
199 // unknown tag, length and data
200         quicktime_write_char(file, 0x06);
201 //      quicktime_write_int32(file, 0x80808001);
202         quicktime_write_char(file, 0x01);
203         quicktime_write_char(file, 0x02);
204
205
206 // write lengths
207         int64_t current_length1 = quicktime_position(file) - length1 - 1;
208         quicktime_atom_write_footer(file, &atom);
209         int64_t current_position = quicktime_position(file);
210 //      quicktime_set_position(file, length1 + 3);
211         quicktime_set_position(file, length1);
212         quicktime_write_char(file, current_length1);
213 //      quicktime_set_position(file, length2 + 3);
214         quicktime_set_position(file, length2);
215         quicktime_write_char(file, current_length2);
216 //      quicktime_set_position(file, length3 + 3);
217         quicktime_set_position(file, length3);
218         quicktime_write_char(file, current_length3);
219         quicktime_set_position(file, current_position);
220 }
221
222 void quicktime_esds_dump(quicktime_esds_t *esds)
223 {
224         if(esds->mpeg4_header_size)
225         {
226                 printf("       elementary stream description\n");
227                 printf("        mpeg4_header_size=0x%x\n", esds->mpeg4_header_size);
228                 printf("        mpeg4_header=");
229                 int i;
230                 for(i = 0; i < esds->mpeg4_header_size; i++)
231                         printf("%02x ", (unsigned char)esds->mpeg4_header[i]);
232                 printf("\n");
233         }
234 }
235
236