Re: [libav-devel] [PATCH] libavcodec/mjpeg_qsv: Add the QSV MJPEG encoder

2017-07-18 Thread Huang, Zhengxu



On 2017/7/17 17:04, Luca Barbato wrote:

Thank you for your contribution, here some comments :)

On 7/17/17 10:40 AM, Huang, Zhengxu wrote:

+#include 

Is the header necessary?

the "MFX_CODEC_JPEG" needs this.



+++ b/libavcodec/qsvenc.c
@@ -435,6 +435,15 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
  q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
  }
  
+if (AV_CODEC_ID_MJPEG == avctx->codec_id) {

+av_log(avctx, AV_LOG_DEBUG, " Init codec is QSV JPEG encode \n");
+q->param.mfx.Interleaved  = 1;
+q->param.mfx.Quality  = q->quality;;
+q->param.mfx.RestartInterval  = 0;
+
+return 0;
+}
+

This should be moved in the specific encoder init function


  ret = select_rc_mode(avctx, q);
  if (ret < 0)
  return ret;
@@ -623,6 +632,11 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, 
QSVEncContext *q)
  
  q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
  
+// for qsv mjpeg the return value maybe 0 so alloc the buffer

+if (0 == q->packet_size) {
+q->packet_size = q->param.mfx.FrameInfo.Height * 
q->param.mfx.FrameInfo.Width * 4;
+}
+

This should be moved there as well.
the qsv mjpeg indeed should be separated from the H264/MPEG2/HEVC 
according to the "mfxInfoMFX" struct's definition in the MSDK.

And I do this in the patch V2.




  if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
  av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
  return AVERROR_UNKNOWN;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index a639904..1384068 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -132,6 +132,9 @@ typedef struct QSVEncContext {
  int int_ref_qp_delta;
  int recovery_point_sei;
  
+// options for MJPEG

+unsigned short quality;
+

There is a global quality option that probably could be reused.

yes, the global_quality should be reused.



  char *load_plugins;
  } QSVEncContext;
  
diff --git a/libavcodec/qsvenc_jpeg.c b/libavcodec/qsvenc_jpeg.c

new file mode 100644
index 000..fc9226d
--- /dev/null
+++ b/libavcodec/qsvenc_jpeg.c
@@ -0,0 +1,93 @@
+/*
+ * Intel MediaSDK QSV based MJPEG encoder
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include 
+#include 
+
+#include 
+
+#include "libavutil/common.h"
+#include "libavutil/opt.h"
+
+#include "avcodec.h"
+#include "internal.h"
+#include "h264.h"
+#include "qsv.h"
+#include "qsv_internal.h"
+#include "qsvenc.h"
+
+typedef struct QSVMJPEGEncContext {
+AVClass *class;
+QSVEncContext qsv;
+} QSVMJPEGEncContext;
+
+static av_cold int qsv_enc_init(AVCodecContext *avctx)
+{
+QSVMJPEGEncContext *q = avctx->priv_data;
+
+return ff_qsv_enc_init(avctx, &q->qsv);
+}
+
+static int qsv_enc_frame(AVCodecContext *avctx, AVPacket *pkt,
+ const AVFrame *frame, int *got_packet)
+{
+QSVMJPEGEncContext *q = avctx->priv_data;
+
+return ff_qsv_encode(avctx, &q->qsv, pkt, frame, got_packet);
+}
+
+static av_cold int qsv_enc_close(AVCodecContext *avctx)
+{
+QSVMJPEGEncContext *q = avctx->priv_data;
+
+return ff_qsv_enc_close(avctx, &q->qsv);
+}
+
+#define OFFSET(x) offsetof(QSVMJPEGEncContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+{ "quality", "Specifies the image quality", OFFSET(qsv.quality), 
AV_OPT_TYPE_INT, { .i64 = 90 }, 1, 100, VE },
+
+{ NULL },
+};
+
+static const AVClass class = {
+.class_name = "mjpeg_qsv encoder",
+.item_name  = av_default_item_name,
+.option = options,
+.version= LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_mjpeg_qsv_encoder = {
+.name   = "mjpeg_qsv",
+.long_name  = NULL_IF_CONFIG_SMALL("MJPEG (Intel Quick Sync Video 
acceleration)"),
+.priv_data_size = sizeof(QSVMJPEGEncContext),
+.type   = AVMEDIA_TYPE_VIDEO,
+.id = AV_CODEC_ID_MJPEG,
+.init   = qsv_enc_init,
+.encode2= qsv_enc_frame,
+.close  = qsv_enc_close,
+.capabilities   = AV_CODEC_CAP_DELAY,
+.pix_fmts   = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV

Re: [libav-devel] [PATCH] libavcodec/mjpeg_qsv: Add the QSV MJPEG encoder

2017-07-18 Thread Huang, Zhengxu

On 2017/7/17 18:13, Diego Biurrun wrote:

On Mon, Jul 17, 2017 at 04:40:38PM +0800, Huang, Zhengxu wrote:

 From 45be66259e8fb99b05796748ead308f0fc73c68c Mon Sep 17 00:00:00 2001
From: "Huang, Zhengxu" 
Date: Tue, 18 Jul 2017 01:13:24 +0800
Subject: [PATCH] libavcodec/mjpeg_qsv: Add the QSV MJPEG encoder

usage:
-hwaccel qsv -c:v h264_qsv -i in -c:v mjpeg_qsv -quality 80 -f mjpeg out

Signed-off-by: ChaoX A Liu 
Signed-off-by: Huang, Zhengxu 
Signed-off-by: Andrew, Zhang 

Looks like first name and last name are reversed here.


  configure|  2 ++
  libavcodec/Makefile  |  1 +
  libavcodec/allcodecs.c   |  1 +
  libavcodec/qsv.c |  3 ++
  libavcodec/qsvenc.c  | 14 
  libavcodec/qsvenc.h  |  3 ++
  libavcodec/qsvenc_jpeg.c | 93 
  7 files changed, 117 insertions(+)
  create mode 100644 libavcodec/qsvenc_jpeg.c

Please add a changelog entry.


--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -272,6 +272,7 @@ OBJS-$(CONFIG_H264_NVENC_ENCODER)  += nvenc_h264.o
  OBJS-$(CONFIG_H264_OMX_ENCODER)+= omx.o
  OBJS-$(CONFIG_H264_QSV_DECODER)+= qsvdec_h2645.o
  OBJS-$(CONFIG_H264_QSV_ENCODER)+= qsvenc_h264.o
+OBJS-$(CONFIG_MJPEG_QSV_ENCODER)   += qsvenc_jpeg.o
  OBJS-$(CONFIG_H264_VAAPI_ENCODER)  += vaapi_encode_h264.o 
vaapi_encode_h26x.o
  OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
  OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o

This list was previously in alphabetic order.


--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -435,6 +435,15 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
  
+if (AV_CODEC_ID_MJPEG == avctx->codec_id) {

We usually reverse the order of comparison.


+av_log(avctx, AV_LOG_DEBUG, " Init codec is QSV JPEG encode \n");

This log message feels superfluous even in debug mode.


@@ -623,6 +632,11 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, 
QSVEncContext *q)
  
  q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
  
+// for qsv mjpeg the return value maybe 0 so alloc the buffer

+if (0 == q->packet_size) {
+q->packet_size = q->param.mfx.FrameInfo.Height * 
q->param.mfx.FrameInfo.Width * 4;
+}

Same comment about comparison order and please drop the {}.


--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -132,6 +132,9 @@ typedef struct QSVEncContext {
  
+// options for MJPEG

+unsigned short quality;

short looks like an odd type to use here, why?


Thanks for your comments and I will modify the patch according to the 
suggestion.

For the "quality"  I will reuse the "global_quality" option.


Diego
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Re: [libav-devel] [PATCH] libavcodec/mjpeg_qsv: Add the QSV MJPEG encoder

2017-07-17 Thread Diego Biurrun
On Mon, Jul 17, 2017 at 04:40:38PM +0800, Huang, Zhengxu wrote:
> 

> From 45be66259e8fb99b05796748ead308f0fc73c68c Mon Sep 17 00:00:00 2001
> From: "Huang, Zhengxu" 
> Date: Tue, 18 Jul 2017 01:13:24 +0800
> Subject: [PATCH] libavcodec/mjpeg_qsv: Add the QSV MJPEG encoder
> 
> usage:
> -hwaccel qsv -c:v h264_qsv -i in -c:v mjpeg_qsv -quality 80 -f mjpeg out
> 
> Signed-off-by: ChaoX A Liu 
> Signed-off-by: Huang, Zhengxu 
> Signed-off-by: Andrew, Zhang 

Looks like first name and last name are reversed here.

>  configure|  2 ++
>  libavcodec/Makefile  |  1 +
>  libavcodec/allcodecs.c   |  1 +
>  libavcodec/qsv.c |  3 ++
>  libavcodec/qsvenc.c  | 14 
>  libavcodec/qsvenc.h  |  3 ++
>  libavcodec/qsvenc_jpeg.c | 93 
> 
>  7 files changed, 117 insertions(+)
>  create mode 100644 libavcodec/qsvenc_jpeg.c

Please add a changelog entry.

> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -272,6 +272,7 @@ OBJS-$(CONFIG_H264_NVENC_ENCODER)  += nvenc_h264.o
>  OBJS-$(CONFIG_H264_OMX_ENCODER)+= omx.o
>  OBJS-$(CONFIG_H264_QSV_DECODER)+= qsvdec_h2645.o
>  OBJS-$(CONFIG_H264_QSV_ENCODER)+= qsvenc_h264.o
> +OBJS-$(CONFIG_MJPEG_QSV_ENCODER)   += qsvenc_jpeg.o
>  OBJS-$(CONFIG_H264_VAAPI_ENCODER)  += vaapi_encode_h264.o 
> vaapi_encode_h26x.o
>  OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
>  OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o

This list was previously in alphabetic order.

> --- a/libavcodec/qsvenc.c
> +++ b/libavcodec/qsvenc.c
> @@ -435,6 +435,15 @@ static int init_video_param(AVCodecContext *avctx, 
> QSVEncContext *q)
>  
> +if (AV_CODEC_ID_MJPEG == avctx->codec_id) {

We usually reverse the order of comparison.

> +av_log(avctx, AV_LOG_DEBUG, " Init codec is QSV JPEG encode \n");

This log message feels superfluous even in debug mode.

> @@ -623,6 +632,11 @@ static int qsv_retrieve_enc_params(AVCodecContext 
> *avctx, QSVEncContext *q)
>  
>  q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
>  
> +// for qsv mjpeg the return value maybe 0 so alloc the buffer
> +if (0 == q->packet_size) {
> +q->packet_size = q->param.mfx.FrameInfo.Height * 
> q->param.mfx.FrameInfo.Width * 4;
> +}

Same comment about comparison order and please drop the {}.

> --- a/libavcodec/qsvenc.h
> +++ b/libavcodec/qsvenc.h
> @@ -132,6 +132,9 @@ typedef struct QSVEncContext {
>  
> +// options for MJPEG
> +unsigned short quality;

short looks like an odd type to use here, why?

Diego
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Re: [libav-devel] [PATCH] libavcodec/mjpeg_qsv: Add the QSV MJPEG encoder

2017-07-17 Thread Luca Barbato
Thank you for your contribution, here some comments :)

On 7/17/17 10:40 AM, Huang, Zhengxu wrote:
> +#include 

Is the header necessary?

> +++ b/libavcodec/qsvenc.c
> @@ -435,6 +435,15 @@ static int init_video_param(AVCodecContext *avctx, 
> QSVEncContext *q)
>  q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
>  }
>  
> +if (AV_CODEC_ID_MJPEG == avctx->codec_id) {
> +av_log(avctx, AV_LOG_DEBUG, " Init codec is QSV JPEG encode \n");
> +q->param.mfx.Interleaved  = 1;
> +q->param.mfx.Quality  = q->quality;;
> +q->param.mfx.RestartInterval  = 0;
> +
> +return 0;
> +}
> +

This should be moved in the specific encoder init function

>  ret = select_rc_mode(avctx, q);
>  if (ret < 0)
>  return ret;
> @@ -623,6 +632,11 @@ static int qsv_retrieve_enc_params(AVCodecContext 
> *avctx, QSVEncContext *q)
>  
>  q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
>  
> +// for qsv mjpeg the return value maybe 0 so alloc the buffer
> +if (0 == q->packet_size) {
> +q->packet_size = q->param.mfx.FrameInfo.Height * 
> q->param.mfx.FrameInfo.Width * 4;
> +}
> +

This should be moved there as well.

>  if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
>  av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
>  return AVERROR_UNKNOWN;
> diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
> index a639904..1384068 100644
> --- a/libavcodec/qsvenc.h
> +++ b/libavcodec/qsvenc.h
> @@ -132,6 +132,9 @@ typedef struct QSVEncContext {
>  int int_ref_qp_delta;
>  int recovery_point_sei;
>  
> +// options for MJPEG
> +unsigned short quality;
> +

There is a global quality option that probably could be reused.

>  char *load_plugins;
>  } QSVEncContext;
>  
> diff --git a/libavcodec/qsvenc_jpeg.c b/libavcodec/qsvenc_jpeg.c
> new file mode 100644
> index 000..fc9226d
> --- /dev/null
> +++ b/libavcodec/qsvenc_jpeg.c
> @@ -0,0 +1,93 @@
> +/*
> + * Intel MediaSDK QSV based MJPEG encoder
> + *
> + * This file is part of Libav.
> + *
> + * Libav 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.
> + *
> + * Libav 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 Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +
> +#include 
> +#include 
> +
> +#include 
> +
> +#include "libavutil/common.h"
> +#include "libavutil/opt.h"
> +
> +#include "avcodec.h"
> +#include "internal.h"
> +#include "h264.h"
> +#include "qsv.h"
> +#include "qsv_internal.h"
> +#include "qsvenc.h"
> +
> +typedef struct QSVMJPEGEncContext {
> +AVClass *class;
> +QSVEncContext qsv;
> +} QSVMJPEGEncContext;
> +
> +static av_cold int qsv_enc_init(AVCodecContext *avctx)
> +{
> +QSVMJPEGEncContext *q = avctx->priv_data;
> +
> +return ff_qsv_enc_init(avctx, &q->qsv);
> +}
> +
> +static int qsv_enc_frame(AVCodecContext *avctx, AVPacket *pkt,
> + const AVFrame *frame, int *got_packet)
> +{
> +QSVMJPEGEncContext *q = avctx->priv_data;
> +
> +return ff_qsv_encode(avctx, &q->qsv, pkt, frame, got_packet);
> +}
> +
> +static av_cold int qsv_enc_close(AVCodecContext *avctx)
> +{
> +QSVMJPEGEncContext *q = avctx->priv_data;
> +
> +return ff_qsv_enc_close(avctx, &q->qsv);
> +}
> +
> +#define OFFSET(x) offsetof(QSVMJPEGEncContext, x)
> +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
> +static const AVOption options[] = {
> +{ "quality", "Specifies the image quality", OFFSET(qsv.quality), 
> AV_OPT_TYPE_INT, { .i64 = 90 }, 1, 100, VE },
> +
> +{ NULL },
> +};
> +
> +static const AVClass class = {
> +.class_name = "mjpeg_qsv encoder",
> +.item_name  = av_default_item_name,
> +.option = options,
> +.version= LIBAVUTIL_VERSION_INT,
> +};
> +
> +AVCodec ff_mjpeg_qsv_encoder = {
> +.name   = "mjpeg_qsv",
> +.long_name  = NULL_IF_CONFIG_SMALL("MJPEG (Intel Quick Sync Video 
> acceleration)"),
> +.priv_data_size = sizeof(QSVMJPEGEncContext),
> +.type   = AVMEDIA_TYPE_VIDEO,
> +.id = AV_CODEC_ID_MJPEG,
> +.init   = qsv_enc_init,
> +.encode2= qsv_enc_frame,
> +.close  = qsv_enc_close,
> +.capabilities   = AV_CODEC_CAP_DELAY,
> +.pix_fmts   = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
> +

[libav-devel] [PATCH] libavcodec/mjpeg_qsv: Add the QSV MJPEG encoder

2017-07-17 Thread Huang, Zhengxu


From 45be66259e8fb99b05796748ead308f0fc73c68c Mon Sep 17 00:00:00 2001
From: "Huang, Zhengxu" 
Date: Tue, 18 Jul 2017 01:13:24 +0800
Subject: [PATCH] libavcodec/mjpeg_qsv: Add the QSV MJPEG encoder

usage:
-hwaccel qsv -c:v h264_qsv -i in -c:v mjpeg_qsv -quality 80 -f mjpeg out

Signed-off-by: ChaoX A Liu 
Signed-off-by: Huang, Zhengxu 
Signed-off-by: Andrew, Zhang 
Change-Id: I6a8a89d04e200a833b58741836645be0e0482257
---
 configure|  2 ++
 libavcodec/Makefile  |  1 +
 libavcodec/allcodecs.c   |  1 +
 libavcodec/qsv.c |  3 ++
 libavcodec/qsvenc.c  | 14 
 libavcodec/qsvenc.h  |  3 ++
 libavcodec/qsvenc_jpeg.c | 93 
 7 files changed, 117 insertions(+)
 create mode 100644 libavcodec/qsvenc_jpeg.c

diff --git a/configure b/configure
index d92ce33..35ae031 100755
--- a/configure
+++ b/configure
@@ -2279,6 +2279,8 @@ hevc_qsv_decoder_select="hevc_mp4toannexb_bsf hevc_parser 
hevc_qsv_hwaccel qsvde
 hevc_qsv_encoder_select="hevc_ps qsvenc"
 hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC"
 hevc_vaapi_encoder_select="vaapi_encode golomb"
+mjpeg_qsv_encoder_deps="libmfx"
+mjpeg_qsv_encoder_select="qsvenc"
 mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
 mjpeg_vaapi_encoder_select="vaapi_encode jpegtables"
 mpeg2_mmal_decoder_deps="mmal"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 2b91588..c3e3e6c 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -272,6 +272,7 @@ OBJS-$(CONFIG_H264_NVENC_ENCODER)  += nvenc_h264.o
 OBJS-$(CONFIG_H264_OMX_ENCODER)+= omx.o
 OBJS-$(CONFIG_H264_QSV_DECODER)+= qsvdec_h2645.o
 OBJS-$(CONFIG_H264_QSV_ENCODER)+= qsvenc_h264.o
+OBJS-$(CONFIG_MJPEG_QSV_ENCODER)   += qsvenc_jpeg.o
 OBJS-$(CONFIG_H264_VAAPI_ENCODER)  += vaapi_encode_h264.o 
vaapi_encode_h26x.o
 OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
 OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 5635ae1..3fcea5b 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -509,6 +509,7 @@ void avcodec_register_all(void)
 REGISTER_ENCODER(HEVC_NVENC,hevc_nvenc);
 REGISTER_ENCODER(HEVC_QSV,  hevc_qsv);
 REGISTER_ENCODER(HEVC_VAAPI,hevc_vaapi);
+REGISTER_ENCODER(MJPEG_QSV, mjpeg_qsv);
 REGISTER_ENCODER(MJPEG_VAAPI,   mjpeg_vaapi);
 REGISTER_ENCODER(MPEG2_QSV, mpeg2_qsv);
 REGISTER_ENCODER(MPEG2_VAAPI,   mpeg2_vaapi);
diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 30d612f..a8ae656 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -20,6 +20,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -56,6 +57,8 @@ int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
 case AV_CODEC_ID_VP8:
 return MFX_CODEC_VP8;
 #endif
+case AV_CODEC_ID_MJPEG:
+return MFX_CODEC_JPEG;
 default:
 break;
 }
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 7c6ad09..6693bec 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -435,6 +435,15 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
 }
 
+if (AV_CODEC_ID_MJPEG == avctx->codec_id) {
+av_log(avctx, AV_LOG_DEBUG, " Init codec is QSV JPEG encode \n");
+q->param.mfx.Interleaved  = 1;
+q->param.mfx.Quality  = q->quality;;
+q->param.mfx.RestartInterval  = 0;
+
+return 0;
+}
+
 ret = select_rc_mode(avctx, q);
 if (ret < 0)
 return ret;
@@ -623,6 +632,11 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, 
QSVEncContext *q)
 
 q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
 
+// for qsv mjpeg the return value maybe 0 so alloc the buffer
+if (0 == q->packet_size) {
+q->packet_size = q->param.mfx.FrameInfo.Height * 
q->param.mfx.FrameInfo.Width * 4;
+}
+
 if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
 av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
 return AVERROR_UNKNOWN;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index a639904..1384068 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -132,6 +132,9 @@ typedef struct QSVEncContext {
 int int_ref_qp_delta;
 int recovery_point_sei;
 
+// options for MJPEG
+unsigned short quality;
+
 char *load_plugins;
 } QSVEncContext;
 
diff --git a/libavcodec/qsvenc_jpeg.c b/libavcodec/qsvenc_jpeg.c
new file mode 100644
index 000..fc9226d
--- /dev/null
+++ b/libavcodec/qsvenc_jpeg.c
@@ -0,0 +1,93 @@
+/*
+ * Intel MediaSDK QSV based MJPEG encoder
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published