lavc/proresdec: add scaffolding for hwdec support

This commit is contained in:
rcombs 2021-11-13 13:37:26 -06:00
parent 350eb59f8c
commit 805bf2ebc9
2 changed files with 41 additions and 8 deletions

View File

@ -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 */

View File

@ -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;