void CQTAudioByteStream::read_frame (uint32_t frame_to_read) { #ifdef DEBUG_QTIME_AUDIO_FRAME player_debug_message("audio read_frame %d", frame_to_read); #endif if (m_frame_in_buffer == frame_to_read) { m_byte_on = 0; return; } m_parent->lock_file_mutex(); m_frame_in_buffer = frame_to_read; unsigned char *buff = (unsigned char *)m_buffer; quicktime_set_audio_position(m_parent->get_file(), frame_to_read, m_track); m_this_frame_size = quicktime_read_audio_frame(m_parent->get_file(), buff, m_max_frame_size, m_track); if (m_this_frame_size < 0) { m_max_frame_size = -m_this_frame_size; m_buffer = (uint8_t *)realloc(m_buffer, m_max_frame_size * sizeof(char)); // Okay - I could have used a goto, but it really grates... m_frame_in_buffer = frame_to_read; buff = (unsigned char *)m_buffer; quicktime_set_audio_position(m_parent->get_file(), frame_to_read, m_track); m_this_frame_size = quicktime_read_audio_frame(m_parent->get_file(), buff, m_max_frame_size, m_track); } #if 0 player_debug_message("qta frame size %u", m_this_frame_size); #endif m_parent->unlock_file_mutex(); m_byte_on = 0; }
long quicktime_read_audio(quicktime_t *file, char *audio_buffer, long samples, int track) { int64_t chunk_sample, chunk; int result = 0, track_num; quicktime_trak_t *trak = file->atracks[track].track; int64_t fragment_len, chunk_end; int64_t start_position = file->atracks[track].current_position; int64_t position = file->atracks[track].current_position; int64_t start = position, end = position + samples; int64_t bytes, total_bytes = 0; int64_t buffer_offset; //printf("quicktime_read_audio 1\n"); quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, position); buffer_offset = 0; while(position < end && !result) { quicktime_set_audio_position(file, position, track); fragment_len = quicktime_chunk_samples(trak, chunk); chunk_end = chunk_sample + fragment_len; fragment_len -= position - chunk_sample; if(position + fragment_len > chunk_end) fragment_len = chunk_end - position; if(position + fragment_len > end) fragment_len = end - position; bytes = quicktime_samples_to_bytes(trak, fragment_len); /* * printf("quicktime_read_audio 2 %llx %llx %d\n", * quicktime_position(file), * quicktime_position(file) + bytes, * samples); * sleep(1); */ result = !quicktime_read_data(file, &audio_buffer[buffer_offset], bytes); //printf("quicktime_read_audio 4\n"); total_bytes += bytes; position += fragment_len; chunk_sample = position; buffer_offset += bytes; chunk++; } //printf("quicktime_read_audio 5\n"); // Create illusion of track being advanced only by samples file->atracks[track].current_position = start_position + samples; if(result) return 0; return total_bytes; }
/************************************************************************** * Quicktime Audio stream functions **************************************************************************/ void CQTAudioByteStream::audio_set_timebase (long frame) { #ifdef DEBUG_QTIME_AUDIO_FRAME player_debug_message("Setting qtime audio timebase to frame %ld", frame); #endif m_eof = 0; m_frame_on = frame; m_parent->lock_file_mutex(); quicktime_set_audio_position(m_parent->get_file(), frame, m_track); m_parent->unlock_file_mutex(); read_frame(0); }
void lqt_gavl_seek_scaled(quicktime_t * file, gavl_time_t * time, int scale) { int imax; int i; int64_t video_time_save = -1; int video_timescale_save = -1; int64_t time_scaled; int timescale; /* We synchronize to the first video track */ imax = quicktime_video_tracks(file); for(i = 0; i < imax; i++) { timescale = lqt_video_time_scale(file, i); time_scaled = gavl_time_rescale(scale, timescale, *time); lqt_seek_video(file, i, time_scaled); if(!i) { video_timescale_save = timescale; video_time_save = time_scaled; } } if(video_time_save >= 0) *time = gavl_time_unscale(video_timescale_save, video_time_save); imax = quicktime_audio_tracks(file); for(i = 0; i < imax; i++) { timescale = quicktime_sample_rate(file, i); time_scaled = gavl_time_rescale(scale, timescale, *time); quicktime_set_audio_position(file, time_scaled, i); } imax = lqt_text_tracks(file); for(i = 0; i < imax; i++) { if(lqt_is_chapter_track(file, i)) continue; timescale = lqt_text_time_scale(file, i); time_scaled = gavl_time_rescale(scale, timescale, *time); lqt_set_text_time(file, i, time_scaled); } }
long quicktime_read_audio(quicktime_t *file, char *audio_buffer, long samples, int track) { long chunk_sample, chunk; int result = 1, track_num; quicktime_trak_t *trak = file->atracks[track].track; long fragment_len, chunk_end; long position = file->atracks[track].current_position; long start = position, end = position + samples; long bytes, total_bytes = 0; long buffer_offset; quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, position); buffer_offset = 0; while(position < end && result) { quicktime_set_audio_position(file, position, track); fragment_len = quicktime_chunk_samples(trak, chunk); chunk_end = chunk_sample + fragment_len; fragment_len -= position - chunk_sample; if(position + fragment_len > chunk_end) fragment_len = chunk_end - position; if(position + fragment_len > end) fragment_len = end - position; bytes = quicktime_samples_to_bytes(trak, fragment_len); result = quicktime_read_data(file, &audio_buffer[buffer_offset], bytes); total_bytes += bytes; position += fragment_len; chunk_sample = position; buffer_offset += bytes; chunk++; } file->atracks[track].current_position = position; if(!result) return 0; return total_bytes; }
long quicktime_read_audio_frame(quicktime_t *file, unsigned char *audio_buffer, int maxBytes, int track) { long bytes; int result = 0; quicktime_trak_t *trak = file->atracks[track].track; bytes = quicktime_audio_frame_size(file, file->atracks[track].current_position, track); if (bytes > maxBytes) { return -bytes; } quicktime_set_audio_position(file, file->atracks[track].current_position, track); result = quicktime_read_data(file, audio_buffer, bytes); file->atracks[track].current_position++; if (!result) return 0; return bytes; }
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)