diff --git a/libavcodec/proresdec.h b/libavcodec/proresdec.h index 06e41dd09a..1e48752e6f 100644 --- a/libavcodec/proresdec.h +++ b/libavcodec/proresdec.h @@ -52,6 +52,7 @@ typedef struct { int first_field; int alpha_info; void (*unpack_alpha)(GetBitContext *gb, uint16_t *dst, int num_coeffs, const int num_bits); + enum AVPixelFormat pix_fmt; } ProresContext; #endif /* AVCODEC_PRORESDEC_H */ diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index 7750620b22..5b1d7da693 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -187,6 +187,8 @@ static av_cold int decode_init(AVCodecContext *avctx) permute(ctx->progressive_scan, ff_prores_progressive_scan, idct_permutation); permute(ctx->interlaced_scan, ff_prores_interlaced_scan, idct_permutation); + ctx->pix_fmt = AV_PIX_FMT_NONE; + if (avctx->bits_per_raw_sample == 10){ ctx->unpack_alpha = unpack_alpha_10; } else if (avctx->bits_per_raw_sample == 12){ @@ -204,6 +206,7 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, int hdr_size, width, height, flags; int version; const uint8_t *ptr; + enum AVPixelFormat pix_fmt; hdr_size = AV_RB16(buf); ff_dlog(avctx, "header size %d\n", hdr_size); @@ -252,18 +255,34 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, if (ctx->alpha_info) { if (avctx->bits_per_raw_sample == 10) { - avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P10 : AV_PIX_FMT_YUVA422P10; + pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P10 : AV_PIX_FMT_YUVA422P10; } else { /* 12b */ - avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P12 : AV_PIX_FMT_YUVA422P12; + pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P12 : AV_PIX_FMT_YUVA422P12; } } else { if (avctx->bits_per_raw_sample == 10) { - avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10; + pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10; } else { /* 12b */ - avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P12 : AV_PIX_FMT_YUV422P12; + pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P12 : AV_PIX_FMT_YUV422P12; } } + if (pix_fmt != ctx->pix_fmt) { +#define HWACCEL_MAX 0 + enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts; + int ret; + + ctx->pix_fmt = pix_fmt; + + *fmtp++ = ctx->pix_fmt; + *fmtp = AV_PIX_FMT_NONE; + + if ((ret = ff_thread_get_format(avctx, pix_fmts)) < 0) + return ret; + + avctx->pix_fmt = ret; + } + avctx->color_primaries = buf[14]; avctx->color_trc = buf[15]; avctx->colorspace = buf[16]; @@ -782,6 +801,22 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, buf += frame_hdr_size; buf_size -= frame_hdr_size; + if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) + return ret; + + if (avctx->hwaccel) { + ret = avctx->hwaccel->start_frame(avctx, NULL, 0); + if (ret < 0) + return ret; + ret = avctx->hwaccel->decode_slice(avctx, avpkt->data, avpkt->size); + if (ret < 0) + return ret; + ret = avctx->hwaccel->end_frame(avctx); + if (ret < 0) + return ret; + goto finish; + } + decode_picture: pic_size = decode_picture_header(avctx, buf, buf_size); if (pic_size < 0) { @@ -789,10 +824,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return pic_size; } - if (ctx->first_field) - if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) - return ret; - if ((ret = decode_picture(avctx)) < 0) { av_log(avctx, AV_LOG_ERROR, "error decoding picture\n"); return ret; @@ -806,6 +837,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, goto decode_picture; } +finish: *got_frame = 1; return avpkt->size;