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
125 int64_t picture_number;125 int64_t picture_number;
126 int key_frame;126 int key_frame;
127 ProgressFrame picture, last_picture;127 ProgressFrame picture, last_picture;
128 void *hwaccel_picture_private, *hwaccel_last_picture_private;
128 uint32_t crcref;129 uint32_t crcref;
129 enum AVPixelFormat pix_fmt;130 enum AVPixelFormat pix_fmt;
131 enum AVPixelFormat configured_pix_fmt;
130 132
131 const AVFrame *cur_enc_frame;133 const AVFrame *cur_enc_frame;
132 int plane_count;134 int plane_count;
libavcodec/ffv1dec.c+73−8
@@ -41,6 +41,9 @@ · 40 unmodified lines
41#include "libavutil/refstruct.h"41#include "libavutil/refstruct.h"
42#include "thread.h"42#include "thread.h"
43#include "decode.h"43#include "decode.h"
44#include "hwconfig.h"
45#include "hwaccel_internal.h"
46#include "config_components.h"
44 47
45static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state,48static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state,
46 int bits)49 int bits)
@@ -403,9 +406,12 @@ static int read_header(FFV1Context *f, RangeCoder *c) · 356 unmodified lines
403 if (ret < 0)406 if (ret < 0)
404 return ret;407 return ret;
405 408
406 f->avctx->pix_fmt = get_pixel_format(f);409 if (f->configured_pix_fmt != f->pix_fmt) {
407 if (f->avctx->pix_fmt < 0)410 f->avctx->pix_fmt = get_pixel_format(f);
408 return AVERROR(EINVAL);411 if (f->avctx->pix_fmt < 0)
412 return AVERROR(EINVAL);
413 f->configured_pix_fmt = f->pix_fmt;
414 }
409 415
410 ff_dlog(f->avctx, "%d %d %d\n",416 ff_dlog(f->avctx, "%d %d %d\n",
411 f->chroma_h_shift, f->chroma_v_shift, f->pix_fmt);417 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
498 FFV1Context *f = avctx->priv_data;504 FFV1Context *f = avctx->priv_data;
499 int ret;505 int ret;
500 506
507 f->pix_fmt = AV_PIX_FMT_NONE;
508 f->configured_pix_fmt = AV_PIX_FMT_NONE;
509
501 if ((ret = ff_ffv1_common_init(avctx, f)) < 0)510 if ((ret = ff_ffv1_common_init(avctx, f)) < 0)
502 return ret;511 return ret;
503 512
@@ -682,13 +691,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, · 178 unmodified lines
682 FFV1Context *f = avctx->priv_data;691 FFV1Context *f = avctx->priv_data;
683 int ret;692 int ret;
684 AVFrame *p;693 AVFrame *p;
694 const FFHWAccel *hwaccel = NULL;
685 695
686 /* This is copied onto the first slice's range coder context */696 /* This is copied onto the first slice's range coder context */
687 RangeCoder c;697 RangeCoder c;
688 698
689 ff_progress_frame_unref(&f->last_picture);699 ff_progress_frame_unref(&f->last_picture);
690 FFSWAP(ProgressFrame, f->picture, f->last_picture);700 av_refstruct_unref(&f->hwaccel_last_picture_private);
691 701
702 FFSWAP(ProgressFrame, f->picture, f->last_picture);
703 FFSWAP(void *, f->hwaccel_picture_private, f->hwaccel_last_picture_private);
692 704
693 f->avctx = avctx;705 f->avctx = avctx;
694 f->frame_damaged = 0;706 f->frame_damaged = 0;
@@ -704,11 +716,18 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, · 9 unmodified lines
704 if (avctx->skip_frame >= AVDISCARD_ALL)716 if (avctx->skip_frame >= AVDISCARD_ALL)
705 return avpkt->size;717 return avpkt->size;
706 718
719 if (avctx->hwaccel)
720 hwaccel = ffhwaccel(avctx->hwaccel);
721
707 ret = ff_progress_frame_get_buffer(avctx, &f->picture,722 ret = ff_progress_frame_get_buffer(avctx, &f->picture,
708 AV_GET_BUFFER_FLAG_REF);723 AV_GET_BUFFER_FLAG_REF);
709 if (ret < 0)724 if (ret < 0)
710 return ret;725 return ret;
711 726
727 ret = ff_hwaccel_frame_priv_alloc(avctx, &f->hwaccel_picture_private);
728 if (ret < 0)
729 return ret;
730
712 p = f->picture.f;731 p = f->picture.f;
713 732
714 p->pict_type = AV_PICTURE_TYPE_I; //FIXME I vs. P733 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
721 p->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;740 p->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
722 }741 }
723 742
743 /* Start */
744 if (hwaccel) {
745 ret = hwaccel->start_frame(avctx, avpkt->data, avpkt->size);
746 if (ret < 0)
747 return ret;
748 }
749
724 ff_thread_finish_setup(avctx);750 ff_thread_finish_setup(avctx);
725 751
726 ret = decode_slices(avctx, c, avpkt);752 /* Decode slices */
727 if (ret < 0)753 if (hwaccel) {
728 return ret;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 }
729 785
730 ff_progress_frame_report(&f->picture, INT_MAX);786 ff_progress_frame_report(&f->picture, INT_MAX);
731 787
732 ff_progress_frame_unref(&f->last_picture);788 ff_progress_frame_unref(&f->last_picture);
789 av_refstruct_unref(&f->hwaccel_last_picture_private);
733 if ((ret = av_frame_ref(rframe, f->picture.f)) < 0)790 if ((ret = av_frame_ref(rframe, f->picture.f)) < 0)
734 return ret;791 return ret;
735 792
@@ -758,6 +815,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) · 22 unmodified lines
758 fdst->ac = fsrc->ac;815 fdst->ac = fsrc->ac;
759 fdst->colorspace = fsrc->colorspace;816 fdst->colorspace = fsrc->colorspace;
760 fdst->pix_fmt = fsrc->pix_fmt;817 fdst->pix_fmt = fsrc->pix_fmt;
818 fdst->configured_pix_fmt = fsrc->configured_pix_fmt;
761 819
762 fdst->ec = fsrc->ec;820 fdst->ec = fsrc->ec;
763 fdst->intra = fsrc->intra;821 fdst->intra = fsrc->intra;
@@ -793,6 +851,8 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) · 29 unmodified lines
793 av_assert1(fdst->max_slice_count == fsrc->max_slice_count);851 av_assert1(fdst->max_slice_count == fsrc->max_slice_count);
794 852
795 ff_progress_frame_replace(&fdst->picture, &fsrc->picture);853 ff_progress_frame_replace(&fdst->picture, &fsrc->picture);
854 av_refstruct_replace(&fdst->hwaccel_picture_private,
855 fsrc->hwaccel_picture_private);
796 856
797 return 0;857 return 0;
798}858}
@@ -803,8 +863,10 @@ static av_cold int ffv1_decode_close(AVCodecContext *avctx) · 4 unmodified lines
803 FFV1Context *const s = avctx->priv_data;863 FFV1Context *const s = avctx->priv_data;
804 864
805 ff_progress_frame_unref(&s->picture);865 ff_progress_frame_unref(&s->picture);
866 av_refstruct_unref(&s->hwaccel_picture_private);
867
806 ff_progress_frame_unref(&s->last_picture);868 ff_progress_frame_unref(&s->last_picture);
807 av_freep(&avctx->stats_out);869 av_refstruct_unref(&s->hwaccel_last_picture_private);
808 870
809 ff_ffv1_close(s);871 ff_ffv1_close(s);
810 872
@@ -826,4 +888,7 @@ const FFCodec ff_ffv1_decoder = { · 15 unmodified lines
826 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |888 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
827 FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM |889 FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM |
828 FF_CODEC_CAP_USES_PROGRESSFRAMES,890 FF_CODEC_CAP_USES_PROGRESSFRAMES,
891 .hw_configs = (const AVCodecHWConfigInternal *const []) {
892 NULL
893 },
829};894};

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