📄 picture.cc
字号:
/* Picture encoding object *//* (C) Andrew Stevens 2003 * This file is free software; you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * *//* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose. In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * */#include "config.h"#include <cassert>#include "mjpeg_types.h"#include "mjpeg_logging.h"#include "mpeg2syntaxcodes.h"#include "cpu_accel.h"#include "motionsearch.h"#include "encoderparams.hh"#include "mpeg2coder.hh"#include "quantize.hh"#include "seqencoder.hh"#include "ratectl.hh"#include "tables.h"Picture::Picture( EncoderParams &_encparams, ElemStrmWriter &writer, Quantizer &_quantizer ) : encparams( _encparams ), quantizer( _quantizer ), coding( new MPEG2CodingBuf( _encparams, writer) ){ int i,j; /* Allocate buffers for picture transformation */ blocks = static_cast<DCTblock*>( bufalloc(encparams.mb_per_pict*BLOCK_COUNT*sizeof(DCTblock))); qblocks = static_cast<DCTblock *>( bufalloc(encparams.mb_per_pict*BLOCK_COUNT*sizeof(DCTblock))); DCTblock *block = blocks; DCTblock *qblock = qblocks; for (j=0; j<encparams.enc_height2; j+=16) { for (i=0; i<encparams.enc_width; i+=16) { mbinfo.push_back(MacroBlock(*this, i,j, block,qblock )); block += BLOCK_COUNT; qblock += BLOCK_COUNT; } } rec_img = new uint8_t *[5]; org_img = new uint8_t *[5]; pred = new uint8_t *[5]; for( i = 0 ; i<3; i++) { int size = (i==0) ? encparams.lum_buffer_size : encparams.chrom_buffer_size; rec_img[i] = static_cast<uint8_t *>(bufalloc(size)); org_img[i] = 0; pred[i] = static_cast<uint8_t *>(bufalloc(size)); } // Initialise the reference image pointers to NULL to ensure errors show fwd_rec = fwd_org = 0; bwd_rec = bwd_org = 0;}Picture::~Picture(){ int i; for( i = 0 ; i<3; i++) { free( rec_img[i] ); free( pred[i] ); } delete rec_img; delete org_img; delete pred; delete coding;}/* * * Reconstruct the decoded image for references images and * for statistics * */void Picture::Reconstruct(){#ifndef OUTPUT_STAT if( pict_type!=B_TYPE) {#endif IQuantize(); ITransform(); CalcSNR(); Stats();#ifndef OUTPUT_STAT }#endif}/******************************************* * * Adjust picture encoding parameters * ******************************************/void Picture::SetEncodingParams( const StreamState &ss, int frames_available ){ new_seq = ss.new_seq; end_seq = ss.end_seq; if( ss.b_idx == 0 ) // Start of a B-group: I or P frame { Set_IP_Frame(ss, frames_available); } else { Set_B_Frame( ss ); } assert( pict_type == ss.frame_type ); decode = ss.FrameInSeq(); // == ss.s_idx; input = temp_ref+ss.gop_start_frame;//ss.InputFrameNum(); // temp_ref+ss.gop_start_frame; dc_prec = encparams.dc_prec; secondfield = false; ipflag = 0; /* Handle picture structure... */ if( encparams.fieldpic ) { pict_struct = encparams.topfirst ? TOP_FIELD : BOTTOM_FIELD; topfirst = 0; repeatfirst = 0; } /* Handle 3:2 pulldown frame pictures */ else if( encparams.pulldown_32 ) { pict_struct = FRAME_PICTURE; switch( present % 4 ) { case 0 : repeatfirst = 1; topfirst = encparams.topfirst; break; case 1 : repeatfirst = 0; topfirst = !encparams.topfirst; break; case 2 : repeatfirst = 1; topfirst = !encparams.topfirst; break; case 3 : repeatfirst = 0; topfirst = encparams.topfirst; break; } } /* Handle ordinary frame pictures */ else { pict_struct = FRAME_PICTURE; repeatfirst = 0; topfirst = encparams.topfirst; } forw_hor_f_code = encparams.motion_data[ss.b_idx].forw_hor_f_code; forw_vert_f_code = encparams.motion_data[ss.b_idx].forw_vert_f_code; sxf = encparams.motion_data[ss.b_idx].sxf; syf = encparams.motion_data[ss.b_idx].syf; switch ( pict_type ) { case I_TYPE : forw_hor_f_code = 15; forw_vert_f_code = 15; back_hor_f_code = 15; back_vert_f_code = 15; break; case P_TYPE : back_hor_f_code = 15; back_vert_f_code = 15; break; case B_TYPE : back_hor_f_code = encparams.motion_data[ss.b_idx].back_hor_f_code; back_vert_f_code = encparams.motion_data[ss.b_idx].back_vert_f_code; sxb = encparams.motion_data[ss.b_idx].sxb; syb = encparams.motion_data[ss.b_idx].syb; break; } /* We currently don't support frame-only DCT/Motion Est. for non progressive frames */ prog_frame = encparams.frame_pred_dct_tab[pict_type-1]; frame_pred_dct = encparams.frame_pred_dct_tab[pict_type-1]; q_scale_type = encparams.qscale_tab[pict_type-1]; intravlc = encparams.intravlc_tab[pict_type-1]; altscan = encparams.altscan_tab[pict_type-1]; scan_pattern = (altscan ? alternate_scan : zig_zag_scan); /* If we're using B frames then we reserve unit coefficient dropping for them as B frames have no 'knock on' information loss */ if( pict_type == B_TYPE || encparams.M == 1 ) { unit_coeff_threshold = abs( encparams.unit_coeff_elim ); unit_coeff_first = encparams.unit_coeff_elim < 0 ? 0 : 1; } else { unit_coeff_threshold = 0; unit_coeff_first = 0; } #ifdef OUTPUT_STAT fprintf(statfile,"\nFrame %d (#%d in display order):\n",decode,display); fprintf(statfile," picture_type=%c\n",pict_type_char[pict_type]); fprintf(statfile," temporal_reference=%d\n",temp_ref); fprintf(statfile," frame_pred_frame_dct=%d\n",frame_pred_dct); fprintf(statfile," q_scale_type=%d\n",q_scale_type); fprintf(statfile," intra_vlc_format=%d\n",intravlc); fprintf(statfile," alternate_scan=%d\n",altscan); if (pict_type!=I_TYPE) { fprintf(statfile," forward search window: %d...%d / %d...%d\n", -sxf,sxf,-syf,syf); fprintf(statfile," forward vector range: %d...%d.5 / %d...%d.5\n", -(4<<forw_hor_f_code),(4<<forw_hor_f_code)-1, -(4<<forw_vert_f_code),(4<<forw_vert_f_code)-1); } if (pict_type==B_TYPE) { fprintf(statfile," backward search window: %d...%d / %d...%d\n", -sxb,sxb,-syb,syb); fprintf(statfile," backward vector range: %d...%d.5 / %d...%d.5\n", -(4<<back_hor_f_code),(4<<back_hor_f_code)-1, -(4<<back_vert_f_code),(4<<back_vert_f_code)-1); }#endif}/************************************************** * * Set the picture encoding paramters for an I or P frame * * num_frames is the total number for frames in the input... * **************************************************/void Picture::Set_IP_Frame( const StreamState &ss, int num_frames ){ // Temp_ref could go beyond end of input sequence (StreamState // currently doesn't check) so need to handle this here. // This is what sorts out correct GOP structure at end of sequence temp_ref = ss.TemporalReference(); if (temp_ref >= (num_frames-ss.gop_start_frame)) temp_ref = (num_frames-ss.gop_start_frame) - 1; present = (ss.s_idx-ss.g_idx)+temp_ref; if (ss.g_idx==0) /* first displayed frame in GOP is I */ { pict_type = I_TYPE; } else { pict_type = P_TYPE; } /* Start of GOP - set GOP data for picture */ if( ss.g_idx == 0 ) { gop_start = true; closed_gop = ss.closed_gop; nb = ss.nb; np = ss.np; } else { gop_start = false; closed_gop = false; new_seq = false; }}/************************************************** * * Set the picture encoding paramters for a B frame * * num_frames is the total number for frames in the input... * **************************************************/void Picture::Set_B_Frame( const StreamState &ss ){ temp_ref = ss.g_idx - 1; present = ss.s_idx-1; pict_type = B_TYPE; gop_start = false; new_seq = false;}/************************************************************************ * * Adjust picture parameters for the second field in a pair of field * pictures. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -