summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/ffmpeg/libavcodec/diracdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/ffmpeg/libavcodec/diracdec.c')
-rw-r--r--chromium/third_party/ffmpeg/libavcodec/diracdec.c157
1 files changed, 96 insertions, 61 deletions
diff --git a/chromium/third_party/ffmpeg/libavcodec/diracdec.c b/chromium/third_party/ffmpeg/libavcodec/diracdec.c
index dbc2aab3348..1be4115c59c 100644
--- a/chromium/third_party/ffmpeg/libavcodec/diracdec.c
+++ b/chromium/third_party/ffmpeg/libavcodec/diracdec.c
@@ -80,7 +80,7 @@
#define DIVRNDUP(a, b) (((a) + (b) - 1) / (b))
typedef struct {
- AVFrame avframe;
+ AVFrame *avframe;
int interpolated[3]; /* 1 if hpel[] is valid */
uint8_t *hpel[3][4];
uint8_t *hpel_base[3][4];
@@ -291,7 +291,7 @@ static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum)
int i, remove_idx = -1;
for (i = 0; framelist[i]; i++)
- if (framelist[i]->avframe.display_picture_number == picnum) {
+ if (framelist[i]->avframe->display_picture_number == picnum) {
remove_pic = framelist[i];
remove_idx = i;
}
@@ -336,8 +336,8 @@ static int alloc_sequence_buffers(DiracContext *s)
w = FFALIGN(CALC_PADDING(w, MAX_DWT_LEVELS), 8); /* FIXME: Should this be 16 for SSE??? */
h = top_padding + CALC_PADDING(h, MAX_DWT_LEVELS) + max_yblen/2;
- s->plane[i].idwt_buf_base = av_mallocz((w+max_xblen)*h * sizeof(IDWTELEM));
- s->plane[i].idwt_tmp = av_malloc((w+16) * sizeof(IDWTELEM));
+ s->plane[i].idwt_buf_base = av_mallocz_array((w+max_xblen), h * sizeof(IDWTELEM));
+ s->plane[i].idwt_tmp = av_malloc_array((w+16), sizeof(IDWTELEM));
s->plane[i].idwt_buf = s->plane[i].idwt_buf_base + top_padding*w;
if (!s->plane[i].idwt_buf_base || !s->plane[i].idwt_tmp)
return AVERROR(ENOMEM);
@@ -347,12 +347,12 @@ static int alloc_sequence_buffers(DiracContext *s)
h = s->source.height;
/* fixme: allocate using real stride here */
- s->sbsplit = av_malloc(sbwidth * sbheight);
- s->blmotion = av_malloc(sbwidth * sbheight * 16 * sizeof(*s->blmotion));
- s->edge_emu_buffer_base = av_malloc((w+64)*MAX_BLOCKSIZE);
+ s->sbsplit = av_malloc_array(sbwidth, sbheight);
+ s->blmotion = av_malloc_array(sbwidth, sbheight * 16 * sizeof(*s->blmotion));
+ s->edge_emu_buffer_base = av_malloc_array((w+64), MAX_BLOCKSIZE);
- s->mctmp = av_malloc((w+64+MAX_BLOCKSIZE) * (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp));
- s->mcscratch = av_malloc((w+64)*MAX_BLOCKSIZE);
+ s->mctmp = av_malloc_array((w+64+MAX_BLOCKSIZE), (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp));
+ s->mcscratch = av_malloc_array((w+64), MAX_BLOCKSIZE);
if (!s->sbsplit || !s->blmotion || !s->mctmp || !s->mcscratch)
return AVERROR(ENOMEM);
@@ -364,8 +364,8 @@ static void free_sequence_buffers(DiracContext *s)
int i, j, k;
for (i = 0; i < MAX_FRAMES; i++) {
- if (s->all_frames[i].avframe.data[0]) {
- av_frame_unref(&s->all_frames[i].avframe);
+ if (s->all_frames[i].avframe->data[0]) {
+ av_frame_unref(s->all_frames[i].avframe);
memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
}
@@ -393,17 +393,23 @@ static void free_sequence_buffers(DiracContext *s)
static av_cold int dirac_decode_init(AVCodecContext *avctx)
{
DiracContext *s = avctx->priv_data;
+ int i;
+
s->avctx = avctx;
s->frame_number = -1;
- if (avctx->flags&CODEC_FLAG_EMU_EDGE) {
- av_log(avctx, AV_LOG_ERROR, "Edge emulation not supported!\n");
- return AVERROR_PATCHWELCOME;
- }
-
ff_dsputil_init(&s->dsp, avctx);
ff_diracdsp_init(&s->diracdsp);
+ for (i = 0; i < MAX_FRAMES; i++) {
+ s->all_frames[i].avframe = av_frame_alloc();
+ if (!s->all_frames[i].avframe) {
+ while (i > 0)
+ av_frame_free(&s->all_frames[--i].avframe);
+ return AVERROR(ENOMEM);
+ }
+ }
+
return 0;
}
@@ -417,7 +423,13 @@ static void dirac_decode_flush(AVCodecContext *avctx)
static av_cold int dirac_decode_end(AVCodecContext *avctx)
{
+ DiracContext *s = avctx->priv_data;
+ int i;
+
dirac_decode_flush(avctx);
+ for (i = 0; i < MAX_FRAMES; i++)
+ av_frame_free(&s->all_frames[i].avframe);
+
return 0;
}
@@ -742,7 +754,7 @@ static void decode_lowdelay(DiracContext *s)
struct lowdelay_slice *slices;
int slice_num = 0;
- slices = av_mallocz(s->lowdelay.num_x * s->lowdelay.num_y * sizeof(struct lowdelay_slice));
+ slices = av_mallocz_array(s->lowdelay.num_x, s->lowdelay.num_y * sizeof(struct lowdelay_slice));
align_get_bits(&s->gb);
/*[DIRAC_STD] 13.5.2 Slices. slice(sx,sy) */
@@ -1343,8 +1355,8 @@ static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5],
motion_y >>= s->chroma_y_shift;
}
- mx = motion_x & ~(-1 << s->mv_precision);
- my = motion_y & ~(-1 << s->mv_precision);
+ mx = motion_x & ~(-1U << s->mv_precision);
+ my = motion_y & ~(-1U << s->mv_precision);
motion_x >>= s->mv_precision;
motion_y >>= s->mv_precision;
/* normalize subpel coordinates to epel */
@@ -1519,8 +1531,8 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in
just use 8 for everything for the moment */
int i, edge = EDGE_WIDTH/2;
- ref->hpel[plane][0] = ref->avframe.data[plane];
- s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */
+ ref->hpel[plane][0] = ref->avframe->data[plane];
+ s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */
/* no need for hpel if we only have fpel vectors */
if (!s->mv_precision)
@@ -1528,18 +1540,18 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in
for (i = 1; i < 4; i++) {
if (!ref->hpel_base[plane][i])
- ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe.linesize[plane] + 32);
+ ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe->linesize[plane] + 32);
/* we need to be 16-byte aligned even for chroma */
- ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe.linesize[plane] + 16;
+ ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe->linesize[plane] + 16;
}
if (!ref->interpolated[plane]) {
s->diracdsp.dirac_hpel_filter(ref->hpel[plane][1], ref->hpel[plane][2],
ref->hpel[plane][3], ref->hpel[plane][0],
- ref->avframe.linesize[plane], width, height);
- s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
- s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
- s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+ ref->avframe->linesize[plane], width, height);
+ s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+ s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+ s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
}
ref->interpolated[plane] = 1;
}
@@ -1565,7 +1577,7 @@ static int dirac_decode_frame_internal(DiracContext *s)
for (comp = 0; comp < 3; comp++) {
Plane *p = &s->plane[comp];
- uint8_t *frame = s->current_picture->avframe.data[comp];
+ uint8_t *frame = s->current_picture->avframe->data[comp];
/* FIXME: small resolutions */
for (i = 0; i < 4; i++)
@@ -1629,6 +1641,29 @@ static int dirac_decode_frame_internal(DiracContext *s)
return 0;
}
+static int get_buffer_with_edge(AVCodecContext *avctx, AVFrame *f, int flags)
+{
+ int ret, i;
+ int chroma_x_shift, chroma_y_shift;
+ avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_x_shift, &chroma_y_shift);
+
+ f->width = avctx->width + 2 * EDGE_WIDTH;
+ f->height = avctx->height + 2 * EDGE_WIDTH + 2;
+ ret = ff_get_buffer(avctx, f, flags);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; f->data[i]; i++) {
+ int offset = (EDGE_WIDTH >> (i && i<3 ? chroma_y_shift : 0)) *
+ f->linesize[i] + 32;
+ f->data[i] += offset;
+ }
+ f->width = avctx->width;
+ f->height = avctx->height;
+
+ return 0;
+}
+
/**
* Dirac Specification ->
* 11.1.1 Picture Header. picture_header()
@@ -1640,7 +1675,7 @@ static int dirac_decode_picture_header(DiracContext *s)
GetBitContext *gb = &s->gb;
/* [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->avframe->display_picture_number = get_bits_long(gb, 32);
av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum);
@@ -1659,9 +1694,9 @@ static int dirac_decode_picture_header(DiracContext *s)
/* Jordi: this is needed if the referenced picture hasn't yet arrived */
for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++)
if (s->ref_frames[j]
- && FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum) < refdist) {
+ && FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum) < refdist) {
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]->avframe->display_picture_number - refnum);
}
if (!s->ref_pics[i] || refdist)
@@ -1670,21 +1705,21 @@ static int dirac_decode_picture_header(DiracContext *s)
/* if there were no references at all, allocate one */
if (!s->ref_pics[i])
for (j = 0; j < MAX_FRAMES; j++)
- if (!s->all_frames[j].avframe.data[0]) {
+ if (!s->all_frames[j].avframe->data[0]) {
s->ref_pics[i] = &s->all_frames[j];
- ff_get_buffer(s->avctx, &s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF);
+ get_buffer_with_edge(s->avctx, s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF);
break;
}
}
/* retire the reference frames that are not used anymore */
- if (s->current_picture->avframe.reference) {
+ if (s->current_picture->avframe->reference) {
retire = picnum + dirac_get_se_golomb(gb);
if (retire != picnum) {
DiracFrame *retire_pic = remove_frame(s->ref_frames, retire);
if (retire_pic)
- retire_pic->avframe.reference &= DELAYED_PIC_REF;
+ retire_pic->avframe->reference &= DELAYED_PIC_REF;
else
av_log(s->avctx, AV_LOG_DEBUG, "Frame to retire not found\n");
}
@@ -1692,7 +1727,7 @@ static int dirac_decode_picture_header(DiracContext *s)
/* if reference array is full, remove the oldest as per the spec */
while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) {
av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n");
- remove_frame(s->ref_frames, s->ref_frames[0]->avframe.display_picture_number)->avframe.reference &= DELAYED_PIC_REF;
+ remove_frame(s->ref_frames, s->ref_frames[0]->avframe->display_picture_number)->avframe->reference &= DELAYED_PIC_REF;
}
}
@@ -1717,7 +1752,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
/* find frame with lowest picture number */
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]->avframe->display_picture_number < out->avframe->display_picture_number) {
out = s->delay_frames[i];
out_idx = i;
}
@@ -1726,9 +1761,9 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
s->delay_frames[i] = s->delay_frames[i+1];
if (out) {
- out->avframe.reference ^= DELAYED_PIC_REF;
+ out->avframe->reference ^= DELAYED_PIC_REF;
*got_frame = 1;
- if((ret = av_frame_ref(picture, &out->avframe)) < 0)
+ if((ret = av_frame_ref(picture, out->avframe)) < 0)
return ret;
}
@@ -1790,14 +1825,14 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int
/* find an unused frame */
for (i = 0; i < MAX_FRAMES; i++)
- if (s->all_frames[i].avframe.data[0] == NULL)
+ if (s->all_frames[i].avframe->data[0] == NULL)
pic = &s->all_frames[i];
if (!pic) {
av_log(avctx, AV_LOG_ERROR, "framelist full\n");
return -1;
}
- avcodec_get_frame_defaults(&pic->avframe);
+ av_frame_unref(pic->avframe);
/* [DIRAC_STD] Defined in 9.6.1 ... */
tmp = parse_code & 0x03; /* [DIRAC_STD] num_refs() */
@@ -1808,16 +1843,16 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int
s->num_refs = tmp;
s->is_arith = (parse_code & 0x48) == 0x08; /* [DIRAC_STD] using_ac() */
s->low_delay = (parse_code & 0x88) == 0x88; /* [DIRAC_STD] is_low_delay() */
- pic->avframe.reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */
- pic->avframe.key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */
- pic->avframe.pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */
+ pic->avframe->reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */
+ pic->avframe->key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */
+ pic->avframe->pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */
- if ((ret = ff_get_buffer(avctx, &pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
+ if ((ret = get_buffer_with_edge(avctx, pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
return ret;
s->current_picture = pic;
- s->plane[0].stride = pic->avframe.linesize[0];
- s->plane[1].stride = pic->avframe.linesize[1];
- s->plane[2].stride = pic->avframe.linesize[2];
+ s->plane[0].stride = pic->avframe->linesize[0];
+ s->plane[1].stride = pic->avframe->linesize[1];
+ s->plane[2].stride = pic->avframe->linesize[2];
/* [DIRAC_STD] 11.1 Picture parse. picture_parse() */
if (dirac_decode_picture_header(s))
@@ -1833,7 +1868,7 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int
static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
{
DiracContext *s = avctx->priv_data;
- DiracFrame *picture = data;
+ AVFrame *picture = data;
uint8_t *buf = pkt->data;
int buf_size = pkt->size;
int i, data_unit_size, buf_idx = 0;
@@ -1841,8 +1876,8 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
/* release unused frames */
for (i = 0; i < MAX_FRAMES; i++)
- if (s->all_frames[i].avframe.data[0] && !s->all_frames[i].avframe.reference) {
- av_frame_unref(&s->all_frames[i].avframe);
+ if (s->all_frames[i].avframe->data[0] && !s->all_frames[i].avframe->reference) {
+ av_frame_unref(s->all_frames[i].avframe);
memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
}
@@ -1887,40 +1922,40 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
if (!s->current_picture)
return buf_size;
- if (s->current_picture->avframe.display_picture_number > s->frame_number) {
+ if (s->current_picture->avframe->display_picture_number > s->frame_number) {
DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);
- s->current_picture->avframe.reference |= DELAYED_PIC_REF;
+ s->current_picture->avframe->reference |= DELAYED_PIC_REF;
if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {
- int min_num = s->delay_frames[0]->avframe.display_picture_number;
+ int min_num = s->delay_frames[0]->avframe->display_picture_number;
/* Too many delayed frames, so we display the frame with the lowest pts */
av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");
delayed_frame = s->delay_frames[0];
for (i = 1; s->delay_frames[i]; i++)
- if (s->delay_frames[i]->avframe.display_picture_number < min_num)
- min_num = s->delay_frames[i]->avframe.display_picture_number;
+ if (s->delay_frames[i]->avframe->display_picture_number < min_num)
+ min_num = s->delay_frames[i]->avframe->display_picture_number;
delayed_frame = remove_frame(s->delay_frames, min_num);
add_frame(s->delay_frames, MAX_DELAY, s->current_picture);
}
if (delayed_frame) {
- delayed_frame->avframe.reference ^= DELAYED_PIC_REF;
- if((ret=av_frame_ref(data, &delayed_frame->avframe)) < 0)
+ delayed_frame->avframe->reference ^= DELAYED_PIC_REF;
+ if((ret=av_frame_ref(data, delayed_frame->avframe)) < 0)
return ret;
*got_frame = 1;
}
- } else if (s->current_picture->avframe.display_picture_number == s->frame_number) {
+ } else if (s->current_picture->avframe->display_picture_number == s->frame_number) {
/* The right frame at the right time :-) */
- if((ret=av_frame_ref(data, &s->current_picture->avframe)) < 0)
+ if((ret=av_frame_ref(data, s->current_picture->avframe)) < 0)
return ret;
*got_frame = 1;
}
if (*got_frame)
- s->frame_number = picture->avframe.display_picture_number + 1;
+ s->frame_number = picture->display_picture_number + 1;
return buf_idx;
}