void decode_mov(decode_t *decode) { quicktime_t *qt_handle=NULL; unsigned char **p_raw_buffer; char *p_v_codec=NULL,*p_a_codec=NULL,*p_buffer=NULL,*p_tmp=NULL; int s_width=0,s_height=0,s_channel=0,s_bits=0,s_buff_size=0,s_audio_size=0,s_video_size=0,s_sample=0; int s_cont,s_frames; double s_fps=0; long s_audio_rate,s_qt_pos; uint16_t *p_mask1, *p_mask2; char msgbuf[TC_BUF_MIN]; qt_handle = quicktime_open((char * )decode->name, 1, 0); if (qt_handle == NULL) { QT_ABORT("can't open quicktime!"); } quicktime_set_preload(qt_handle, 10240000); s_fps = quicktime_frame_rate(qt_handle, 0); if (decode->format == TC_CODEC_PCM) { if (quicktime_audio_tracks(qt_handle) == 0) { QT_ABORT("no audio track in quicktime found!"); } s_channel = quicktime_track_channels(qt_handle, 0); s_audio_rate = quicktime_sample_rate(qt_handle, 0); s_bits = quicktime_audio_bits(qt_handle, 0); s_audio_size = quicktime_audio_length(qt_handle,0); p_a_codec = quicktime_audio_compressor(qt_handle, 0); if (decode->frame_limit[1] < s_audio_size) { s_audio_size = decode->frame_limit[1] - decode->frame_limit[0]; } else { s_audio_size -= decode->frame_limit[0]; } if (decode->verbose) { tc_log_info(__FILE__, "Audio codec=%s, rate=%ld Hz, bits=%d, channels=%d", p_a_codec, s_audio_rate, s_bits, s_channel); } if ((s_bits != 8) && (s_bits != 16)) { tc_snprintf(msgbuf, sizeof(msgbuf), "unsupported %d bit rate" " in quicktime!", s_bits); QT_ABORT(msgbuf); } if (s_channel > 2) { tc_snprintf(msgbuf, sizeof(msgbuf), "too many audio tracks " "(%d) found in quicktime!", s_channel); QT_ABORT(msgbuf); } if (strlen(p_a_codec) == 0) { QT_ABORT("unsupported codec (empty!) in quicktime!"); } if (quicktime_supported_audio(qt_handle, 0) != 0) { s_qt_pos = quicktime_audio_position(qt_handle,0); s_sample = (1.00 * s_channel * s_bits *s_audio_rate)/(s_fps * 8); s_buff_size = s_sample * sizeof(uint16_t); p_buffer = tc_malloc(s_buff_size); if (s_bits == 16) s_sample /= 2; if (s_channel == 1) { p_mask1=(uint16_t *)p_buffer; quicktime_set_audio_position(qt_handle, s_qt_pos + decode->frame_limit[0], 0); for (; s_audio_size > 0; s_audio_size -= s_sample) { if (quicktime_decode_audio(qt_handle, p_mask1, NULL, s_sample, 0) < 0) { QT_ABORT("error reading quicktime audio frame"); } QT_WRITE(decode->fd_out, p_buffer, s_buff_size); } } else { s_sample /= 2; p_mask1 = (uint16_t *)p_buffer; p_mask2 = tc_malloc(s_sample * sizeof(uint16_t)); s_qt_pos += decode->frame_limit[0]; quicktime_set_audio_position(qt_handle, s_qt_pos, 0); for (; s_audio_size > 0; s_audio_size -= s_sample) { if (quicktime_decode_audio(qt_handle, p_mask1, NULL, s_sample, 0) < 0) { QT_ABORT("error reading quicktime audio frame"); } quicktime_set_audio_position(qt_handle, s_qt_pos, 0); if (quicktime_decode_audio(qt_handle,p_mask2, NULL,s_sample, 1) < 0) { QT_ABORT("error reading quicktime audio frame"); } for (s_cont = s_sample - 1; s_cont >= 0; s_cont--) p_mask1[s_cont<<1] = p_mask1[s_cont]; for (s_cont = 0; s_cont < s_sample; s_cont++) p_mask1[1+(s_cont<<1)] = p_mask2[s_cont]; s_qt_pos += s_sample; QT_WRITE(decode->fd_out, p_buffer, s_buff_size >> 1); } free(p_mask2); } free(p_buffer); } #if !defined(LIBQUICKTIME_000904) else if ((strcasecmp(p_a_codec, QUICKTIME_RAW) == 0)
int quicktime_read_info(quicktime_t *file) { int result = 0, got_header = 0; int i, channel, trak_channel, track; int64_t start_position = quicktime_position(file); quicktime_atom_t leaf_atom; quicktime_trak_t *trak; char avi_avi[4]; int got_avi = 0; int got_asf = 0; quicktime_set_position(file, 0LL); /* Test file format */ do { file->use_avi = 1; file->use_asf = 1; result = quicktime_atom_read_header(file, &leaf_atom); if(!result && quicktime_atom_is(&leaf_atom, "RIFF")) { quicktime_read_data(file, avi_avi, 4); if(quicktime_match_32(avi_avi, "AVI ")) { got_avi = 1; } else { result = 0; break; } } else { result = 0; break; } }while(1); if(!got_avi) file->use_avi = 0; if(!got_asf) file->use_asf = 0; quicktime_set_position(file, 0LL); /* McRoweSoft AVI section */ if(file->use_avi) { //printf("quicktime_read_info 1\n"); /* Import first RIFF */ do { result = quicktime_atom_read_header(file, &leaf_atom); if(!result) { if(quicktime_atom_is(&leaf_atom, "RIFF")) { quicktime_read_riff(file, &leaf_atom); /* Return success */ got_header = 1; } } }while(!result && !got_header && quicktime_position(file) < file->total_length); //printf("quicktime_read_info 10\n"); /* Construct indexes. */ quicktime_import_avi(file); //printf("quicktime_read_info 20\n"); } /* Quicktime section */ else if(!file->use_avi) { do { result = quicktime_atom_read_header(file, &leaf_atom); if(!result) { if(quicktime_atom_is(&leaf_atom, "mdat")) { quicktime_read_mdat(file, &(file->mdat), &leaf_atom); } else if(quicktime_atom_is(&leaf_atom, "moov")) { /* Set preload and preload the moov atom here */ int64_t start_position = quicktime_position(file); long temp_size = leaf_atom.end - start_position; unsigned char *temp = malloc(temp_size); quicktime_set_preload(file, (temp_size < 0x100000) ? 0x100000 : temp_size); quicktime_read_data(file, temp, temp_size); quicktime_set_position(file, start_position); free(temp); if(quicktime_read_moov(file, &(file->moov), &leaf_atom)) return 1; got_header = 1; } else quicktime_atom_skip(file, &leaf_atom); } }while(!result && quicktime_position(file) < file->total_length); /* go back to the original position */ quicktime_set_position(file, start_position); } /* Initialize track map objects */ if(got_header) { quicktime_init_maps(file); } /* Shut down preload in case of an obsurdly high temp_size */ quicktime_set_preload(file, 0); //printf("quicktime_read_info 100\n"); return !got_header; }
void quicktime_read_riff(quicktime_t *file, quicktime_atom_t *parent_atom) { quicktime_riff_t *riff = quicktime_new_riff(file); quicktime_atom_t leaf_atom; int result = 0; int i; char data[5]; riff->atom = *parent_atom; // AVI quicktime_read_data(file, data, 4); //printf("quicktime_read_riff 1 %llx\n", quicktime_position(file)); // Certain AVI parameters must be copied over to quicktime objects: // hdrl -> moov // movi -> mdat // idx1 -> moov do { result = quicktime_atom_read_header(file, &leaf_atom); /* * printf("quicktime_read_riff 1 %llx %llx %c%c%c%c\n", * leaf_atom.start, * leaf_atom.size, * leaf_atom.type[0], * leaf_atom.type[1], * leaf_atom.type[2], * leaf_atom.type[3]); */ if(!result) { if(quicktime_atom_is(&leaf_atom, "LIST")) { data[4] = 0; result = !quicktime_read_data(file, data, 4); if(!result) { // Got LIST 'hdrl' if(quicktime_match_32(data, "hdrl")) { // No size here. //printf("quicktime_read_riff 10 %llx\n", quicktime_position(file)); quicktime_read_hdrl(file, &riff->hdrl, &leaf_atom); //printf("quicktime_read_riff 20 %llx\n", quicktime_position(file)); } else // Got LIST 'movi' if(quicktime_match_32(data, "movi")) { //printf("quicktime_read_riff 30 %llx\n", quicktime_position(file)); quicktime_read_movi(file, &leaf_atom, &riff->movi); //printf("quicktime_read_riff 40 %llx\n", quicktime_position(file)); } } // Skip it quicktime_atom_skip(file, &leaf_atom); } else // Got 'movi' if(quicktime_atom_is(&leaf_atom, "movi")) { quicktime_read_movi(file, &leaf_atom, &riff->movi); } else // Got 'idx1' original index if(quicktime_atom_is(&leaf_atom, "idx1")) { //printf("quicktime_read_riff 50 %llx\n", quicktime_position(file)); // Preload idx1 here int64_t start_position = quicktime_position(file); long temp_size = leaf_atom.end - start_position; unsigned char *temp = malloc(temp_size); quicktime_set_preload(file, (temp_size < 0x100000) ? 0x100000 : temp_size); quicktime_read_data(file, temp, temp_size); quicktime_set_position(file, start_position); free(temp); // Read idx1 quicktime_read_idx1(file, riff, &leaf_atom); //printf("quicktime_read_riff 60 %llx\n", quicktime_position(file)); } else /* Skip it */ { quicktime_atom_skip(file, &leaf_atom); } } }while(!result && quicktime_position(file) < parent_atom->end); //printf("quicktime_read_riff 10\n"); }