History

ffv1dec: add support for hwaccels

This commit adds support for hardware accelerated decoding to the decoder. The previous commits already refactored the decoder, this commit simply adds calls to hooks to decode.

Lynne committed 1 year ago

Commit 23eb4991 parent 53ff9002 files · +75 −8Browse files

Showing the changes to libavcodec (2 of 2 files). Show all

Unified · Split

2 files
  1. libavcodec/ffv1.h +2 −0
  2. libavcodec/ffv1dec.c +73 −8
libavcodec/ffv1.h+2−0
@@ -125,8 +125,10 @@ typedef struct FFV1Context { · 124 unmodified lines
125125 int64_t picture_number;
126126 int key_frame;
127127 ProgressFrame picture, last_picture;
128+ void *hwaccel_picture_private, *hwaccel_last_picture_private;
128129 uint32_t crcref;
129130 enum AVPixelFormat pix_fmt;
131+ enum AVPixelFormat configured_pix_fmt;
130132
131133 const AVFrame *cur_enc_frame;
132134 int plane_count;
libavcodec/ffv1dec.c+73−8
@@ -41,6 +41,9 @@ · 40 unmodified lines
4141 #include "libavutil/refstruct.h"
4242 #include "thread.h"
4343 #include "decode.h"
44+#include "hwconfig.h"
45+#include "hwaccel_internal.h"
46+#include "config_components.h"
4447
4548 static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state,
4649 int bits)
@@ -403,9 +406,12 @@ static int read_header(FFV1Context *f, RangeCoder *c) · 356 unmodified lines
403406 if (ret < 0)
404407 return ret;
405408
406− f->avctx->pix_fmt = get_pixel_format(f);
407− if (f->avctx->pix_fmt < 0)
408− return AVERROR(EINVAL);
409+ if (f->configured_pix_fmt != f->pix_fmt) {
410+ f->avctx->pix_fmt = get_pixel_format(f);
411+ if (f->avctx->pix_fmt < 0)
412+ return AVERROR(EINVAL);
413+ f->configured_pix_fmt = f->pix_fmt;
414+ }
409415
410416 ff_dlog(f->avctx, "%d %d %d\n",
411417 f->chroma_h_shift, f->chroma_v_shift, f->pix_fmt);
@@ -498,6 +504,9 @@ static av_cold int decode_init(AVCodecContext *avctx) · 86 unmodified lines
498504 FFV1Context *f = avctx->priv_data;
499505 int ret;
500506
507+ f->pix_fmt = AV_PIX_FMT_NONE;
508+ f->configured_pix_fmt = AV_PIX_FMT_NONE;
509+
501510 if ((ret = ff_ffv1_common_init(avctx, f)) < 0)
502511 return ret;
503512
@@ -682,13 +691,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, · 178 unmodified lines
682691 FFV1Context *f = avctx->priv_data;
683692 int ret;
684693 AVFrame *p;
694+ const FFHWAccel *hwaccel = NULL;
685695
686696 /* This is copied onto the first slice's range coder context */
687697 RangeCoder c;
688698
689699 ff_progress_frame_unref(&f->last_picture);
690− FFSWAP(ProgressFrame, f->picture, f->last_picture);
700+ av_refstruct_unref(&f->hwaccel_last_picture_private);
691701
702+ FFSWAP(ProgressFrame, f->picture, f->last_picture);
703+ FFSWAP(void *, f->hwaccel_picture_private, f->hwaccel_last_picture_private);
692704
693705 f->avctx = avctx;
694706 f->frame_damaged = 0;
@@ -704,11 +716,18 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, · 9 unmodified lines
704716 if (avctx->skip_frame >= AVDISCARD_ALL)
705717 return avpkt->size;
706718
719+ if (avctx->hwaccel)
720+ hwaccel = ffhwaccel(avctx->hwaccel);
721+
707722 ret = ff_progress_frame_get_buffer(avctx, &f->picture,
708723 AV_GET_BUFFER_FLAG_REF);
709724 if (ret < 0)
710725 return ret;
711726
727+ ret = ff_hwaccel_frame_priv_alloc(avctx, &f->hwaccel_picture_private);
728+ if (ret < 0)
729+ return ret;
730+
712731 p = f->picture.f;
713732
714733 p->pict_type = AV_PICTURE_TYPE_I; //FIXME I vs. P
@@ -721,15 +740,53 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, · 6 unmodified lines
721740 p->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
722741 }
723742
743+ /* Start */
744+ if (hwaccel) {
745+ ret = hwaccel->start_frame(avctx, avpkt->data, avpkt->size);
746+ if (ret < 0)
747+ return ret;
748+ }
749+
724750 ff_thread_finish_setup(avctx);
725751
726− ret = decode_slices(avctx, c, avpkt);
727− if (ret < 0)
728− return ret;
752+ /* Decode slices */
753+ if (hwaccel) {
754+ uint8_t *buf_end = avpkt->data + avpkt->size;
755+
756+ if (!(p->flags & AV_FRAME_FLAG_KEY) && f->last_picture.f)
757+ ff_progress_frame_await(&f->last_picture, f->slice_count - 1);
758+
759+ for (int i = f->slice_count - 1; i >= 0; i--) {
760+ uint8_t *pos;
761+ uint32_t len;
762+ ret = find_next_slice(avctx, avpkt->data, buf_end, i,
763+ &pos, &len);
764+ if (ret < 0)
765+ return ret;
766+
767+ buf_end -= len;
768+
769+ ret = hwaccel->decode_slice(avctx, pos, len);
770+ if (ret < 0)
771+ return ret;
772+ }
773+ } else {
774+ ret = decode_slices(avctx, c, avpkt);
775+ if (ret < 0)
776+ return ret;
777+ }
778+
779+ /* Finalize */
780+ if (hwaccel) {
781+ ret = hwaccel->end_frame(avctx);
782+ if (ret < 0)
783+ return ret;
784+ }
729785
730786 ff_progress_frame_report(&f->picture, INT_MAX);
731787
732788 ff_progress_frame_unref(&f->last_picture);
789+ av_refstruct_unref(&f->hwaccel_last_picture_private);
733790 if ((ret = av_frame_ref(rframe, f->picture.f)) < 0)
734791 return ret;
735792
@@ -758,6 +815,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) · 22 unmodified lines
758815 fdst->ac = fsrc->ac;
759816 fdst->colorspace = fsrc->colorspace;
760817 fdst->pix_fmt = fsrc->pix_fmt;
818+ fdst->configured_pix_fmt = fsrc->configured_pix_fmt;
761819
762820 fdst->ec = fsrc->ec;
763821 fdst->intra = fsrc->intra;
@@ -793,6 +851,8 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) · 29 unmodified lines
793851 av_assert1(fdst->max_slice_count == fsrc->max_slice_count);
794852
795853 ff_progress_frame_replace(&fdst->picture, &fsrc->picture);
854+ av_refstruct_replace(&fdst->hwaccel_picture_private,
855+ fsrc->hwaccel_picture_private);
796856
797857 return 0;
798858 }
@@ -803,8 +863,10 @@ static av_cold int ffv1_decode_close(AVCodecContext *avctx) · 4 unmodified lines
803863 FFV1Context *const s = avctx->priv_data;
804864
805865 ff_progress_frame_unref(&s->picture);
866+ av_refstruct_unref(&s->hwaccel_picture_private);
867+
806868 ff_progress_frame_unref(&s->last_picture);
807− av_freep(&avctx->stats_out);
869+ av_refstruct_unref(&s->hwaccel_last_picture_private);
808870
809871 ff_ffv1_close(s);
810872
@@ -826,4 +888,7 @@ const FFCodec ff_ffv1_decoder = { · 15 unmodified lines
826888 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
827889 FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM |
828890 FF_CODEC_CAP_USES_PROGRESSFRAMES,
891+ .hw_configs = (const AVCodecHWConfigInternal *const []) {
892+ NULL
893+ },
829894 };

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t