bunch of small fixes, add msg.txt to about prefs
[goodguy/history.git] / cinelerra-5.0 / quicktime / qtasf.c
1 #include "funcprotos.h"
2 #include "qtasf.h"
3 #include "qtasf_codes.h"
4
5 #include <string.h>
6
7 /* We have lifted sections of ASF decoding from ffmpeg */
8 /* to add direct copy support and seeking to it */
9
10 int quicktime_read_guid(quicktime_t *file, quicktime_guid_t *guid)
11 {
12         int i;
13         guid->v1 = quicktime_read_int32_le(file);
14     guid->v2 = quicktime_read_int16_le(file);
15     guid->v3 = quicktime_read_int16_le(file);
16     for(i = 0; i < 8; i++)
17         guid->v4[i] = quicktime_read_char(file);
18         return 0;
19 }
20
21 quicktime_asfstream_t* new_asfstream()
22 {
23         quicktime_asfstream_t *result = calloc(1, sizeof(quicktime_asfstream_t));
24         return result;
25 }
26
27 void delete_asfstream(quicktime_asfstream_t *stream)
28 {
29         if(stream->extradata)
30                 free(stream->extradata);
31 }
32
33 void quicktime_delete_asf(quicktime_asf_t *asf)
34 {
35         int i;
36         if(asf)
37         {
38                 for(i = 0; i < asf->total_streams; i++)
39                         delete_asfstream(asf->streams[i]);
40         }
41 }
42
43 int quicktime_read_asf(quicktime_t *file)
44 {
45         quicktime_asf_t *asf = calloc(1, sizeof(quicktime_asf_t));
46         int got_header = 0;
47         int i;
48
49         file->asf = asf;
50         quicktime_set_position(file, 16 + 14);
51         
52         while(1)
53         {
54                 quicktime_guid_t guid;
55                 int64_t guid_size;
56                 int64_t guid_start = quicktime_position(file);
57
58                 bzero(&guid, sizeof(guid));
59                 quicktime_read_guid(file, &guid);
60                 guid_size = quicktime_read_int64_le(file);
61
62                 printf("quicktime_read_asf start=0x%jx size=0x%jx\n", guid_start, guid_size);
63
64 // Glitch
65                 if(guid_size < 24) return 1;
66                 
67                 
68                 if(!memcmp(&guid, &file_header, sizeof(guid)))
69                 {
70                         quicktime_guid_t leaf_guid;
71                         got_header = 1;
72                         quicktime_read_guid(file, &leaf_guid);
73                         asf->header.file_size = quicktime_read_int64_le(file);
74                         asf->header.create_time = quicktime_read_int64_le(file);
75                         asf->header.total_packets = quicktime_read_int64_le(file);
76                         asf->header.send_time = quicktime_read_int64_le(file);
77                         asf->header.play_time = quicktime_read_int64_le(file);
78                         asf->header.preroll = quicktime_read_int32_le(file);
79                         asf->header.ignore = quicktime_read_int32_le(file);
80                         asf->header.flags = quicktime_read_int32_le(file);
81                         asf->header.min_packet = quicktime_read_int32_le(file);
82                         asf->header.max_packet = quicktime_read_int32_le(file);
83                         asf->header.max_bitrate = quicktime_read_int32_le(file);
84                         asf->header.packet_size = asf->header.max_packet;
85                 }
86                 else if(!memcmp(&guid, &index_guid, sizeof(guid)))
87                 {
88                         quicktime_guid_t leaf_guid;
89 // Leaf Guid
90                         quicktime_read_guid(file, &leaf_guid);
91 // indexed interval
92                         quicktime_read_int64_le(file);
93 // max
94                         quicktime_read_int32_le(file);
95 // count
96                         asf->index_size = quicktime_read_int32_le(file);
97                         asf->index = calloc(sizeof(quicktime_asfpacket_t), asf->index_size);
98
99                         for(i = 0; i < asf->index_size; i++)
100                         {
101                                 asf->index[i].number = quicktime_read_int32_le(file);
102                                 asf->index[i].count = quicktime_read_int16_le(file);
103                         }
104                 }
105                 else if(!memcmp(&guid, &stream_header, sizeof(guid)))
106                 {
107                         quicktime_asfstream_t *stream = 
108                                 asf->streams[asf->total_streams++] = 
109                                 new_asfstream();
110                         quicktime_guid_t leaf_guid;
111                         quicktime_read_guid(file, &leaf_guid);
112                         if(!memcmp(&leaf_guid, &audio_stream, sizeof(leaf_guid)))
113                                 stream->is_audio = 1;
114                         else if(!memcmp(&leaf_guid, &video_stream, sizeof(leaf_guid)))
115                                 stream->is_video = 1;
116                         else if(!memcmp(&leaf_guid, &ext_stream_embed_stream_header, sizeof(leaf_guid)))
117                                 stream->is_ext_audio = 1;
118                         quicktime_read_guid(file, &leaf_guid);
119                         
120                         stream->total_size = quicktime_read_int64_le(file);
121                         stream->type_specific_size = quicktime_read_int32_le(file);
122                         quicktime_read_int32_le(file);
123                         stream->id = quicktime_read_int16_le(file) & 0x7f;
124                         quicktime_read_int32_le(file);
125                         if(stream->is_ext_audio)
126                         {
127                                 quicktime_read_guid(file, &leaf_guid);
128                                 if (!memcmp(&leaf_guid, &ext_stream_audio_stream, sizeof(leaf_guid)))
129                                 {
130                                         stream->is_audio = 1;
131                                         stream->is_ext_audio = 0;
132                                         quicktime_read_guid(file, &leaf_guid);
133                                         quicktime_read_int32_le(file);
134                                         quicktime_read_int32_le(file);
135                                         quicktime_read_int32_le(file);
136                                         quicktime_read_guid(file, &leaf_guid);
137                                         quicktime_read_int32_le(file);
138                                 }
139                         }
140                         
141                         
142                         if(stream->is_audio)
143                         {
144 // Get WAV header
145                                 stream->codec_tag = quicktime_read_int16_le(file);
146                                 stream->channels = quicktime_read_int16_le(file);
147                                 stream->samplerate = quicktime_read_int32_le(file);
148                                 stream->bitrate = quicktime_read_int32_le(file);
149                                 stream->block_align = quicktime_read_int16_le(file);
150                                 if(stream->type_specific_size == 14)
151                                         stream->bits_per_sample = 8;
152                                 else
153                                         stream->bits_per_sample = quicktime_read_int16_le(file);
154                                 if(stream->type_specific_size > 16)
155                                 {
156                                         stream->extradata_size = quicktime_read_int16_le(file);
157                                         if (stream->extradata_size > 0) 
158                                         {
159                                                 if (stream->extradata_size > stream->type_specific_size - 18)
160                                                         stream->extradata_size = stream->type_specific_size - 18;
161                                                 stream->extradata = calloc(1, stream->extradata_size + 1024);
162                                                 quicktime_read_data(file, (char*)stream->extradata, stream->extradata_size);
163                                         }
164                                         else
165                                                 stream->extradata_size = 0;
166                                         
167                                         if(stream->type_specific_size - stream->extradata_size - 18 > 0)
168                                                 quicktime_set_position(file,
169                                                         quicktime_position(file) + 
170                                                         stream->type_specific_size - 
171                                                         stream->extradata_size - 18);
172                                 }
173
174 // Make fourcc from codec_tag and bits_per_sample
175                         }
176                         else if(stream->is_video)
177                         {
178                                 int size1;
179                                 quicktime_read_int32_le(file);
180                                 quicktime_read_int32_le(file);
181                                 quicktime_read_char(file);
182                                 size1 = quicktime_read_int16_le(file);
183                                 quicktime_read_int32_le(file);
184                                 stream->width = quicktime_read_int32_le(file);
185                                 stream->height = quicktime_read_int32_le(file);
186                                 quicktime_read_int16_le(file);
187                                 stream->bits_per_sample = quicktime_read_int16_le(file);
188                                 stream->codec_tag = quicktime_read_int32_le(file);
189                                 quicktime_set_position(file, quicktime_position(file) + 20);
190                                 if(size1 > 40)
191                                 {
192                                         stream->extradata_size = size1 - 40;
193                                         stream->extradata = calloc(1, stream->extradata_size + 1024);
194                                         quicktime_read_data(file, (char*)stream->extradata, stream->extradata_size);
195                                 }
196
197 // Make fourcc from codec_tag
198                                 stream->fourcc[0] = (stream->codec_tag & 0xff);
199                                 stream->fourcc[1] = (stream->codec_tag & 0xff00) >> 8;
200                                 stream->fourcc[2] = (stream->codec_tag & 0xff0000) >> 16;
201                                 stream->fourcc[3] = (stream->codec_tag & 0xff000000) >> 24;
202                         }
203                 }
204
205                 quicktime_set_position(file, guid_start + guid_size);
206                 if(quicktime_position(file) >= file->total_length) break;
207         }
208
209         quicktime_dump_asf(asf);
210         return !got_header;
211 }
212
213 void quicktime_dump_asf(quicktime_asf_t *asf)
214 {
215         int i;
216         printf("asf header:\n");
217         printf("  total_packets=%jd\n  min_packet=%d\n  max_packet=%d\n  packet_size=%d\n",
218                 asf->header.total_packets,
219                 asf->header.min_packet,
220                 asf->header.max_packet,
221                 asf->header.packet_size);
222         printf("  total streams=%d\n", asf->total_streams);
223
224         for(i = 0; i < asf->total_streams; i++)
225         {
226                 quicktime_asfstream_t *stream = asf->streams[i];
227                 printf("  stream %d\n", i);
228                 printf("    is_audio=%d\n    is_video=%d\n", 
229                         stream->is_audio,
230                         stream->is_video);
231                 if(stream->is_audio)
232                 {
233                         printf("    codec_tag=0x%04x\n    channels=%d\n    samplerate=%d\n",
234                                 stream->codec_tag,
235                                 stream->channels,
236                                 stream->samplerate);
237                 }
238                 else
239                 if(stream->is_video)
240                 {
241                         printf("    codec_tag='%s'\n    width=%d\n    height=%d\n",
242                                 stream->fourcc,
243                                 stream->width,
244                                 stream->height);
245                 }
246
247                 printf("    extradata_size=%d\n", stream->extradata_size);
248         }
249
250         printf("  index size=%d\n", asf->index_size);
251
252         for(i = 0; i < asf->index_size; i++)
253         {
254                 printf("    packet_number=%d packet_count=%d\n",
255                         asf->index[i].number,
256                         asf->index[i].count);
257         }
258 }
259
260
261