mirror of https://git.ffmpeg.org/ffmpeg.git
avcodec/diracdec: do not use AVFrame.display_picture_number for decoding
Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
parent
6b6f7db819
commit
817141c562
|
@ -77,6 +77,7 @@ typedef struct {
|
||||||
uint8_t *hpel[3][4];
|
uint8_t *hpel[3][4];
|
||||||
uint8_t *hpel_base[3][4];
|
uint8_t *hpel_base[3][4];
|
||||||
int reference;
|
int reference;
|
||||||
|
unsigned picture_number;
|
||||||
} DiracFrame;
|
} DiracFrame;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -252,13 +253,13 @@ static inline int divide3(int x)
|
||||||
return (int)((x+1U)*21845 + 10922) >> 16;
|
return (int)((x+1U)*21845 + 10922) >> 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum)
|
static DiracFrame *remove_frame(DiracFrame *framelist[], unsigned picnum)
|
||||||
{
|
{
|
||||||
DiracFrame *remove_pic = NULL;
|
DiracFrame *remove_pic = NULL;
|
||||||
int i, remove_idx = -1;
|
int i, remove_idx = -1;
|
||||||
|
|
||||||
for (i = 0; framelist[i]; i++)
|
for (i = 0; framelist[i]; i++)
|
||||||
if (framelist[i]->avframe->display_picture_number == picnum) {
|
if (framelist[i]->picture_number == picnum) {
|
||||||
remove_pic = framelist[i];
|
remove_pic = framelist[i];
|
||||||
remove_idx = i;
|
remove_idx = i;
|
||||||
}
|
}
|
||||||
|
@ -2002,7 +2003,7 @@ static int dirac_decode_picture_header(DiracContext *s)
|
||||||
GetBitContext *gb = &s->gb;
|
GetBitContext *gb = &s->gb;
|
||||||
|
|
||||||
/* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */
|
/* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */
|
||||||
picnum = s->current_picture->avframe->display_picture_number = get_bits_long(gb, 32);
|
picnum = s->current_picture->picture_number = get_bits_long(gb, 32);
|
||||||
|
|
||||||
|
|
||||||
av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum);
|
av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum);
|
||||||
|
@ -2021,9 +2022,9 @@ static int dirac_decode_picture_header(DiracContext *s)
|
||||||
/* Jordi: this is needed if the referenced picture hasn't yet arrived */
|
/* Jordi: this is needed if the referenced picture hasn't yet arrived */
|
||||||
for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++)
|
for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++)
|
||||||
if (s->ref_frames[j]
|
if (s->ref_frames[j]
|
||||||
&& FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum) < refdist) {
|
&& FFABS(s->ref_frames[j]->picture_number - refnum) < refdist) {
|
||||||
s->ref_pics[i] = s->ref_frames[j];
|
s->ref_pics[i] = s->ref_frames[j];
|
||||||
refdist = FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum);
|
refdist = FFABS(s->ref_frames[j]->picture_number - refnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->ref_pics[i] || refdist)
|
if (!s->ref_pics[i] || refdist)
|
||||||
|
@ -2062,7 +2063,7 @@ static int dirac_decode_picture_header(DiracContext *s)
|
||||||
/* if reference array is full, remove the oldest as per the spec */
|
/* if reference array is full, remove the oldest as per the spec */
|
||||||
while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) {
|
while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) {
|
||||||
av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n");
|
av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n");
|
||||||
remove_frame(s->ref_frames, s->ref_frames[0]->avframe->display_picture_number)->reference &= DELAYED_PIC_REF;
|
remove_frame(s->ref_frames, s->ref_frames[0]->picture_number)->reference &= DELAYED_PIC_REF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2090,7 +2091,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
|
||||||
|
|
||||||
/* find frame with lowest picture number */
|
/* find frame with lowest picture number */
|
||||||
for (i = 1; s->delay_frames[i]; i++)
|
for (i = 1; s->delay_frames[i]; i++)
|
||||||
if (s->delay_frames[i]->avframe->display_picture_number < out->avframe->display_picture_number) {
|
if (s->delay_frames[i]->picture_number < out->picture_number) {
|
||||||
out = s->delay_frames[i];
|
out = s->delay_frames[i];
|
||||||
out_idx = i;
|
out_idx = i;
|
||||||
}
|
}
|
||||||
|
@ -2102,6 +2103,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
|
||||||
out->reference ^= DELAYED_PIC_REF;
|
out->reference ^= DELAYED_PIC_REF;
|
||||||
if((ret = av_frame_ref(picture, out->avframe)) < 0)
|
if((ret = av_frame_ref(picture, out->avframe)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
picture->display_picture_number = out->picture_number;
|
||||||
*got_frame = 1;
|
*got_frame = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2318,19 +2320,19 @@ static int dirac_decode_frame(AVCodecContext *avctx, AVFrame *picture,
|
||||||
if (!s->current_picture)
|
if (!s->current_picture)
|
||||||
return buf_size;
|
return buf_size;
|
||||||
|
|
||||||
if (s->current_picture->avframe->display_picture_number > s->frame_number) {
|
if (s->current_picture->picture_number > s->frame_number) {
|
||||||
DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);
|
DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);
|
||||||
|
|
||||||
s->current_picture->reference |= DELAYED_PIC_REF;
|
s->current_picture->reference |= DELAYED_PIC_REF;
|
||||||
|
|
||||||
if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {
|
if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {
|
||||||
int min_num = s->delay_frames[0]->avframe->display_picture_number;
|
unsigned min_num = s->delay_frames[0]->picture_number;
|
||||||
/* Too many delayed frames, so we display the frame with the lowest pts */
|
/* Too many delayed frames, so we display the frame with the lowest pts */
|
||||||
av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");
|
av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");
|
||||||
|
|
||||||
for (i = 1; s->delay_frames[i]; i++)
|
for (i = 1; s->delay_frames[i]; i++)
|
||||||
if (s->delay_frames[i]->avframe->display_picture_number < min_num)
|
if (s->delay_frames[i]->picture_number < min_num)
|
||||||
min_num = s->delay_frames[i]->avframe->display_picture_number;
|
min_num = s->delay_frames[i]->picture_number;
|
||||||
|
|
||||||
delayed_frame = remove_frame(s->delay_frames, min_num);
|
delayed_frame = remove_frame(s->delay_frames, min_num);
|
||||||
add_frame(s->delay_frames, MAX_DELAY, s->current_picture);
|
add_frame(s->delay_frames, MAX_DELAY, s->current_picture);
|
||||||
|
@ -2340,18 +2342,19 @@ static int dirac_decode_frame(AVCodecContext *avctx, AVFrame *picture,
|
||||||
delayed_frame->reference ^= DELAYED_PIC_REF;
|
delayed_frame->reference ^= DELAYED_PIC_REF;
|
||||||
if((ret = av_frame_ref(picture, delayed_frame->avframe)) < 0)
|
if((ret = av_frame_ref(picture, delayed_frame->avframe)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
s->frame_number = delayed_frame->picture_number + 1LL;
|
||||||
|
picture->display_picture_number = delayed_frame->picture_number;
|
||||||
*got_frame = 1;
|
*got_frame = 1;
|
||||||
}
|
}
|
||||||
} else if (s->current_picture->avframe->display_picture_number == s->frame_number) {
|
} else if (s->current_picture->picture_number == s->frame_number) {
|
||||||
/* The right frame at the right time :-) */
|
/* The right frame at the right time :-) */
|
||||||
if((ret = av_frame_ref(picture, s->current_picture->avframe)) < 0)
|
if((ret = av_frame_ref(picture, s->current_picture->avframe)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
s->frame_number = s->current_picture->picture_number + 1LL;
|
||||||
|
picture->display_picture_number = s->current_picture->picture_number;
|
||||||
*got_frame = 1;
|
*got_frame = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*got_frame)
|
|
||||||
s->frame_number = picture->display_picture_number + 1LL;
|
|
||||||
|
|
||||||
return buf_idx;
|
return buf_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue