lqt_codecs.c
来自「这个库实现了录象功能」· C语言 代码 · 共 1,088 行 · 第 1/3 页
C
1,088 行
{ track->stts_index++; track->stts_count = 0; } track->current_position++; }/* Set the io_rowspan for the case the user didn't. */static void set_default_rowspan(quicktime_t *file, int track) { if(file->vtracks[track].io_row_span) return; lqt_get_default_rowspan(file->vtracks[track].io_cmodel, quicktime_video_width(file, track), &(file->vtracks[track].io_row_span), &(file->vtracks[track].io_row_span_uv)); }/* * Same as quicktime_decode_video but doesn't force BC_RGB888 */int lqt_decode_video(quicktime_t *file, unsigned char **row_pointers, int track){ int result; int height; int width; set_default_rowspan(file, track); height = quicktime_video_height(file, track); width = quicktime_video_width(file, track); if(file->vtracks[track].io_cmodel != file->vtracks[track].stream_cmodel) { if(!file->vtracks[track].temp_frame) { file->vtracks[track].temp_frame = lqt_rows_alloc(width, height, file->vtracks[track].stream_cmodel, &(file->vtracks[track].stream_row_span), &(file->vtracks[track].stream_row_span_uv)); } result = ((quicktime_codec_t*)file->vtracks[track].codec)->decode_video(file, file->vtracks[track].temp_frame, track); cmodel_transfer(row_pointers, // unsigned char **output_rows, /* Leave NULL if non existent */ file->vtracks[track].temp_frame, // unsigned char **input_rows, 0, // int in_x, /* Dimensions to capture from input frame */ 0, // int in_y, width, // int in_w, height, // int in_h, width, // int out_w, height, // int out_h, file->vtracks[track].stream_cmodel, // int in_colormodel, file->vtracks[track].io_cmodel, // int out_colormodel, file->vtracks[track].stream_row_span, /* For planar use the luma rowspan */ file->vtracks[track].io_row_span, /* For planar use the luma rowspan */ file->vtracks[track].stream_row_span_uv, /* Chroma rowspan */ file->vtracks[track].io_row_span_uv /* Chroma rowspan */); } else { file->vtracks[track].stream_row_span = file->vtracks[track].io_row_span; file->vtracks[track].stream_row_span_uv = file->vtracks[track].io_row_span_uv; result = ((quicktime_codec_t*)file->vtracks[track].codec)->decode_video(file, row_pointers, track); } lqt_update_frame_position(&(file->vtracks[track])); return result;}/* The original function, which forces BG_RGB888 */int quicktime_decode_video(quicktime_t *file, unsigned char **row_pointers, int track) { file->vtracks[track].io_cmodel = BC_RGB888; return lqt_decode_video(file, row_pointers, track); }long quicktime_decode_scaled(quicktime_t *file, int in_x, /* Location of input frame to take picture */ int in_y, int in_w, int in_h, int out_w, /* Dimensions of output frame */ int out_h, int color_model, /* One of the color models defined above */ unsigned char **row_pointers, int track){ int result; int height; int width; set_default_rowspan(file, track); height = quicktime_video_height(file, track); width = quicktime_video_width(file, track); file->vtracks[track].io_cmodel = color_model; if(!file->vtracks[track].temp_frame) { file->vtracks[track].temp_frame = lqt_rows_alloc(width, height, file->vtracks[track].stream_cmodel, &(file->vtracks[track].stream_row_span), &(file->vtracks[track].stream_row_span_uv)); } result = ((quicktime_codec_t*)file->vtracks[track].codec)->decode_video(file, file->vtracks[track].temp_frame, track); cmodel_transfer(row_pointers, // unsigned char **output_rows, /* Leave NULL if non existent */ file->vtracks[track].temp_frame, // unsigned char **input_rows, in_x, // int in_x, /* Dimensions to capture from input frame */ in_y, // int in_y, in_w, // int in_w, in_h, // int in_h, out_w, // int out_w, out_h, // int out_h, file->vtracks[track].stream_cmodel, // int in_colormodel, file->vtracks[track].io_cmodel, // int out_colormodel, file->vtracks[track].stream_row_span, /* For planar use the luma rowspan */ file->vtracks[track].io_row_span, /* For planar use the luma rowspan */ file->vtracks[track].stream_row_span_uv, /* Chroma rowspan */ file->vtracks[track].io_row_span_uv /* Chroma rowspan */); lqt_update_frame_position(&(file->vtracks[track])); return result;}int lqt_set_video_pass(quicktime_t *file, int pass, int total_passes, const char * stats_file, int track) { if(((quicktime_codec_t*)file->vtracks[track].codec)->set_pass) return ((quicktime_codec_t*)file->vtracks[track].codec)->set_pass(file, track, pass, total_passes, stats_file); else return 0; }static void start_encoding(quicktime_t *file) { int i; if(file->encoding_started) return; file->encoding_started = 1; if(file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML)) { quicktime_set_position(file, 0); // Write RIFF chunk quicktime_init_riff(file); } /* Trigger warnings if codecs are in the wrong container */ for(i = 0; i < file->total_atracks; i++) { if(!(file->atracks[i].compatibility_flags & file->file_type)) lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN, "Audio codec and container are not known to be compatible. File might be playable by libquicktime only."); } for(i = 0; i < file->total_vtracks; i++) { if(!(file->vtracks[i].compatibility_flags & file->file_type)) lqt_log(file, LQT_LOG_WARNING, LOG_DOMAIN, "Video codec and container are not known to be compatible. File might be playable by libquicktime only."); } }static int do_encode_video(quicktime_t *file, unsigned char **row_pointers, int track) { int result; int height; int width; start_encoding(file); set_default_rowspan(file, track); height = quicktime_video_height(file, track); width = quicktime_video_width(file, track); if(file->vtracks[track].io_cmodel != file->vtracks[track].stream_cmodel) { if(!file->vtracks[track].temp_frame) { file->vtracks[track].temp_frame = lqt_rows_alloc(width, height, file->vtracks[track].stream_cmodel, &(file->vtracks[track].stream_row_span), &(file->vtracks[track].stream_row_span_uv)); } cmodel_transfer(file->vtracks[track].temp_frame, // unsigned char **output_rows, /* Leave NULL if non existent */ row_pointers, // unsigned char **input_rows, 0, // int in_x, /* Dimensions to capture from input frame */ 0, // int in_y, width, // int in_w, height, // int in_h, width, // int out_w, height, // int out_h, file->vtracks[track].io_cmodel, // int in_colormodel, file->vtracks[track].stream_cmodel, // int out_colormodel, file->vtracks[track].io_row_span, /* For planar use the luma rowspan */ file->vtracks[track].stream_row_span, /* For planar use the luma rowspan */ file->vtracks[track].io_row_span_uv, /* Chroma rowspan */ file->vtracks[track].stream_row_span_uv /* Chroma rowspan */); result = ((quicktime_codec_t*)file->vtracks[track].codec)->encode_video(file, file->vtracks[track].temp_frame, track); } else { file->vtracks[track].stream_row_span = file->vtracks[track].io_row_span; file->vtracks[track].stream_row_span_uv = file->vtracks[track].io_row_span_uv; result = ((quicktime_codec_t*)file->vtracks[track].codec)->encode_video(file, row_pointers, track); } return result; }int lqt_encode_video(quicktime_t *file, unsigned char **row_pointers, int track, int64_t time) { int64_t stts_index, stts_count, dts; int result; /* Must set valid timestamp for encoders */ int64_t last_time = file->vtracks[track].timestamp; file->vtracks[track].timestamp = time; /* B-Frame handling: B-Frame enabled codecs can have a delay */ /* Here, we use vtrack->current_chunk as index of the actually written frame (implicitely assuming, that ther is never more than one frame per chunk), vtrack->current_position is number of frames, which came from the user */ result = do_encode_video(file, row_pointers, track); if (result) return(result); if(file->io_error) return 1; if(file->vtracks[track].has_b_frames) { file->vtracks[track].track->mdia.minf.stbl.has_ctts = 1; if(file->vtracks[track].current_position) quicktime_update_stts(&file->vtracks[track].track->mdia.minf.stbl.stts, file->vtracks[track].current_position - 1, time - last_time); if(file->vtracks[track].current_chunk > 1) /* Update ctts */ { dts = quicktime_sample_to_time(&file->vtracks[track].track->mdia.minf.stbl.stts, file->vtracks->current_chunk-2, &stts_index, &stts_count); quicktime_update_ctts(&file->vtracks[track].track->mdia.minf.stbl.ctts, file->vtracks[track].current_chunk - 2, file->vtracks[track].coded_timestamp - dts); } } else { if(file->vtracks[track].current_position) quicktime_update_stts(&file->vtracks[track].track->mdia.minf.stbl.stts, file->vtracks[track].current_position - 1, time - last_time); } if(file->vtracks[track].timecode_track) lqt_flush_timecode(file, track, time, 0); file->vtracks[track].current_position++; return 0; }int quicktime_encode_video(quicktime_t *file, unsigned char **row_pointers, int track) { return lqt_encode_video(file, row_pointers, track, file->vtracks[track].timestamp + file->vtracks[track].track->mdia.minf.stbl.stts.default_duration); }static int bytes_per_sample(lqt_sample_format_t format) { switch(format) { case LQT_SAMPLE_INT8: case LQT_SAMPLE_UINT8: return 1; break; case LQT_SAMPLE_INT16: return 2; break; case LQT_SAMPLE_INT32: return 4; break; case LQT_SAMPLE_FLOAT: /* Float is ALWAYS machine native */ return sizeof(float); break; case LQT_SAMPLE_DOUBLE: /* Double is ALWAYS machine native */ return sizeof(double); break; case LQT_SAMPLE_UNDEFINED: return 0; } return 0; }/* Decode raw samples */int lqt_decode_audio_raw(quicktime_t *file, void * output, long samples, int track) { int result; quicktime_audio_map_t * atrack; atrack = &(file->atracks[track]); result = ((quicktime_codec_t*)(atrack->codec))->decode_audio(file, output, samples, track); file->atracks[track].current_position += samples; return result; }int lqt_encode_audio_raw(quicktime_t *file, void * input, long samples, int track) { int result; quicktime_audio_map_t * atrack; if(!samples) return 0; atrack = &(file->atracks[track]); start_encoding(file); file->atracks[track].current_position += samples; result = ((quicktime_codec_t*)(atrack->codec))->encode_audio(file, input, samples, track); if(file->io_error) return 0; else return samples; }/* Compatibility function for old decoding API */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?