This source file includes following definitions.
- reset
- compute_derived_values
- read_short_term_ref_pic_set
- write_short_term_ref_pic_set_nopred
- write_short_term_ref_pic_set
- dump_short_term_ref_pic_set
- dump_compact_short_term_ref_pic_set
#include "refpic.h"
#include "decctx.h"
#include "util.h"
#include <assert.h>
#include <stdlib.h>
#if defined(_MSC_VER) || defined(__MINGW32__)
# include <malloc.h>
#elif defined(HAVE_ALLOCA_H)
# include <alloca.h>
#endif
void ref_pic_set::reset()
{
NumNegativePics = 0;
NumPositivePics = 0;
NumDeltaPocs = 0;
NumPocTotalCurr_shortterm_only = 0;
for (int i=0;i<MAX_NUM_REF_PICS;i++) {
DeltaPocS0[i] = 0;
DeltaPocS1[i] = 0;
UsedByCurrPicS0[i] = 0;
UsedByCurrPicS1[i] = 0;
}
}
void ref_pic_set::compute_derived_values()
{
NumPocTotalCurr_shortterm_only = 0;
for (int i=0; i<NumNegativePics; i++)
if (UsedByCurrPicS0[i])
NumPocTotalCurr_shortterm_only++;
for (int i=0; i<NumPositivePics; i++)
if (UsedByCurrPicS1[i])
NumPocTotalCurr_shortterm_only++;
NumDeltaPocs = NumNegativePics + NumPositivePics;
}
bool read_short_term_ref_pic_set(error_queue* errqueue,
const seq_parameter_set* sps,
bitreader* br,
ref_pic_set* out_set,
int idxRps,
const std::vector<ref_pic_set>& sets,
bool sliceRefPicSet)
{
char inter_ref_pic_set_prediction_flag;
if (idxRps != 0) {
inter_ref_pic_set_prediction_flag = get_bits(br,1);
}
else {
inter_ref_pic_set_prediction_flag = 0;
}
if (inter_ref_pic_set_prediction_flag) {
int vlc;
int delta_idx;
if (sliceRefPicSet) {
delta_idx = vlc = get_uvlc(br);
if (delta_idx==UVLC_ERROR) {
return false;
}
if (delta_idx>=idxRps) {
return false;
}
delta_idx++;
} else {
delta_idx = 1;
}
int RIdx = idxRps - delta_idx;
assert(RIdx>=0);
int delta_rps_sign = get_bits(br,1);
int abs_delta_rps = vlc = get_uvlc(br);
if (vlc==UVLC_ERROR) { return false; }
abs_delta_rps++;
int DeltaRPS = (delta_rps_sign ? -abs_delta_rps : abs_delta_rps);
logtrace(LogHeaders,"predicted from %d with delta %d\n",RIdx,DeltaRPS);
int nDeltaPocsRIdx= sets[RIdx].NumDeltaPocs;
char *const used_by_curr_pic_flag = (char *)alloca((nDeltaPocsRIdx+1) * sizeof(char));
char *const use_delta_flag = (char *)alloca((nDeltaPocsRIdx+1) * sizeof(char));
for (int j=0;j<=nDeltaPocsRIdx;j++) {
used_by_curr_pic_flag[j] = get_bits(br,1);
if (used_by_curr_pic_flag[j]) {
use_delta_flag[j] = 1;
} else {
use_delta_flag[j] = get_bits(br,1);
}
}
logtrace(LogHeaders,"flags: ");
for (int j=0;j<=nDeltaPocsRIdx;j++) {
logtrace(LogHeaders,"%d ", use_delta_flag[j]);
}
logtrace(LogHeaders,"\n");
int nNegativeRIdx = sets[RIdx].NumNegativePics;
int nPositiveRIdx = sets[RIdx].NumPositivePics;
int i=0;
for (int j=nPositiveRIdx-1;j>=0;j--) {
assert(RIdx >= 0 && RIdx < sets.size());
assert(j>=0 && j < MAX_NUM_REF_PICS);
int dPoc = sets[RIdx].DeltaPocS1[j] + DeltaRPS;
if (dPoc<0 && use_delta_flag[nNegativeRIdx+j]) {
if (i>= MAX_NUM_REF_PICS) { return false; }
out_set->DeltaPocS0[i] = dPoc;
out_set->UsedByCurrPicS0[i] = used_by_curr_pic_flag[nNegativeRIdx+j];
i++;
}
}
if (DeltaRPS<0 && use_delta_flag[nDeltaPocsRIdx]) {
if (i>= MAX_NUM_REF_PICS) { return false; }
out_set->DeltaPocS0[i] = DeltaRPS;
out_set->UsedByCurrPicS0[i] = used_by_curr_pic_flag[nDeltaPocsRIdx];
i++;
}
for (int j=0;j<nNegativeRIdx;j++) {
int dPoc = sets[RIdx].DeltaPocS0[j] + DeltaRPS;
if (dPoc<0 && use_delta_flag[j]) {
if (i>= MAX_NUM_REF_PICS) { return false; }
out_set->DeltaPocS0[i] = dPoc;
out_set->UsedByCurrPicS0[i] = used_by_curr_pic_flag[j];
i++;
}
}
out_set->NumNegativePics = i;
i=0;
for (int j=nNegativeRIdx-1;j>=0;j--) {
int dPoc = sets[RIdx].DeltaPocS0[j] + DeltaRPS;
if (dPoc>0 && use_delta_flag[j]) {
if (i>= MAX_NUM_REF_PICS) { return false; }
out_set->DeltaPocS1[i] = dPoc;
out_set->UsedByCurrPicS1[i] = used_by_curr_pic_flag[j];
i++;
}
}
if (DeltaRPS>0 && use_delta_flag[nDeltaPocsRIdx]) {
if (i>= MAX_NUM_REF_PICS) { return false; }
out_set->DeltaPocS1[i] = DeltaRPS;
out_set->UsedByCurrPicS1[i] = used_by_curr_pic_flag[nDeltaPocsRIdx];
i++;
}
for (int j=0;j<nPositiveRIdx;j++) {
int dPoc = sets[RIdx].DeltaPocS1[j] + DeltaRPS;
if (dPoc>0 && use_delta_flag[nNegativeRIdx+j]) {
if (i>= MAX_NUM_REF_PICS) { return false; }
out_set->DeltaPocS1[i] = dPoc;
out_set->UsedByCurrPicS1[i] = used_by_curr_pic_flag[nNegativeRIdx+j];
i++;
}
}
out_set->NumPositivePics = i;
} else {
int num_negative_pics = get_uvlc(br);
int num_positive_pics = get_uvlc(br);
if (num_negative_pics + num_positive_pics >
sps->sps_max_dec_pic_buffering[ sps->sps_max_sub_layers-1 ]) {
out_set->NumNegativePics = 0;
out_set->NumPositivePics = 0;
out_set->NumDeltaPocs = 0;
out_set->NumPocTotalCurr_shortterm_only = 0;
errqueue->add_warning(DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED, false);
return false;
}
if (num_negative_pics > MAX_NUM_REF_PICS ||
num_positive_pics > MAX_NUM_REF_PICS) {
errqueue->add_warning(DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED, false);
return false;
}
out_set->NumNegativePics = num_negative_pics;
out_set->NumPositivePics = num_positive_pics;
int lastPocS=0;
for (int i=0;i<num_negative_pics;i++) {
int delta_poc_s0 = get_uvlc(br);
if (delta_poc_s0==UVLC_ERROR) { return false; }
delta_poc_s0++;
char used_by_curr_pic_s0_flag = get_bits(br,1);
out_set->DeltaPocS0[i] = lastPocS - delta_poc_s0;
out_set->UsedByCurrPicS0[i] = used_by_curr_pic_s0_flag;
lastPocS = out_set->DeltaPocS0[i];
}
lastPocS=0;
for (int i=0;i<num_positive_pics;i++) {
int delta_poc_s1 = get_uvlc(br);
if (delta_poc_s1==UVLC_ERROR) { return false; }
delta_poc_s1++;
char used_by_curr_pic_s1_flag = get_bits(br,1);
out_set->DeltaPocS1[i] = lastPocS + delta_poc_s1;
out_set->UsedByCurrPicS1[i] = used_by_curr_pic_s1_flag;
lastPocS = out_set->DeltaPocS1[i];
}
}
out_set->compute_derived_values();
return true;
}
bool write_short_term_ref_pic_set_nopred(error_queue* errqueue,
const seq_parameter_set* sps,
CABAC_encoder& out,
const ref_pic_set* in_set,
int idxRps,
const std::vector<ref_pic_set>& sets,
bool sliceRefPicSet)
{
if (idxRps != 0) {
out.write_bit(0);
}
out.write_uvlc(in_set->NumNegativePics);
out.write_uvlc(in_set->NumPositivePics);
int lastPocS=0;
for (int i=0;i<in_set->NumNegativePics;i++) {
int delta_poc_s0 = lastPocS - in_set->DeltaPocS0[i];
char used_by_curr_pic_s0_flag = in_set->UsedByCurrPicS0[i];
assert(delta_poc_s0 >= 1);
out.write_uvlc(delta_poc_s0-1);
out.write_bit(used_by_curr_pic_s0_flag);
lastPocS = in_set->DeltaPocS0[i];
}
lastPocS=0;
for (int i=0;i<in_set->NumPositivePics;i++) {
int delta_poc_s1 = in_set->DeltaPocS1[i] - lastPocS;
char used_by_curr_pic_s1_flag = in_set->UsedByCurrPicS1[i];
assert(delta_poc_s1 >= 1);
out.write_uvlc(delta_poc_s1-1);
out.write_bit(used_by_curr_pic_s1_flag);
lastPocS = in_set->DeltaPocS1[i];
}
return true;
}
bool write_short_term_ref_pic_set(error_queue* errqueue,
const seq_parameter_set* sps,
CABAC_encoder& out,
const ref_pic_set* in_set,
int idxRps,
const std::vector<ref_pic_set>& sets,
bool sliceRefPicSet)
{
return write_short_term_ref_pic_set_nopred(errqueue, sps, out, in_set, idxRps, sets,
sliceRefPicSet);
}
void dump_short_term_ref_pic_set(const ref_pic_set* set, FILE* fh)
{
log2fh(fh,"NumDeltaPocs: %d [-:%d +:%d]\n", set->NumDeltaPocs,
set->NumNegativePics, set->NumPositivePics);
log2fh(fh,"DeltaPocS0:");
for (int i=0;i<set->NumNegativePics;i++) {
if (i) { log2fh(fh,","); }
log2fh(fh," %d/%d",set->DeltaPocS0[i],set->UsedByCurrPicS0[i]);
}
log2fh(fh,"\n");
log2fh(fh,"DeltaPocS1:");
for (int i=0;i<set->NumPositivePics;i++) {
if (i) { log2fh(fh,","); }
log2fh(fh," %d/%d",set->DeltaPocS1[i],set->UsedByCurrPicS1[i]);
}
log2fh(fh,"\n");
}
void dump_compact_short_term_ref_pic_set(const ref_pic_set* set, int range, FILE* fh)
{
char *const log = (char *)alloca((range+1+range+1) * sizeof(char));
log[2*range+1] = 0;
for (int i=0;i<2*range+1;i++) log[i]='.';
log[range]='|';
for (int i=set->NumNegativePics-1;i>=0;i--) {
int n = set->DeltaPocS0[i];
if (n>=-range) {
if (set->UsedByCurrPicS0[i]) log[n+range] = 'X';
else log[n+range] = 'o';
} else { log2fh(fh,"*%d%c ",n, set->UsedByCurrPicS0[i] ? 'X':'o'); }
}
for (int i=set->NumPositivePics-1;i>=0;i--) {
int n = set->DeltaPocS1[i];
if (n<=range) {
if (set->UsedByCurrPicS1[i]) log[n+range] = 'X';
else log[n+range] = 'o';
} else { log2fh(fh,"*%d%c ",n, set->UsedByCurrPicS1[i] ? 'X':'o'); }
}
log2fh(fh,"*%s\n",log);
}