📄 image.c
字号:
/*!
*************************************************************************************
* \file image.c
*
* \brief
* Code one image/slice
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Inge Lille-Lang鴜 <inge.lille-langoy@telenor.com>
* - Rickard Sjoberg <rickard.sjoberg@era.ericsson.se>
* - Jani Lainema <jani.lainema@nokia.com>
* - Sebastian Purreiter <sebastian.purreiter@mch.siemens.de>
* - Byeong-Moon Jeon <jeonbm@lge.com>
* - Yoon-Seong Soh <yunsung@lge.com>
* - Thomas Stockhammer <stockhammer@ei.tum.de>
* - Detlev Marpe <marpe@hhi.de>
* - Guido Heising <heising@hhi.de>
* - Thomas Wedi <wedi@tnt.uni-hannover.de>
* - Ragip Kurceren <ragip.kurceren@nokia.com>
* - Antti Hallapuro <antti.hallapuro@nokia.com>
* - Alexis Michael Tourapis <alexis@mobilygen.com, alexismt@ieee.org>
*************************************************************************************
*/
#include "contributors.h"
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <sys/timeb.h>
#include <string.h>
#include <assert.h>
#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include "global.h"
#include "refbuf.h"
#include "mbuffer.h"
#include "intrarefresh.h"
#include "fmo.h"
#include "sei.h"
#include "memalloc.h"
#include "nalu.h"
#include "ratectl.h"
#include "mb_access.h"
void code_a_picture(Picture *pic);
void frame_picture (Picture *frame);
void field_picture(Picture *top, Picture *bottom);
static int writeout_picture(Picture *pic);
static int picture_structure_decision(Picture *frame, Picture *top, Picture *bot);
static void distortion_fld (float *dis_fld_y, float *dis_fld_u, float *dis_fld_v);
static void find_snr();
static void find_distortion();
static void field_mode_buffer(int bit_field, float snr_field_y, float snr_field_u, float snr_field_v);
static void frame_mode_buffer (int bit_frame, float snr_frame_y, float snr_frame_u, float snr_frame_v);
static void init_frame();
static void init_field();
static void put_buffer_frame();
static void put_buffer_top();
static void put_buffer_bot();
static void copy_motion_vectors_MB();
static void CopyFrameToOldImgOrgVariables (Sourceframe *sf);
static void CopyTopFieldToOldImgOrgVariables (Sourceframe *sf);
static void CopyBottomFieldToOldImgOrgVariables (Sourceframe *sf);
static Sourceframe *AllocSourceframe (int xs, int ys, int xs_cr, int ys_cr);
static void FreeSourceframe (Sourceframe *sf);
static void ReadOneFrame (int FrameNoInFile, int HeaderSize, int xs, int ys, int xs_cr, int ys_cr, Sourceframe *sf);
static void writeUnit(Bitstream* currStream ,int partition);
#ifdef _ADAPT_LAST_GROUP_
int *last_P_no;
int *last_P_no_frm;
int *last_P_no_fld;
#endif
static void ReportFirstframe(int tmp_time, int me_time);
static void ReportIntra(int tmp_time, int me_time);
static void ReportSP(int tmp_time, int me_time);
static void ReportBS(int tmp_time, int me_time);
static void ReportP(int tmp_time, int me_time);
static void ReportB(int tmp_time, int me_time);
static void ReportNALNonVLCBits(int tmp_time, int me_time);
/*
static void ReportFirstframe(int tmp_time);
static void ReportIntra(int tmp_time);
static void ReportSP(int tmp_time);
static void ReportBS(int tmp_time);
static void ReportP(int tmp_time);
static void ReportB(int tmp_time);
*/
int CalculateFrameNumber(); // Calculates the next frame number
static int FrameNumberInFile; // The current frame number in the input file
static Sourceframe *srcframe;
StorablePicture *enc_picture;
StorablePicture *enc_frame_picture;
StorablePicture *enc_top_picture;
StorablePicture *enc_bottom_picture;
//Rate control
int QP;
const int ONE_FOURTH_TAP[3][2] =
{
{20,20},
{-5,-4},
{ 1, 0},
};
//added by yjy
extern int8_t *yuv_buffer, *encoded_data;
extern int * out_len;
void MbAffPostProc()
{
imgpel temp[16][32];
imgpel ** imgY = enc_picture->imgY;
imgpel ***imgUV = enc_picture->imgUV;
int i, x, y, x0, y0, uv;
if (img->yuv_format != YUV400)
{
for (i=0; i<(int)img->PicSizeInMbs; i+=2)
{
if (enc_picture->mb_field[i])
{
get_mb_pos(i, &x0, &y0);
for (y=0; y<(2*MB_BLOCK_SIZE);y++)
for (x=0; x<MB_BLOCK_SIZE; x++)
temp[x][y] = imgY[y0+y][x0+x];
for (y=0; y<MB_BLOCK_SIZE;y++)
for (x=0; x<MB_BLOCK_SIZE; x++)
{
imgY[y0+(2*y)][x0+x] = temp[x][y];
imgY[y0+(2*y+1)][x0+x] = temp[x][y+MB_BLOCK_SIZE];
}
x0 = x0 / (16/img->mb_cr_size_x);
y0 = y0 / (16/img->mb_cr_size_y);
for (uv=0; uv<2; uv++)
{
for (y=0; y<(2*img->mb_cr_size_y);y++)
for (x=0; x<img->mb_cr_size_x; x++)
temp[x][y] = imgUV[uv][y0+y][x0+x];
for (y=0; y<img->mb_cr_size_y;y++)
for (x=0; x<img->mb_cr_size_x; x++)
{
imgUV[uv][y0+(2*y)][x0+x] = temp[x][y];
imgUV[uv][y0+(2*y+1)][x0+x] = temp[x][y+img->mb_cr_size_y];
}
}
}
}
}
else
{
for (i=0; i<(int)img->PicSizeInMbs; i+=2)
{
if (enc_picture->mb_field[i])
{
get_mb_pos(i, &x0, &y0);
for (y=0; y<(2*MB_BLOCK_SIZE);y++)
for (x=0; x<MB_BLOCK_SIZE; x++)
temp[x][y] = imgY[y0+y][x0+x];
for (y=0; y<MB_BLOCK_SIZE;y++)
for (x=0; x<MB_BLOCK_SIZE; x++)
{
imgY[y0+(2*y)][x0+x] = temp[x][y];
imgY[y0+(2*y+1)][x0+x] = temp[x][y+MB_BLOCK_SIZE];
}
}
}
}
}
/*!
************************************************************************
* \brief
* Encodes a picture
*
* This is the main picture coding loop.. It is called by all this
* frame and field coding stuff after the img-> elements have been
* set up. Not sure whether it is useful for MB-adaptive frame/field
* coding
************************************************************************
*/
void code_a_picture(Picture *pic)
{
int NumberOfCodedMBs = 0;
int SliceGroup = 0;
int j;
img->currentPicture = pic;
img->currentPicture->idr_flag = ((!IMG_NUMBER) && (!(img->structure==BOTTOM_FIELD))) || (input->idr_enable && (img->type == I_SLICE || img->type==SP_SLICE || img->type==SI_SLICE)&& (!(img->structure==BOTTOM_FIELD)));
pic->no_slices = 0;
pic->distortion_u = pic->distortion_v = pic->distortion_y = 0.0;
RandomIntraNewPicture (); //! Allocates forced INTRA MBs (even for fields!)
// The slice_group_change_cycle can be changed here.
// FmoInit() is called before coding each picture, frame or field
img->slice_group_change_cycle=1;
FmoInit(img, active_pps, active_sps);
FmoStartPicture (); //! picture level initialization of FMO
CalculateQuantParam();
if(input->AllowTransform8x8)
CalculateQuant8Param();
while (NumberOfCodedMBs < img->total_number_mb) // loop over slices
{
// Encode one SLice Group
while (!FmoSliceGroupCompletelyCoded (SliceGroup))
{
// Encode the current slice
NumberOfCodedMBs += encode_one_slice (SliceGroup, pic);
FmoSetLastMacroblockInSlice (img->current_mb_nr);
// Proceed to next slice
img->current_slice_nr++;
stats->bit_slice = 0;
}
// Proceed to next SliceGroup
SliceGroup++;
}
FmoEndPicture ();
if (input->rdopt == 2 && (img->type != B_SLICE))
for (j = 0; j < input->NoOfDecoders; j++)
DeblockFrame (img, decs->decY_best[j], NULL);
DeblockFrame (img, enc_picture->imgY, enc_picture->imgUV); //comment out to disable loop filter
if (img->MbaffFrameFlag)
MbAffPostProc();
}
/*!
************************************************************************
* \brief
* Encodes one frame
************************************************************************
*/
int encode_one_frame ()
{
static int prev_frame_no = 0; // POC200301
static int consecutive_non_reference_pictures = 0; // POC200301
#ifdef _LEAKYBUCKET_
extern long Bit_Buffer[10000];
extern unsigned long total_frame_buffer;
#endif
time_t ltime1;
time_t ltime2;
#ifdef WIN32
struct _timeb tstruct1;
struct _timeb tstruct2;
#else
struct timeb tstruct1;
struct timeb tstruct2;
#endif
int tmp_time;
int bits_frm = 0, bits_fld = 0;
float dis_frm = 0, dis_frm_y = 0, dis_frm_u = 0, dis_frm_v = 0;
float dis_fld = 0, dis_fld_y = 0, dis_fld_u = 0, dis_fld_v = 0;
//Rate control
int pic_type, bits = 0;
me_time=0;
#ifdef WIN32
_ftime (&tstruct1); // start time ms
#else
ftime (&tstruct1);
#endif
time (<ime1); // start time s
//Rate control
img->write_macroblock = 0;
/*
//Shankar Regunathan (Oct 2002)
//Prepare Panscanrect SEI payload
UpdatePanScanRectInfo ();
//Prepare Arbitrarydata SEI Payload
UpdateUser_data_unregistered ();
//Prepare Registered data SEI Payload
UpdateUser_data_registered_itu_t_t35 ();
//Prepare RandomAccess SEI Payload
UpdateRandomAccess ();
*/
put_buffer_frame (); // sets the pointers to the frame structures
// (and not to one of the field structures)
init_frame ();
FrameNumberInFile = CalculateFrameNumber();
srcframe = AllocSourceframe (img->width, img->height, img->width_cr, img->height_cr);
// ReadOneFrame (FrameNumberInFile, input->infile_header,img->width, img->height, img->width_cr, img->height_cr, srcframe);
CopyOneFrame(srcframe);
CopyFrameToOldImgOrgVariables (srcframe);
// Set parameters for directmode and Deblocking filter
img->direct_spatial_mv_pred_flag = input->direct_spatial_mv_pred_flag;
img->LFDisableIdc = input->LFDisableIdc;
img->LFAlphaC0Offset = input->LFAlphaC0Offset;
img->LFBetaOffset = input->LFBetaOffset;
if (img->type == B_SLICE)
Bframe_ctr++; // Bframe_ctr only used for statistics, should go to stats->
if (input->PicInterlace == FIELD_CODING)
{
//Rate control
img->FieldControl=1;
img->field_picture = 1; // we encode fields
field_picture (top_pic, bottom_pic);
img->fld_flag = 1;
}
else
{
//Rate control
img->FieldControl=0;
// For frame coding, turn MB level field/frame coding flag on
if (input->MbInterlace)
mb_adaptive = 1;
img->field_picture = 0; // we encode a frame
//Rate control
if(input->RCEnable)
{
/*update the number of MBs in the basic unit for MB adaptive
f/f coding*/
if((input->MbInterlace)&&(input->basicunit<img->Frame_Total_Number_MB)\
&&(img->type==P_SLICE)&&(img->IFLAG==0))
img->BasicUnit=input->basicunit*2;
else
img->BasicUnit=input->basicunit;
rc_init_pict(1,0,1);
img->qp = updateQuantizationParameter(0);
pic_type = img->type;
QP =0;
}
if( active_sps->frame_mbs_only_flag)
img->TopFieldFlag=0;
frame_picture (frame_pic);
// For field coding, turn MB level field/frame coding flag off
if (input->MbInterlace)
mb_adaptive = 0;
if (input->PicInterlace == ADAPTIVE_CODING)
{
//Rate control
img->FieldControl=1;
img->write_macroblock = 0;
img->bot_MB = 0;
img->field_picture = 1; // we encode fields
field_picture (top_pic, bottom_pic);
//! Note: the distortion for a field coded picture is stored in the top field
//! the distortion values in the bottom field are dummies
dis_fld = top_pic->distortion_y + top_pic->distortion_u + top_pic->distortion_v;
dis_frm = frame_pic->distortion_y + frame_pic->distortion_u + frame_pic->distortion_v;
img->fld_flag = picture_structure_decision (frame_pic, top_pic, bottom_pic);
update_field_frame_contexts (img->fld_flag);
//Rate control
if(img->fld_flag==0)
img->FieldFrame=1;
/*the current choice is field coding*/
else
img->FieldFrame=0;
}
else
img->fld_flag = 0;
}
if (img->fld_flag)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -