This change decouples the frame dimensions from avctx, which is useful for DXV decoding, and fixes incorrect behavior in the existing implementation. Tested with `make fate THREADS=7` and `make fate THREADS=7 THREAD_TYPE=slice`.
Unified · Split
| @@ -636,6 +636,8 @@ static int dds_decode(AVCodecContext *avctx, AVFrame *frame, · 635 unmodified lines | |||
| 636 | ctx->dec.tex_data.in = gbc->buffer; | 636 | ctx->dec.tex_data.in = gbc->buffer; |
| 637 | ctx->dec.frame_data.out = frame->data[0]; | 637 | ctx->dec.frame_data.out = frame->data[0]; |
| 638 | ctx->dec.stride = frame->linesize[0]; | 638 | ctx->dec.stride = frame->linesize[0]; |
| 639 | ctx->dec.width = avctx->coded_width; | ||
| 640 | ctx->dec.height = avctx->coded_height; | ||
| 639 | ff_texturedsp_exec_decompress_threads(avctx, &ctx->dec); | 641 | ff_texturedsp_exec_decompress_threads(avctx, &ctx->dec); |
| 640 | } else if (!ctx->paletted && ctx->bpp == 4 && avctx->pix_fmt == AV_PIX_FMT_PAL8) { | 642 | } else if (!ctx->paletted && ctx->bpp == 4 && avctx->pix_fmt == AV_PIX_FMT_PAL8) { |
| 641 | uint8_t *dst = frame->data[0]; | 643 | uint8_t *dst = frame->data[0]; |
| @@ -843,7 +843,6 @@ static int dxv_decode(AVCodecContext *avctx, AVFrame *frame, · 842 unmodified lines | |||
| 843 | { | 843 | { |
| 844 | DXVContext *ctx = avctx->priv_data; | 844 | DXVContext *ctx = avctx->priv_data; |
| 845 | GetByteContext *gbc = &ctx->gbc; | 845 | GetByteContext *gbc = &ctx->gbc; |
| 846 | AVCodecContext cavctx = *avctx; | ||
| 847 | TextureDSPThreadContext texdsp_ctx, ctexdsp_ctx; | 846 | TextureDSPThreadContext texdsp_ctx, ctexdsp_ctx; |
| 848 | int (*decompress_tex)(AVCodecContext *avctx); | 847 | int (*decompress_tex)(AVCodecContext *avctx); |
| 849 | const char *msgcomp, *msgtext; | 848 | const char *msgcomp, *msgtext; |
| @@ -854,9 +853,6 @@ static int dxv_decode(AVCodecContext *avctx, AVFrame *frame, · 4 unmodified lines | |||
| 854 | 853 | ||
| 855 | bytestream2_init(gbc, avpkt->data, avpkt->size); | 854 | bytestream2_init(gbc, avpkt->data, avpkt->size); |
| 856 | 855 | ||
| 857 | cavctx.coded_height = avctx->coded_height / 2; | ||
| 858 | cavctx.coded_width = avctx->coded_width / 2; | ||
| 859 | |||
| 860 | avctx->pix_fmt = AV_PIX_FMT_RGBA; | 856 | avctx->pix_fmt = AV_PIX_FMT_RGBA; |
| 861 | avctx->colorspace = AVCOL_SPC_RGB; | 857 | avctx->colorspace = AVCOL_SPC_RGB; |
| 862 | 858 | ||
| @@ -943,7 +939,8 @@ static int dxv_decode(AVCodecContext *avctx, AVFrame *frame, · 80 unmodified lines | |||
| 943 | texdsp_ctx.slice_count = av_clip(avctx->thread_count, 1, | 939 | texdsp_ctx.slice_count = av_clip(avctx->thread_count, 1, |
| 944 | avctx->coded_height / TEXTURE_BLOCK_H); | 940 | avctx->coded_height / TEXTURE_BLOCK_H); |
| 945 | ctexdsp_ctx.slice_count = av_clip(avctx->thread_count, 1, | 941 | ctexdsp_ctx.slice_count = av_clip(avctx->thread_count, 1, |
| 946 | cavctx.coded_height / TEXTURE_BLOCK_H); | 942 | avctx->coded_height / 2 / TEXTURE_BLOCK_H); |
| 943 | |||
| 947 | /* New header is 12 bytes long. */ | 944 | /* New header is 12 bytes long. */ |
| 948 | if (!old_type) { | 945 | if (!old_type) { |
| 949 | version_major = bytestream2_get_byte(gbc) - 1; | 946 | version_major = bytestream2_get_byte(gbc) - 1; |
| @@ -979,8 +976,8 @@ static int dxv_decode(AVCodecContext *avctx, AVFrame *frame, · 29 unmodified lines | |||
| 979 | if (avctx->pix_fmt != AV_PIX_FMT_RGBA) { | 976 | if (avctx->pix_fmt != AV_PIX_FMT_RGBA) { |
| 980 | int i; | 977 | int i; |
| 981 | 978 | ||
| 982 | ctx->ctex_size = cavctx.coded_width / ctexdsp_ctx.raw_ratio * | 979 | ctx->ctex_size = avctx->coded_width / 2 / ctexdsp_ctx.raw_ratio * |
| 983 | cavctx.coded_height / TEXTURE_BLOCK_H * | 980 | avctx->coded_height / 2 / TEXTURE_BLOCK_H * |
| 984 | ctexdsp_ctx.tex_ratio; | 981 | ctexdsp_ctx.tex_ratio; |
| 985 | 982 | ||
| 986 | ctx->op_size[0] = avctx->coded_width * avctx->coded_height / 16; | 983 | ctx->op_size[0] = avctx->coded_width * avctx->coded_height / 16; |
| @@ -1007,6 +1004,10 @@ static int dxv_decode(AVCodecContext *avctx, AVFrame *frame, · 20 unmodified lines | |||
| 1007 | if (ret < 0) | 1004 | if (ret < 0) |
| 1008 | return ret; | 1005 | return ret; |
| 1009 | 1006 | ||
| 1007 | texdsp_ctx.width = avctx->coded_width; | ||
| 1008 | texdsp_ctx.height = avctx->coded_height; | ||
| 1009 | ctexdsp_ctx.width = avctx->coded_width / 2; | ||
| 1010 | ctexdsp_ctx.height = avctx->coded_height / 2; | ||
| 1010 | switch (tag) { | 1011 | switch (tag) { |
| 1011 | case DXV_FMT_YG10: | 1012 | case DXV_FMT_YG10: |
| 1012 | /* BC5 texture with alpha in the second half of each block */ | 1013 | /* BC5 texture with alpha in the second half of each block */ |
| @@ -1022,13 +1023,13 @@ static int dxv_decode(AVCodecContext *avctx, AVFrame *frame, · 9 unmodified lines | |||
| 1022 | ctexdsp_ctx.tex_data.in = ctx->ctex_data; | 1023 | ctexdsp_ctx.tex_data.in = ctx->ctex_data; |
| 1023 | ctexdsp_ctx.frame_data.out = frame->data[2]; | 1024 | ctexdsp_ctx.frame_data.out = frame->data[2]; |
| 1024 | ctexdsp_ctx.stride = frame->linesize[2]; | 1025 | ctexdsp_ctx.stride = frame->linesize[2]; |
| 1025 | ret = ff_texturedsp_exec_decompress_threads(&cavctx, &ctexdsp_ctx); | 1026 | ret = ff_texturedsp_exec_decompress_threads(avctx, &ctexdsp_ctx); |
| 1026 | if (ret < 0) | 1027 | if (ret < 0) |
| 1027 | return ret; | 1028 | return ret; |
| 1028 | ctexdsp_ctx.tex_data.in = ctx->ctex_data + ctexdsp_ctx.tex_ratio / 2; | 1029 | ctexdsp_ctx.tex_data.in = ctx->ctex_data + ctexdsp_ctx.tex_ratio / 2; |
| 1029 | ctexdsp_ctx.frame_data.out = frame->data[1]; | 1030 | ctexdsp_ctx.frame_data.out = frame->data[1]; |
| 1030 | ctexdsp_ctx.stride = frame->linesize[1]; | 1031 | ctexdsp_ctx.stride = frame->linesize[1]; |
| 1031 | ret = ff_texturedsp_exec_decompress_threads(&cavctx, &ctexdsp_ctx); | 1032 | ret = ff_texturedsp_exec_decompress_threads(avctx, &ctexdsp_ctx); |
| 1032 | if (ret < 0) | 1033 | if (ret < 0) |
| 1033 | return ret; | 1034 | return ret; |
| 1034 | /* fallthrough */ | 1035 | /* fallthrough */ |
| @@ -233,6 +233,8 @@ static int dxv_encode(AVCodecContext *avctx, AVPacket *pkt, · 232 unmodified lines | |||
| 233 | ctx->enc.tex_data.out = ctx->tex_data; | 233 | ctx->enc.tex_data.out = ctx->tex_data; |
| 234 | ctx->enc.frame_data.in = frame->data[0]; | 234 | ctx->enc.frame_data.in = frame->data[0]; |
| 235 | ctx->enc.stride = frame->linesize[0]; | 235 | ctx->enc.stride = frame->linesize[0]; |
| 236 | ctx->enc.width = avctx->width; | ||
| 237 | ctx->enc.height = avctx->height; | ||
| 236 | ff_texturedsp_exec_compress_threads(avctx, &ctx->enc); | 238 | ff_texturedsp_exec_compress_threads(avctx, &ctx->enc); |
| 237 | } else { | 239 | } else { |
| 238 | /* unimplemented: YCoCg formats */ | 240 | /* unimplemented: YCoCg formats */ |
| @@ -323,6 +323,8 @@ static int hap_decode(AVCodecContext *avctx, AVFrame *frame, · 322 unmodified lines | |||
| 323 | 323 | ||
| 324 | ctx->dec[t].frame_data.out = frame->data[0]; | 324 | ctx->dec[t].frame_data.out = frame->data[0]; |
| 325 | ctx->dec[t].stride = frame->linesize[0]; | 325 | ctx->dec[t].stride = frame->linesize[0]; |
| 326 | ctx->dec[t].width = avctx->coded_width; | ||
| 327 | ctx->dec[t].height = avctx->coded_height; | ||
| 326 | ff_texturedsp_exec_decompress_threads(avctx, &ctx->dec[t]); | 328 | ff_texturedsp_exec_decompress_threads(avctx, &ctx->dec[t]); |
| 327 | } | 329 | } |
| 328 | 330 | ||
| @@ -63,6 +63,8 @@ static int compress_texture(AVCodecContext *avctx, uint8_t *out, int out_length, · 62 unmodified lines | |||
| 63 | ctx->enc.tex_data.out = out; | 63 | ctx->enc.tex_data.out = out; |
| 64 | ctx->enc.frame_data.in = f->data[0]; | 64 | ctx->enc.frame_data.in = f->data[0]; |
| 65 | ctx->enc.stride = f->linesize[0]; | 65 | ctx->enc.stride = f->linesize[0]; |
| 66 | ctx->enc.width = avctx->width; | ||
| 67 | ctx->enc.height = avctx->height; | ||
| 66 | ff_texturedsp_exec_compress_threads(avctx, &ctx->enc); | 68 | ff_texturedsp_exec_compress_threads(avctx, &ctx->enc); |
| 67 | 69 | ||
| 68 | return 0; | 70 | return 0; |
| @@ -72,6 +72,7 @@ typedef struct TextureDSPThreadContext { · 71 unmodified lines | |||
| 72 | uint8_t *out; // Output frame data | 72 | uint8_t *out; // Output frame data |
| 73 | } frame_data; | 73 | } frame_data; |
| 74 | ptrdiff_t stride; // Frame linesize | 74 | ptrdiff_t stride; // Frame linesize |
| 75 | int width, height; // Frame width / height | ||
| 75 | union { | 76 | union { |
| 76 | const uint8_t *in; // Compressed texture for decompression | 77 | const uint8_t *in; // Compressed texture for decompression |
| 77 | uint8_t *out; // Compressed texture of compression | 78 | uint8_t *out; // Compressed texture of compression |
| @@ -27,8 +27,8 @@ static int exec_func(AVCodecContext *avctx, void *arg, · 26 unmodified lines | |||
| 27 | { | 27 | { |
| 28 | const TextureDSPThreadContext *ctx = arg; | 28 | const TextureDSPThreadContext *ctx = arg; |
| 29 | uint8_t *d = ctx->tex_data.out; | 29 | uint8_t *d = ctx->tex_data.out; |
| 30 | int w_block = avctx->coded_width / TEXTURE_BLOCK_W; | 30 | int w_block = ctx->width / TEXTURE_BLOCK_W; |
| 31 | int h_block = avctx->coded_height / TEXTURE_BLOCK_H; | 31 | int h_block = ctx->height / TEXTURE_BLOCK_H; |
| 32 | int x, y; | 32 | int x, y; |
| 33 | int start_slice, end_slice; | 33 | int start_slice, end_slice; |
| 34 | int base_blocks_per_slice = h_block / ctx->slice_count; | 34 | int base_blocks_per_slice = h_block / ctx->slice_count; |
| @@ -162,6 +162,8 @@ static int vbn_decode_frame(AVCodecContext *avctx, · 161 unmodified lines | |||
| 162 | ctx->dec.raw_ratio = 16; | 162 | ctx->dec.raw_ratio = 16; |
| 163 | ctx->dec.frame_data.out = frame->data[0] + frame->linesize[0] * (frame->height - 1); | 163 | ctx->dec.frame_data.out = frame->data[0] + frame->linesize[0] * (frame->height - 1); |
| 164 | ctx->dec.stride = -frame->linesize[0]; | 164 | ctx->dec.stride = -frame->linesize[0]; |
| 165 | ctx->dec.width = avctx->coded_width; | ||
| 166 | ctx->dec.height = avctx->coded_height; | ||
| 165 | ff_texturedsp_exec_decompress_threads(avctx, &ctx->dec); | 167 | ff_texturedsp_exec_decompress_threads(avctx, &ctx->dec); |
| 166 | } | 168 | } |
| 167 | 169 | ||
| @@ -114,6 +114,8 @@ static int vbn_encode(AVCodecContext *avctx, AVPacket *pkt, · 113 unmodified lines | |||
| 114 | ctx->enc.frame_data.in = (frame->height - 1) * frame->linesize[0] + frame->data[0]; | 114 | ctx->enc.frame_data.in = (frame->height - 1) * frame->linesize[0] + frame->data[0]; |
| 115 | ctx->enc.stride = -frame->linesize[0]; | 115 | ctx->enc.stride = -frame->linesize[0]; |
| 116 | ctx->enc.tex_data.out = pkt->data + VBN_HEADER_SIZE; | 116 | ctx->enc.tex_data.out = pkt->data + VBN_HEADER_SIZE; |
| 117 | ctx->enc.width = avctx->width; | ||
| 118 | ctx->enc.height = avctx->height; | ||
| 117 | ff_texturedsp_exec_compress_threads(avctx, &ctx->enc); | 119 | ff_texturedsp_exec_compress_threads(avctx, &ctx->enc); |
| 118 | } else { | 120 | } else { |
| 119 | const uint8_t *flipped = frame->data[0] + frame->linesize[0] * (frame->height - 1); | 121 | const uint8_t *flipped = frame->data[0] + frame->linesize[0] * (frame->height - 1); |