lqt_transcode.c
来自「这个库实现了录象功能」· C语言 代码 · 共 599 行 · 第 1/2 页
C
599 行
out_cmodel = lqt_get_cmodel(h->out_file, 0); if(quicktime_reads_cmodel(h->in_file, out_cmodel, 0)) { h->colormodel = out_cmodel; } else if(quicktime_writes_cmodel(h->out_file, in_cmodel, 0)) { h->colormodel = in_cmodel; } else { h->colormodel = BC_RGB888; } h->video_buffer = lqt_rows_alloc(h->width, h->height, h->colormodel, &(h->rowspan), &(h->rowspan_uv)); quicktime_set_cmodel(h->in_file, h->colormodel); quicktime_set_cmodel(h->out_file, h->colormodel); lqt_destroy_codec_info(codec_info); h->num_video_frames = quicktime_video_length(h->in_file, 0); h->video_duration = lqt_video_duration(h->in_file, 0); } /* Check for audio */ if(quicktime_audio_tracks(h->in_file) && quicktime_supported_audio(h->in_file, 0)) h->do_audio = 1; if(h->do_audio) { h->audio_bits = quicktime_audio_bits(h->in_file, 0); h->samplerate = quicktime_sample_rate(h->in_file, 0); h->num_channels = lqt_total_channels(h->in_file); /* Codec info for encoding */ codec_info = lqt_find_audio_codec_by_name(audio_codec); if(!codec_info) { fprintf(stderr, _("Unsupported audio codec %s, try -la\n"), audio_codec); return 0; } /* Set up audio track */ lqt_set_audio(h->out_file, h->num_channels, h->samplerate, h->audio_bits, codec_info[0]); lqt_destroy_codec_info(codec_info); /* Decide about audio frame size */ /* Ok, we must take care about the audio frame size. The sample count, we pass to encode_audio() directly affects interleaving. Many small audio chunks make decoding inefficient, few large chunks make seeking slower because many samples inside a chunk have to be skipped. Ok, then lets just take half a second and see how it works :-) On a 25 fps system this means, that one audio chunks comes after an average of 12.5 video frames. This is roughly what we see in files created with other Software */ h->samples_per_frame = h->samplerate / 2; /* Avoid too odd numbers */ h->samples_per_frame = 16 * ((h->samples_per_frame + 15) / 16); /* Allocate output buffer */ if(floataudio) { h->audio_buffer_f = malloc(h->num_channels * sizeof(float*)); h->audio_buffer_f[0] = malloc(h->num_channels * h->samples_per_frame * sizeof(float)); for(i = 1; i < h->num_channels; i++) h->audio_buffer_f[i] = &(h->audio_buffer_f[0][i*h->samples_per_frame]); } else { h->audio_buffer_i = malloc(h->num_channels * sizeof(int16_t*)); h->audio_buffer_i[0] = malloc(h->num_channels * h->samples_per_frame * sizeof(int16_t)); for(i = 1; i < h->num_channels; i++) h->audio_buffer_i[i] = &(h->audio_buffer_i[0][i*h->samples_per_frame]); } h->num_audio_samples = quicktime_audio_length(h->in_file, 0); } if (qtvr) { if(strncmp(qtvr,"obj", 3) == 0) { lqt_qtvr_set_type(h->out_file, QTVR_OBJ, h->width , h->height, h->frame_duration, h->timescale, 0); } if(strncmp(qtvr,"pano", 4) == 0) { lqt_qtvr_set_type(h->out_file, QTVR_PAN, h->width/2, h->width, h->frame_duration, h->timescale, 0); } if(qtvr_columns && qtvr_rows) { lqt_qtvr_set_rows(h->out_file, qtvr_rows); lqt_qtvr_set_columns(h->out_file, qtvr_columns); } } return 1; }static int transcode_iteration(transcode_handle * h) { double audio_time; double video_time; int num_samples; int do_audio = 0; float progress; int64_t frame_time; if(h->do_audio && h->do_video) { audio_time = (float)(h->audio_samples_written)/(float)(h->samplerate); video_time = (float)(h->video_frames_written * h->frame_duration)/h->timescale; if(audio_time < video_time) do_audio = 1; } else if(h->do_audio) { do_audio = 1; } /* Audio Iteration */ if(do_audio) { // lqt_decode_audio(h->in_file, h->audio_buffer_i, h->audio_buffer_f, h->samples_per_frame); lqt_decode_audio_track(h->in_file, h->audio_buffer_i, h->audio_buffer_f, h->samples_per_frame, 0); num_samples = lqt_last_audio_position(h->in_file, 0) - h->audio_samples_written; // fprintf(stderr, "Num samples: %d\n",num_samples); quicktime_encode_audio(h->out_file, h->audio_buffer_i, h->audio_buffer_f, num_samples); h->audio_samples_written += num_samples; if(num_samples < h->samples_per_frame) h->do_audio = 0; progress = (float)(h->audio_samples_written)/(float)(h->num_audio_samples); } /* Video Iteration */ else { frame_time = lqt_frame_time(h->in_file, 0); lqt_decode_video(h->in_file, h->video_buffer, 0); lqt_encode_video(h->out_file, h->video_buffer, 0, frame_time); h->video_frames_written++; if(h->video_frames_written >= h->num_video_frames) h->do_video = 0; progress = (float)(h->video_frames_written)/(float)(h->num_video_frames); } if(!h->do_audio && !h->do_video) return 0; /* Calculate the progress */ if(progress > h->progress) h->progress = progress; return 1; }static void transcode_cleanup(transcode_handle * h) { quicktime_close(h->in_file); quicktime_close(h->out_file); }int main(int argc, char ** argv) { char * in_file = (char*)0; char * out_file = (char*)0; char * video_codec = (char*)0; char * audio_codec = (char*)0; char * format = (char*)0; char * qtvr = (char*)0; unsigned short qtvr_rows = 0; unsigned short qtvr_columns = 0; int i; lqt_file_type_t type = LQT_FILE_NONE, floataudio = 0; transcode_handle handle; int progress_written = 0; memset(&handle, 0, sizeof(handle)); switch(argc) { case 1: print_usage(); exit(0); break; case 2: if(!strcmp(argv[1], "-lv")) list_video_codecs(); else if(!strcmp(argv[1], "-la")) list_audio_codecs(); else if(!strcmp(argv[1], "-lf")) list_formats(); else print_usage(); exit(0); break; default: for(i = 1; i < argc - 2; i++) { if(!strcmp(argv[i], "-vc")) { video_codec = argv[i+1]; i++; } else if(!strcmp(argv[i], "-ac")) { audio_codec = argv[i+1]; i++; } else if(!strcmp(argv[i], "-f")) { format = argv[i+1]; i++; } else if(!strcmp(argv[i], "-avi")) format = "avi"; else if(!strcmp(argv[i], "-floataudio")) floataudio = 1; else if(!strcmp(argv[i], "-qtvr")) { qtvr = argv[i+1]; i++; } else if(!strcmp(argv[i], "-qtvr_rows")) { qtvr_rows = atoi(argv[i+1]); i++; } else if(!strcmp(argv[i], "-qtvr_columns")) { qtvr_columns = atoi(argv[i+1]); i++; } } in_file = argv[argc-2]; out_file = argv[argc-1]; } /* Get file type */ if(format) { for(i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) { if(!strcasecmp(format, formats[i].name)) { type = formats[i].type; break; } } if(type == LQT_FILE_NONE) { fprintf(stderr, _("Unsupported format %s, try -lf"), format); return -1; } } if(!transcode_init(&handle, in_file, out_file, video_codec, audio_codec, floataudio, type, qtvr, qtvr_rows, qtvr_columns)) { return -1; } i = 10; while(transcode_iteration(&handle)) { if(i == 10) { if(progress_written) putchar('\r'); printf(_("%6.2f%% Completed"), handle.progress*100.0); fflush(stdout); i = 0; progress_written = 1; } i++; } printf(_("%6.2f%% Completed\n"), 100.0); if(handle.audio_samples_written) printf("Transcoded %"PRId64" audio samples\n", handle.audio_samples_written); if(handle.video_frames_written) printf("Transcoded %"PRId64" video frames\n", handle.video_frames_written); transcode_cleanup(&handle); return 0; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?