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); }
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; }
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 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); }
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; }
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++; }
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; }
/* * 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); }
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); }
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; }