📄 image.cpp
字号:
/*!
***********************************************************************
* \file image.c
*
* \brief
* Decode a Slice
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Inge Lille-Langoy <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>
* - Thomas Wedi <wedi@tnt.uni-hannover.de>
* - Gabi Blaettermann <blaetter@hhi.de>
* - Ye-Kui Wang <wyk@ieee.org>
* - Antti Hallapuro <antti.hallapuro@nokia.com>
* - Alexis Tourapis <alexismt@ieee.org>
***********************************************************************
*/
#include "contributors.h"
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <sys/timeb.h>
#include <string.h>
#include <assert.h>
#include "global.h"
#include "errorconcealment.h"
#include "image.h"
#include "mbuffer.h"
#include "fmo.h"
#include "parsetcommon.h"
#include "parset.h"
#include "header.h"
#include "rtp.h"
#include "sei.h"
#include "output.h"
#include "mb_access.h"
#include "annexb.h"
#include "vlc.h"
pic_parameter_set_rbsp_t *active_pps;
seq_parameter_set_rbsp_t *active_sps;
extern int FileFormat;
extern int g_new_frame;
extern StorablePicture **listX[2];
StorablePicture *dec_picture;
int frame_no;
// global picture format dependend buffers, mem allocation in decod.c ******************
/*!
***********************************************************************
* \brief
* decodes one I- or P-frame
*
***********************************************************************
*/
int decode_one_frame(struct img_par *img)
{
int current_header;
Slice *currSlice = img->currentSlice;
int ercStartMB;
int ercSegment;
img->current_slice_nr = 0;
img->current_mb_nr = -4711; // initialized to an impossible value for debugging -- correct value is taken from slice header
currSlice->next_header = -8888; // initialized to an impossible value for debugging -- correct value is taken from slice header
img->num_dec_mb = 0;
while ((currSlice->next_header != EOS && currSlice->next_header != SOP))
{
current_header = read_new_slice();
if (current_header == EOS)
return EOS;
//decode_frame_slice(img, current_header);
Slice *currSlice = img->currentSlice;
// init new frame
if (current_header == SOP)
init_frame(img);
// decode main slice information
if ((current_header == SOP || current_header == SOS) && currSlice->ei_flag == 0)
{
//decode_one_slice
Boolean end_of_slice = FALSE;
img->cod_counter=-1;
while (end_of_slice == FALSE) // loop over macroblocks
{
// Initializes the current macroblock
start_macroblock(img, img->current_mb_nr);
// Get the syntax elements from the NAL
read_one_macroblock(img);
decode_one_macroblock(img);
end_of_slice=exit_macroblock(img,1);
}
}
img->current_slice_nr++;
}
//deblocking for frame
DeblockFrame( img, dec_picture->imgY, dec_picture->imgUV ) ;
store_picture_in_dpb(dec_picture);
dec_picture=NULL;
g_new_frame=1;
//! this is always true at the beginning of a frame
ercStartMB = 0;
ercSegment = 0;
post_poc( img ); // POC200301
//! TO 19.11.2001 Known Problem: for init_frame we have to know the picture type of the actual frame
//! in case the first slice of the P-Frame following the I-Frame was lost we decode this P-Frame but
//! do not write it because it was assumed to be an I-Frame in init_frame. So we force the decoder to
//! guess the right picture type. This is a hack a should be removed by the time there is a clean
//! solution where we do not have to know the picture type for the function init_frame.
if(img->type == I_SLICE)
img->type = P_SLICE;
//! End TO 19.11.2001
img->number++;
//exit_frame(img);
img->pre_frame_num = img->frame_num;
img->current_mb_nr = -4712; // impossible value for debugging, StW
img->current_slice_nr = 0;
return (SOP);
}
/*!
************************************************************************
* \brief
* Interpolation of 1/4 subpixel
************************************************************************
*/
void get_block(int ref_frame, StorablePicture **list, int x_pos, int y_pos, struct img_par *img, int block[4][4])
{
int dx, dy;
int i, j;
int maxold_x,maxold_y;
int result,pres_idx,mode_idx;
int pres_x;
int pres_y;
int tmp_res[4][9];
static const int COEF[6] = {1, -5, 20, 20, -5, 1};
dx = x_pos&3;
dy = y_pos&3;
mode_idx=block_mode[dy][dx];
x_pos = (x_pos-dx)>>2;
y_pos = (y_pos-dy)>>2;
maxold_x = img->width-1;
maxold_y = img->height-1;
switch(mode_idx)
{
case 1:
for (j = 0; j < 4; j++){
pres_idx=Clip3(0,maxold_y,y_pos+j);
for (i = 0; i < 4; i++)
block[i][j] = list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i)];
}
return;
case 2:
for (j = 0; j < 4; j++) {
pres_idx=Clip3(0,maxold_y,y_pos+j);
for (i = 0; i < 4; i++) {
result = 0;
result += list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i-2)]*COEF[0]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i-1)]*COEF[1]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i)]*COEF[2]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+1)]*COEF[3]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+2)]*COEF[4]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+3)]*COEF[5];
block[i][j] = Clip1((result+16)>>5);
}
}
return;
case 3:
for (j = 0; j < 4; j++) {
pres_idx=Clip3(0,maxold_y,y_pos+j);
for (i = 0; i < 4; i++) {
result = 0;
result += list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i-2)]*COEF[0]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i-1)]*COEF[1]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i)]*COEF[2]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+1)]*COEF[3]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+2)]*COEF[4]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+3)]*COEF[5];
block[i][j] = (Clip1((result+16)>>5) + list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+dx/2)] +1 )/2;
}
}
return;
case 4:
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++){
pres_idx = Clip3(0,maxold_x,x_pos+i);
result = 0;
result += list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j-2)][pres_idx]*COEF[0]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j-1)][pres_idx]*COEF[1]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j)][pres_idx]*COEF[2]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+1)][pres_idx]*COEF[3]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+2)][pres_idx]*COEF[4]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+3)][pres_idx]*COEF[5];
block[i][j] = Clip1((result+16)>>5);
}
}
return;
case 5:
for (i = 0; i < 4; i++) {
pres_idx = Clip3(0,maxold_x,x_pos+i);
for (j = 0; j < 4; j++){
result = 0;
result += list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j-2)][pres_idx]*COEF[0]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j-1)][pres_idx]*COEF[1]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j)][pres_idx]*COEF[2]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+1)][pres_idx]*COEF[3]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+2)][pres_idx]*COEF[4]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+3)][pres_idx]*COEF[5];
block[i][j] = (Clip1((result+16)>>5) + list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+dy/2)][pres_idx] +1 )/2;
}
}
return;
case 6:
for (j = -2; j < 4+3; j++) {
pres_idx = Clip3(0,maxold_y,y_pos+j);
for (i = 0; i < 4; i++){
tmp_res[i][j+2] = 0;
tmp_res[i][j+2] += list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i-2)]*COEF[0]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i-1)]*COEF[1]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i)]*COEF[2]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+1)]*COEF[3]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+2)]*COEF[4]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+3)]*COEF[5];
}
}
for (j = 0; j < 4; j++) {
for (i = 0; i < 4; i++) {
result = 0,
result += tmp_res[i][j]*COEF[0]
+tmp_res[i][j+1]*COEF[1]
+tmp_res[i][j+2]*COEF[2]
+tmp_res[i][j+3]*COEF[3]
+tmp_res[i][j+4]*COEF[4]
+tmp_res[i][j+5]*COEF[5];
block[i][j] = Clip1((result+512)>>10);
}
}
return;
case 7:
for (j = -2; j < 4+3; j++) {
pres_idx = Clip3(0,maxold_y,y_pos+j);
for (i = 0; i < 4; i++){
tmp_res[i][j+2] = 0;
tmp_res[i][j+2] += list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i-2)]*COEF[0]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i-1)]*COEF[1]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i)]*COEF[2]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+1)]*COEF[3]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+2)]*COEF[4]
+list[ref_frame]->imgY[pres_idx][Clip3(0,maxold_x,x_pos+i+3)]*COEF[5];
}
}
for (j = 0; j < 4; j++) {
for (i = 0; i < 4; i++) {
result = 0,
result += tmp_res[i][j]*COEF[0]
+tmp_res[i][j+1]*COEF[1]
+tmp_res[i][j+2]*COEF[2]
+tmp_res[i][j+3]*COEF[3]
+tmp_res[i][j+4]*COEF[4]
+tmp_res[i][j+5]*COEF[5];
block[i][j] = (Clip1((result+512)>>10) + Clip1((tmp_res[i][j+2+dy/2]+16)>>5) +1 )/2;
}
}
return;
case 8:
for (i = -2; i < 4+3; i++) {
pres_idx = Clip3(0,maxold_x,x_pos+i);
for (j = 0; j < 4; j++){
tmp_res[j][i+2] = 0;
tmp_res[j][i+2] += list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j-2)][pres_idx]*COEF[0]
+ list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j-1)][pres_idx]*COEF[1]
+ list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j)][pres_idx]*COEF[2]
+ list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+1)][pres_idx]*COEF[3]
+ list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+2)][pres_idx]*COEF[4]
+ list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+3)][pres_idx]*COEF[5];
}
}
for (j = 0; j < 4; j++) {
for (i = 0; i < 4; i++) {
result = 0;
result += tmp_res[j][i]*COEF[0]
+tmp_res[j][i+1]*COEF[1]
+tmp_res[j][i+2]*COEF[2]
+tmp_res[j][i+3]*COEF[3]
+tmp_res[j][i+4]*COEF[4]
+tmp_res[j][i+5]*COEF[5];
block[i][j] = (Clip1((result+512)>>10) + Clip1((tmp_res[j][2+i+dx/2]+16)>>5)+1)/2;
}
}
return;
default:
for (j = 0; j < 4; j++) {
for (i = 0; i < 4; i++) {
pres_y = dy == 1 ? y_pos+j : y_pos+j+1;
pres_y = Clip3(0,maxold_y,pres_y);
result = 0;
result += list[ref_frame]->imgY[pres_y][Clip3(0,maxold_x,x_pos+i-2)]*COEF[0]
+list[ref_frame]->imgY[pres_y][Clip3(0,maxold_x,x_pos+i-1)]*COEF[1]
+list[ref_frame]->imgY[pres_y][Clip3(0,maxold_x,x_pos+i)]*COEF[2]
+list[ref_frame]->imgY[pres_y][Clip3(0,maxold_x,x_pos+i+1)]*COEF[3]
+list[ref_frame]->imgY[pres_y][Clip3(0,maxold_x,x_pos+i+2)]*COEF[4]
+list[ref_frame]->imgY[pres_y][Clip3(0,maxold_x,x_pos+i+3)]*COEF[5];
block[i][j] = Clip1((result+16)>>5);
pres_x = dx == 1 ? x_pos+i : x_pos+i+1;
pres_x = Clip3(0,maxold_x,pres_x);
result = 0;
result += list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j-2)][pres_x]*COEF[0]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j-1)][pres_x]*COEF[1]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j)][pres_x]*COEF[2]
+list[ref_frame]->imgY[Clip3(0,maxold_y,y_pos+j+1)][pres_x]*COEF[3]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -