📄 mpegvideo.c
字号:
/* Allocate MB type table */
CHECKED_ALLOCZ(s->mb_type , mb_array_size * sizeof(uint16_t)) //needed for encoding
CHECKED_ALLOCZ(s->lambda_table, mb_array_size * sizeof(int))
CHECKED_ALLOCZ(s->q_intra_matrix, 64*32 * sizeof(int))
CHECKED_ALLOCZ(s->q_inter_matrix, 64*32 * sizeof(int))
CHECKED_ALLOCZ(s->q_intra_matrix16, 64*32*2 * sizeof(uint16_t))
CHECKED_ALLOCZ(s->q_inter_matrix16, 64*32*2 * sizeof(uint16_t))
CHECKED_ALLOCZ(s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*))
CHECKED_ALLOCZ(s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*))
if(s->avctx->noise_reduction){
CHECKED_ALLOCZ(s->dct_offset, 2 * 64 * sizeof(uint16_t))
}
}
CHECKED_ALLOCZ(s->picture, MAX_PICTURE_COUNT * sizeof(Picture))
CHECKED_ALLOCZ(s->error_status_table, mb_array_size*sizeof(uint8_t))
if(s->codec_id==CODEC_ID_MPEG4 || (s->flags & CODEC_FLAG_INTERLACED_ME)){
/* interlaced direct mode decoding tables */
for(i=0; i<2; i++){
int j, k;
for(j=0; j<2; j++){
for(k=0; k<2; k++){
CHECKED_ALLOCZ(s->b_field_mv_table_base[i][j][k] , mv_table_size * 2 * sizeof(int16_t))
s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + s->mb_stride + 1;
}
CHECKED_ALLOCZ(s->b_field_select_table[i][j] , mb_array_size * 2 * sizeof(uint8_t))
CHECKED_ALLOCZ(s->p_field_mv_table_base[i][j] , mv_table_size * 2 * sizeof(int16_t))
s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + s->mb_stride + 1;
}
CHECKED_ALLOCZ(s->p_field_select_table[i] , mb_array_size * 2 * sizeof(uint8_t))
}
}
if (s->out_format == FMT_H263) {
/* ac values */
CHECKED_ALLOCZ(s->ac_val_base, yc_size * sizeof(int16_t) * 16);
s->ac_val[0] = s->ac_val_base + s->b8_stride + 1;
s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1;
s->ac_val[2] = s->ac_val[1] + c_size;
/* cbp values */
CHECKED_ALLOCZ(s->coded_block_base, y_size);
s->coded_block= s->coded_block_base + s->b8_stride + 1;
/* cbp, ac_pred, pred_dir */
CHECKED_ALLOCZ(s->cbp_table , mb_array_size * sizeof(uint8_t))
CHECKED_ALLOCZ(s->pred_dir_table, mb_array_size * sizeof(uint8_t))
}
if (s->h263_pred || s->h263_plus || !s->encoding) {
/* dc values */
//MN: we need these for error resilience of intra-frames
CHECKED_ALLOCZ(s->dc_val_base, yc_size * sizeof(int16_t));
s->dc_val[0] = s->dc_val_base + s->b8_stride + 1;
s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1;
s->dc_val[2] = s->dc_val[1] + c_size;
for(i=0;i<yc_size;i++)
s->dc_val_base[i] = 1024;
}
/* which mb is a intra block */
CHECKED_ALLOCZ(s->mbintra_table, mb_array_size);
memset(s->mbintra_table, 1, mb_array_size);
/* init macroblock skip table */
CHECKED_ALLOCZ(s->mbskip_table, mb_array_size+2);
//Note the +1 is for a quicker mpeg4 slice_end detection
CHECKED_ALLOCZ(s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE);
s->parse_context.state= -1;
if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){
s->visualization_buffer[0] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);
s->visualization_buffer[1] = av_malloc((s->mb_width*8 + EDGE_WIDTH) * s->mb_height*8 + EDGE_WIDTH);
s->visualization_buffer[2] = av_malloc((s->mb_width*8 + EDGE_WIDTH) * s->mb_height*8 + EDGE_WIDTH);
}
s->context_initialized = 1;
s->thread_context[0]= s;
for(i=1; i<s->avctx->thread_count; i++){
s->thread_context[i]= av_malloc(sizeof(MpegEncContext));
memcpy(s->thread_context[i], s, sizeof(MpegEncContext));
}
for(i=0; i<s->avctx->thread_count; i++){
if(init_duplicate_context(s->thread_context[i], s) < 0)
goto fail;
s->thread_context[i]->start_mb_y= (s->mb_height*(i ) + s->avctx->thread_count/2) / s->avctx->thread_count;
s->thread_context[i]->end_mb_y = (s->mb_height*(i+1) + s->avctx->thread_count/2) / s->avctx->thread_count;
}
return 0;
fail:
MPV_common_end(s);
return -1;
}
/* init common structure for both encoder and decoder */
void MPV_common_end(MpegEncContext *s)
{
int i, j, k;
for(i=0; i<s->avctx->thread_count; i++){
free_duplicate_context(s->thread_context[i]);
}
for(i=1; i<s->avctx->thread_count; i++){
av_freep(&s->thread_context[i]);
}
av_freep(&s->parse_context.buffer);
s->parse_context.buffer_size=0;
av_freep(&s->mb_type);
av_freep(&s->p_mv_table_base);
av_freep(&s->b_forw_mv_table_base);
av_freep(&s->b_back_mv_table_base);
av_freep(&s->b_bidir_forw_mv_table_base);
av_freep(&s->b_bidir_back_mv_table_base);
av_freep(&s->b_direct_mv_table_base);
s->p_mv_table= NULL;
s->b_forw_mv_table= NULL;
s->b_back_mv_table= NULL;
s->b_bidir_forw_mv_table= NULL;
s->b_bidir_back_mv_table= NULL;
s->b_direct_mv_table= NULL;
for(i=0; i<2; i++){
for(j=0; j<2; j++){
for(k=0; k<2; k++){
av_freep(&s->b_field_mv_table_base[i][j][k]);
s->b_field_mv_table[i][j][k]=NULL;
}
av_freep(&s->b_field_select_table[i][j]);
av_freep(&s->p_field_mv_table_base[i][j]);
s->p_field_mv_table[i][j]=NULL;
}
av_freep(&s->p_field_select_table[i]);
}
av_freep(&s->dc_val_base);
av_freep(&s->ac_val_base);
av_freep(&s->coded_block_base);
av_freep(&s->mbintra_table);
av_freep(&s->cbp_table);
av_freep(&s->pred_dir_table);
av_freep(&s->mbskip_table);
av_freep(&s->prev_pict_types);
av_freep(&s->bitstream_buffer);
s->allocated_bitstream_buffer_size=0;
av_freep(&s->avctx->stats_out);
av_freep(&s->ac_stats);
av_freep(&s->error_status_table);
av_freep(&s->mb_index2xy);
av_freep(&s->lambda_table);
av_freep(&s->q_intra_matrix);
av_freep(&s->q_inter_matrix);
av_freep(&s->q_intra_matrix16);
av_freep(&s->q_inter_matrix16);
av_freep(&s->input_picture);
av_freep(&s->reordered_input_picture);
av_freep(&s->dct_offset);
if(s->picture){
for(i=0; i<MAX_PICTURE_COUNT; i++){
free_picture(s, &s->picture[i]);
}
}
av_freep(&s->picture);
s->context_initialized = 0;
s->last_picture_ptr=
s->next_picture_ptr=
s->current_picture_ptr= NULL;
s->linesize= s->uvlinesize= 0;
for(i=0; i<3; i++)
av_freep(&s->visualization_buffer[i]);
avcodec_default_free_buffers(s->avctx);
}
#ifdef CONFIG_ENCODERS
/* init video encoder */
int MPV_encode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
int i;
int chroma_h_shift, chroma_v_shift;
MPV_encode_defaults(s);
switch (avctx->codec_id) {
case CODEC_ID_MPEG2VIDEO:
if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){
av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n");
return -1;
}
break;
case CODEC_ID_LJPEG:
case CODEC_ID_MJPEG:
if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P &&
((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P) || avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL)){
av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n");
return -1;
}
break;
default:
if(avctx->pix_fmt != PIX_FMT_YUV420P){
av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n");
return -1;
}
}
switch (avctx->pix_fmt) {
case PIX_FMT_YUVJ422P:
case PIX_FMT_YUV422P:
s->chroma_format = CHROMA_422;
break;
case PIX_FMT_YUVJ420P:
case PIX_FMT_YUV420P:
default:
s->chroma_format = CHROMA_420;
break;
}
s->bit_rate = avctx->bit_rate;
s->width = avctx->width;
s->height = avctx->height;
if(avctx->gop_size > 600 && avctx->strict_std_compliance>FF_COMPLIANCE_EXPERIMENTAL){
av_log(avctx, AV_LOG_ERROR, "Warning keyframe interval too large! reducing it ...\n");
avctx->gop_size=600;
}
s->gop_size = avctx->gop_size;
s->avctx = avctx;
s->flags= avctx->flags;
s->flags2= avctx->flags2;
s->max_b_frames= avctx->max_b_frames;
s->codec_id= avctx->codec->id;
s->luma_elim_threshold = avctx->luma_elim_threshold;
s->chroma_elim_threshold= avctx->chroma_elim_threshold;
s->strict_std_compliance= avctx->strict_std_compliance;
s->data_partitioning= avctx->flags & CODEC_FLAG_PART;
s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0;
s->mpeg_quant= avctx->mpeg_quant;
s->rtp_mode= !!avctx->rtp_payload_size;
s->intra_dc_precision= avctx->intra_dc_precision;
s->user_specified_pts = AV_NOPTS_VALUE;
if (s->gop_size <= 1) {
s->intra_only = 1;
s->gop_size = 12;
} else {
s->intra_only = 0;
}
s->me_method = avctx->me_method;
/* Fixed QSCALE */
s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE);
s->adaptive_quant= ( s->avctx->lumi_masking
|| s->avctx->dark_masking
|| s->avctx->temporal_cplx_masking
|| s->avctx->spatial_cplx_masking
|| s->avctx->p_masking
|| s->avctx->border_masking
|| (s->flags&CODEC_FLAG_QP_RD))
;//&& !s->fixed_qscale; /* intentional difference ??? */
s->obmc= !!(s->flags & CODEC_FLAG_OBMC);
s->loop_filter= !!(s->flags & CODEC_FLAG_LOOP_FILTER);
s->alternate_scan= !!(s->flags & CODEC_FLAG_ALT_SCAN);
s->intra_vlc_format= !!(s->flags2 & CODEC_FLAG2_INTRA_VLC);
s->q_scale_type= !!(s->flags2 & CODEC_FLAG2_NON_LINEAR_QUANT);
if(avctx->rc_max_rate && !avctx->rc_buffer_size){
av_log(avctx, AV_LOG_ERROR, "a vbv buffer size is needed, for encoding with a maximum bitrate\n");
return -1;
}
if(avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate){
av_log(avctx, AV_LOG_INFO, "Warning min_rate > 0 but min_rate != max_rate isn't recommended!\n");
}
if(avctx->rc_min_rate && avctx->rc_min_rate > avctx->bit_rate){
av_log(avctx, AV_LOG_ERROR, "bitrate below min bitrate\n");
return -1;
}
if(avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate){
av_log(avctx, AV_LOG_INFO, "bitrate above max bitrate\n");
return -1;
}
if(avctx->rc_buffer_size && avctx->bit_rate*av_q2d(avctx->time_base) > avctx->rc_buffer_size){
av_log(avctx, AV_LOG_ERROR, "VBV buffer too small for bitrate\n");
return -1;
}
if(avctx->bit_rate*av_q2d(avctx->time_base) > avctx->bit_rate_tolerance){
av_log(avctx, AV_LOG_ERROR, "bitrate tolerance too small for bitrate\n");
return -1;
}
if( s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate
&& (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO)
&& 90000LL * (avctx->rc_buffer_size-1) > s->avctx->rc_max_rate*0xFFFFLL){
av_log(avctx, AV_LOG_INFO, "Warning vbv_delay will be set to 0xFFFF (=VBR) as the specified vbv buffer is too large for the given bitrate!\n");
}
if((s->flags & CODEC_FLAG_4MV) && s->codec_id != CODEC_ID_MPEG4
&& s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P && s->codec_id != CODEC_ID_FLV1){
av_log(avctx, AV_LOG_ERROR, "4MV not supported by codec\n");
return -1;
}
if(s->obmc && s->avctx->mb_decision != FF_MB_DECISION_SIMPLE){
av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with simple mb decision\n");
return -1;
}
if(s->obmc && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P){
av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with H263(+)\n");
return -1;
}
if(s->quarter_sample && s->codec_id != CODEC_ID_MPEG4){
av_log(avctx, AV_LOG_ERROR, "qpel not supported by codec\n");
return -1;
}
if(s->data_partitioning && s->codec_id != CODEC_ID_MPEG4){
av_log(avctx, AV_LOG_ERROR, "data partitioning not supported by codec\n");
return -1;
}
if(s->max_b_frames && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO){
av_log(avctx, AV_LOG_ERROR, "b frames not supported by codec\n");
return -1;
}
if((s->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN))
&& s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG2VIDEO){
av_log(avctx, AV_LOG_ERROR, "interlacing not supported by codec\n");
return -1;
}
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -