00001 #include "funcprotos.h"
00002 #include "quicktime.h"
00003
00004
00005 static int decode_length(quicktime_t *file)
00006 {
00007 int bytes = 0;
00008 int result = 0;
00009 int byte;
00010 do
00011 {
00012 byte = quicktime_read_char(file);
00013 result = (result << 7) + (byte & 0x7f);
00014 bytes++;
00015 }while((byte & 0x80) && bytes < 4);
00016 return result;
00017 }
00018
00019 void quicktime_delete_esds(quicktime_esds_t *esds)
00020 {
00021 if(esds->mpeg4_header) free(esds->mpeg4_header);
00022 }
00023
00024 void quicktime_esds_samplerate(quicktime_stsd_table_t *table,
00025 quicktime_esds_t *esds)
00026 {
00027
00028 if(esds->mpeg4_header_size > 1 &&
00029 quicktime_match_32(table->format, QUICKTIME_MP4A))
00030 {
00031 static int samplerate_table[] =
00032 {
00033 96000, 88200, 64000, 48000, 44100, 32000,
00034 24000, 22050, 16000, 12000, 11025, 8000,
00035 7350, 0, 0, 0
00036 };
00037
00038 unsigned char *ptr = esds->mpeg4_header;
00039 int samplerate_index = ((ptr[0] & 7) << 1) + ((ptr[1] >> 7) & 1);
00040 table->channels = (ptr[1] >> 3) & 0xf;
00041 table->sample_rate =
00042 samplerate_table[samplerate_index];
00043
00044 }
00045 }
00046
00047 void quicktime_read_esds(quicktime_t *file,
00048 quicktime_atom_t *parent_atom,
00049 quicktime_esds_t *esds)
00050 {
00051
00052
00053 quicktime_read_char(file);
00054
00055 quicktime_read_int24(file);
00056
00057
00058 if(quicktime_read_char(file) == 0x3)
00059 {
00060 int len = decode_length(file);
00061
00062 quicktime_read_int16(file);
00063
00064 quicktime_read_char(file);
00065
00066 if(quicktime_read_char(file) == 0x4)
00067 {
00068 int len2 = decode_length(file);
00069
00070 quicktime_read_char(file);
00071
00072 quicktime_read_char(file);
00073
00074 quicktime_read_int24(file);
00075
00076 quicktime_read_int32(file);
00077
00078 quicktime_read_int32(file);
00079
00080
00081 if(quicktime_read_char(file) == 0x5)
00082 {
00083 esds->mpeg4_header_size = decode_length(file);
00084 if(!esds->mpeg4_header_size) return;
00085
00086
00087 esds->mpeg4_header = calloc(1,
00088 esds->mpeg4_header_size + 1024);
00089
00090 quicktime_read_data(file,
00091 esds->mpeg4_header,
00092 esds->mpeg4_header_size);
00093
00094
00095 quicktime_atom_skip(file, parent_atom);
00096 return;
00097 }
00098 else
00099 {
00100
00101 quicktime_atom_skip(file, parent_atom);
00102 return;
00103 }
00104 }
00105 else
00106 {
00107
00108 quicktime_atom_skip(file, parent_atom);
00109 return;
00110 }
00111 }
00112 else
00113 {
00114
00115 quicktime_atom_skip(file, parent_atom);
00116 return;
00117 }
00118 }
00119
00120
00121
00122 void quicktime_write_esds(quicktime_t *file,
00123 quicktime_esds_t *esds,
00124 int do_video,
00125 int do_audio)
00126 {
00127 quicktime_atom_t atom;
00128 quicktime_atom_write_header(file, &atom, "esds");
00129
00130 quicktime_write_char(file, 0);
00131
00132 quicktime_write_int24(file, 0);
00133
00134
00135 quicktime_write_char(file, 0x3);
00136
00137
00138 int64_t length1 = quicktime_position(file);
00139
00140 quicktime_write_char(file, 0x00);
00141
00142
00143 quicktime_write_int16(file, 0x1);
00144
00145
00146
00147
00148
00149
00150
00151 quicktime_write_char(file, 0);
00152
00153
00154
00155 quicktime_write_char(file, 0x4);
00156
00157 int64_t length2 = quicktime_position(file);
00158
00159 quicktime_write_char(file, 0x00);
00160
00161
00162 if(do_video)
00163 {
00164
00165 quicktime_write_char(file, 0x20);
00166
00167 quicktime_write_char(file, 0x11);
00168
00169
00170 quicktime_write_int24(file, 0x000000);
00171
00172
00173 quicktime_write_int32(file, 0x000030d40);
00174
00175
00176 quicktime_write_int32(file, 0x00000000);
00177 }
00178 else
00179 {
00180
00181 quicktime_write_char(file, 0x40);
00182
00183 quicktime_write_char(file, 0x15);
00184
00185 quicktime_write_int24(file, 0x001800);
00186
00187 quicktime_write_int32(file, 0x00004e20);
00188
00189 quicktime_write_int32(file, 0x00003e80);
00190 }
00191
00192
00193 quicktime_write_char(file, 0x05);
00194
00195 int64_t length3 = quicktime_position(file);
00196
00197 quicktime_write_char(file, 0x00);
00198
00199
00200 quicktime_write_data(file, esds->mpeg4_header, esds->mpeg4_header_size);
00201
00202
00203 int64_t current_length2 = quicktime_position(file) - length2 - 1;
00204 int64_t current_length3 = quicktime_position(file) - length3 - 1;
00205
00206
00207 quicktime_write_char(file, 0x06);
00208
00209 quicktime_write_char(file, 0x01);
00210 quicktime_write_char(file, 0x02);
00211
00212
00213
00214 int64_t current_length1 = quicktime_position(file) - length1 - 1;
00215 quicktime_atom_write_footer(file, &atom);
00216 int64_t current_position = quicktime_position(file);
00217
00218 quicktime_set_position(file, length1);
00219 quicktime_write_char(file, current_length1);
00220
00221 quicktime_set_position(file, length2);
00222 quicktime_write_char(file, current_length2);
00223
00224 quicktime_set_position(file, length3);
00225 quicktime_write_char(file, current_length3);
00226 quicktime_set_position(file, current_position);
00227 }
00228
00229 void quicktime_esds_dump(quicktime_esds_t *esds)
00230 {
00231 printf(" elementary stream description\n");
00232 printf(" mpeg4_header_size=0x%x\n", esds->mpeg4_header_size);
00233 printf(" mpeg4_header=");
00234 int i;
00235 for(i = 0; i < esds->mpeg4_header_size; i++)
00236 printf("%02x ", (unsigned char)esds->mpeg4_header[i]);
00237 printf("\n");
00238 }
00239
00240