[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