[FFmpeg-devel] [PATCH] exr: slice threading
Paul B Mahol
onemda at gmail.com
Fri Feb 22 21:07:10 CET 2013
On 2/22/13, Paul B Mahol <onemda at gmail.com> wrote:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
> libavcodec/exr.c | 348
> +++++++++++++++++++++++++++++++------------------------
> 1 file changed, 198 insertions(+), 150 deletions(-)
>
> diff --git a/libavcodec/exr.c b/libavcodec/exr.c
> index 2e9ee31..ff83314 100644
> --- a/libavcodec/exr.c
> +++ b/libavcodec/exr.c
> @@ -48,17 +48,33 @@ enum ExrCompr {
> EXR_B44A = 7,
> };
>
> +typedef struct EXRThreadData {
> + uint8_t *uncompressed_data;
> + int uncompressed_size;
> +
> + uint8_t *tmp;
> + int tmp_size;
> +} EXRThreadData;
> +
> typedef struct EXRContext {
> AVFrame picture;
> int compr;
> int bits_per_color_id;
> int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha
> + const AVPixFmtDescriptor *desc;
>
> - uint8_t *uncompressed_data;
> - int uncompressed_size;
> + uint32_t xmax, xmin;
> + uint32_t ymax, ymin;
> + uint32_t xdelta, ydelta;
>
> - uint8_t *tmp;
> - int tmp_size;
> + uint64_t scan_line_size;
> + int scan_lines_per_block;
> +
> + const uint8_t *buf, *table;
> + int buf_size;
> +
> + EXRThreadData *thread_data;
> + int thread_data_size;
> } EXRContext;
>
> /**
> @@ -219,6 +235,129 @@ static int rle_uncompress(const uint8_t *src, int
> ssize, uint8_t *dst, int dsize
> return dend != d;
> }
>
> +static int decode_block(AVCodecContext *avctx, void *tdata,
> + int jobnr, int threadnr)
> +{
> + EXRContext *s = avctx->priv_data;
> + AVFrame *const p = &s->picture;
> + EXRThreadData *td = &s->thread_data[threadnr];
> + const uint8_t *channel_buffer[4] = { 0 };
> + const uint8_t *buf = s->buf;
> + uint64_t line_offset, uncompressed_size;
> + uint32_t xdelta = s->xdelta;
> + uint16_t *ptr_x;
> + uint8_t *ptr;
> + int32_t data_size, line;
> + const uint8_t *src;
> + int axmax = (avctx->width - (s->xmax + 1)) * 2 *
> s->desc->nb_components;
> + int bxmin = s->xmin * 2 * s->desc->nb_components;
> + int i, x, buf_size = s->buf_size;
> +
> + line_offset = AV_RL64(s->table + jobnr * 8);
> + // Check if the buffer has the required bytes needed from the offset
> + if (line_offset > buf_size - 8)
> + return AVERROR_INVALIDDATA;
> +
> + src = buf + line_offset + 8;
> + line = AV_RL32(src - 8);
> + if (line < s->ymin || line > s->ymax)
> + return AVERROR_INVALIDDATA;
> +
> + data_size = AV_RL32(src - 4);
> + if (data_size <= 0 || data_size > buf_size)
> + return AVERROR_INVALIDDATA;
> +
> + uncompressed_size = s->scan_line_size * FFMIN(s->scan_lines_per_block,
> s->ymax - line + 1);
> + if ((s->compr == EXR_RAW && (data_size != uncompressed_size ||
> + line_offset > buf_size -
> uncompressed_size)) ||
> + (s->compr != EXR_RAW && line_offset > buf_size - data_size)) {
> + return AVERROR_INVALIDDATA;
> + }
> +
> + if (data_size < uncompressed_size) {
> + av_fast_padded_malloc(&td->uncompressed_data,
> &td->uncompressed_size, uncompressed_size);
> + av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size);
added check locally
[...]
More information about the ffmpeg-devel
mailing list