Message ID | 20171124005134.5683-14-sw@jkqxz.net |
---|---|
State | New |
Headers | show |
On 2017/11/24 8:51, Mark Thompson wrote: > Also adds some extra fields to the main context structure that may > be needed by a hwaccel decoder. > --- > The YUVJ formats really mess with this. This patch hacks them out so that the hwaccel works, suggestions welcome on what to actually do about them. > > > libavcodec/mjpegdec.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++-- > libavcodec/mjpegdec.h | 11 ++++++++ > 2 files changed, 79 insertions(+), 2 deletions(-) > > diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c > index f01d44a169..846dec2f42 100644 > --- a/libavcodec/mjpegdec.c > +++ b/libavcodec/mjpegdec.c > @@ -36,6 +36,7 @@ > #include "avcodec.h" > #include "blockdsp.h" > #include "copy_block.h" > +#include "hwaccel.h" > #include "idctdsp.h" > #include "internal.h" > #include "jpegtables.h" > @@ -147,6 +148,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) > s->org_height = avctx->coded_height; > avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; > avctx->colorspace = AVCOL_SPC_BT470BG; > + s->hwaccel_pix_fmt = s->hwaccel_sw_pix_fmt = AV_PIX_FMT_NONE; > > if ((ret = build_basic_mjpeg_vlc(s)) < 0) > return ret; > @@ -279,6 +281,11 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) > code_max + 1, 0, 0)) < 0) > return ret; > } > + > + for (i = 0; i < 16; i++) > + s->raw_huffman_lengths[class][index][i] = bits_table[i + 1]; > + for (i = 0; i < 256; i++) > + s->raw_huffman_values[class][index][i] = val_table[i]; > } > return 0; > } > @@ -636,6 +643,26 @@ unk_pixfmt: > return AVERROR_BUG; > } > > + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ420P) > + s->avctx->pix_fmt = AV_PIX_FMT_YUV420P; > + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ422P) > + s->avctx->pix_fmt = AV_PIX_FMT_YUV422P; > + Maybe need to give a comments in the code for this workaround, not just in the commit message. > + if (s->avctx->pix_fmt == s->hwaccel_sw_pix_fmt) { > + s->avctx->pix_fmt = s->hwaccel_pix_fmt; > + } else { > + enum AVPixelFormat pix_fmts[] = { > + s->avctx->pix_fmt, > + AV_PIX_FMT_NONE, > + }; > + s->hwaccel_pix_fmt = ff_get_format(s->avctx, pix_fmts); > + if (s->hwaccel_pix_fmt < 0) > + return AVERROR(EINVAL); > + > + s->hwaccel_sw_pix_fmt = s->avctx->pix_fmt; > + s->avctx->pix_fmt = s->hwaccel_pix_fmt; > + } > + > if (s->avctx->skip_frame == AVDISCARD_ALL) { > s->picture_ptr->pict_type = AV_PICTURE_TYPE_I; > s->picture_ptr->key_frame = 1; > @@ -683,6 +710,19 @@ unk_pixfmt: > } > memset(s->coefs_finished, 0, sizeof(s->coefs_finished)); > } > + > + if (s->avctx->hwaccel) { > + s->hwaccel_picture_private = > + av_mallocz(s->avctx->hwaccel->frame_priv_data_size); > + if (!s->hwaccel_picture_private) > + return AVERROR(ENOMEM); > + > + ret = s->avctx->hwaccel->start_frame(s->avctx, s->raw_buffer, > + s->raw_buffer_size); > + if (ret < 0) > + return ret; > + } > + > return 0; > } > > @@ -1510,7 +1550,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, > } > } > > - av_assert0(s->picture_ptr->data[0]); > + //av_assert0(s->picture_ptr->data[0]); Remove the assert ? > /* XXX: verify len field validity */ > len = get_bits(&s->gb, 16); > nb_components = get_bits(&s->gb, 8); > @@ -1600,7 +1640,18 @@ next_field: > for (i = 0; i < nb_components; i++) > s->last_dc[i] = (4 << s->bits); > > - if (s->lossless) { > + if (s->avctx->hwaccel) { > + int bytes_to_start = get_bits_count(&s->gb) / 8; > + av_assert0(bytes_to_start >= 0 && > + s->raw_buffer_size >= bytes_to_start); > + > + ret = s->avctx->hwaccel->decode_slice(s->avctx, > + s->raw_buffer + bytes_to_start, > + s->raw_buffer_size - bytes_to_start); > + if (ret < 0) > + return ret; > + > + } else if (s->lossless) { > av_assert0(s->picture_ptr == s->picture); > if (CONFIG_JPEGLS_DECODER && s->ls) { > // for () { > @@ -2226,6 +2277,9 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, > goto fail; > } > > + s->raw_buffer = buf_ptr; > + s->raw_buffer_size = buf_end - buf_ptr; > + > s->start_code = start_code; > if (s->avctx->debug & FF_DEBUG_STARTCODE) > av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); > @@ -2349,6 +2403,13 @@ eoi_parser: > s->got_picture = 0; > goto the_end_no_picture; > } > + if (s->avctx->hwaccel) { > + ret = s->avctx->hwaccel->end_frame(s->avctx); > + if (ret < 0) > + return ret; > + > + av_freep(&s->hwaccel_picture_private); > + } > if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0) > return ret; > *got_frame = 1; > @@ -2673,6 +2734,8 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) > > reset_icc_profile(s); > > + av_freep(&s->hwaccel_picture_private); > + > return 0; > } > > @@ -2713,6 +2776,9 @@ AVCodec ff_mjpeg_decoder = { > .priv_class = &mjpegdec_class, > .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | > FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, > + .hw_configs = (const AVCodecHWConfigInternal*[]) { > + NULL > + }, > }; > #endif > #if CONFIG_THP_DECODER > diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h > index c84a40aa6e..50443937b4 100644 > --- a/libavcodec/mjpegdec.h > +++ b/libavcodec/mjpegdec.h > @@ -135,6 +135,17 @@ typedef struct MJpegDecodeContext { > int *iccdatalens; > int iccnum; > int iccread; > + > + // Raw stream data for hwaccel use. > + const uint8_t *raw_buffer; > + size_t raw_buffer_size; > + > + uint8_t raw_huffman_lengths[2][4][16]; > + uint8_t raw_huffman_values[2][4][256]; > + > + enum AVPixelFormat hwaccel_sw_pix_fmt; > + enum AVPixelFormat hwaccel_pix_fmt; > + void *hwaccel_picture_private; > } MJpegDecodeContext; > > int ff_mjpeg_decode_init(AVCodecContext *avctx);
2017-11-24 1:51 GMT+01:00 Mark Thompson <sw@jkqxz.net>: > Also adds some extra fields to the main context structure > that may be needed by a hwaccel decoder. > --- > The YUVJ formats really mess with this. This patch hacks > them out so that the hwaccel works, suggestions welcome > on what to actually do about them. > + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ420P) > + s->avctx->pix_fmt = AV_PIX_FMT_YUV420P; > + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ422P) > + s->avctx->pix_fmt = AV_PIX_FMT_YUV422P; The hardware decoders output mpeg-scaled frames? Carl Eugen
On 24/11/17 07:25, Jun Zhao wrote: > > > On 2017/11/24 8:51, Mark Thompson wrote: >> Also adds some extra fields to the main context structure that may >> be needed by a hwaccel decoder. >> --- >> The YUVJ formats really mess with this. This patch hacks them out so that the hwaccel works, suggestions welcome on what to actually do about them. >> >> >> libavcodec/mjpegdec.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++-- >> libavcodec/mjpegdec.h | 11 ++++++++ >> 2 files changed, 79 insertions(+), 2 deletions(-) >> >> diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c >> index f01d44a169..846dec2f42 100644 >> --- a/libavcodec/mjpegdec.c >> +++ b/libavcodec/mjpegdec.c >> @@ -36,6 +36,7 @@ >> #include "avcodec.h" >> #include "blockdsp.h" >> #include "copy_block.h" >> +#include "hwaccel.h" >> #include "idctdsp.h" >> #include "internal.h" >> #include "jpegtables.h" >> @@ -147,6 +148,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) >> s->org_height = avctx->coded_height; >> avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; >> avctx->colorspace = AVCOL_SPC_BT470BG; >> + s->hwaccel_pix_fmt = s->hwaccel_sw_pix_fmt = AV_PIX_FMT_NONE; >> >> if ((ret = build_basic_mjpeg_vlc(s)) < 0) >> return ret; >> @@ -279,6 +281,11 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) >> code_max + 1, 0, 0)) < 0) >> return ret; >> } >> + >> + for (i = 0; i < 16; i++) >> + s->raw_huffman_lengths[class][index][i] = bits_table[i + 1]; >> + for (i = 0; i < 256; i++) >> + s->raw_huffman_values[class][index][i] = val_table[i]; >> } >> return 0; >> } >> @@ -636,6 +643,26 @@ unk_pixfmt: >> return AVERROR_BUG; >> } >> >> + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ420P) >> + s->avctx->pix_fmt = AV_PIX_FMT_YUV420P; >> + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ422P) >> + s->avctx->pix_fmt = AV_PIX_FMT_YUV422P; >> + > Maybe need to give a comments in the code for this workaround, not just > in the commit message. This hack is not intended to be applied. The note above after the commit message is inviting comment on what to actually do. - Mark
On 24/11/17 11:17, Carl Eugen Hoyos wrote: > 2017-11-24 1:51 GMT+01:00 Mark Thompson <sw@jkqxz.net>: >> Also adds some extra fields to the main context structure >> that may be needed by a hwaccel decoder. >> --- >> The YUVJ formats really mess with this. This patch hacks >> them out so that the hwaccel works, suggestions welcome >> on what to actually do about them. > >> + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ420P) >> + s->avctx->pix_fmt = AV_PIX_FMT_YUV420P; >> + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ422P) >> + s->avctx->pix_fmt = AV_PIX_FMT_YUV422P; > > The hardware decoders output mpeg-scaled frames? I think some do, though I haven't seen it myself. Those that don't (like VAAPI) will use the color_range metadata - I think don't it is sensible to add lots of extra paths to support YUVJ formats in AVHWFramesContext.sw_format. Thanks, - Mark
On Fri, 24 Nov 2017 00:51:31 +0000 Mark Thompson <sw@jkqxz.net> wrote: > Also adds some extra fields to the main context structure that may > be needed by a hwaccel decoder. > --- > The YUVJ formats really mess with this. This patch hacks them out so > that the hwaccel works, suggestions welcome on what to actually do > about them. > > > libavcodec/mjpegdec.c | 70 > +++++++++++++++++++++++++++++++++++++++++++++++++-- > libavcodec/mjpegdec.h | 11 ++++++++ 2 files changed, 79 > insertions(+), 2 deletions(-) > > diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c > index f01d44a169..846dec2f42 100644 > --- a/libavcodec/mjpegdec.c > +++ b/libavcodec/mjpegdec.c > @@ -36,6 +36,7 @@ > #include "avcodec.h" > #include "blockdsp.h" > #include "copy_block.h" > +#include "hwaccel.h" > #include "idctdsp.h" > #include "internal.h" > #include "jpegtables.h" > @@ -147,6 +148,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext > *avctx) s->org_height = avctx->coded_height; > avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; > avctx->colorspace = AVCOL_SPC_BT470BG; > + s->hwaccel_pix_fmt = s->hwaccel_sw_pix_fmt = AV_PIX_FMT_NONE; > > if ((ret = build_basic_mjpeg_vlc(s)) < 0) > return ret; > @@ -279,6 +281,11 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) > code_max + 1, 0, 0)) < 0) > return ret; > } > + > + for (i = 0; i < 16; i++) > + s->raw_huffman_lengths[class][index][i] = bits_table[i + > 1]; > + for (i = 0; i < 256; i++) > + s->raw_huffman_values[class][index][i] = val_table[i]; > } > return 0; > } > @@ -636,6 +643,26 @@ unk_pixfmt: > return AVERROR_BUG; > } > > + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ420P) > + s->avctx->pix_fmt = AV_PIX_FMT_YUV420P; > + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ422P) > + s->avctx->pix_fmt = AV_PIX_FMT_YUV422P; > + > + if (s->avctx->pix_fmt == s->hwaccel_sw_pix_fmt) { > + s->avctx->pix_fmt = s->hwaccel_pix_fmt; > + } else { > + enum AVPixelFormat pix_fmts[] = { > + s->avctx->pix_fmt, > + AV_PIX_FMT_NONE, > + }; > + s->hwaccel_pix_fmt = ff_get_format(s->avctx, pix_fmts); > + if (s->hwaccel_pix_fmt < 0) > + return AVERROR(EINVAL); > + > + s->hwaccel_sw_pix_fmt = s->avctx->pix_fmt; > + s->avctx->pix_fmt = s->hwaccel_pix_fmt; > + } > + If I'm reading this right, your hack here means that the pix_fmt is changed for all usage, whether hwaccel is used or not, right? Presumably you just want to do this if an hwaccel ends up being used; so at least you want to restore the original fmt in the non-hwaccel case? > if (s->avctx->skip_frame == AVDISCARD_ALL) { > s->picture_ptr->pict_type = AV_PICTURE_TYPE_I; > s->picture_ptr->key_frame = 1; > @@ -683,6 +710,19 @@ unk_pixfmt: > } > memset(s->coefs_finished, 0, sizeof(s->coefs_finished)); > } > + > + if (s->avctx->hwaccel) { > + s->hwaccel_picture_private = > + av_mallocz(s->avctx->hwaccel->frame_priv_data_size); > + if (!s->hwaccel_picture_private) > + return AVERROR(ENOMEM); > + > + ret = s->avctx->hwaccel->start_frame(s->avctx, s->raw_buffer, > + s->raw_buffer_size); nvdec needs the entire avpkt->data to be able to decode successfully. > + if (ret < 0) > + return ret; > + } > + > return 0; > } > > @@ -1510,7 +1550,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, > const uint8_t *mb_bitmask, } > } > > - av_assert0(s->picture_ptr->data[0]); > + //av_assert0(s->picture_ptr->data[0]); > /* XXX: verify len field validity */ > len = get_bits(&s->gb, 16); > nb_components = get_bits(&s->gb, 8); > @@ -1600,7 +1640,18 @@ next_field: > for (i = 0; i < nb_components; i++) > s->last_dc[i] = (4 << s->bits); > > - if (s->lossless) { > + if (s->avctx->hwaccel) { > + int bytes_to_start = get_bits_count(&s->gb) / 8; > + av_assert0(bytes_to_start >= 0 && > + s->raw_buffer_size >= bytes_to_start); > + > + ret = s->avctx->hwaccel->decode_slice(s->avctx, > + s->raw_buffer + > bytes_to_start, > + s->raw_buffer_size - > bytes_to_start); > + if (ret < 0) > + return ret; > + > + } else if (s->lossless) { > av_assert0(s->picture_ptr == s->picture); > if (CONFIG_JPEGLS_DECODER && s->ls) { > // for () { > @@ -2226,6 +2277,9 @@ int ff_mjpeg_decode_frame(AVCodecContext > *avctx, void *data, int *got_frame, goto fail; > } > > + s->raw_buffer = buf_ptr; > + s->raw_buffer_size = buf_end - buf_ptr; > + > s->start_code = start_code; > if (s->avctx->debug & FF_DEBUG_STARTCODE) > av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", > start_code); @@ -2349,6 +2403,13 @@ eoi_parser: > s->got_picture = 0; > goto the_end_no_picture; > } > + if (s->avctx->hwaccel) { > + ret = s->avctx->hwaccel->end_frame(s->avctx); > + if (ret < 0) > + return ret; > + > + av_freep(&s->hwaccel_picture_private); > + } > if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0) > return ret; > *got_frame = 1; > @@ -2673,6 +2734,8 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext > *avctx) > reset_icc_profile(s); > > + av_freep(&s->hwaccel_picture_private); > + > return 0; > } > > @@ -2713,6 +2776,9 @@ AVCodec ff_mjpeg_decoder = { > .priv_class = &mjpegdec_class, > .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | > FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, > + .hw_configs = (const AVCodecHWConfigInternal*[]) { > + NULL > + }, > }; > #endif > #if CONFIG_THP_DECODER > diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h > index c84a40aa6e..50443937b4 100644 > --- a/libavcodec/mjpegdec.h > +++ b/libavcodec/mjpegdec.h > @@ -135,6 +135,17 @@ typedef struct MJpegDecodeContext { > int *iccdatalens; > int iccnum; > int iccread; > + > + // Raw stream data for hwaccel use. > + const uint8_t *raw_buffer; > + size_t raw_buffer_size; > + > + uint8_t raw_huffman_lengths[2][4][16]; > + uint8_t raw_huffman_values[2][4][256]; > + > + enum AVPixelFormat hwaccel_sw_pix_fmt; > + enum AVPixelFormat hwaccel_pix_fmt; > + void *hwaccel_picture_private; > } MJpegDecodeContext; > > int ff_mjpeg_decode_init(AVCodecContext *avctx); --phil
On Fri, Nov 24, 2017 at 12:51:31AM +0000, Mark Thompson wrote: > Also adds some extra fields to the main context structure that may > be needed by a hwaccel decoder. > --- > The YUVJ formats really mess with this. This patch hacks them out so that the hwaccel works, suggestions welcome on what to actually do about them. Can you explain what the problem is exactly ? [...]
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index f01d44a169..846dec2f42 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -36,6 +36,7 @@ #include "avcodec.h" #include "blockdsp.h" #include "copy_block.h" +#include "hwaccel.h" #include "idctdsp.h" #include "internal.h" #include "jpegtables.h" @@ -147,6 +148,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) s->org_height = avctx->coded_height; avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; avctx->colorspace = AVCOL_SPC_BT470BG; + s->hwaccel_pix_fmt = s->hwaccel_sw_pix_fmt = AV_PIX_FMT_NONE; if ((ret = build_basic_mjpeg_vlc(s)) < 0) return ret; @@ -279,6 +281,11 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) code_max + 1, 0, 0)) < 0) return ret; } + + for (i = 0; i < 16; i++) + s->raw_huffman_lengths[class][index][i] = bits_table[i + 1]; + for (i = 0; i < 256; i++) + s->raw_huffman_values[class][index][i] = val_table[i]; } return 0; } @@ -636,6 +643,26 @@ unk_pixfmt: return AVERROR_BUG; } + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ420P) + s->avctx->pix_fmt = AV_PIX_FMT_YUV420P; + if (s->avctx->pix_fmt == AV_PIX_FMT_YUVJ422P) + s->avctx->pix_fmt = AV_PIX_FMT_YUV422P; + + if (s->avctx->pix_fmt == s->hwaccel_sw_pix_fmt) { + s->avctx->pix_fmt = s->hwaccel_pix_fmt; + } else { + enum AVPixelFormat pix_fmts[] = { + s->avctx->pix_fmt, + AV_PIX_FMT_NONE, + }; + s->hwaccel_pix_fmt = ff_get_format(s->avctx, pix_fmts); + if (s->hwaccel_pix_fmt < 0) + return AVERROR(EINVAL); + + s->hwaccel_sw_pix_fmt = s->avctx->pix_fmt; + s->avctx->pix_fmt = s->hwaccel_pix_fmt; + } + if (s->avctx->skip_frame == AVDISCARD_ALL) { s->picture_ptr->pict_type = AV_PICTURE_TYPE_I; s->picture_ptr->key_frame = 1; @@ -683,6 +710,19 @@ unk_pixfmt: } memset(s->coefs_finished, 0, sizeof(s->coefs_finished)); } + + if (s->avctx->hwaccel) { + s->hwaccel_picture_private = + av_mallocz(s->avctx->hwaccel->frame_priv_data_size); + if (!s->hwaccel_picture_private) + return AVERROR(ENOMEM); + + ret = s->avctx->hwaccel->start_frame(s->avctx, s->raw_buffer, + s->raw_buffer_size); + if (ret < 0) + return ret; + } + return 0; } @@ -1510,7 +1550,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, } } - av_assert0(s->picture_ptr->data[0]); + //av_assert0(s->picture_ptr->data[0]); /* XXX: verify len field validity */ len = get_bits(&s->gb, 16); nb_components = get_bits(&s->gb, 8); @@ -1600,7 +1640,18 @@ next_field: for (i = 0; i < nb_components; i++) s->last_dc[i] = (4 << s->bits); - if (s->lossless) { + if (s->avctx->hwaccel) { + int bytes_to_start = get_bits_count(&s->gb) / 8; + av_assert0(bytes_to_start >= 0 && + s->raw_buffer_size >= bytes_to_start); + + ret = s->avctx->hwaccel->decode_slice(s->avctx, + s->raw_buffer + bytes_to_start, + s->raw_buffer_size - bytes_to_start); + if (ret < 0) + return ret; + + } else if (s->lossless) { av_assert0(s->picture_ptr == s->picture); if (CONFIG_JPEGLS_DECODER && s->ls) { // for () { @@ -2226,6 +2277,9 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, goto fail; } + s->raw_buffer = buf_ptr; + s->raw_buffer_size = buf_end - buf_ptr; + s->start_code = start_code; if (s->avctx->debug & FF_DEBUG_STARTCODE) av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); @@ -2349,6 +2403,13 @@ eoi_parser: s->got_picture = 0; goto the_end_no_picture; } + if (s->avctx->hwaccel) { + ret = s->avctx->hwaccel->end_frame(s->avctx); + if (ret < 0) + return ret; + + av_freep(&s->hwaccel_picture_private); + } if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0) return ret; *got_frame = 1; @@ -2673,6 +2734,8 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) reset_icc_profile(s); + av_freep(&s->hwaccel_picture_private); + return 0; } @@ -2713,6 +2776,9 @@ AVCodec ff_mjpeg_decoder = { .priv_class = &mjpegdec_class, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .hw_configs = (const AVCodecHWConfigInternal*[]) { + NULL + }, }; #endif #if CONFIG_THP_DECODER diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index c84a40aa6e..50443937b4 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -135,6 +135,17 @@ typedef struct MJpegDecodeContext { int *iccdatalens; int iccnum; int iccread; + + // Raw stream data for hwaccel use. + const uint8_t *raw_buffer; + size_t raw_buffer_size; + + uint8_t raw_huffman_lengths[2][4][16]; + uint8_t raw_huffman_values[2][4][256]; + + enum AVPixelFormat hwaccel_sw_pix_fmt; + enum AVPixelFormat hwaccel_pix_fmt; + void *hwaccel_picture_private; } MJpegDecodeContext; int ff_mjpeg_decode_init(AVCodecContext *avctx);