📄 video.c
字号:
vtrack->chroma_placement = LQT_CHROMA_PLACEMENT_MPEG2;#ifndef DO_INTERLACE // Seems not to work yet /* enable interlaced encoding */ vtrack->interlace_mode = LQT_INTERLACE_NONE;#endif } else if(codec->encoder->id == CODEC_ID_DVVIDEO) { vtrack->chroma_placement = LQT_CHROMA_PLACEMENT_DVPAL; }#ifndef DO_INTERLACE // Seems not to work yet else /* enable interlaced encoding */ vtrack->interlace_mode = LQT_INTERLACE_NONE;#endif } return 0; } if(!codec->initialized) { codec->frame = avcodec_alloc_frame(); /* time_base is 1/framerate for constant framerate */ codec->avctx->time_base.den = lqt_video_time_scale(file, track); codec->avctx->time_base.num = lqt_frame_duration(file, track, NULL); // codec->avctx->time_base.den = 1; // codec->avctx->time_base.num = lqt_video_time_scale(file, track); if(codec->avctx->flags & CODEC_FLAG_QSCALE) codec->avctx->global_quality = codec->qscale; codec->avctx->width = width; codec->avctx->height = height; codec->avctx->pix_fmt = lqt_ffmpeg_get_ffmpeg_colormodel(vtrack->stream_cmodel); lqt_get_pixel_aspect(file, track, &pixel_width, &pixel_height); codec->avctx->sample_aspect_ratio.num = pixel_width; codec->avctx->sample_aspect_ratio.den = pixel_height; /* Use global headers for mp4v */ if(codec->encoder->id == CODEC_ID_MPEG4) { if(!(file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML))) { codec->avctx->flags |= CODEC_FLAG_GLOBAL_HEADER; codec->write_global_header = 1; } /* Tweak some stream headers so even bad players play this */ else { strncpy(trak->strl->strh.fccHandler, "divx", 4); strncpy(trak->strl->strf.bh.biCompression, "DX50", 4); }#ifdef DO_INTERLACE // Seems not to work yet /* enable interlaced encoding */ if(vtrack->interlace_mode != LQT_INTERLACE_NONE) { lqt_log(file, LQT_LOG_INFO, LOG_DOMAIN, "Enabling interlaced encoding"); codec->avctx->flags |= (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN); }#endif } else if((codec->encoder->id == CODEC_ID_MSMPEG4V3) && (trak->strl) && !strncmp(trak->strl->strf.bh.biCompression, "DIV3", 4)) { strncpy(trak->strl->strh.fccHandler, "div3", 4); } else if((codec->encoder->id == CODEC_ID_H263) && (file->file_type & (LQT_FILE_MP4|LQT_FILE_3GP))) { uint8_t d263_data[] = { 'l', 'q', 't', ' ', /* Vendor? */ 0, /* Decoder version */ 0xa, /* Level */ 0 /* Profile */ }; quicktime_user_atoms_add_atom(&(trak->mdia.minf.stbl.stsd.table[0].user_atoms), "d263", d263_data, sizeof(d263_data)); strncpy(trak->mdia.minf.stbl.stsd.table[0].format, "s263", 4); } else if(codec->encoder->id == CODEC_ID_FFVHUFF) { if(!(file->file_type & (LQT_FILE_AVI|LQT_FILE_AVI_ODML))) { codec->avctx->flags |= CODEC_FLAG_GLOBAL_HEADER; codec->write_global_header = 1; } } /* Initialize 2-pass */ if(codec->total_passes) { if(codec->pass == 1) { codec->stats_file = fopen(codec->stats_filename, "w"); codec->avctx->flags |= CODEC_FLAG_PASS1; } else if(codec->pass == codec->total_passes) { codec->stats_file = fopen(codec->stats_filename, "r"); fseek(codec->stats_file, 0, SEEK_END); stats_len = ftell(codec->stats_file); fseek(codec->stats_file, 0, SEEK_SET); codec->avctx->stats_in = av_malloc(stats_len + 1); fread(codec->avctx->stats_in, stats_len, 1, codec->stats_file); codec->avctx->stats_in[stats_len] = '\0'; fclose(codec->stats_file); codec->stats_file = (FILE*)0; codec->avctx->flags |= CODEC_FLAG_PASS2; } } /* Open codec */ if(avcodec_open(codec->avctx, codec->encoder) != 0) return -1; codec->buffer_alloc = width * height * 4 + 1024*256; codec->buffer = malloc(codec->buffer_alloc); if(!codec->buffer) return -1; if(codec->avctx->max_b_frames > 0) vtrack->has_b_frames = 1; codec->initialized = 1; } // codec->lqt_colormodel = ffmepg_2_lqt(codec->com.ffcodec_enc); codec->frame->data[0] = row_pointers[0]; codec->frame->data[1] = row_pointers[1]; codec->frame->data[2] = row_pointers[2]; codec->frame->linesize[0] = vtrack->stream_row_span; codec->frame->linesize[1] = vtrack->stream_row_span_uv; codec->frame->linesize[2] = vtrack->stream_row_span_uv; codec->frame->pts = vtrack->timestamp; if(codec->avctx->flags & CODEC_FLAG_QSCALE) codec->frame->quality = codec->qscale;#ifdef DO_INTERLACE if(vtrack->interlace_mode != LQT_INTERLACE_NONE) { codec->frame->interlaced_frame = 1; if(vtrack->interlace_mode == LQT_INTERLACE_TOP_FIRST) codec->frame->top_field_first = 1; }#endif bytes_encoded = avcodec_encode_video(codec->avctx, codec->buffer, codec->buffer_alloc, codec->frame); if(bytes_encoded < 0) return -1; if(bytes_encoded) { vtrack->coded_timestamp = codec->avctx->coded_frame->pts; quicktime_write_chunk_header(file, trak, &chunk_atom); result = !quicktime_write_data(file, codec->buffer, bytes_encoded); quicktime_write_chunk_footer(file, trak, vtrack->current_chunk, &chunk_atom, 1); if(codec->avctx->coded_frame->key_frame) quicktime_insert_keyframe(file, vtrack->current_chunk-1, track); vtrack->current_chunk++; /* Write stats */ if((codec->pass == 1) && codec->avctx->stats_out && codec->stats_file) fprintf(codec->stats_file, codec->avctx->stats_out); } /* Check whether to write the global header */ if(codec->write_global_header && !codec->global_header_written) { if(codec->encoder->id == CODEC_ID_FFVHUFF) { quicktime_user_atoms_add_atom(&(trak->mdia.minf.stbl.stsd.table[0].user_atoms), "glbl", codec->avctx->extradata, codec->avctx->extradata_size ); } else if(codec->encoder->id == CODEC_ID_MPEG4) { esds = quicktime_set_esds(trak, codec->avctx->extradata, codec->avctx->extradata_size); esds->version = 0; esds->flags = 0; esds->esid = 0; esds->stream_priority = 0; esds->objectTypeId = 32; /* MPEG-4 video */ esds->streamType = 0x11; /* from qt4l and CDR_Dinner_350k-994.mp4 */ esds->bufferSizeDB = 64000; /* Hopefully not important :) */ /* Maybe correct these later? */ esds->maxBitrate = 200000; esds->avgBitrate = 200000; /* Set iods profile */ if(codec->avctx->max_b_frames || (codec->avctx->flags & (CODEC_FLAG_QPEL|CODEC_FLAG_GMC))) file->moov.iods.videoProfileId = 0xf3; // Advanced Simple Profile @ Level 3 else file->moov.iods.videoProfileId = 0x03; // Simple Profile @ Level 3 } codec->global_header_written = 1; } return result;}static int flush(quicktime_t *file, int track) { int result = 0; int bytes_encoded; quicktime_video_map_t *vtrack = &(file->vtracks[track]); quicktime_trak_t *trak = vtrack->track; quicktime_ffmpeg_video_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv; quicktime_atom_t chunk_atom; /* Do nothing if we didn't encode anything yet */ if(!codec->initialized) return 0; bytes_encoded = avcodec_encode_video(codec->avctx, codec->buffer, codec->buffer_alloc, (AVFrame*)0); if(bytes_encoded < 0) return 0; vtrack->coded_timestamp = codec->avctx->coded_frame->pts; if(bytes_encoded) { quicktime_write_chunk_header(file, trak, &chunk_atom); result = !quicktime_write_data(file, codec->buffer, bytes_encoded); quicktime_write_chunk_footer(file, trak, vtrack->current_chunk, &chunk_atom, 1); if(codec->avctx->coded_frame->key_frame) quicktime_insert_keyframe(file, vtrack->current_chunk-1, track); vtrack->current_chunk++; if((codec->pass == 1) && codec->avctx->stats_out && codec->stats_file) fprintf(codec->stats_file, codec->avctx->stats_out); return 1; } return 0; }static int set_parameter_video(quicktime_t *file, int track, const char *key, const void *value) { quicktime_ffmpeg_video_codec_t *codec = ((quicktime_codec_t*)file->vtracks[track].codec)->priv;#if 1 if(!strcasecmp(key, "ff_qscale")) { codec->qscale = *(int*)(value) * FF_QP2LAMBDA; return 0; } lqt_ffmpeg_set_parameter(codec->avctx, key, value);#endif return 0; }void quicktime_init_video_codec_ffmpeg(quicktime_video_map_t *vtrack, AVCodec *encoder, AVCodec *decoder){ quicktime_ffmpeg_video_codec_t *codec; char *compressor = vtrack->track->mdia.minf.stbl.stsd.table[0].format; avcodec_init(); codec = calloc(1, sizeof(*codec)); if(!codec) return; codec->avctx = avcodec_alloc_context(); if (quicktime_match_32(compressor, "dvc ")) codec->encode_colormodel = BC_YUV411P; else if (quicktime_match_32(compressor, "dv5n") || quicktime_match_32(compressor, "dv5p") || quicktime_match_32(compressor, "AVdn")) codec->encode_colormodel = BC_YUV422P; else if (quicktime_match_32(compressor, "MJPG")) codec->encode_colormodel = BC_YUVJ420P; else if (quicktime_match_32(compressor, "rle ")) codec->encode_colormodel = BC_RGB888; // else if(quicktime_match_32(compressor, "dvcp")) // codec->encode_colormodel = BC_YUV411P; else codec->encode_colormodel = BC_YUV420P; codec->encoder = encoder; codec->decoder = decoder; ((quicktime_codec_t*)vtrack->codec)->priv = (void *)codec; ((quicktime_codec_t*)vtrack->codec)->delete_vcodec = lqt_ffmpeg_delete_video; ((quicktime_codec_t*)vtrack->codec)->flush = flush; ((quicktime_codec_t*)vtrack->codec)->resync = resync_ffmpeg; if(encoder) { ((quicktime_codec_t*)vtrack->codec)->encode_video = lqt_ffmpeg_encode_video; ((quicktime_codec_t*)vtrack->codec)->set_pass = set_pass_ffmpeg; } if(decoder) ((quicktime_codec_t*)vtrack->codec)->decode_video = lqt_ffmpeg_decode_video; ((quicktime_codec_t*)vtrack->codec)->set_parameter = set_parameter_video;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -