Exemple #1
0
long quicktime_read_audio(quicktime_t *file,
	char *audio_buffer, long samples, int track)
{
	quicktime_audio_map_t *track_map = &file->atracks[track];
	quicktime_trak_t *trak = track_map->track;
	int64_t position, chunk, chunk_sample;
	long ret, bytes, chunk_offset, chunk_len;
	int result = 0;

	position = file->atracks[track].current_position;
	quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, position);
	ret = 0;

	while( samples > 0 ) {
		int64_t offset = quicktime_sample_to_offset(file, trak, position);
		quicktime_set_position(file, offset);
		chunk_offset = position - chunk_sample;
		chunk_len = quicktime_chunk_samples(trak, chunk) - chunk_offset;
		if( chunk_len > samples ) chunk_len = samples;
		else ++chunk;
		chunk_sample = (position += chunk_len);
		bytes = quicktime_samples_to_bytes(trak, chunk_len);
		result = !quicktime_read_data(file, &audio_buffer[ret], bytes);
		if( result ) break;
		ret += bytes;
		samples -= chunk_len;
	}
//printf("quicktime_read_audio 5\n");

	track_map->current_position = position;
	track_map->current_chunk = chunk;
	return !result ? ret : 0;
}
Exemple #2
0
int64_t quicktime_read_int64_le(quicktime_t *file)
{
	uint64_t result, a, b, c, d, e, f, g, h;
	char data[8];

	quicktime_read_data(file, data, 8);
	a = (unsigned char)data[7];
	b = (unsigned char)data[6];
	c = (unsigned char)data[5];
	d = (unsigned char)data[4];
	e = (unsigned char)data[3];
	f = (unsigned char)data[2];
	g = (unsigned char)data[1];
	h = (unsigned char)data[0];

	result = (a << 56) | 
		(b << 48) | 
		(c << 40) | 
		(d << 32) | 
		(e << 24) | 
		(f << 16) | 
		(g << 8) | 
		h;
	return (int64_t)result;
}
Exemple #3
0
static int chunk_len(quicktime_t *file, int64_t offset, int64_t next_chunk)
{
	int result = 0;
	unsigned char buffer[BUFFER_FRAGMENT];
	int accum = 0;
	int segment_count = 0;
	int page_size = 0;
	int i;

	while(offset < next_chunk)
	{
		quicktime_set_position(file, offset);
		result = !quicktime_read_data(file, (char*)buffer, BUFFER_FRAGMENT);
		if(result || memcmp(buffer, "OggS", 4))
			return accum;

// Decode size of OggS page
		segment_count = buffer[SEGMENT_OFFSET];

// Decode one segment at a time
		i = LACE_OFFSET;
		page_size = 0;
		while(segment_count > 0)
		{
			page_size += buffer[i++];
			segment_count--;
		}
		accum += i + page_size;
		offset += i + page_size;
	}


	return accum;
}
Exemple #4
0
int quicktime_read_chunk(quicktime_t *file, char *output, int track, long chunk, long byte_start, long byte_len)
{
	quicktime_set_position(file, quicktime_chunk_to_offset(file->atracks[track].track, chunk) + byte_start);
	if(quicktime_read_data(file, output, byte_len)) return 0;
	else
	return 1;
}
Exemple #5
0
long quicktime_read_frame(quicktime_t *file, unsigned char *video_buffer, int track)
{
	long bytes;
	int result = 0;

	quicktime_trak_t *trak = file->vtracks[track].track;
	bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track);

	if(!file->vtracks[track].frames_cached)
	{
		quicktime_set_video_position(file, file->vtracks[track].current_position, track);
		result = quicktime_read_data(file, video_buffer, bytes);
	}
	else
	{
		int i;
		unsigned char *cached_frame;

		if(file->vtracks[track].current_position >= file->vtracks[track].frames_cached) result = 1;
		if(!result)
		{
			cached_frame = file->vtracks[track].frame_cache[file->vtracks[track].current_position];

			for(i = 0; i < bytes; i++)
				video_buffer[i] = cached_frame[i];
		}
	}
	file->vtracks[track].current_position++;

	if(!result) return 0;
	return bytes;
}
Exemple #6
0
void quicktime_read_hdrl(quicktime_t *file,
	quicktime_hdrl_t *hdrl,
	quicktime_atom_t *parent_atom)
{
	quicktime_atom_t leaf_atom;
	char data[4];
	int current_track = 0;

//printf("quicktime_read_hdrl 1\n");
	do
	{
		quicktime_atom_read_header(file, &leaf_atom);

/* Got LIST */
		if(quicktime_atom_is(&leaf_atom, "LIST"))
		{
			data[0] = data[1] = data[2] = data[3] = 0;
			quicktime_read_data(file, data, 4);

/* Got strl */
			if(quicktime_match_32(data, "strl"))
			{
				quicktime_strl_t *strl =
					hdrl->strl[current_track++] =
					quicktime_new_strl();
				quicktime_read_strl(file, strl, &leaf_atom);
			}
		}

		quicktime_atom_skip(file, &leaf_atom);
	}while(quicktime_position(file) < parent_atom->end);

	quicktime_atom_skip(file, &leaf_atom);
}
Exemple #7
0
static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
{
	int bytes;
	quicktime_video_map_t *vtrack = &(file->vtracks[track]);
	quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
	int width = quicktime_video_width(file, track);
	int height = quicktime_video_height(file, track);
	int result = 0;

	initialize(vtrack, codec, width, height);
	quicktime_set_video_position(file, vtrack->current_position, track);
	bytes = quicktime_frame_size(file, vtrack->current_position, track);

        result = !quicktime_read_data(file, (char*)codec->work_buffer, bytes);
	if(codec->is_2vuy)
		convert_decode_2vuy(codec);
	else
		convert_decode_yuv2(codec);

	cmodel_transfer(row_pointers, codec->rows,
		row_pointers[0], row_pointers[1], row_pointers[2],
		0, 0, 0,
		file->in_x, file->in_y, file->in_w, file->in_h,
		0, 0, file->out_w, file->out_h,
		BC_YUV422, file->color_model,
		0, codec->coded_w, file->out_w);

	return result;
}
Exemple #8
0
int quicktime_read_avcc(quicktime_t *file, 
                        quicktime_atom_t *parent_atom,
                        quicktime_avcc_t *avcc)
{
    avcc->data_size = parent_atom->size - 8;
    quicktime_read_data(file, 
        avcc->data, 
        avcc->data_size);
    quicktime_atom_skip(file, parent_atom);
    return 0;
}
Exemple #9
0
float quicktime_read_fixed16(quicktime_t *file)
{
	unsigned char data[2];
	
	quicktime_read_data(file, data, 2);
//printf("quicktime_read_fixed16 %02x%02x\n", data[0], data[1]);
	if(data[1])
		return (float)data[0] + (float)data[1] / 256;
	else
		return (float)data[0];
}
Exemple #10
0
int quicktime_read_esds(quicktime_t *file, quicktime_esds_t *esds)
{
    u_int8_t tag;
    u_int32_t length;

    esds->version = quicktime_read_char(file);
    esds->flags = quicktime_read_int24(file);

    /* get and verify ES_DescrTag */
    tag = quicktime_read_char(file);
    if (tag == 0x03) {
        /* read length */
        if (quicktime_read_mp4_descr_length(file) < 5 + 15) {
            return 1;
        }
        /* skip 3 bytes */
        quicktime_set_position(file, quicktime_position(file) + 3);
    } else {
        /* skip 2 bytes */
        quicktime_set_position(file, quicktime_position(file) + 2);
    }

    /* get and verify DecoderConfigDescrTab */
    if (quicktime_read_char(file) != 0x04) {
        return 1;
    }

    /* read length */
    if (quicktime_read_mp4_descr_length(file) < 15) {
        return 1;
    }

    /* skip 13 bytes */
    quicktime_set_position(file, quicktime_position(file) + 13);

    /* get and verify DecSpecificInfoTag */
    if (quicktime_read_char(file) != 0x05) {
        return 1;
    }

    /* read length */
    esds->decoderConfigLen = quicktime_read_mp4_descr_length(file);

    free(esds->decoderConfig);
    esds->decoderConfig = malloc(esds->decoderConfigLen);
    if (esds->decoderConfig) {
        quicktime_read_data(file, esds->decoderConfig, esds->decoderConfigLen);
    } else {
        esds->decoderConfigLen = 0;
    }

    /* will skip the remainder of the atom */
    return 0;
}
Exemple #11
0
void quicktime_read_stsd_audio(quicktime_t *file, 
	quicktime_stsd_table_t *table, 
	quicktime_atom_t *parent_atom)
{
	quicktime_atom_t leaf_atom;

	table->version = quicktime_read_int16(file);
	table->revision = quicktime_read_int16(file);
	quicktime_read_data(file, table->vendor, 4);
	table->channels = quicktime_read_int16(file);
	table->sample_size = quicktime_read_int16(file);
	table->compression_id = quicktime_read_int16(file);
	table->packet_size = quicktime_read_int16(file);
	table->sample_rate = quicktime_read_fixed32(file);

// Kluge for fixed32 limitation
if(table->sample_rate + 65536 == 96000 ||
	table->sample_rate + 65536 == 88200) table->sample_rate += 65536;


// Version 1 fields
	if(table->version > 0)
	{
		table->samples_per_packet = quicktime_read_int32(file);
		table->bytes_per_packet = quicktime_read_int32(file);
		table->bytes_per_frame = quicktime_read_int32(file);
		table->bytes_per_sample = quicktime_read_int32(file);

// Skip another 20 bytes
		if(table->version == 2)
		{
			quicktime_set_position(file, quicktime_position(file) + 0x14);
		}

		while(quicktime_position(file) < parent_atom->end)
		{
			quicktime_atom_read_header(file, &leaf_atom);

			if(quicktime_atom_is(&leaf_atom, "wave"))
			{
				read_wave(file, table, &leaf_atom);
			}
			else
			{
				quicktime_atom_skip(file, &leaf_atom);
			}
		}
	}

// FFMPEG says the esds sometimes contains a sample rate that overrides
// the sample table.
	quicktime_esds_samplerate(table, &table->esds);
}
Exemple #12
0
static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
{
	int i;
	int64_t bytes;
	int result = 0;
	quicktime_video_map_t *vtrack = &(file->vtracks[track]);
	quicktime_v308_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
	int width = vtrack->track->tkhd.track_width;
	int height = vtrack->track->tkhd.track_height;
	unsigned char **input_rows;
	if(!codec->work_buffer)
		codec->work_buffer = malloc(vtrack->track->tkhd.track_width * 
			vtrack->track->tkhd.track_height *
			3);



	quicktime_set_video_position(file, vtrack->current_position, track);
	bytes = quicktime_frame_size(file, vtrack->current_position, track);
	result = !quicktime_read_data(file, codec->work_buffer, bytes);



	input_rows = malloc(sizeof(unsigned char*) * height);
	for(i = 0; i < height; i++)
		input_rows[i] = codec->work_buffer + i * width * 3;

	cmodel_transfer(row_pointers, 
		input_rows,
		row_pointers[0],
		row_pointers[1],
		row_pointers[2],
		0,
		0,
		0,
		file->in_x, 
		file->in_y, 
		file->in_w, 
		file->in_h,
		0, 
		0, 
		file->out_w, 
		file->out_h,
		BC_VYU888, 
		file->color_model,
		0,
		width,
		file->out_w);

	free(input_rows);

	return result;
}
Exemple #13
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;
}
Exemple #14
0
int quicktime_read_int16_le(quicktime_t *file)
{
	unsigned long result;
	unsigned long a, b;
	char data[2];
	
	quicktime_read_data(file, data, 2);
	a = (unsigned char)data[0];
	b = (unsigned char)data[1];

	result = (b << 8) | a;
	return (int)result;
}
Exemple #15
0
void quicktime_read_dref_table(quicktime_t *file, quicktime_dref_table_t *table)
{
	table->size = quicktime_read_int32(file);
	quicktime_read_char32(file, table->type);
	table->version = quicktime_read_char(file);
	table->flags = quicktime_read_int24(file);
	if(table->data_reference) free(table->data_reference);

	table->data_reference = malloc(table->size);
	if(table->size > 12)
		quicktime_read_data(file, table->data_reference, table->size - 12);
	table->data_reference[table->size - 12] = 0;
}
Exemple #16
0
long quicktime_read_int24(quicktime_t *file)
{
	unsigned long result;
	unsigned long a, b, c;
	char data[4];
	
	quicktime_read_data(file, data, 3);
	a = (unsigned char)data[0];
	b = (unsigned char)data[1];
	c = (unsigned char)data[2];

	result = (a << 16) | (b << 8) | c;
	return (long)result;
}
Exemple #17
0
long quicktime_read_frame(quicktime_t *file, unsigned char *video_buffer, int track)
{
	int64_t bytes;
	int result = 0;

	quicktime_trak_t *trak = file->vtracks[track].track;
	bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track);

	quicktime_set_video_position(file, file->vtracks[track].current_position, track);
	result = quicktime_read_data(file, video_buffer, bytes);
	file->vtracks[track].current_position++;

	if(!result) return 0;
	return bytes;
}
Exemple #18
0
long quicktime_read_int32_le(quicktime_t *file)
{
	unsigned long result;
	unsigned long a, b, c, d;
	char data[4];

	quicktime_read_data(file, data, 4);
	a = (unsigned char)data[0];
	b = (unsigned char)data[1];
	c = (unsigned char)data[2];
	d = (unsigned char)data[3];

	result = (d << 24) | (c << 16) | (b << 8) | a;
	return (long)result;
}
Exemple #19
0
void quicktime_read_stsd_table(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_table_t *table)
{
	quicktime_atom_t leaf_atom;

	quicktime_atom_read_header(file, &leaf_atom);

	table->format[0] = leaf_atom.type[0];
	table->format[1] = leaf_atom.type[1];
	table->format[2] = leaf_atom.type[2];
	table->format[3] = leaf_atom.type[3];
	quicktime_read_data(file, table->reserved, 6);
	table->data_reference = quicktime_read_int16(file);

	if(minf->is_audio) quicktime_read_stsd_audio(file, table, &leaf_atom);
	if(minf->is_video) quicktime_read_stsd_video(file, table, &leaf_atom);
}
Exemple #20
0
long quicktime_read_frame(quicktime_t *file, unsigned char *video_buffer, int track)
{
	int result = 0;
	int64_t bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track);
	quicktime_set_video_position(file, file->vtracks[track].current_position, track);

/*
 * printf("quicktime_read_frame 0x%llx %lld\n",
 * quicktime_ftell(file),
 * bytes);
 */
	result = quicktime_read_data(file, (char*)video_buffer, bytes);
	file->vtracks[track].current_position++;

	if(!result) return 0;
	return bytes;
}
Exemple #21
0
int quicktime_check_sig(char *path)
{
	quicktime_t file;
	quicktime_atom_t leaf_atom;
	int result = 0, result1 = 0, result2 = 0;
	char avi_test[12];

	quicktime_init(&file);
	result = quicktime_file_open(&file, path, 1, 0);

	if(!result)
	{
// Check for Microsoft AVI
		quicktime_read_data(&file, avi_test, 12);
		quicktime_set_position(&file, 0);
		if(quicktime_match_32(avi_test, "RIFF") && 
			quicktime_match_32(avi_test + 8, "AVI "))
		{
			result2 = 1;
		}
		else
		{
			do
			{
				result1 = quicktime_atom_read_header(&file, &leaf_atom);

				if(!result1)
				{
/* just want the "moov" atom */
					if(quicktime_atom_is(&leaf_atom, "moov"))
					{
						result2 = 1;
					}
					else
						quicktime_atom_skip(&file, &leaf_atom);
				}
			}while(!result1 && !result2 && quicktime_position(&file) < file.total_length);
		}
	}

//printf(__FUNCTION__ " 2 %d\n", result2);
	quicktime_file_close(&file);
	quicktime_delete(&file);
	return result2;
}
Exemple #22
0
int quicktime_read_tkhd(quicktime_t *file, quicktime_tkhd_t *tkhd)
{
	tkhd->version = quicktime_read_char(file);
	tkhd->flags = quicktime_read_int24(file);
	tkhd->creation_time = quicktime_read_int32(file);
	tkhd->modification_time = quicktime_read_int32(file);
	tkhd->track_id = quicktime_read_int32(file);
	tkhd->reserved1 = quicktime_read_int32(file);
	tkhd->duration = quicktime_read_int32(file);
	quicktime_read_data(file, tkhd->reserved2, 8);
	tkhd->layer = quicktime_read_int16(file);
	tkhd->alternate_group = quicktime_read_int16(file);
	tkhd->volume = quicktime_read_fixed16(file);
	tkhd->reserved3 = quicktime_read_int16(file);
	quicktime_read_matrix(file, &(tkhd->matrix));
	tkhd->track_width = quicktime_read_fixed32(file);
	tkhd->track_height = quicktime_read_fixed32(file);
}
Exemple #23
0
float quicktime_read_fixed32(quicktime_t *file)
{
	unsigned long a, b, c, d;
	unsigned char data[4];

	quicktime_read_data(file, data, 4);
	a = data[0];
	b = data[1];
	c = data[2];
	d = data[3];
	
	a = (a << 8) + b;
	b = (c << 8) + d;

	if(b)
		return (float)a + (float)b / 65536;
	else
		return a;
}
Exemple #24
0
int quicktime_read_mvhd(quicktime_t *file, quicktime_mvhd_t *mvhd)
{
    mvhd->version = quicktime_read_char(file);
    mvhd->flags = quicktime_read_int24(file);
    mvhd->creation_time = quicktime_read_int32(file);
    mvhd->modification_time = quicktime_read_int32(file);
    mvhd->time_scale = quicktime_read_int32(file);
    mvhd->duration = quicktime_read_int32(file);
    mvhd->preferred_rate = quicktime_read_fixed32(file);
    mvhd->preferred_volume = quicktime_read_fixed16(file);
    quicktime_read_data(file, mvhd->reserved, 10);
    quicktime_read_matrix(file, &(mvhd->matrix));
    mvhd->preview_time = quicktime_read_int32(file);
    mvhd->preview_duration = quicktime_read_int32(file);
    mvhd->poster_time = quicktime_read_int32(file);
    mvhd->selection_time = quicktime_read_int32(file);
    mvhd->selection_duration = quicktime_read_int32(file);
    mvhd->current_time = quicktime_read_int32(file);
    mvhd->next_track_id = quicktime_read_int32(file);

    return 0;
}
Exemple #25
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;
}
Exemple #26
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;
}
Exemple #27
0
int quicktime_atom_read_header(quicktime_t *file, quicktime_atom_t *atom)
{
	int result = 0;
	char header[10];

	if(file->use_avi)
	{
		reset(atom);
		atom->start = quicktime_position(file);
		if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
		atom->type[0] = header[0];
		atom->type[1] = header[1];
		atom->type[2] = header[2];
		atom->type[3] = header[3];
		atom->type[4] = 0;
		atom->size = 
			(((unsigned char)header[4])      ) |
			(((unsigned char)header[5]) << 8 ) |
			(((unsigned char)header[6]) << 16) |
			(((unsigned char)header[7]) << 24);
		atom->end = quicktime_add3(atom->start, atom->size, 8);
	}
	else
	{
		int64_t size2;

		reset(atom);

		atom->start = quicktime_position(file);

		if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
		result = read_type(header, atom->type);
		atom->size = read_size(header);
		atom->end = atom->start + atom->size;
/*
 * printf("quicktime_atom_read_header 1 %c%c%c%c start %llx size %llx end %llx ftell %llx %llx\n", 
 * 	atom->type[0], atom->type[1], atom->type[2], atom->type[3],
 * 	atom->start, atom->size, atom->end,
 * 	file->file_position,
 * 	(int64_t)FTELL(file->stream));
 */

/* Skip placeholder atom */
		if(quicktime_match_32(atom->type, "wide"))
		{
			atom->start = quicktime_position(file);
			reset(atom);
			if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
			result = read_type(header, atom->type);
			atom->size -= 8;
			if(atom->size <= 0)
			{
/* Wrapper ended.  Get new atom size */
				atom->size = read_size(header);
			}
			atom->end = atom->start + atom->size;
		}
		else
/* Get extended size */
		if(atom->size == 1)
		{
			if(!quicktime_read_data(file, header, HEADER_LENGTH)) return 1;
			atom->size = read_size64(header);
			atom->end = atom->start + atom->size;
/*
 * printf("quicktime_atom_read_header 2 %c%c%c%c start %llx size %llx end %llx ftell %llx\n", 
 * 	atom->type[0], atom->type[1], atom->type[2], atom->type[3],
 * 	atom->start, atom->size, atom->end,
 * 	file->file_position);
 */
		}
	}


	return result;
}
Exemple #28
0
int main(int argc, char *argv[])
{
	quicktime_t *file;
	FILE *output;
	int result = 0;
	int i, j;
	int64_t length;
	char string[1024], *prefix = 0, *input = 0;
	char *data = 0;
	int bytes = 0, old_bytes = 0;
	float output_rate = 0;
	float input_rate;
	int64_t input_frame;
	int64_t new_length;
	int width, height;
	int rgb_to_ppm = 0;

	if(argc < 3)
	{
		usage();
	}

	for(i = 1, j = 0; i < argc; i++)
	{
		if(!strcmp(argv[i], "-f"))
		{
			if(i + 1 < argc)
			{
				output_rate = atof(argv[++i]);
			}
			else
				usage();
		}
		else
		if(j == 0)
		{
			input = argv[i];
			j++;
		}
		else
		if(j == 1)
		{
			prefix = argv[i];
			j++;
		}
	}

	if(!prefix || !input) usage();

	if(!(file = quicktime_open(input, 1, 0)))
	{
		printf("Open failed\n");
		exit(1);
	}
	
	if(!quicktime_video_tracks(file))
	{
		printf("No video tracks.\n");
		exit(1);
	}
	
	if(quicktime_match_32(quicktime_video_compressor(file, 0), QUICKTIME_RAW))
	{
		printf("Converting to ppm.\n");
		rgb_to_ppm = 1;
	}

	length = quicktime_video_length(file, 0);
	input_rate = quicktime_frame_rate(file, 0);
	if(!output_rate) output_rate = input_rate;
	new_length = output_rate / input_rate * length;
	width = quicktime_video_width(file, 0);
	height = quicktime_video_height(file, 0);

	for(i = 0; i < new_length; i++)
	{
/* Get output file */
		sprintf(string, "%s%06d", prefix, i);
		if(!(output = fopen(string, "wb")))
		{
			perror("Open failed");
			exit(1);
		}

/* Get input frame */
		input_frame = (int64_t)(input_rate / output_rate * i);
		bytes = quicktime_frame_size(file, input_frame, 0);

		if(data)
		{
			if(bytes > old_bytes) { free(data); data = 0; }
		}

		if(!data)
		{
			old_bytes = bytes;
			data = malloc(bytes);
		}

		quicktime_set_video_position(file, input_frame, 0);
		quicktime_read_data(file, data, bytes);
		if(rgb_to_ppm)
		{
			fprintf(output, "P6\n%d %d\n%d\n", width, height, 0xff);
		}

		if(!fwrite(data, bytes, 1, output))
		{
			perror("write failed");
		}
		fclose(output);
	}

	quicktime_close(file);
}
Exemple #29
0
int quicktime_make_streamable(char *in_path, char *out_path)
{
	quicktime_t file, *old_file, new_file;
	int moov_exists = 0, mdat_exists = 0, result, atoms = 1;
	int64_t mdat_start, mdat_size;
	quicktime_atom_t leaf_atom;
	int64_t moov_length;
	
	quicktime_init(&file);

/* find the moov atom in the old file */
	
	if(!(file.stream = fopen(in_path, "rb")))
	{
		perror("quicktime_make_streamable");
		return 1;
	}

	file.total_length = quicktime_get_file_length(in_path);

/* get the locations of moov and mdat atoms */
	do
	{
/*printf("%x\n", quicktime_position(&file)); */
		result = quicktime_atom_read_header(&file, &leaf_atom);

		if(!result)
		{
			if(quicktime_atom_is(&leaf_atom, "moov"))
			{
				moov_exists = atoms;
				moov_length = leaf_atom.size;
			}
			else
			if(quicktime_atom_is(&leaf_atom, "mdat"))
			{
				mdat_start = quicktime_position(&file) - HEADER_LENGTH;
				mdat_size = leaf_atom.size;
				mdat_exists = atoms;
			}

			quicktime_atom_skip(&file, &leaf_atom);

			atoms++;
		}
	}while(!result && quicktime_position(&file) < file.total_length);

	fclose(file.stream);

	if(!moov_exists)
	{
		printf("quicktime_make_streamable: no moov atom\n");
		return 1;
	}

	if(!mdat_exists)
	{
		printf("quicktime_make_streamable: no mdat atom\n");
		return 1;
	}

/* copy the old file to the new file */
	if(moov_exists && mdat_exists)
	{
/* moov wasn't the first atom */
		if(moov_exists > 1)
		{
			char *buffer;
			int64_t buf_size = 1000000;

			result = 0;

/* read the header proper */
			if(!(old_file = quicktime_open(in_path, 1, 0)))
			{
				return 1;
			}

			quicktime_shift_offsets(&(old_file->moov), moov_length);

/* open the output file */
			if(!(new_file.stream = fopen(out_path, "wb")))
			{
				perror("quicktime_make_streamable");
				result =  1;
			}
			else
			{
/* set up some flags */
				new_file.wr = 1;
				new_file.rd = 0;
				quicktime_write_moov(&new_file, &(old_file->moov));
				quicktime_set_position(old_file, mdat_start);

				if(!(buffer = calloc(1, buf_size)))
				{
					result = 1;
					printf("quicktime_make_streamable: out of memory\n");
				}
				else
				{
					while(quicktime_position(old_file) < mdat_start + mdat_size && !result)
					{
						if(quicktime_position(old_file) + buf_size > mdat_start + mdat_size)
							buf_size = mdat_start + mdat_size - quicktime_position(old_file);

						if(!quicktime_read_data(old_file, buffer, buf_size)) result = 1;
						if(!result)
						{
							if(!quicktime_write_data(&new_file, buffer, buf_size)) result = 1;
						}
					}
					free(buffer);
				}
				fclose(new_file.stream);
			}
			quicktime_close(old_file);
		}
		else
		{
			printf("quicktime_make_streamable: header already at 0 offset\n");
			return 0;
		}
	}
	
	return 0;
}
Exemple #30
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;
}