From 45be66259e8fb99b05796748ead308f0fc73c68c Mon Sep 17 00:00:00 2001 From: "Huang, Zhengxu" <[email protected]> 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 <[email protected]> Signed-off-by: Huang, Zhengxu <[email protected]> Signed-off-by: Andrew, Zhang <[email protected]> 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 <mfx/mfxvideo.h> #include <mfx/mfxplugin.h> +#include <mfx/mfxjpeg.h> #include <stdio.h> #include <string.h> @@ -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 0000000..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 <stdint.h> +#include <sys/types.h> + +#include <mfx/mfxvideo.h> + +#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, + AV_PIX_FMT_QSV, + AV_PIX_FMT_NONE }, + .priv_class = &class, +}; -- 1.8.3.1
_______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
