1 #include "funcprotos.h"
3 #include "qtasf_codes.h"
7 /* We have lifted sections of ASF decoding from ffmpeg */
8 /* to add direct copy support and seeking to it */
10 int quicktime_read_guid(quicktime_t *file, quicktime_guid_t *guid)
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);
21 quicktime_asfstream_t* new_asfstream()
23 quicktime_asfstream_t *result = calloc(1, sizeof(quicktime_asfstream_t));
27 void delete_asfstream(quicktime_asfstream_t *stream)
30 free(stream->extradata);
33 void quicktime_delete_asf(quicktime_asf_t *asf)
38 for(i = 0; i < asf->total_streams; i++)
39 delete_asfstream(asf->streams[i]);
43 int quicktime_read_asf(quicktime_t *file)
45 quicktime_asf_t *asf = calloc(1, sizeof(quicktime_asf_t));
50 quicktime_set_position(file, 16 + 14);
54 quicktime_guid_t guid;
56 int64_t guid_start = quicktime_position(file);
58 bzero(&guid, sizeof(guid));
59 quicktime_read_guid(file, &guid);
60 guid_size = quicktime_read_int64_le(file);
62 printf("quicktime_read_asf start=0x%jx size=0x%jx\n", guid_start, guid_size);
65 if(guid_size < 24) return 1;
68 if(!memcmp(&guid, &file_header, sizeof(guid)))
70 quicktime_guid_t leaf_guid;
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;
86 else if(!memcmp(&guid, &index_guid, sizeof(guid)))
88 quicktime_guid_t leaf_guid;
90 quicktime_read_guid(file, &leaf_guid);
92 quicktime_read_int64_le(file);
94 quicktime_read_int32_le(file);
96 asf->index_size = quicktime_read_int32_le(file);
97 asf->index = calloc(sizeof(quicktime_asfpacket_t), asf->index_size);
99 for(i = 0; i < asf->index_size; i++)
101 asf->index[i].number = quicktime_read_int32_le(file);
102 asf->index[i].count = quicktime_read_int16_le(file);
105 else if(!memcmp(&guid, &stream_header, sizeof(guid)))
107 quicktime_asfstream_t *stream =
108 asf->streams[asf->total_streams++] =
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);
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)
127 quicktime_read_guid(file, &leaf_guid);
128 if (!memcmp(&leaf_guid, &ext_stream_audio_stream, sizeof(leaf_guid)))
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);
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;
153 stream->bits_per_sample = quicktime_read_int16_le(file);
154 if(stream->type_specific_size > 16)
156 stream->extradata_size = quicktime_read_int16_le(file);
157 if (stream->extradata_size > 0)
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);
165 stream->extradata_size = 0;
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);
174 // Make fourcc from codec_tag and bits_per_sample
176 else if(stream->is_video)
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);
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);
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;
205 quicktime_set_position(file, guid_start + guid_size);
206 if(quicktime_position(file) >= file->total_length) break;
209 quicktime_dump_asf(asf);
213 void quicktime_dump_asf(quicktime_asf_t *asf)
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);
224 for(i = 0; i < asf->total_streams; i++)
226 quicktime_asfstream_t *stream = asf->streams[i];
227 printf(" stream %d\n", i);
228 printf(" is_audio=%d\n is_video=%d\n",
233 printf(" codec_tag=0x%04x\n channels=%d\n samplerate=%d\n",
241 printf(" codec_tag='%s'\n width=%d\n height=%d\n",
247 printf(" extradata_size=%d\n", stream->extradata_size);
250 printf(" index size=%d\n", asf->index_size);
252 for(i = 0; i < asf->index_size; i++)
254 printf(" packet_number=%d packet_count=%d\n",
255 asf->index[i].number,
256 asf->index[i].count);