Re: [FFmpeg-devel] [PATCH 14/17] mjpegdec: Add hwaccel hooks
On Fri, Nov 24, 2017 at 12:51:31AM +, 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 ? [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Rewriting code that is poorly written but fully understood is good. Rewriting code that one doesnt understand is a sign that one is less smart then the original author, trying to rewrite it will not make it better. signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 14/17] mjpegdec: Add hwaccel hooks
On Fri, 24 Nov 2017 00:51:31 + 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; > + > +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_DEBU
Re: [FFmpeg-devel] [PATCH 14/17] mjpegdec: Add hwaccel hooks
On 24/11/17 11:17, Carl Eugen Hoyos wrote: > 2017-11-24 1:51 GMT+01:00 Mark Thompson : >> 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 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 14/17] mjpegdec: Add hwaccel hooks
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 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 14/17] mjpegdec: Add hwaccel hooks
2017-11-24 1:51 GMT+01:00 Mark Thompson : > 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 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 14/17] mjpegdec: Add hwaccel hooks
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; >
[FFmpeg-devel] [PATCH 14/17] mjpegdec: Add hwaccel hooks
--- This works nicely on the Intel driver for YUV 4:2:2 (like you usually get from UVC webcams) with ffmpeg via hw_device_ctx, but YUV 4:2:0 requires trickier surface setup because it doesn't work on normal NV12 surfaces. It can be used via hw_frames_ctx by making the right surfaces externally, but doesn't work by hw_device_ctx without additional hackery. I will look into this further - it should be possible to propagate the layout requirements so that hw_device_ctx works for 4:2:0 as well. configure | 2 + libavcodec/Makefile | 1 + libavcodec/hwaccels.h | 1 + libavcodec/mjpegdec.c | 6 ++ libavcodec/vaapi_decode.c | 2 + libavcodec/vaapi_mjpeg.c | 160 ++ 6 files changed, 172 insertions(+) create mode 100644 libavcodec/vaapi_mjpeg.c diff --git a/configure b/configure index b95a91cbf0..0a103b3f67 100755 --- a/configure +++ b/configure @@ -2699,6 +2699,8 @@ hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" hevc_vdpau_hwaccel_select="hevc_decoder" hevc_videotoolbox_hwaccel_deps="videotoolbox" hevc_videotoolbox_hwaccel_select="hevc_decoder" +mjpeg_vaapi_hwaccel_deps="vaapi" +mjpeg_vaapi_hwaccel_select="mjpeg_decoder" mpeg_xvmc_hwaccel_deps="xvmc" mpeg_xvmc_hwaccel_select="mpeg2video_decoder" mpeg1_nvdec_hwaccel_deps="nvdec" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 0ebd2820eb..640edfb590 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -849,6 +849,7 @@ OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o +OBJS-$(CONFIG_MJPEG_VAAPI_HWACCEL)+= vaapi_mjpeg.o OBJS-$(CONFIG_MPEG1_NVDEC_HWACCEL)+= nvdec_mpeg12.o OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL)+= vdpau_mpeg12.o OBJS-$(CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h index afe7289341..cefd2b15be 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -37,6 +37,7 @@ extern const AVHWAccel ff_hevc_nvdec_hwaccel; extern const AVHWAccel ff_hevc_vaapi_hwaccel; extern const AVHWAccel ff_hevc_vdpau_hwaccel; extern const AVHWAccel ff_hevc_videotoolbox_hwaccel; +extern const AVHWAccel ff_mjpeg_vaapi_hwaccel; extern const AVHWAccel ff_mpeg1_nvdec_hwaccel; extern const AVHWAccel ff_mpeg1_vdpau_hwaccel; extern const AVHWAccel ff_mpeg1_videotoolbox_hwaccel; diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 846dec2f42..2b79cd21bb 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -652,6 +652,9 @@ unk_pixfmt: s->avctx->pix_fmt = s->hwaccel_pix_fmt; } else { enum AVPixelFormat pix_fmts[] = { +#if CONFIG_MJPEG_VAAPI_HWACCEL +AV_PIX_FMT_VAAPI, +#endif s->avctx->pix_fmt, AV_PIX_FMT_NONE, }; @@ -2777,6 +2780,9 @@ AVCodec ff_mjpeg_decoder = { .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .hw_configs = (const AVCodecHWConfigInternal*[]) { +#if CONFIG_MJPEG_VAAPI_HWACCEL +HWACCEL_VAAPI(mjpeg), +#endif NULL }, }; diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 572b3a40ac..b30d397113 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -253,6 +253,8 @@ static const struct { MAP(HEVC,HEVC_MAIN, HEVCMain), MAP(HEVC,HEVC_MAIN_10,HEVCMain10 ), #endif +MAP(MJPEG, MJPEG_HUFFMAN_BASELINE_DCT, + JPEGBaseline), MAP(WMV3,VC1_SIMPLE, VC1Simple ), MAP(WMV3,VC1_MAIN,VC1Main ), MAP(WMV3,VC1_COMPLEX, VC1Advanced ), diff --git a/libavcodec/vaapi_mjpeg.c b/libavcodec/vaapi_mjpeg.c new file mode 100644 index 00..0277cb04f0 --- /dev/null +++ b/libavcodec/vaapi_mjpeg.c @@ -0,0 +1,160 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "hwaccel.h" +#include "vaapi_decode.h" +#include "mjpegdec.
[FFmpeg-devel] [PATCH 14/17] mjpegdec: Add hwaccel hooks
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(AVCodecC