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 (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); -- 2.11.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel