📄 image.c
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU disclaims
* any and all warranties, whether express, implied, or
* statutory, including any implied warranties of merchantability
* or of fitness for a particular purpose. In no event shall the
* contributor or the ITU 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 ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/
/*!
*************************************************************************************
* \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>
*************************************************************************************
*/
#include "contributors.h"
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <memory.h>
#include <assert.h>
#include "global.h"
#include "image.h"
#include "refbuf.h"
#ifdef _ADAPT_LAST_GROUP_
int *last_P_no;
#endif
//! The followibng two variables are used for debug purposes. They store
//! the status of the currStream data structure elements after the header
//! writing, and are used whether any MB bits were written during the
//! macroblock coding stage. We need to worry about empty slices!
static int Byte_Pos_After_Header;
static int Bits_To_Go_After_Header;
static void UnifiedOneForthPix (pel_t **imgY, pel_t** imgU, pel_t **imgV,
pel_t **out4Y, pel_t **outU, pel_t **outV, pel_t *ref11);
/*!
************************************************************************
* \brief
* Encodes one frame
************************************************************************
*/
int encode_one_frame()
{
#ifdef _LEAKYBUCKET_
extern long Bit_Buffer[10000];
extern unsigned long total_frame_buffer;
#endif
Boolean end_of_frame = FALSE;
SyntaxElement sym;
time_t ltime1; // for time measurement
time_t ltime2;
#ifdef WIN32
struct _timeb tstruct1;
struct _timeb tstruct2;
#else
struct timeval tstruct1;
struct timeval tstruct2;
#endif
int tmp_time;
#ifdef WIN32
_ftime( &tstruct1 ); // start time ms
#else
gettimeofday(&tstruct1, NULL);
#endif
time( <ime1 ); // start time s
// Initialize frame with all stat and img variables
img->total_number_mb = (img->width * img->height)/(MB_BLOCK_SIZE*MB_BLOCK_SIZE);
init_frame();
// Read one new frame
#ifndef H26L_LIB
read_one_new_frame();
#endif
if (img->type == B_IMG)
Bframe_ctr++;
while (end_of_frame == FALSE) // loop over slices
{
// Encode the current slice
encode_one_slice(&sym);
// Proceed to next slice
img->current_slice_nr++;
stat->bit_slice = 0;
if (img->current_mb_nr == img->total_number_mb) // end of frame reached?
end_of_frame = TRUE;
}
// in future only one call of oneforthpix() for all frame tyoes will be necessary, because
// mref buffer will be increased by one frame to store also the next P-frame. Then mref_P
// will not be used any more
if (img->type != B_IMG) //all I- and P-frames
{
if (input->successive_Bframe == 0 || img->number == 0)
interpolate_frame(); // I- and P-frames:loop-filtered imgY, imgUV -> mref[][][], mcef[][][][]
else
interpolate_frame_2(); // I- and P-frames prior a B-frame:loop-filtered imgY, imgUV -> mref_P[][][], mcef_P[][][][]
// I- and P-frames prior a B-frame:loop-filtered imgY, imgUV -> mref_P[][][], mcef_P[][][][]
}
else
if (img->b_frame_to_code == input->successive_Bframe)
copy2mref(img); // last successive B-frame: mref_P[][][], mcef_P[][][][] (loop-filtered imgY, imgUV)-> mref[][][], mcef[][][][]
if (input->rdopt==2)
UpdateDecoders(); // simulate packet losses and move decoded image to reference buffers
find_snr(snr,img);
time(<ime2); // end time sec
#ifdef WIN32
_ftime(&tstruct2); // end time ms
tmp_time=(ltime2*1000+tstruct2.millitm) - (ltime1*1000+tstruct1.millitm);
#else
gettimeofday(&tstruct2, NULL); // end time ms
tmp_time=(ltime2*1000+tstruct2.tv_usec/1000) - (ltime1*1000+(tstruct1.tv_usec / 1000));
#endif
tot_time=tot_time + tmp_time;
#ifndef H26L_LIB
// Write reconstructed images
write_reconstructed_image();
#endif
#ifdef _LEAKYBUCKET_
// Store bits used for this frame and increment counter of no. of coded frames
Bit_Buffer[total_frame_buffer] = stat->bit_ctr - stat->bit_ctr_n;
total_frame_buffer++;
#endif
if(img->number == 0)
{
printf("%3d(I) %8d %4d %7.4f %7.4f %7.4f %5d \n",
frame_no, stat->bit_ctr-stat->bit_ctr_n,
img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time);
stat->bitr0=stat->bitr;
stat->bit_ctr_0=stat->bit_ctr;
stat->bit_ctr=0;
}
else
{
if (img->type == INTRA_IMG)
{
stat->bit_ctr_P += stat->bit_ctr-stat->bit_ctr_n;
printf("%3d(I) %8d %4d %7.4f %7.4f %7.4f %5d \n",
frame_no, stat->bit_ctr-stat->bit_ctr_n,
img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time);
}
else if (img->type != B_IMG)
{
stat->bit_ctr_P += stat->bit_ctr-stat->bit_ctr_n;
if(img->types == SP_IMG)
printf("%3d(SP) %8d %4d %7.4f %7.4f %7.4f %5d %3d\n",
frame_no, stat->bit_ctr-stat->bit_ctr_n,
img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, intras);
else
printf("%3d(P) %8d %4d %7.4f %7.4f %7.4f %5d %3d\n",
frame_no, stat->bit_ctr-stat->bit_ctr_n,
img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, intras);
}
else
{
stat->bit_ctr_B += stat->bit_ctr-stat->bit_ctr_n;
printf("%3d(B) %8d %4d %7.4f %7.4f %7.4f %5d \n",
frame_no, stat->bit_ctr-stat->bit_ctr_n, img->qp,
snr->snr_y, snr->snr_u, snr->snr_v, tmp_time);
}
}
stat->bit_ctr_n=stat->bit_ctr;
if(img->number == 0)
return 0;
else
return 1;
}
/*!
************************************************************************
* \brief
* Encodes one slice
************************************************************************
*/
void encode_one_slice(SyntaxElement *sym)
{
Boolean end_of_slice = FALSE;
Boolean recode_macroblock;
int len;
img->cod_counter=0;
// Initializes the parameters of the current slice
init_slice();
// Write slice or picture header
len = start_slice(sym);
Byte_Pos_After_Header = img->currentSlice->partArr[0].bitstream->byte_pos;
Bits_To_Go_After_Header = img->currentSlice->partArr[0].bitstream->bits_to_go;
if (input->of_mode==PAR_OF_RTP)
{
assert (Byte_Pos_After_Header > 0); // there must be a header
assert (Bits_To_Go_After_Header == 8); // byte alignment must have been established
}
// Update statistics
stat->bit_slice += len;
stat->bit_use_header[img->type] += len;
while (end_of_slice == FALSE) // loop over macroblocks
{
// recode_macroblock is used in slice mode two and three where
// backing of one macroblock in the bitstream is possible
recode_macroblock = FALSE;
// Initializes the current macroblock
start_macroblock();
// Encode one macroblock
encode_one_macroblock();
// Pass the generated syntax elements to the NAL
write_one_macroblock();
// Terminate processing of the current macroblock
terminate_macroblock(&end_of_slice, &recode_macroblock);
if (recode_macroblock == FALSE) // The final processing of the macroblock has been done
proceed2nextMacroblock(); // Go to next macroblock
}
terminate_slice();
}
/*!
************************************************************************
* \brief
* Initializes the parameters for a new frame
************************************************************************
*/
void init_frame()
{
int i,j,k;
int prevP_no, nextP_no;
img->current_mb_nr=0;
img->current_slice_nr=0;
stat->bit_slice = 0;
if(input->UseConstrainedIntraPred)
{
for (i=0; i<img->total_number_mb; i++)
img->intra_mb[i] = 1; // default 1 = intra mb
}
img->mhor = img->width *4-1;
img->mvert = img->height*4-1;
img->mb_y = img->mb_x = 0;
img->block_y = img->pix_y = img->pix_c_y = 0; // define vertical positions
img->block_x = img->pix_x = img->block_c_x = img->pix_c_x = 0; // define horizontal positions
if (input->intra_upd > 0 && img->mb_y <= img->mb_y_intra)
img->height_err=(img->mb_y_intra*16)+15; // for extra intra MB
else
img->height_err=img->height-1;
if(img->type != B_IMG)
{
img->refPicID ++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -