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;
}
Beispiel #2
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);
}
Beispiel #4
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);
    }
  }
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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)