Re: [FFmpeg-devel] [PATCH 14/17] mjpegdec: Add hwaccel hooks

2017-11-24 Thread Michael Niedermayer
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

2017-11-24 Thread Philip Langdale
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

2017-11-24 Thread Mark Thompson
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

2017-11-24 Thread Mark Thompson
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 Thread Carl Eugen Hoyos
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

2017-11-23 Thread Jun Zhao


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

2017-11-23 Thread Mark Thompson
---
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

2017-11-23 Thread 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.


 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