putpic.cc

来自「Motion JPEG编解码器源代码」· CC 代码 · 共 402 行

CC
402
字号
/* putpic.c, block and motion vector encoding routines                      */ /*  (C) 2000-2005 Andrew Stevens *//* These modifications are 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. * */ /* Original reference encoder from which this derived: * Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. *//* * 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 <stdio.h>#include <cassert>#include "mpeg2syntaxcodes.h"#include "tables.h"#include "simd.h"#include "mpeg2encoder.hh"#include "mpeg2coder.hh"#include "ratectl.hh"#include "macroblock.hh"#include "picture.hh"    /* output motion vectors (6.2.5.2, 6.3.16.2) * * this routine also updates the predictions for motion vectors (PMV) */void Picture::PutMVs( MotionEst &me, bool back ){	int hor_f_code;	int vert_f_code;	if( back )	{		hor_f_code = back_hor_f_code;		vert_f_code = back_vert_f_code;	}	else	{		hor_f_code = forw_hor_f_code;		vert_f_code = forw_vert_f_code;	}	if (pict_struct==FRAME_PICTURE)	{		if (me.motion_type==MC_FRAME)		{			/* frame prediction */			coding->PutMV(me.MV[0][back][0]-PMV[0][back][0],hor_f_code);			coding->PutMV(me.MV[0][back][1]-PMV[0][back][1],vert_f_code);			PMV[0][back][0]=PMV[1][back][0]=me.MV[0][back][0];			PMV[0][back][1]=PMV[1][back][1]=me.MV[0][back][1];		}		else if (me.motion_type==MC_FIELD)		{			/* field prediction */			coding->PutBits(me.field_sel[0][back],1);			coding->PutMV(me.MV[0][back][0]-PMV[0][back][0],hor_f_code);			coding->PutMV((me.MV[0][back][1]>>1)-(PMV[0][back][1]>>1),vert_f_code);			coding->PutBits(me.field_sel[1][back],1);			coding->PutMV(me.MV[1][back][0]-PMV[1][back][0],hor_f_code);			coding->PutMV((me.MV[1][back][1]>>1)-(PMV[1][back][1]>>1),vert_f_code);			PMV[0][back][0]=me.MV[0][back][0];			PMV[0][back][1]=me.MV[0][back][1];			PMV[1][back][0]=me.MV[1][back][0];			PMV[1][back][1]=me.MV[1][back][1];		}		else		{#ifdef DEBUG_DPME            MotionVector DMV[Parity::dim /*pred*/];                        calc_DMV(*this,                         DMV,                         me.dualprimeMV,                         me.MV[0][0][0],                         me.MV[0][0][1]>>1);                                     printf( "PR%06d: %03d %03d %03d %03d %03d %03d\n", dp_mv,                me.MV[0][0][0], (me.MV[0][0][1]>>1), DMV[0][0], DMV[0][1], DMV[1][0], DMV[1][1] );            ++dp_mv;            if( dp_mv == 45000 )                exit(0);#endif			/* dual prime prediction */			coding->PutMV(me.MV[0][back][0]-PMV[0][back][0],hor_f_code);			coding->PutDMV(me.dualprimeMV[0]);			coding->PutMV((me.MV[0][back][1]>>1)-(PMV[0][back][1]>>1),vert_f_code);			coding->PutDMV(me.dualprimeMV[1]);			PMV[0][back][0]=PMV[1][back][0]=me.MV[0][back][0];			PMV[0][back][1]=PMV[1][back][1]=me.MV[0][back][1];		}	}	else	{		/* field picture */		if (me.motion_type==MC_FIELD)		{			/* field prediction */			coding->PutBits(me.field_sel[0][back],1);			coding->PutMV(me.MV[0][back][0]-PMV[0][back][0],hor_f_code);			coding->PutMV(me.MV[0][back][1]-PMV[0][back][1],vert_f_code);			PMV[0][back][0]=PMV[1][back][0]=me.MV[0][back][0];			PMV[0][back][1]=PMV[1][back][1]=me.MV[0][back][1];		}		else if (me.motion_type==MC_16X8)		{			/* 16x8 prediction */			coding->PutBits(me.field_sel[0][back],1);			coding->PutMV(me.MV[0][back][0]-PMV[0][back][0],hor_f_code);			coding->PutMV(me.MV[0][back][1]-PMV[0][back][1],vert_f_code);			coding->PutBits(me.field_sel[1][back],1);			coding->PutMV(me.MV[1][back][0]-PMV[1][back][0],hor_f_code);			coding->PutMV(me.MV[1][back][1]-PMV[1][back][1],vert_f_code);			PMV[0][back][0]=me.MV[0][back][0];			PMV[0][back][1]=me.MV[0][back][1];			PMV[1][back][0]=me.MV[1][back][0];			PMV[1][back][1]=me.MV[1][back][1];		}		else		{			/* dual prime prediction */			coding->PutMV(me.MV[0][back][0]-PMV[0][back][0],hor_f_code);			coding->PutDMV(me.dualprimeMV[0]);			coding->PutMV(me.MV[0][back][1]-PMV[0][back][1],vert_f_code);			coding->PutDMV(me.dualprimeMV[1]);			PMV[0][back][0]=PMV[1][back][0]=me.MV[0][back][0];			PMV[0][back][1]=PMV[1][back][1]=me.MV[0][back][1];		}	}}void MacroBlock::PutBlocks( ){    int comp;    int cc;    for (comp=0; comp<BLOCK_COUNT; comp++)    {        /* block loop */        if( cbp & (1<<(BLOCK_COUNT-1-comp)))        {            if (final_me.mb_type & MB_INTRA)            {                // TODO: 420 Only?                cc = (comp<4) ? 0 : (comp&1)+1;                picture->coding->PutIntraBlk(picture, qdctblocks[comp],cc);            }            else            {                picture->coding->PutNonIntraBlk(picture,qdctblocks[comp]);            }        }    }}void MacroBlock::SkippedCoding( bool slice_begin_end ){    skipped = false;    if( slice_begin_end || cbp )    {        /* there's no VLC for 'No MC, Not Coded':         * we have to transmit (0,0) motion vectors         */        if (picture->pict_type==P_TYPE && !cbp)            final_me.mb_type|= MB_FORWARD;        return;    }    MacroBlock *prev_mb = picture->prev_mb;    /* P picture, no motion vectors -> skip */    if (picture->pict_type==P_TYPE && !(final_me.mb_type&MB_FORWARD))    {        /* reset predictors */        picture->Reset_DC_DCT_Pred();        picture->Reset_MV_Pred();        skipped = true;        return;    }        if(picture->pict_type==B_TYPE )    {        /* B frame picture with same prediction type         * (forward/backward/interp.)  and same active vectors         * as in previous macroblock -> skip         */        if (  picture->pict_struct==FRAME_PICTURE              && final_me.motion_type==MC_FRAME              && ((prev_mb->final_me.mb_type ^ final_me.mb_type) &(MB_FORWARD|MB_BACKWARD))==0              && (!(final_me.mb_type&MB_FORWARD) ||                  (picture->PMV[0][0][0]==final_me.MV[0][0][0] &&                   picture->PMV[0][0][1]==final_me.MV[0][0][1]))              && (!(final_me.mb_type&MB_BACKWARD) ||                  (picture->PMV[0][1][0]==final_me.MV[0][1][0] &&                   picture->PMV[0][1][1]==final_me.MV[0][1][1])))        {            skipped = true;            return;        }        /* B field picture macroblock with same prediction         * type (forward/backward/interp.) and active         * vectors as previous macroblock and same         * vertical field selects as current field -> skio         */        if (picture->pict_struct!=FRAME_PICTURE            && final_me.motion_type==MC_FIELD            && ((prev_mb->final_me.mb_type^final_me.mb_type)&(MB_FORWARD|MB_BACKWARD))==0            && (!(final_me.mb_type&MB_FORWARD) ||                (picture->PMV[0][0][0]==final_me.MV[0][0][0] &&                 picture->PMV[0][0][1]==final_me.MV[0][0][1] &&                 final_me.field_sel[0][0]==(picture->pict_struct==BOTTOM_FIELD)))            && (!(final_me.mb_type&MB_BACKWARD) ||                (picture->PMV[0][1][0]==final_me.MV[0][1][0] &&                 picture->PMV[0][1][1]==final_me.MV[0][1][1] &&                 final_me.field_sel[0][1]==(picture->pict_struct==BOTTOM_FIELD))))        {            skipped = true;            return;        }    }}/* generate picture header (6.2.3, 6.3.10) */void Picture::PutHeader(){	assert( coding->Aligned() );	coding->PutBits(PICTURE_START_CODE,32); /* picture_start_code */	coding->PutBits(temp_ref,10); /* temporal_reference */	coding->PutBits(pict_type,3); /* picture_coding_type */	coding->PutBits(vbv_delay,16); /* vbv_delay */	if (pict_type==P_TYPE || pict_type==B_TYPE)	{		coding->PutBits(0,1); /* full_pel_forward_vector */		if (encparams.mpeg1)			coding->PutBits(forw_hor_f_code,3);		else			coding->PutBits(7,3); /* forward_f_code */	}	if (pict_type==B_TYPE)	{		coding->PutBits(0,1); /* full_pel_backward_vector */		if (encparams.mpeg1)			coding->PutBits(back_hor_f_code,3);		else			coding->PutBits(7,3); /* backward_f_code */	}	coding->PutBits(0,1); /* extra_bit_picture */    coding->AlignBits();	if ( !encparams.mpeg1 )	{		PutCodingExt();	}}/* generate picture coding extension (6.2.3.1, 6.3.11) * * composite display information (v_axis etc.) not implemented */void Picture::PutCodingExt(){	assert( coding->Aligned() );	coding->PutBits(EXT_START_CODE,32); /* extension_start_code */	coding->PutBits(CODING_ID,4); /* extension_start_code_identifier */	coding->PutBits(forw_hor_f_code,4); /* forward_horizontal_f_code */	coding->PutBits(forw_vert_f_code,4); /* forward_vertical_f_code */	coding->PutBits(back_hor_f_code,4); /* backward_horizontal_f_code */	coding->PutBits(back_vert_f_code,4); /* backward_vertical_f_code */	coding->PutBits(dc_prec,2); /* intra_dc_precision */	coding->PutBits(pict_struct,2); /* picture_structure */	coding->PutBits((pict_struct==FRAME_PICTURE)?topfirst : 0, 1); /* top_field_first */	coding->PutBits(frame_pred_dct,1); /* frame_pred_frame_dct */	coding->PutBits(0,1); /* concealment_motion_vectors  -- currently not implemented */	coding->PutBits(q_scale_type,1); /* q_scale_type */	coding->PutBits(intravlc,1); /* intra_vlc_format */	coding->PutBits(altscan,1); /* alternate_scan */	coding->PutBits(repeatfirst,1); /* repeat_first_field */	coding->PutBits(prog_frame,1); /* chroma_420_type */	coding->PutBits(prog_frame,1); /* progressive_frame */	coding->PutBits(0,1); /* composite_display_flag */    coding->AlignBits();}void Picture::PutSliceHdr( int slice_mb_y, int mquant ){    /* slice header (6.2.4) */    coding->AlignBits();        if (encparams.mpeg1 || encparams.vertical_size<=2800)        coding->PutBits(SLICE_MIN_START+slice_mb_y,32); /* slice_start_code */    else    {        coding->PutBits(SLICE_MIN_START+(slice_mb_y&127),32); /* slice_start_code */        coding->PutBits(slice_mb_y>>7,3); /* slice_vertical_position_extension */    }        /* quantiser_scale_code */    coding->PutBits(q_scale_type             ? map_non_linear_mquant[mquant]             : mquant >> 1, 5);        coding->PutBits(0,1); /* extra_bit_slice */    } /* ********************************** *  * PutHeaders - Put sequence of headers and user data elements that 'belong' * to this frame.  We count sequence and GOP headers as belong to the first * following picture. *  * ********************************/ void Picture::PutHeaders(){    /* Sequence header if new sequence or we're generating for a       format like (S)VCD that mandates sequence headers every GOP to       do fast forward, rewind etc.    */    if( new_seq || decode == 0 || (gop_start && encparams.seq_hdr_every_gop) )    {      coding->PutSeqHdr();    }       if( gop_start )    {      coding->PutGopHdr( decode,  closed_gop );    }        /* picture header and picture coding extension */    PutHeader();    /* TODO: This should really be a member of the picture object */   if( encparams.svcd_scan_data && pict_type == I_TYPE )   {      coding->PutUserData( dummy_svcd_scan_data, sizeof(dummy_svcd_scan_data) );   }}/*  * Local variables: *  c-file-style: "stroustrup" *  tab-width: 4 *  indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?