Luca, let me know how fate gets on on your machine with this version -
sorry for the initial duff fix

On 23 July 2015 at 00:03, Tom Butterworth <[email protected]> wrote:
> A bug was introduced in 6b2b26e7af3ede0abfb46eb5725c26d1083f50bc whereby when
> frame height wasn't divisible by the number of threads, pixels would be 
> omitted
> from the bottom rows during decode.
> ---
>  libavcodec/dds.c | 26 +++++++++++++++++---------
>  1 file changed, 17 insertions(+), 9 deletions(-)
>
> diff --git a/libavcodec/dds.c b/libavcodec/dds.c
> index 625cb30..2c3a2f2 100644
> --- a/libavcodec/dds.c
> +++ b/libavcodec/dds.c
> @@ -105,7 +105,7 @@ typedef struct DDSContext {
>
>      const uint8_t *tex_data; // Compressed texture
>      int tex_ratio;           // Compression ratio
> -    int slice_size;          // Optimal slice size
> +    int slice_count;         // Number of slices for threaded operations
>
>      /* Pointer to the selected compress or decompress function. */
>      int (*tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
> @@ -421,14 +421,23 @@ static int decompress_texture_thread(AVCodecContext 
> *avctx, void *arg,
>      AVFrame *frame = arg;
>      const uint8_t *d = ctx->tex_data;
>      int w_block = avctx->coded_width / TEXTURE_BLOCK_W;
> +    int h_block = avctx->coded_height / TEXTURE_BLOCK_H;
>      int x, y;
>      int start_slice, end_slice;
> +    int base_blocks_per_slice = h_block / ctx->slice_count;
> +    int remainder_blocks = h_block % ctx->slice_count;
>
> -    start_slice = slice * ctx->slice_size;
> -    end_slice   = FFMIN(start_slice + ctx->slice_size, avctx->coded_height);
> +    /* When the frame height (in blocks) doesn't divide evenly between the
> +     * number of slices, spread the remaining blocks evenly between the first
> +     * operations */
> +    start_slice = slice * base_blocks_per_slice;
> +    /* Add any extra blocks (one per slice) that have been added before this 
> slice */
> +    start_slice += FFMIN(slice, remainder_blocks);
>
> -    start_slice /= TEXTURE_BLOCK_H;
> -    end_slice   /= TEXTURE_BLOCK_H;
> +    end_slice = start_slice + base_blocks_per_slice;
> +    /* Add an extra block if there are still remainder blocks to be 
> accounted for */
> +    if (slice < remainder_blocks)
> +        end_slice++;
>
>      for (y = start_slice; y < end_slice; y++) {
>          uint8_t *p = frame->data[0] + y * frame->linesize[0] * 
> TEXTURE_BLOCK_H;
> @@ -633,13 +642,12 @@ static int dds_decode(AVCodecContext *avctx, void *data,
>          return ret;
>
>      if (ctx->compressed) {
> -        int slices = FFMIN(avctx->thread_count,
> -                           avctx->coded_height / TEXTURE_BLOCK_H);
> -        ctx->slice_size = avctx->coded_height / slices;
> +        ctx->slice_count = av_clip(avctx->thread_count, 1,
> +                                   avctx->coded_height / TEXTURE_BLOCK_H);
>
>          /* Use the decompress function on the texture, one block per thread. 
> */
>          ctx->tex_data = gbc->buffer;
> -        avctx->execute2(avctx, decompress_texture_thread, frame, NULL, 
> slices);
> +        avctx->execute2(avctx, decompress_texture_thread, frame, NULL, 
> ctx->slice_count);
>      } else {
>          int linesize = av_image_get_linesize(avctx->pix_fmt, frame->width, 
> 0);
>
> --
> 2.3.2 (Apple Git-55)
>
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to