📄 h26l.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.
************************************************************************
*/
/*
* Feb 28, 2002
* dmackie@cisco.com
* Restructured version of lencod.c that provides a library API to encoder
*/
/*!
***********************************************************************
* \mainpage
* This is the H.26L encoder reference software. For detailed documentation
* see the comments in each file.
*
* \author
* The main contributors are listed in contributors.h
*
* \version
* TML 9.4
*
* \note
* tags are used for document system "doxygen"
* available at http://www.doxygen.org
*/
/*!
* \file
* lencod.c
* \brief
* TML encoder project main
* \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>
* - Stephan Wenger <stewe@cs.tu-berlin.de>
* - Jani Lainema <jani.lainema@nokia.com>
* - 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>
*
***********************************************************************
*/
#include "contributors.h"
#include <string.h>
#include <math.h>
#include <time.h>
#include <sys/timeb.h>
#include <stdlib.h>
#if defined WIN32
#include <conio.h>
#endif
#include "global.h"
#include "configfile.h"
#include "leaky_bucket.h"
#define TML "9"
#define VERSION "9.40"
InputParameters inputs, *input = &inputs;
ImageParameters images, *img = &images;
StatParameters stats, *stat = &stats;
SNRParameters snrs, *snr = &snrs;
#ifdef H26L_LIB
byte* memout;
int memoutlength;
#endif
#ifdef _ADAPT_LAST_GROUP_
int initial_Bframes = 0;
#endif
int H26L_InUse = 0;
/*!
***********************************************************************
* \brief
* Main function for encoder.
* \param argc
* number of command line arguments
* \param argv
* command line arguments
* \return
* exit code
***********************************************************************
*/
int H26L_Init(char *config)
{
char* argv[1];
/* dmackie@cisco.com
* Since code uses globals everywhere
* we need to ensure only 1 calling instance
*/
if (H26L_InUse) {
return -1;
}
H26L_InUse = 1;
p_dec = p_dec_u = p_dec_v = p_stat = p_log = p_datpart = p_trace = NULL;
argv[0] = config;
Configure (1, argv);
// Initialize Image Parameters
init_img();
// Allocate Slice data struct
malloc_slice();
// create and init structure for rd-opt. mode decision
init_rdopt ();
#ifdef _FAST_FULL_ME_
// create arrays for fast full motion estimation
InitializeFastFullIntegerSearch (input->search_range);
#endif
// Initialize Statistic Parameters
init_stat();
// allocate memory for frame buffers
get_mem4global_buffers();
// Just some information which goes to the standard output
information_init();
// Write sequence header; open bitstream files
stat->bit_slice = start_sequence();
// B pictures
Bframe_ctr=0;
img->refPicID=-1; //WYK: Oct. 16, 2001
tot_time=0; // time for total encoding session
#ifdef _ADAPT_LAST_GROUP_
if (input->last_frame > 0)
input->no_frames = 1 + (input->last_frame + input->jumpd) / (input->jumpd + 1);
initial_Bframes = input->successive_Bframe;
#endif
return 0;
}
int H26L_Encode(byte* pY, byte* pU, byte* pV,
byte* pEncoded, int* pEncodedLength)
{
int image_type;
if (H26L_InUse == 0) {
return -1;
}
memout = pEncoded;
memoutlength = 0;
if (input->intra_period == 0)
{
if (img->number == 0)
{
img->type = INTRA_IMG; // set image type for first image to I-frame
}
else
{
img->type = INTER_IMG; // P-frame
if (input->sp_periodicity)
{
if ((img->number % input->sp_periodicity) ==0)
{
img->types=SP_IMG;
}
else img->types=INTER_IMG;
}
}
}
else
{
if ((img->number%input->intra_period) == 0)
{
img->type = INTRA_IMG;
}
else
{
img->type = INTER_IMG; // P-frame
if (input->sp_periodicity)
{
if ((img->number % input->sp_periodicity) ==0)
img->types=SP_IMG;
else img->types=INTER_IMG;
}
}
}
#ifdef _ADAPT_LAST_GROUP_
if (input->successive_Bframe && input->last_frame && img->number+1 == input->no_frames)
{
int bi = (int)((float)(input->jumpd+1)/(input->successive_Bframe+1.0)+0.499999);
input->successive_Bframe = (input->last_frame-(img->number-1)*(input->jumpd+1))/bi-1;
}
#endif
image_type = img->type;
/* start of read_one_frame emulation */
if(img->type == B_IMG)
frame_no = (img->number-1)*(input->jumpd+1)+img->b_interval*img->b_frame_to_code;
else {
frame_no = img->number*(input->jumpd+1);
#ifdef _ADAPT_LAST_GROUP_
if (input->last_frame && img->number+1 == input->no_frames)
frame_no=input->last_frame;
#endif
}
memcpy(*imgY_org, pY, img->width * img->height);
memcpy(*(imgUV_org[0]), pU, img->width_cr * img->height_cr);
memcpy(*(imgUV_org[1]), pV, img->width_cr * img->height_cr);
/* end of read_one_frame emulation */
encode_one_frame(); // encode one I- or P-frame
if ((input->successive_Bframe != 0) && (img->number > 0)) // B-frame(s) to encode
{
img->type = B_IMG; // set image type to B-frame
img->types= INTER_IMG;
for(img->b_frame_to_code=1; img->b_frame_to_code<=input->successive_Bframe; img->b_frame_to_code++)
encode_one_frame(); // encode one B-frame
}
if (image_type == INTRA_IMG || img->types==SP_IMG)
{
img->nb_references = 1;
}
else
{
img->nb_references += 1;
img->nb_references = min(img->nb_references, img->buf_cycle);
}
*pEncodedLength = memoutlength;
img->number++;
return 0;
}
int H26L_GetReconstructed(byte* pY, byte* pU, byte* pV)
{
memcpy(pY, *imgY, img->width * img->height);
memcpy(pU, *(imgUV[0]), img->width_cr * img->height_cr);
memcpy(pV, *(imgUV[1]), img->width_cr * img->height_cr);
return 0;
}
int H26L_Close()
{
if (H26L_InUse == 0) {
return -1;
}
// terminate sequence
terminate_sequence();
#ifdef _FAST_FULL_ME_
// free arrays for fast full motion estimation
ClearFastFullIntegerSearch ();
#endif
// free structure for rd-opt. mode decision
clear_rdopt ();
#ifdef _LEAKYBUCKET_
calc_buffer();
#endif
#ifndef H26L_LIB
// report everything
report();
#endif
free_slice();
// free allocated memory for frame buffers
free_mem4global_buffers();
// free image mem
free_img ();
H26L_InUse = 0;
return 0;
}
/*!
***********************************************************************
* \brief
* Initializes the Image structure with appropriate parameters.
* \par Input:
* Input Parameters struct inp_par *inp
* \par Output:
* Image Parameters struct img_par *img
***********************************************************************
*/
void init_img()
{
int i,j;
img->no_multpred=input->no_multpred;
#ifdef _ADDITIONAL_REFERENCE_FRAME_
img->buf_cycle = max (input->no_multpred, input->add_ref_frame+1);
#else
img->buf_cycle = input->no_multpred;
#endif
img->framerate=INIT_FRAME_RATE; // The basic frame rate (of the original sequence)
get_mem_mv (&(img->mv));
get_mem_mv (&(img->p_fwMV));
get_mem_mv (&(img->p_bwMV));
get_mem_mv (&(img->all_mv));
get_mem_mv (&(img->all_bmv));
img->width = input->img_width;
img->height = input->img_height;
img->width_cr = input->img_width/2;
img->height_cr= input->img_height/2;
if(((img->mb_data) = (Macroblock *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(Macroblock))) == NULL)
no_mem_exit("init_img: img->mb_data");
if(((img->slice_numbers) = (int *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(int))) == NULL)
no_mem_exit("init_img: img->slice_numbers");
if(input->UseConstrainedIntraPred)
{
if(((img->intra_mb) = (int *) calloc((img->width/MB_BLOCK_SIZE) * (img->height/MB_BLOCK_SIZE),sizeof(int))) == NULL)
no_mem_exit("init_img: img->intra_mb");
}
init(img);
// allocate memory for intra pred mode buffer for each block: img->ipredmode
// int img->ipredmode[90][74];
get_mem2Dint(&(img->ipredmode), img->width/BLOCK_SIZE+2, img->height/BLOCK_SIZE+2);
// Prediction mode is set to -1 outside the frame, indicating that no prediction can be made from this part
for (i=0; i < img->width/BLOCK_SIZE+1; i++)
{
img->ipredmode[i+1][0]=-1;
}
for (j=0; j < img->height/BLOCK_SIZE+1; j++)
{
img->ipredmode[0][j+1]=-1;
}
img->mb_y_upd=0;
}
/*!
***********************************************************************
* \brief
* Free the Image structures
* \par Input:
* Image Parameters struct img_par *img
***********************************************************************
*/
void free_img ()
{
free_mem_mv (img->mv);
free_mem_mv (img->p_fwMV);
free_mem_mv (img->p_bwMV);
free_mem_mv (img->all_mv);
free_mem_mv (img->all_bmv);
}
/*!
************************************************************************
* \brief
* Allocates the slice structure along with its dependent
* data structures
* \par Input:
* Input Parameters struct inp_par *inp, struct img_par *img
************************************************************************
*/
void malloc_slice()
{
int i;
DataPartition *dataPart;
Slice *currSlice;
const int buffer_size = (img->width * img->height * 3)/2; // DM 070301: The only assumption here is that we
// do not consider the case of data expansion.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -