📄 mbuffer.c
字号:
void assign_long_term_id(int shortID, int longID, ImageParameters *img)
{
int i, uv;
int idx=-1;
Frame *f;
int j,idx1,id;
// try to find short term picture in buffer
for (i=0;i<fb->short_used;i++)
{
if (fb->picbuf_short[i]->picID==shortID)
idx=i;
}
// short term picture not found: error
if (idx==-1)
error ("Trying to assign a long term ID to a not existent short term picture",400);
// return if reassignment (no error)
if (fb->picbuf_short[idx]->lt_picID==longID)
return;
// copy the frame to the long term buffer
// this may not be the best solution, but avoids messing up pointers
printf("Storing long term ID=%d\n",longID);
/* delete frames with same short term ID */
remove_long_term(longID);
/* cycle frame buffer */
f=fb->picbuf_long[fb->long_size-1];
for (i=fb->long_size-2;i>=0;i--)
fb->picbuf_long[i+1]=fb->picbuf_long[i];
fb->picbuf_long[0]=f;
fb->picbuf_long[0]->used=1;
fb->picbuf_long[0]->picID=shortID;
fb->picbuf_long[0]->lt_picID=longID;
fb->picbuf_short[idx]->lt_picID=longID;
(fb->long_used)++;
if (fb->long_used>fb->long_size)
fb->long_used=fb->long_size;
memcpy (fb->picbuf_long[0]->mref[0], fb->picbuf_short[idx]->mref[0], ((img->height+2*IMG_PAD_SIZE)*4)*((img->width+2*IMG_PAD_SIZE)*4));
if (input->WeightedPrediction || input->WeightedBiprediction)
memcpy (fb->picbuf_long[0]->mref_w[0], fb->picbuf_short[idx]->mref_w[0], ((img->height+2*IMG_PAD_SIZE)*4)*((img->width+2*IMG_PAD_SIZE)*4));
for (uv=0; uv < 2; uv++)
memcpy (fb->picbuf_long[0]->mcef[uv][0], fb->picbuf_short[idx]->mcef[uv][0], img->width_cr*img->height_cr);
memcpy (fb->picbuf_long[0]->Refbuf11, fb->picbuf_short[idx]->Refbuf11, img->width*img->height);
if (input->WeightedPrediction || input->WeightedBiprediction)
memcpy (fb->picbuf_long[0]->Refbuf11, fb->picbuf_short[idx]->Refbuf11, img->width*img->height);
// sort the long term buffer by lt_IDs
// Note: Just a simple bubble sort implementation. The buffer is not very large
// so this should not take too much time. Feel free to implement something better.
for (i=0,idx1=0;i<fb->long_used-1;i++)
{
id=fb->picbuf_long[i]->lt_picID;
for (j=i+1;j<fb->long_used;j++)
{
if (fb->picbuf_long[j]->lt_picID<id)
{
id=fb->picbuf_long[j]->lt_picID;
idx1=j;
}
}
if (id<fb->picbuf_long[i]->lt_picID)
{
f=fb->picbuf_long[i];
fb->picbuf_long[i]=fb->picbuf_long[idx1];
fb->picbuf_long[idx1]=f;
}
}
}
/*!
************************************************************************
* \brief
* remove long term frame from buffer
*
* \param longID
* long term ID
*
************************************************************************
*/
void remove_long_term(int longID)
{
int i,j;
Frame *f;
for (i=0;i<fb->long_used;i++)
{
if ((fb->picbuf_long[i]->lt_picID)==longID)
{
fb->picbuf_long[i]->used=0;
fb->picbuf_long[i]->picID=-1;
fb->picbuf_long[i]->lt_picID=-1;
fb->long_used--;
if (i<fb->long_used)
{
f=fb->picbuf_long[i];
for (j=i;j<fb->long_used;j++)
fb->picbuf_long[j]=fb->picbuf_long[j+1];
fb->picbuf_long[fb->long_used]=f;
}
}
}
}
/*!
************************************************************************
* \brief
* remove short term frame from buffer
*
* \param shortID
* short term ID
*
************************************************************************
*/
void remove_short_term(int shortID)
{
int i,j;
Frame *f;
for (i=0;i<fb->short_used;i++)
{
if ((fb->picbuf_short[i]->picID)==shortID)
{
fb->picbuf_short[i]->used=0;
fb->picbuf_short[i]->lt_picID=-1;
fb->picbuf_short[i]->picID=-1;
fb->short_used--;
// Tian Dong: June 15, 2002
// Use short_size to replace short_used.
if (i<fb->short_size)
{
f=fb->picbuf_short[i];
for (j=i;j<fb->short_size-1;j++)
fb->picbuf_short[j]=fb->picbuf_short[j+1];
fb->picbuf_short[fb->short_size-1]=f;
}
// old lines:
/* if (i<fb->short_size)
{
f=fb->picbuf_short[i];
for (j=i;j<fb->short_used-1;j++);
fb->picbuf_short[j]=fb->picbuf_short[j+1];
fb->picbuf_short[fb->short_used-1]=f;
} */
}
}
}
/*!
************************************************************************
* \brief
* (re)-allocate memory for mref pointer structure
************************************************************************
*/
void alloc_mref(ImageParameters *img)
{
if (mref_frm)
free (mref_frm);
if((mref_frm = (byte***)calloc(frm->short_size+frm->long_size,sizeof(byte**))) == NULL)
no_mem_exit("alloc_mref: mref_frm");
if (mcef_frm)
free (mcef_frm);
if((mcef_frm = (byte****)calloc(frm->short_size+frm->long_size,sizeof(byte***))) == NULL)
no_mem_exit("alloc_mref: mcef_frm");
if(input->InterlaceCodingOption != FRAME_CODING)
{
if (mref_fld)
free (mref_fld);
if ((mref_fld = (byte***)calloc(fld->short_size+fld->long_size,sizeof(byte**))) == NULL)
no_mem_exit("alloc_mref: mref_fld");
if (mcef_fld)
free (mcef_fld);
if ((mcef_fld = (byte****)calloc(fld->short_size+fld->long_size,sizeof(byte***))) == NULL)
no_mem_exit("alloc_mref: mcef_fld");
if (parity_fld)
free (parity_fld);
if((parity_fld = (int *)calloc(fld->short_size+fld->long_size, sizeof(int))) == NULL)
no_mem_exit("alloc_mref: parity_fld");
}
if (input->WeightedPrediction || input->WeightedBiprediction)
{
if (mref_frm_w)
free (mref_frm_w);
if((mref_frm_w = (byte***)calloc(frm->short_size+frm->long_size,sizeof(byte**))) == NULL)
no_mem_exit("alloc_mref: mref_frm_w");
if(input->InterlaceCodingOption != FRAME_CODING)
{
if (mref_fld_w)
free (mref_fld_w);
if ((mref_fld_w = (byte***)calloc(fld->short_size+fld->long_size,sizeof(byte**))) == NULL)
no_mem_exit("alloc_mref: mref_fld_w");
}
}
}
/*!
************************************************************************
* \brief
* init mref pointer structure
************************************************************************
*/
void init_mref()
{
int i,j;
for (i=0,j=0;i<fb->short_used;i++,j++)
{
mref[j]=fb->picbuf_short[i]->mref;
if (input->WeightedPrediction || input->WeightedBiprediction)
mref_w[j]=fb->picbuf_short[i]->mref_w;
mcef[j]=fb->picbuf_short[i]->mcef;
if(mref==mref_fld) parity_fld[j] = fb->picbuf_short[i]->parity;
}
for (i=0;i<fb->long_used;i++,j++)
{
mref[j]=fb->picbuf_long[i]->mref;
if (input->WeightedPrediction || input->WeightedBiprediction)
mref_w[j]=fb->picbuf_long[i]->mref_w;
mcef[j]=fb->picbuf_long[i]->mcef;
if(mref==mref_fld) parity_fld[j] = fb->picbuf_long[i]->parity;
}
// set all other mref pointers to NULL !KS!
for (;j<fb->long_size+fb->short_size;j++)
{
mref[j]=NULL;
if (input->WeightedPrediction || input->WeightedBiprediction)
mref_w[j]=NULL;
mcef[j]=NULL;
if(mref==mref_fld) parity_fld[j] = -1;
}
}
/*!
************************************************************************
* \brief
* process RMPNI command list
************************************************************************
*/
void reorder_mref(ImageParameters *img)
{
RMPNIbuffer_t *r;
int pnp = img->pn;
int pnq = 0;
int index = 0,i;
int size;
int islong=0;
int found=0;
Frame **fr;
Frame *f;
// if nothing to do update mref and return
if (img->currentSlice->rmpni_buffer== NULL)
{
init_mref();
init_Refbuf(img);
return;
}
// We have to do the reordering with complete frame structures
// so we need a temporary frame buffer of ordered references
size=fb->short_used+fb->long_used;
if ((fr=(Frame**)calloc(size,sizeof (Frame*)))==NULL) no_mem_exit("init_frame_buffers: fb->picbuf_long");
for (i=0;i<fb->short_used;i++)
{
fr[i]=fb->picbuf_short[i];
fr[i]->islong=0;
}
for (i=0;i<fb->long_used;i++)
{
fr[i+fb->short_used]=fb->picbuf_long[i];
fr[i+fb->short_used]->islong=1;
}
r=img->currentSlice->rmpni_buffer;
while (r)
{
switch (r->RMPNI)
{
case 0:
// ADPN correspondig to negative difference
if ((pnp-r->Data)<0)
pnq=pnp-r->Data+fb->short_size;
else
pnq=pnp-r->Data;
islong=0;
break;
case 1:
// ADPN correspondig to positive difference
if ((pnp+r->Data)>fb->short_size-1)
pnq=pnp+r->Data-fb->short_size;
else
pnq=pnp+r->Data;
islong=0;
break;
case 2:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -