예제 #1
0
파일: dump.c 프로젝트: Cuchulain/cinelerra
main(int argc, char *argv[])
{
	quicktime_t *file;
	int result = 0;
	
	if(argc < 2)
	{
		printf("Dump all tables in movie.\n");
		exit(1);
	}

	if(!(file = quicktime_open(argv[1], 1, 0)))
	{
		printf("Open failed\n");
		exit(1);
	}

	quicktime_dump(file);

	quicktime_close(file);
}
예제 #2
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;
}
예제 #3
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)
예제 #4
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);
}
예제 #5
0
void probe_mov(info_t *ipipe)
{

  quicktime_t *qt_file=NULL;
  char *codec=NULL;

  int j, tracks;

  /* open movie for video probe */
  if(qt_file==NULL)
    if(NULL == (qt_file = quicktime_open((char *)ipipe->name,1,0))){
      tc_log_error(__FILE__,"can't open quicktime!");
      ipipe->error=1;
      return;
    }

  // extract audio parameters
  tracks=quicktime_audio_tracks(qt_file);

  if(tracks>TC_MAX_AUD_TRACKS) {
    tc_log_warn(__FILE__, "only %d of %d audio tracks scanned",
                TC_MAX_AUD_TRACKS, tracks);
    tracks=TC_MAX_AUD_TRACKS;
  }

  for(j=0; j<tracks; ++j) {

    ipipe->probe_info->track[j].samplerate = quicktime_sample_rate(qt_file, j);
    ipipe->probe_info->track[j].chan = quicktime_track_channels(qt_file, j);
    ipipe->probe_info->track[j].bits = quicktime_audio_bits(qt_file, j);

    codec  = quicktime_audio_compressor(qt_file, j);

    if(strcasecmp(codec,QUICKTIME_RAW)==0 || strcasecmp(codec,QUICKTIME_TWOS)==0)
      ipipe->probe_info->track[j].format = CODEC_PCM;
    else if(strcasecmp(codec,QUICKTIME_IMA4)==0)
      ipipe->probe_info->track[j].format = CODEC_IMA4;
    else
      /* XXX not right but works */
      ipipe->probe_info->track[j].format = CODEC_PCM;

    if (! binary_dump)
    	tc_log_info(__FILE__, "audio codec=%s", codec);

    if(ipipe->probe_info->track[j].chan>0) ++ipipe->probe_info->num_tracks;
  }


  // read all video parameter from input file
  ipipe->probe_info->width  =  quicktime_video_width(qt_file, 0);
  ipipe->probe_info->height =  quicktime_video_height(qt_file, 0);
  ipipe->probe_info->fps = quicktime_frame_rate(qt_file, 0);

  ipipe->probe_info->frames = quicktime_video_length(qt_file, 0);

  codec  =  quicktime_video_compressor(qt_file, 0);

  //check for supported codecs

  if(codec!=NULL) {

    if(strlen(codec)==0) {
      ipipe->probe_info->codec=TC_CODEC_RGB;
    } else {

      if(strcasecmp(codec,QUICKTIME_DV)==0)
	ipipe->probe_info->codec=TC_CODEC_DV;

      if(strcasecmp(codec,"dvsd")==0)
	ipipe->probe_info->codec=TC_CODEC_DV;

      if(strcasecmp(codec,"DIV3")==0)
	ipipe->probe_info->codec=TC_CODEC_DIVX3;

      if(strcasecmp(codec,"DIVX")==0)
	ipipe->probe_info->codec=TC_CODEC_DIVX4;

      if(strcasecmp(codec,"DX50")==0)
	ipipe->probe_info->codec=TC_CODEC_DIVX5;

      if(strcasecmp(codec,"MJPG")==0 || strcasecmp(codec,"JPEG")==0)
	ipipe->probe_info->codec=TC_CODEC_MJPEG;

      if(strcasecmp(codec,"YUV2")==0)
	ipipe->probe_info->codec=TC_CODEC_YUV2;

      if(strcasecmp(codec,"SVQ1")==0)
	ipipe->probe_info->codec=TC_CODEC_SVQ1;

      if(strcasecmp(codec,"SVQ3")==0)
	ipipe->probe_info->codec=TC_CODEC_SVQ3;
    }
  } else
    ipipe->probe_info->codec=TC_CODEC_UNKNOWN;

  if (! binary_dump)
  	tc_log_info(__FILE__, "video codec=%s", codec);
  ipipe->probe_info->magic=TC_MAGIC_MOV;
  tc_frc_code_from_value(&(ipipe->probe_info->frc),
                         ipipe->probe_info->fps);

  return;
}
예제 #6
0
void write_frame()
{
	int result = 0;
	int i;

// Shift data into frame buffer
	frame_buffer_size = frame_end - buffer;
	memcpy(frame_buffer, buffer, frame_buffer_size);





/*
 * if(
 * buffer[0] == 0xc2 &&
 * buffer[1] == 0x5c &&
 * buffer[2] == 0x43 &&
 * buffer[3] == 0x49 &&
 * buffer[4] == 0x95 &&
 * buffer[5] == 0xc4 &&
 * buffer[6] == 0xa6 &&
 * buffer[7] == 0x2b)
 * printf("write_frame %d\n", __LINE__);
 */

// Shift input buffer
	buffer_size = end - frame_end;
	memcpy(buffer, frame_end, buffer_size);

// Seek to end of this NAL
	ptr -= (frame_end - buffer);
	end = buffer + buffer_size;

	if(!frame_buffer_size) return;




/*
 * static int debug_count = 0;
 * char string[1024];
 * sprintf(string, "test%06d", debug_count++);
 * printf("write_frame %d: %s\n", __LINE__, string);
 * FILE *test = fopen(string, "w");
 * fwrite(frame_buffer, frame_buffer_size, 1, test);
 * fclose(test);
 */


	
	int got_picture = 0;
	AVFrame picture;


// Skip frames until first keyframe
/*
 * 	if(!bytes_written && !is_keyframe)
 * 	{
 * 	}
 * 	else
 */
	if(pass == 0)
	{
// Decode header only

printf("write_frame %d pass=%d %d\n", __LINE__, pass, frame_buffer_size);

/*
* static FILE *test = 0;
* if(!test) test = fopen("test", "w");
* fwrite(buffer, output_size, 1, test);
*/

		avcodec_get_frame_defaults(&picture);
		avcodec_decode_video(decoder_context, 
			&picture, 
			&got_picture, 
			buffer, 
			frame_buffer_size);


printf("write_frame %d %d\n", __LINE__, frame_buffer_size);


		if(decoder_context->width > 0)
		{
			video_width = decoder_context->width;
			video_height = decoder_context->height;
			video_frame_rate = (double)decoder_context->time_base.den / 
				decoder_context->time_base.num / 
				2;
			got_header = 1;
printf("%s format:\nwidth=%d\nheight=%d\nframerate=%f\naudio_track=%d\nsamplerate=%d\nchannels=%d\n", 
in_path,
video_width, 
video_height,
video_frame_rate,
audio_track,
audio_samplerate,
audio_channels);
		}

	}
	else
	{
/*
* printf("write_frame: %s at offset %llx\n", 
* is_keyframe ? "Keyframe" : "Frame", 
* bytes_written);
*/
		if(!quicktime_fd)
		{
			quicktime_fd = quicktime_open(out_path, 0, 1);
			if(!quicktime_fd)
			{
				fprintf(stderr, 
					"write_frame: Failed to open %s for writing\n",
					out_path);
				exit(1);
			}

#ifdef ENCODE_AUDIO
			quicktime_set_audio(quicktime_fd, 
				audio_channels, 
				audio_samplerate, 
				16, 
				QUICKTIME_MP4A);
			quicktime_set_parameter(quicktime_fd, "mp4a_bitrate", &audio_bitrate);
#endif

			quicktime_set_video(quicktime_fd, 
				1, 
				video_width, 
				video_height,
				video_frame_rate,
				QUICKTIME_H264);
		}



// Convert NAL codes to AVC format
		unsigned char *ptr2 = frame_buffer + NAL_CODE_SIZE;
		unsigned char *end2 = frame_buffer + frame_buffer_size;
		unsigned char *last_start = frame_buffer;
		int nal_size;
		int total_nals = 1;
		while(ptr2 < end2 + NAL_CODE_SIZE)
		{
// Start of next NAL code
			if(ptr2[0] == 0x00 &&
				ptr2[1] == 0x00 &&
				ptr2[2] == 0x00 &&
				ptr2[3] == 0x01)
			{
				nal_size = ptr2 - last_start - 4;
				last_start[0] = (nal_size & 0xff000000) >> 24;
				last_start[1] = (nal_size & 0xff0000) >> 16;
				last_start[2] = (nal_size & 0xff00) >> 8;
				last_start[3] = (nal_size & 0xff);
				last_start = ptr2;
				ptr2 += 4;
				total_nals++;
			}
			else
				ptr2++;
		}
예제 #7
0
파일: quicktime.c 프로젝트: knutj/cinelerra
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_start, moov_end;
	int ftyp_exists = 0;
	int ftyp_size = 0;
	unsigned char *ftyp_data = 0;

	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
	{
		result = quicktime_atom_read_header(&file, &leaf_atom);
//printf("0x%llx %s\n", quicktime_position(&file), leaf_atom.type);

		if(!result)
		{
			if(quicktime_atom_is(&leaf_atom, "ftyp"))
			{
				ftyp_exists = 1;
				ftyp_data = calloc(1, leaf_atom.size);
				ftyp_size = leaf_atom.size;
				quicktime_set_position(&file,
					quicktime_position(&file) - HEADER_LENGTH);
				quicktime_read_data(&file, (char*)ftyp_data, ftyp_size);
			}
			else
			if(quicktime_atom_is(&leaf_atom, "moov"))
			{
				moov_exists = atoms;
			}
			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");
		if(ftyp_data) free(ftyp_data);
		return 1;
	}

	if(!mdat_exists)
	{
		printf("quicktime_make_streamable: no mdat atom\n");
		if(ftyp_data) free(ftyp_data);
		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)))
			{
				if(ftyp_data) free(ftyp_data);
				return 1;
			}


/* 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;

/* Write ftyp header */
				if(ftyp_exists)
				{
					quicktime_write_data(&new_file, (char*)ftyp_data, ftyp_size);
				}


/* Write moov once to get final size with our substituted headers */
				moov_start = quicktime_position(&new_file);
				quicktime_write_moov(&new_file, &(old_file->moov), 0);
				moov_end = quicktime_position(&new_file);

printf("make_streamable 0x%llx 0x%llx\n", (long long)moov_end - moov_start, (long long)mdat_start);
				quicktime_shift_offsets(&(old_file->moov),
					moov_end - moov_start - mdat_start + ftyp_size);

/* Write again with shifted offsets */
				quicktime_set_position(&new_file, moov_start);
				quicktime_write_moov(&new_file, &(old_file->moov), 0);
				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");
			if(ftyp_data) free(ftyp_data);
			return 0;
		}
	}

	if(ftyp_data) free(ftyp_data);
	return 0;
}
예제 #8
0
파일: mp4extract.c 프로젝트: cmjonze/faad
/*
 * mp4extract
 * required arg1 should be the MP4 input file
 * required arg2 should be the output file for the extracted track
 */
int main(int argc, char** argv)
{
    /* variables controlable from command line */
    bool extractVideo = TRUE;

    /* internal variables */
    char* mp4FileName = NULL;
    char* outFileName = NULL;
    quicktime_t* mp4File = NULL;
    FILE* outFile = NULL;
    int track = 0;
    int frame, numFrames;
    u_int8_t buf[64*1024];  /* big enough? */
    int bufSize;

    /* begin process command line */
    progName = argv[0];
    while (1) {
        int c = -1;
        int option_index = 0;
        static struct option long_options[] = {
            { "audio", 0, 0, 'a' },
            { "video", 0, 0, 'v' },
            { NULL, 0, 0, 0 }
        };

        c = getopt_long(argc, argv, "av",
            long_options, &option_index);

        if (c == -1)
            break;

        switch (c) {
        case 'a': {
            extractVideo = FALSE;
            break;
        }
        case 'v': {
            extractVideo = TRUE;
            break;
        }
        case '?':
            break;
        default:
            fprintf(stderr, "%s: unknown option specified, ignoring: %c\n",
                progName, c);
        }
    }

    /* check that we have at least two non-option arguments */
    if ((argc - optind) < 2) {
        fprintf(stderr,
            "usage: %s <mpeg-file> <mov-file>\n",
            progName);
        exit(1);
    }

    /* point to the specified file names */
    mp4FileName = argv[optind++];
    outFileName = argv[optind++];

    /* warn about extraneous non-option arguments */
    if (optind < argc) {
        fprintf(stderr, "%s: unknown options specified, ignoring: ", progName);
        while (optind < argc) {
            fprintf(stderr, "%s ", argv[optind++]);
        }
        fprintf(stderr, "\n");
    }

    /* end processing of command line */

    /* open the MP4 file */
    mp4File = quicktime_open(mp4FileName, 1, 0, 0);
    if (mp4File == NULL) {
        fprintf(stderr,
            "%s: error %s: %s\n",
            progName, mp4FileName, strerror(errno));
        exit(2);
    }

    /* open output file for writing */
    outFile = fopen(outFileName, "wb");
    if (outFile == NULL) {
        fprintf(stderr,
            "%s: error opening %s: %s\n",
            progName, outFileName, strerror(errno));
        exit(3);
    }

    /* add MPEG-4 video config info at beginning of output file */
    if (extractVideo) {
        if (!strcasecmp(quicktime_video_compressor(mp4File, track), "mp4v")) {
            u_char* pConfig;
            int configSize;

            quicktime_get_mp4_video_decoder_config(mp4File, track,
                &pConfig, &configSize);

            if (fwrite(pConfig, 1, configSize, outFile) != configSize) {
                fprintf(stderr,
                    "%s: write error: %s\n",
                    progName, strerror(errno));
                exit(4);
            }
            free(pConfig);
        }
    }

    if (extractVideo) {
        numFrames = quicktime_video_length(mp4File, track);
    } else {
        numFrames = quicktime_audio_length(mp4File, track);
    }

    for (frame = 0; frame < numFrames; frame++) {
        if (extractVideo) {
            bufSize = quicktime_read_frame(mp4File,
                &buf[0], track);
        } else { // extract audio
            bufSize = quicktime_read_audio_frame(mp4File,
                &buf[0], sizeof(buf), track);
        }
        if (bufSize <= 0) {
            fprintf(stderr,
                "%s: read error: %s\n",
                progName, strerror(errno));
            exit(5);
        }

        if (fwrite(buf, 1, bufSize, outFile) != bufSize) {
            fprintf(stderr,
                "%s: write error: %s\n",
                progName, strerror(errno));
            exit(4);
        }
    }

    /* cleanup */
    quicktime_close(mp4File);
    fclose(outFile);
    exit(0);
}
예제 #9
0
int main(int argc, char *argv[])
{
	int error = 0;
	int frame_count = -1;
	char *row_pointers[3];
	int do_audio = 0;
	int do_video = 0;
	int channels = 0;
	long afragment = 65536;
	float **audio_output;
	int layer = 0;
	int astream = 0;
	char input_path[1024];
	char output_path[1024];
	int i;
	long current_frame = 0;
	long current_sample = 0;

	pthread_mutex_init(&mutex, NULL);
	signal(SIGINT, trap_interrupt);

	input_path[0] = 0;
	output_path[0] = 0;

	if(argc < 3)
	{
		printf("Usage: %s [-a] [-v] <mpeg file> <output movie> [frame count]\n", argv[0]);
		exit(1);
	}

	for(i = 1; i < argc; i++)
	{
		if(!strcmp(argv[i], "-a"))
		{
			do_audio = 1;
		}
		else
		if(!strcmp(argv[i], "-v"))
		{
			do_video = 1;
		}
		else
		if(!input_path[0])
		{
			strcpy(input_path, argv[i]);
		}
		else
		if(!output_path[0])
		{
			strcpy(output_path, argv[i]);
		}
		else
			frame_count = atol(argv[i]);
	}

//printf("main 1\n");
	if(!(input = mpeg3_open(input_path, &error)))
	{
		exit(1);
	}
//printf("main 1\n");

	if(!(output = quicktime_open(output_path, 0, 1)))
	{
		exit(1);
	}
//printf("main 1\n");

	if(do_video)
	{
		if(!mpeg3_total_vstreams(input))
		{
			do_video = 0;
		}
		else
		{
			quicktime_set_video(output, 
				1, 
				mpeg3_video_width(input, layer), 
				mpeg3_video_height(input, layer), 
				mpeg3_frame_rate(input, layer), 
				VIDEO_CODEC);
			quicktime_set_jpeg(output, 80, 0);
		}
	}
//printf("main 1\n");

	if(do_audio)
	{
		if(!mpeg3_total_astreams(input))
		{
			do_audio = 0;
		}
		else
		{
			int i;
			channels = mpeg3_audio_channels(input, astream);

			quicktime_set_audio(output, 
				channels, 
				mpeg3_sample_rate(input, 0), 
				24, 
				AUDIO_CODEC);

			audio_output = malloc(sizeof(float*) * channels);
			for(i = 0; i < channels; i++)
				audio_output[i] = malloc(sizeof(float) * afragment);
		}
	}
//printf("main 1\n");

//	quicktime_set_jpeg(output, 100, 0);
//	mpeg3_set_mmx(input, 0);

	while((!(do_video && mpeg3_end_of_video(input, layer)) || 
			!(do_audio && mpeg3_end_of_audio(input, astream))) &&
		(current_frame < frame_count || frame_count < 0))
	{
//printf("%d %d\n", mpeg3_end_of_video(input, layer), mpeg3_end_of_audio(input, astream));
		if(do_audio)
		{
			if(!mpeg3_end_of_audio(input, astream))
			{
				int fragment = afragment;
				int i, j, k;

				i = astream;
				k = 0;
				for(j = 0; j < mpeg3_audio_channels(input, i); j++, k++)
				{
					if(j == 0)
						mpeg3_read_audio(input, 
							audio_output[k], 	 /* Pointer to pre-allocated buffer of floats */
							0,      /* Pointer to pre-allocated buffer of int16's */
							j,          /* Channel to decode */
							fragment,         /* Number of samples to decode */
							i);
					else
						mpeg3_reread_audio(input, 
							audio_output[k], 	 /* Pointer to pre-allocated buffer of floats */
							0,      /* Pointer to pre-allocated buffer of int16's */
							j,          /* Channel to decode */
							fragment,         /* Number of samples to decode */
							i);
				}



				quicktime_encode_audio(output, 
					0, 
					audio_output, 
					fragment);

				current_sample += fragment;
				if(!do_video)
				{
					printf(" %d samples written\r", current_sample);
					fflush(stdout);
				}
			}
			else
				current_sample += afragment;
		}

		if(do_video)
		{
			if(!mpeg3_end_of_video(input, layer))
			{
				int fragment;
				if(do_audio)
					fragment = (long)((double)current_sample / 
							mpeg3_sample_rate(input, 0) *
							mpeg3_frame_rate(input, layer) - 
						current_frame);
				else
					fragment = 1;

				for(i = 0; i < fragment && !mpeg3_end_of_video(input, layer); i++)
				{
					mpeg3_read_yuvframe_ptr(input,
						&row_pointers[0],
						&row_pointers[1],
						&row_pointers[2],
						layer);

					switch(mpeg3_colormodel(input, layer))
					{
						case MPEG3_YUV420P:
							quicktime_set_cmodel(output, BC_YUV420P);
							break;
						case MPEG3_YUV422P:
							quicktime_set_cmodel(output, BC_YUV422P);
							break;
					}
					quicktime_encode_video(output, 
						(unsigned char **)row_pointers, 
						0);

					current_frame++;
					printf(" %d frames written\r", current_frame);
					fflush(stdout);
				}
			}
		}
	}
printf("main 2\n");

	printf("\n");
	quicktime_close(output);
	mpeg3_close(input);
}
예제 #10
0
int
cmdline_main (int argc, char *argv[])
{
    guchar *output;
    int num_frames = 1;
#ifdef MOVIES
    int generate_movie = 0;
    quicktime_t *output_movie;
    guchar **rows;
#endif
    int antialiasing = 0, supersampling = 0;
    int img_width, img_height;
    char *generator = 0;
    userval_info_t *userval_info;
    int num_input_drawables = 0;
    gboolean size_is_set = FALSE;
    char *script = NULL;
    char *output_filename;
    gboolean htmldoc = FALSE;
    define_t *defines = NULL;
    int bench_render_count = 1;
    int render_num;
    gboolean bench_no_output = FALSE;
    gboolean bench_no_backend = FALSE;
    int compile_time_limit = DEFAULT_OPTIMIZATION_TIMEOUT;

    for (;;)
    {
	static struct option long_options[] =
	    {
		{ "version", no_argument, 0, OPTION_VERSION },
		{ "help", no_argument, 0, OPTION_HELP },
		{ "intersampling", no_argument, 0, 'i' },
		{ "oversampling", no_argument, 0, 'o' },
		{ "cache", required_argument, 0, 'c' },
		{ "generator", required_argument, 0, 'g' },
		{ "size", required_argument, 0, 's' },
		{ "script-file", required_argument, 0, 'f' },
		{ "htmldoc", no_argument, 0, OPTION_HTMLDOC },
		{ "bench-no-output", no_argument, 0, OPTION_BENCH_NO_OUTPUT },
		{ "bench-only-compile", no_argument, 0, OPTION_BENCH_ONLY_COMPILE },
		{ "bench-no-compile-time-limit", no_argument, 0, OPTION_BENCH_NO_COMPILE_TIME_LIMIT },
		{ "bench-no-backend", no_argument, 0, OPTION_BENCH_NO_BACKEND },
		{ "bench-render-count", required_argument, 0, OPTION_BENCH_RENDER_COUNT },
#ifdef MOVIES
		{ "frames", required_argument, 0, 'F' },
		{ "movie", required_argument, 0, 'M' },
#endif
		{ 0, 0, 0, 0 }
	    };

	int option, option_index;

	option = getopt_long(argc, argv, 
#ifdef MOVIES
			     "f:ioF:D:M:c:g:s:", 
#else
			     "f:ioD:c:g:s:",
#endif
			     long_options, &option_index);

	if (option == -1)
	    break;

	switch (option)
	{
	    case OPTION_VERSION :
		printf("MathMap " MATHMAP_VERSION "\n"
		       "\n"
		       "Copyright (C) 1997-2009 Mark Probst\n"
		       "\n"
		       "This program is free software; you can redistribute it and/or modify\n"
		       "it under the terms of the GNU General Public License as published by\n"
		       "the Free Software Foundation; either version 2 of the License, or\n"
		       "(at your option) any later version.\n"
		       "\n"
		       "This program is distributed in the hope that it will be useful,\n"
		       "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
		       "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
		       "GNU General Public License for more details.\n"
		       "\n"
		       "You should have received a copy of the GNU General Public License\n"
		       "along with this program; if not, write to the Free Software\n"
		       "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n");
		return 0;

	    case OPTION_HELP :
		usage();
		return 0;

	    case OPTION_HTMLDOC :
		htmldoc = TRUE;
		break;

	    case 'f' :
		if (!g_file_get_contents(optarg, &script, NULL, NULL))
		{
		    fprintf(stderr, _("Error: The script file `%s' could not be read.\n"), optarg);
		    return 1;
		}
		break;

	    case 'i' :
		antialiasing = 1;
		break;

	    case 'o' :
		supersampling = 1;
		break;

	    case 'c' :
		cache_size = atoi(optarg);
		assert(cache_size > 0);
		break;

	    case 'D' :
		append_define(optarg, &defines);
		break;

	    case 'I' :
		alloc_cmdline_image_input_drawable(optarg);
		break;

	    case 'g' :
		generator = optarg;
		break;

	    case 's' :
		if (!parse_image_size(optarg, &img_width, &img_height))
		{
		    fprintf(stderr, _("Error: Invalid image size.  Syntax is <width>x<height>.  Example: 1024x768.\n"));
		    exit(1);
		}
		size_is_set = 1;
		break;

	    case OPTION_BENCH_RENDER_COUNT :
		bench_render_count = atoi(optarg);
		break;

	    case OPTION_BENCH_ONLY_COMPILE :
		bench_render_count = 0;
		break;

	    case OPTION_BENCH_NO_OUTPUT :
		bench_no_output = TRUE;
		break;

	    case OPTION_BENCH_NO_COMPILE_TIME_LIMIT :
		compile_time_limit = -1;
		break;

	    case OPTION_BENCH_NO_BACKEND :
		bench_no_backend = TRUE;
		break;

#ifdef MOVIES
	    case 'F' :
		generate_movie = 1;
		num_frames = atoi(optarg);
		assert(num_frames > 0);
		break;

	    case 'M' :
		alloc_cmdline_movie_input_drawable(optarg);
		break;
#endif
	}
    }

    if (script != NULL)
    {
	if (argc - optind != 1)
	{
	    usage();
	    return 1;
	}

	output_filename = argv[optind];
    }
    else
    {
	if (argc - optind != 2)
	{
	    usage();
	    return 1;
	}

	script = argv[optind];
	output_filename = argv[optind + 1];
    }

    init_tags();
    init_builtins();
    init_macros();
    init_compiler();

    if (htmldoc)
    {
	mathmap_t *mathmap = parse_mathmap(script);
	filter_t *filter;
	FILE *out;

	if (mathmap == NULL)
	{
	    fprintf(stderr, _("Error: Could not read MathMap script: %s\n"), error_string);
	    return 1;
	}

	out = fopen(output_filename, "w");
	if (out == NULL)
	{
	    fprintf(stderr, _("Error: Cannot open file `%s' for writing: %s\n"),
		    output_filename, strerror(errno));
	    return 1;
	}

	for (filter = mathmap->filters; filter != NULL; filter = filter->next)
	{
	    if (filter->kind != FILTER_MATHMAP)
		continue;

	    if (!write_filter_html_doc(out, filter->v.mathmap.decl))
		return 1;
	}

	fclose(out);
    }
    else if (generator == 0)
    {
	char *support_paths[4];
	mathmap_t *mathmap;
	mathmap_invocation_t *invocation;
	int current_frame;

	support_paths[0] = g_strdup_printf("%s/mathmap", GIMPDATADIR);
	support_paths[1] = g_strdup_printf("%s/.gimp-2.6/mathmap", getenv("HOME"));
	support_paths[2] = g_strdup_printf("%s/.gimp-2.4/mathmap", getenv("HOME"));
	support_paths[3] = NULL;

	mathmap = compile_mathmap(script, support_paths, compile_time_limit, bench_no_backend);

	if (bench_no_backend)
	    return 0;

	if (mathmap == 0)
	{
	    fprintf(stderr, _("Error: %s\n"), error_string);
	    exit(1);
	}

	if (bench_render_count == 0)
	    return 0;

	if (!size_is_set)
	    for (userval_info = mathmap->main_filter->userval_infos;
		 userval_info != NULL;
		 userval_info = userval_info->next)
	    {
		define_t *define;
		unsigned char *image;

		if (userval_info->type != USERVAL_IMAGE)
		    continue;

		define = lookup_define(defines, userval_info->name);
		if (define == NULL)
		{
		    fprintf(stderr, _("Error: No value defined for input image `%s'.\n"), userval_info->name);
		    return 1;
		}

		image = read_image(define->value, &img_width, &img_height);
		if (image == NULL)
		{
		    fprintf(stderr, _("Error: Could not read input image `%s'.\n"), define->value);
		    return 1;
		}
		free(image);

		size_is_set = TRUE;

		break;
	    }

	if (!size_is_set)
	{
	    fprintf(stderr, _("Error: Image size not set and no input images given.\n"));
	    exit(1);
	}

	invocation = invoke_mathmap(mathmap, NULL, img_width, img_height, TRUE);

	for (userval_info = mathmap->main_filter->userval_infos;
	     userval_info != NULL;
	     userval_info = userval_info->next)
	{
	    userval_t *userval = &invocation->uservals[userval_info->index];
	    define_t *define = lookup_define(defines, userval_info->name);

	    if (define == NULL)
	    {
		if (userval_info->type == USERVAL_IMAGE)
		{
		    fprintf(stderr, _("Error: No value defined for input image `%s'.\n"), userval_info->name);
		    return 1;
		}
	    }
	    else
		switch (userval_info->type)
		{
		    case USERVAL_INT_CONST :
			userval->v.int_const = atoi(define->value);
			break;

		    case USERVAL_FLOAT_CONST :
			userval->v.float_const = g_ascii_strtod(define->value, NULL);
			break;

		    case USERVAL_BOOL_CONST :
			userval->v.bool_const = (float)atoi(define->value);
			break;

		    case USERVAL_IMAGE :
			assign_image_userval_drawable(userval_info, userval,
						      alloc_cmdline_image_input_drawable(define->value));
			++num_input_drawables;
			break;

		    default :
			fprintf(stderr, _("Error: Can only define user values for types int, float, bool and image.\n"));
			return 1;
		}
	}

	for (render_num = 0; render_num < bench_render_count; ++render_num)
	{
#ifdef MOVIES
	    for (i = 0; i < num_input_drawables; ++i)
		if (input_drawables[i].type == DRAWABLE_MOVIE)
		{
		    assert(quicktime_video_width(input_drawables[i].v.movie, 0) == img_width);
		    assert(quicktime_video_height(input_drawables[i].v.movie, 0) == img_height);
		}
#endif

	    invocation_set_antialiasing(invocation, antialiasing);
	    invocation->supersampling = supersampling;

	    invocation->output_bpp = 4;

	    output = (guchar*)malloc((long)invocation->output_bpp * (long)img_width * (long)img_height);
	    assert(output != 0);

#ifdef MOVIES
	    if (generate_movie)
	    {
		output_movie = quicktime_open(output_filename, 0, 1);
		assert(output_movie != 0);

		quicktime_set_video(output_movie, 1, img_width, img_height, 25, QUICKTIME_JPEG);
		assert(quicktime_supported_video(output_movie, 0));
		quicktime_seek_start(output_movie);

		rows = (guchar**)malloc(sizeof(guchar*) * img_height);
		for (i = 0; i < img_height; ++i)
		    rows[i] = output + img_width * invocation->output_bpp * i;
	    }
#endif

	    for (current_frame = 0; current_frame < num_frames; ++current_frame)
	    {
		float current_t = (float)current_frame / (float)num_frames;
		image_t *closure = closure_image_alloc(&invocation->mathfuncs,
						       NULL,
						       invocation->mathmap->main_filter->num_uservals,
						       invocation->uservals,
						       img_width, img_height);
		mathmap_frame_t *frame = invocation_new_frame(invocation, closure,
							      current_frame, current_t);

		call_invocation_parallel_and_join(frame, closure, 0, 0, img_width, img_height, output, 1);

		invocation_free_frame(frame);

#ifdef MOVIES
		if (generate_movie && !bench_no_output)
		{
		    fprintf(stderr, _("writing frame %d\n"), current_frame);
		    assert(quicktime_encode_video(output_movie, rows, 0) == 0);
		}
#endif

		closure_image_free(closure);
	    }

	    if (!bench_no_output)
	    {
#ifdef MOVIES
		if (generate_movie)
		    quicktime_close(output_movie);
		else
#endif
		    write_image(output_filename, img_width, img_height, output,
				invocation->output_bpp, img_width * invocation->output_bpp, IMAGE_FORMAT_PNG);
	    }

	    free(output);
	}
    }
    else
    {
	if (strcmp(generator, "blender") == 0)
	{
	    if (!blender_generate_plug_in(script, output_filename))
		return 1;
	}
	/*
	else if (strcmp(generator, "pixeltree") == 0)
	{
	    if (!pixeltree_generate_plug_in(argv[optind], argv[optind + 1]))
		return 1;
	}
	*/
	else
	{
	    fprintf(stderr, _("Unknown generator `%s'\n"), generator);
	    return 1;
	}
    }

    return 0;
}