[FFmpeg-cvslog] Merge commit '83f230c2445a94fdd94c66504482217fcece5909'

Derek Buitenhuis git at videolan.org
Sun May 8 23:47:05 CEST 2016


ffmpeg | branch: master | Derek Buitenhuis <derek.buitenhuis at gmail.com> | Sun May  8 22:46:52 2016 +0100| [939345854a9e8ab32e88b9c9c99c8772049fb965] | committer: Derek Buitenhuis

Merge commit '83f230c2445a94fdd94c66504482217fcece5909'

* commit '83f230c2445a94fdd94c66504482217fcece5909':
  lavc: VAAPI MJPEG encoder

Merged-by: Derek Buitenhuis <derek.buitenhuis at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=939345854a9e8ab32e88b9c9c99c8772049fb965
---

 Changelog                       |    2 +-
 configure                       |    3 +
 libavcodec/Makefile             |    1 +
 libavcodec/allcodecs.c          |    1 +
 libavcodec/vaapi_encode_mjpeg.c |  420 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 426 insertions(+), 1 deletion(-)

diff --git a/Changelog b/Changelog
index edd2b3b..ad2f6ba 100644
--- a/Changelog
+++ b/Changelog
@@ -30,7 +30,7 @@ version <next>:
 - libnpp/CUDA-accelerated format conversion and scaling
 - Duck TrueMotion 2.0 Real Time decoder
 - Wideband Single-bit Data (WSD) demuxer
-- VAAPI-accelerated H.264/HEVC encoding
+- VAAPI-accelerated H.264/HEVC/MJPEG encoding
 
 version 3.0:
 - Common Encryption (CENC) MP4 encoding and decoding support
diff --git a/configure b/configure
index a944bcb..21808ea 100755
--- a/configure
+++ b/configure
@@ -2395,6 +2395,8 @@ mimic_decoder_select="blockdsp bswapdsp hpeldsp idctdsp"
 mjpeg_decoder_select="blockdsp hpeldsp exif idctdsp jpegtables"
 mjpeg_encoder_select="aandcttables jpegtables mpegvideoenc"
 mjpegb_decoder_select="mjpeg_decoder"
+mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
+mjpeg_vaapi_encoder_select="vaapi_encode jpegtables"
 mlp_decoder_select="mlp_parser"
 motionpixels_decoder_select="bswapdsp"
 mp1_decoder_select="mpegaudio"
@@ -5477,6 +5479,7 @@ check_type "va/va.h" "VADecPictureParameterBufferVP9"
 check_type "va/va.h va/va_vpp.h" "VAProcPipelineParameterBuffer"
 check_type "va/va.h va/va_enc_h264.h" "VAEncPictureParameterBufferH264"
 check_type "va/va.h va/va_enc_hevc.h" "VAEncPictureParameterBufferHEVC"
+check_type "va/va.h va/va_enc_jpeg.h" "VAEncPictureParameterBufferJPEG"
 
 check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC"
 
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 971d11d..b502e06 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -367,6 +367,7 @@ OBJS-$(CONFIG_MIMIC_DECODER)           += mimic.o
 OBJS-$(CONFIG_MJPEG_DECODER)           += mjpegdec.o
 OBJS-$(CONFIG_MJPEG_ENCODER)           += mjpegenc.o mjpegenc_common.o
 OBJS-$(CONFIG_MJPEGB_DECODER)          += mjpegbdec.o
+OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER)     += vaapi_encode_mjpeg.o
 OBJS-$(CONFIG_MLP_DECODER)             += mlpdec.o mlpdsp.o
 OBJS-$(CONFIG_MMVIDEO_DECODER)         += mmvideo.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)    += motionpixels.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index f206fec..c5b675b 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -225,6 +225,7 @@ void avcodec_register_all(void)
     REGISTER_DECODER(MIMIC,             mimic);
     REGISTER_ENCDEC (MJPEG,             mjpeg);
     REGISTER_DECODER(MJPEGB,            mjpegb);
+    REGISTER_ENCODER(MJPEG_VAAPI,       mjpeg_vaapi);
     REGISTER_DECODER(MMVIDEO,           mmvideo);
     REGISTER_DECODER(MOTIONPIXELS,      motionpixels);
 #if FF_API_XVMC
diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c
new file mode 100644
index 0000000..ef944d1
--- /dev/null
+++ b/libavcodec/vaapi_encode_mjpeg.c
@@ -0,0 +1,420 @@
+/*
+ * 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 <va/va.h>
+#include <va/va_enc_jpeg.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixfmt.h"
+
+#include "avcodec.h"
+#include "internal.h"
+#include "jpegtables.h"
+#include "mjpeg.h"
+#include "put_bits.h"
+#include "vaapi_encode.h"
+
+
+// Standard JPEG quantisation tables, in zigzag order.
+static const unsigned char vaapi_encode_mjpeg_quant_luminance[64] = {
+    16,  11,  12,  14,  12,  10,  16,  14,
+    13,  14,  18,  17,  16,  19,  24,  40,
+    26,  24,  22,  22,  24,  49,  35,  37,
+    29,  40,  58,  51,  61,  60,  57,  51,
+    56,  55,  64,  72,  92,  78,  64,  68,
+    87,  69,  55,  56,  80, 109,  81,  87,
+    95,  98, 103, 104, 103,  62,  77, 113,
+   121, 112, 100, 120,  92, 101, 103,  99,
+};
+static const unsigned char vaapi_encode_mjpeg_quant_chrominance[64] = {
+    17,  18,  18,  24,  21,  24,  47,  26,
+    26,  47,  99,  66,  56,  66,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99,
+    99,  99,  99,  99,  99,  99,  99,  99,
+};
+
+typedef struct VAAPIEncodeMJPEGContext {
+    int quality;
+    int component_subsample_h[3];
+    int component_subsample_v[3];
+
+    VAQMatrixBufferJPEG quant_tables;
+    VAHuffmanTableBufferJPEGBaseline huffman_tables;
+} VAAPIEncodeMJPEGContext;
+
+static av_cold void vaapi_encode_mjpeg_copy_huffman(unsigned char *dst_lengths,
+                                                    unsigned char *dst_values,
+                                                    const unsigned char *src_lengths,
+                                                    const unsigned char *src_values)
+{
+    int i, mt;
+
+    ++src_lengths;
+
+    mt = 0;
+    for (i = 0; i < 16; i++)
+        mt += (dst_lengths[i] = src_lengths[i]);
+
+    for (i = 0; i < mt; i++)
+        dst_values[i] = src_values[i];
+}
+
+static av_cold void vaapi_encode_mjpeg_init_tables(AVCodecContext *avctx)
+{
+    VAAPIEncodeContext                *ctx = avctx->priv_data;
+    VAAPIEncodeMJPEGContext          *priv = ctx->priv_data;
+    VAQMatrixBufferJPEG             *quant = &priv->quant_tables;
+    VAHuffmanTableBufferJPEGBaseline *huff = &priv->huffman_tables;
+    int i;
+
+    quant->load_lum_quantiser_matrix = 1;
+    quant->load_chroma_quantiser_matrix = 1;
+
+    for (i = 0; i < 64; i++) {
+        quant->lum_quantiser_matrix[i] =
+            vaapi_encode_mjpeg_quant_luminance[i];
+        quant->chroma_quantiser_matrix[i] =
+            vaapi_encode_mjpeg_quant_chrominance[i];
+    }
+
+    huff->load_huffman_table[0] = 1;
+    vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[0].num_dc_codes,
+                                    huff->huffman_table[0].dc_values,
+                                    avpriv_mjpeg_bits_dc_luminance,
+                                    avpriv_mjpeg_val_dc);
+    vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[0].num_ac_codes,
+                                    huff->huffman_table[0].ac_values,
+                                    avpriv_mjpeg_bits_ac_luminance,
+                                    avpriv_mjpeg_val_ac_luminance);
+    memset(huff->huffman_table[0].pad, 0, sizeof(huff->huffman_table[0].pad));
+
+    huff->load_huffman_table[1] = 1;
+    vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[1].num_dc_codes,
+                                    huff->huffman_table[1].dc_values,
+                                    avpriv_mjpeg_bits_dc_chrominance,
+                                    avpriv_mjpeg_val_dc);
+    vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[1].num_ac_codes,
+                                    huff->huffman_table[1].ac_values,
+                                    avpriv_mjpeg_bits_ac_chrominance,
+                                    avpriv_mjpeg_val_ac_chrominance);
+    memset(huff->huffman_table[1].pad, 0, sizeof(huff->huffman_table[1].pad));
+}
+
+static void vaapi_encode_mjpeg_write_marker(PutBitContext *pbc, int marker)
+{
+    put_bits(pbc, 8, 0xff);
+    put_bits(pbc, 8, marker);
+}
+
+static int vaapi_encode_mjpeg_write_image_header(AVCodecContext *avctx,
+                                                 VAAPIEncodePicture *pic,
+                                                 VAAPIEncodeSlice *slice,
+                                                 char *data, size_t *data_len)
+{
+    VAAPIEncodeContext               *ctx = avctx->priv_data;
+    VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params;
+    VAEncSliceParameterBufferJPEG *vslice = slice->codec_slice_params;
+    VAAPIEncodeMJPEGContext         *priv = ctx->priv_data;
+    PutBitContext pbc;
+    int t, i, quant_scale;
+
+    init_put_bits(&pbc, data, *data_len);
+
+    vaapi_encode_mjpeg_write_marker(&pbc, SOI);
+
+    // Quantisation table coefficients are scaled for quality by the driver,
+    // so we also need to do it ourselves here so that headers match.
+    if (priv->quality < 50)
+        quant_scale = 5000 / priv->quality;
+    else
+        quant_scale = 200 - 2 * priv->quality;
+
+    for (t = 0; t < 2; t++) {
+        int q;
+
+        vaapi_encode_mjpeg_write_marker(&pbc, DQT);
+
+        put_bits(&pbc, 16, 3 + 64); // Lq
+        put_bits(&pbc, 4, 0); // Pq
+        put_bits(&pbc, 4, t); // Tq
+
+        for (i = 0; i < 64; i++) {
+            q = i[t ? priv->quant_tables.chroma_quantiser_matrix
+                    : priv->quant_tables.lum_quantiser_matrix];
+            q = (q * quant_scale) / 100;
+            if (q < 1)   q = 1;
+            if (q > 255) q = 255;
+            put_bits(&pbc, 8, q);
+        }
+    }
+
+    vaapi_encode_mjpeg_write_marker(&pbc, SOF0);
+
+    put_bits(&pbc, 16, 8 + 3 * vpic->num_components); // Lf
+    put_bits(&pbc, 8,  vpic->sample_bit_depth); // P
+    put_bits(&pbc, 16, vpic->picture_height);   // Y
+    put_bits(&pbc, 16, vpic->picture_width);    // X
+    put_bits(&pbc, 8,  vpic->num_components);   // Nf
+
+    for (i = 0; i < vpic->num_components; i++) {
+        put_bits(&pbc, 8, vpic->component_id[i]); // Ci
+        put_bits(&pbc, 4, priv->component_subsample_h[i]); // Hi
+        put_bits(&pbc, 4, priv->component_subsample_v[i]); // Vi
+        put_bits(&pbc, 8, vpic->quantiser_table_selector[i]); // Tqi
+    }
+
+    for (t = 0; t < 4; t++) {
+        int mt;
+        unsigned char *lengths, *values;
+
+        vaapi_encode_mjpeg_write_marker(&pbc, DHT);
+
+        if ((t & 1) == 0) {
+            lengths = priv->huffman_tables.huffman_table[t / 2].num_dc_codes;
+            values  = priv->huffman_tables.huffman_table[t / 2].dc_values;
+        } else {
+            lengths = priv->huffman_tables.huffman_table[t / 2].num_ac_codes;
+            values  = priv->huffman_tables.huffman_table[t / 2].ac_values;
+        }
+
+        mt = 0;
+        for (i = 0; i < 16; i++)
+            mt += lengths[i];
+
+        put_bits(&pbc, 16, 2 + 17 + mt); // Lh
+        put_bits(&pbc, 4, t & 1); // Tc
+        put_bits(&pbc, 4, t / 2); // Th
+
+        for (i = 0; i < 16; i++)
+            put_bits(&pbc, 8, lengths[i]);
+        for (i = 0; i < mt; i++)
+            put_bits(&pbc, 8, values[i]);
+    }
+
+    vaapi_encode_mjpeg_write_marker(&pbc, SOS);
+
+    av_assert0(vpic->num_components == vslice->num_components);
+
+    put_bits(&pbc, 16, 6 + 2 * vslice->num_components); // Ls
+    put_bits(&pbc, 8,  vslice->num_components); // Ns
+
+    for (i = 0; i < vslice->num_components; i++) {
+        put_bits(&pbc, 8, vslice->components[i].component_selector); // Csj
+        put_bits(&pbc, 4, vslice->components[i].dc_table_selector);  // Tdj
+        put_bits(&pbc, 4, vslice->components[i].ac_table_selector);  // Taj
+    }
+
+    put_bits(&pbc, 8, 0); // Ss
+    put_bits(&pbc, 8, 63); // Se
+    put_bits(&pbc, 4, 0); // Ah
+    put_bits(&pbc, 4, 0); // Al
+
+    *data_len = put_bits_count(&pbc);
+    flush_put_bits(&pbc);
+
+    return 0;
+}
+
+static int vaapi_encode_mjpeg_write_extra_buffer(AVCodecContext *avctx,
+                                                 VAAPIEncodePicture *pic,
+                                                 int index, int *type,
+                                                 char *data, size_t *data_len)
+{
+    VAAPIEncodeContext       *ctx = avctx->priv_data;
+    VAAPIEncodeMJPEGContext *priv = ctx->priv_data;
+
+    if (index == 0) {
+        // Write quantisation tables.
+        if (*data_len < sizeof(priv->quant_tables))
+            return AVERROR(EINVAL);
+        *type = VAQMatrixBufferType;
+        memcpy(data, &priv->quant_tables,
+               *data_len = sizeof(priv->quant_tables));
+
+    } else if (index == 1) {
+        // Write huffman tables.
+        if (*data_len < sizeof(priv->huffman_tables))
+            return AVERROR(EINVAL);
+        *type = VAHuffmanTableBufferType;
+        memcpy(data, &priv->huffman_tables,
+               *data_len = sizeof(priv->huffman_tables));
+
+    } else {
+        return AVERROR_EOF;
+    }
+    return 0;
+}
+
+static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,
+                                                  VAAPIEncodePicture *pic)
+{
+    VAAPIEncodeContext               *ctx = avctx->priv_data;
+    VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params;
+    VAAPIEncodeMJPEGContext         *priv = ctx->priv_data;
+
+    vpic->reconstructed_picture = pic->recon_surface;
+    vpic->coded_buf = pic->output_buffer;
+
+    vpic->picture_width  = ctx->input_width;
+    vpic->picture_height = ctx->input_height;
+
+    vpic->pic_flags.bits.profile      = 0;
+    vpic->pic_flags.bits.progressive  = 0;
+    vpic->pic_flags.bits.huffman      = 1;
+    vpic->pic_flags.bits.interleaved  = 0;
+    vpic->pic_flags.bits.differential = 0;
+
+    vpic->sample_bit_depth = 8;
+    vpic->num_scan = 1;
+
+    vpic->num_components = 3;
+
+    vpic->component_id[0] = 1;
+    vpic->component_id[1] = 2;
+    vpic->component_id[2] = 3;
+
+    priv->component_subsample_h[0] = 2;
+    priv->component_subsample_v[0] = 2;
+    priv->component_subsample_h[1] = 1;
+    priv->component_subsample_v[1] = 1;
+    priv->component_subsample_h[2] = 1;
+    priv->component_subsample_v[2] = 1;
+
+    vpic->quantiser_table_selector[0] = 0;
+    vpic->quantiser_table_selector[1] = 1;
+    vpic->quantiser_table_selector[2] = 1;
+
+    vpic->quality = priv->quality;
+
+    pic->nb_slices = 1;
+
+    return 0;
+}
+
+static int vaapi_encode_mjpeg_init_slice_params(AVCodecContext *avctx,
+                                                VAAPIEncodePicture *pic,
+                                                VAAPIEncodeSlice *slice)
+{
+    VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params;
+    VAEncSliceParameterBufferJPEG *vslice = slice->codec_slice_params;
+    int i;
+
+    vslice->restart_interval = 0;
+
+    vslice->num_components = vpic->num_components;
+    for (i = 0; i < vslice->num_components; i++) {
+        vslice->components[i].component_selector = i + 1;
+        vslice->components[i].dc_table_selector = (i > 0);
+        vslice->components[i].ac_table_selector = (i > 0);
+    }
+
+    return 0;
+}
+
+static VAConfigAttrib vaapi_encode_mjpeg_config_attributes[] = {
+    { .type  = VAConfigAttribRTFormat,
+      .value = VA_RT_FORMAT_YUV420 },
+    { .type  = VAConfigAttribEncPackedHeaders,
+      .value = VA_ENC_PACKED_HEADER_SEQUENCE },
+};
+
+static av_cold int vaapi_encode_mjpeg_init_internal(AVCodecContext *avctx)
+{
+    VAAPIEncodeContext       *ctx = avctx->priv_data;
+    VAAPIEncodeMJPEGContext *priv = ctx->priv_data;
+
+    ctx->va_profile    = VAProfileJPEGBaseline;
+    ctx->va_entrypoint = VAEntrypointEncPicture;
+
+    ctx->input_width    = avctx->width;
+    ctx->input_height   = avctx->height;
+    ctx->aligned_width  = FFALIGN(ctx->input_width,  8);
+    ctx->aligned_height = FFALIGN(ctx->input_height, 8);
+
+    ctx->config_attributes    = vaapi_encode_mjpeg_config_attributes;
+    ctx->nb_config_attributes =
+        FF_ARRAY_ELEMS(vaapi_encode_mjpeg_config_attributes);
+
+    priv->quality = avctx->global_quality;
+    if (priv->quality < 1 || priv->quality > 100) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid quality value %d "
+               "(must be 1-100).\n", priv->quality);
+        return AVERROR(EINVAL);
+    }
+
+    vaapi_encode_mjpeg_init_tables(avctx);
+
+    return 0;
+}
+
+static VAAPIEncodeType vaapi_encode_type_mjpeg = {
+    .priv_data_size        = sizeof(VAAPIEncodeMJPEGContext),
+
+    .init                  = &vaapi_encode_mjpeg_init_internal,
+
+    .picture_params_size   = sizeof(VAEncPictureParameterBufferJPEG),
+    .init_picture_params   = &vaapi_encode_mjpeg_init_picture_params,
+
+    .slice_params_size     = sizeof(VAEncSliceParameterBufferJPEG),
+    .init_slice_params     = &vaapi_encode_mjpeg_init_slice_params,
+
+    .slice_header_type     = VAEncPackedHeaderRawData,
+    .write_slice_header    = &vaapi_encode_mjpeg_write_image_header,
+
+    .write_extra_buffer    = &vaapi_encode_mjpeg_write_extra_buffer,
+};
+
+static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx)
+{
+    return ff_vaapi_encode_init(avctx, &vaapi_encode_type_mjpeg);
+}
+
+static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = {
+    { "global_quality", "80" },
+    { NULL },
+};
+
+static const AVClass vaapi_encode_mjpeg_class = {
+    .class_name = "mjpeg_vaapi",
+    .item_name  = av_default_item_name,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_mjpeg_vaapi_encoder = {
+    .name           = "mjpeg_vaapi",
+    .long_name      = NULL_IF_CONFIG_SMALL("MJPEG (VAAPI)"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MJPEG,
+    .priv_data_size = sizeof(VAAPIEncodeContext),
+    .init           = &vaapi_encode_mjpeg_init,
+    .encode2        = &ff_vaapi_encode2,
+    .close          = &ff_vaapi_encode_close,
+    .priv_class     = &vaapi_encode_mjpeg_class,
+    .defaults       = vaapi_encode_mjpeg_defaults,
+    .pix_fmts = (const enum AVPixelFormat[]) {
+        AV_PIX_FMT_VAAPI,
+        AV_PIX_FMT_NONE,
+    },
+};


======================================================================

diff --cc Changelog
index edd2b3b,211d691..ad2f6ba
--- a/Changelog
+++ b/Changelog
@@@ -2,201 -2,17 +2,201 @@@ Entries are sorted chronologically fro
  releases are sorted from youngest to oldest.
  
  version <next>:
 -- aliases and defaults for Ogg subtypes (opus, spx)
 -- HEVC/H.265 RTP payload format (draft v6) packetizer and depacketizer
 -- avplay now exits by default at the end of playback
 -- XCB-based screen-grabber
 -- creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer
 -- H.261 RTP payload format (RFC 4587) depacketizer and experimental packetizer
 +- DXVA2-accelerated HEVC Main10 decoding
 +- fieldhint filter
 +- loop video filter and aloop audio filter
 +- Bob Weaver deinterlacing filter
 +- firequalizer filter
 +- datascope filter
 +- bench and abench filters
 +- ciescope filter
 +- protocol blacklisting API
 +- MediaCodec H264 decoding
 +- VC-2 HQ RTP payload format (draft v1) depacketizer and packetizer
 +- AudioToolbox audio decoders
 +- AudioToolbox audio encoders
 +- coreimage filter (GPU based image filtering on OSX)
 +- libdcadec removed
 +- bitstream filter for extracting DTS core
 +- ADPCM IMA DAT4 decoder
 +- musx demuxer
 +- aix demuxer
 +- remap filter
 +- hash and framehash muxers
 +- colorspace filter
 +- hdcd filter
 +- readvitc filter
 +- VAAPI-accelerated format conversion and scaling
 +- libnpp/CUDA-accelerated format conversion and scaling
 +- Duck TrueMotion 2.0 Real Time decoder
 +- Wideband Single-bit Data (WSD) demuxer
- - VAAPI-accelerated H.264/HEVC encoding
++- VAAPI-accelerated H.264/HEVC/MJPEG encoding
 +
 +version 3.0:
 +- Common Encryption (CENC) MP4 encoding and decoding support
 +- DXV decoding
 +- extrastereo filter
 +- ocr filter
 +- alimiter filter
 +- stereowiden filter
 +- stereotools filter
 +- rubberband filter
 +- tremolo filter
 +- agate filter
 +- chromakey filter
 +- maskedmerge filter
 +- Screenpresso SPV1 decoding
 +- chromaprint fingerprinting muxer
 +- ffplay dynamic volume control
 +- displace filter
 +- selectivecolor filter
 +- extensive native AAC encoder improvements and removal of experimental flag
 +- ADPCM PSX decoder
 +- 3dostr, dcstr, fsb, genh, vag, xvag, ads, msf, svag & vpk demuxer
 +- zscale filter
 +- wve demuxer
 +- zero-copy Intel QSV transcoding in ffmpeg
 +- shuffleframes filter
 +- SDX2 DPCM decoder
 +- vibrato filter
 +- innoHeim/Rsupport Screen Capture Codec decoder
 +- ADPCM AICA decoder
 +- Interplay ACM demuxer and audio decoder
 +- XMA1 & XMA2 decoder
 +- realtime filter
 +- anoisesrc audio filter source
 +- IVR demuxer
 +- compensationdelay filter
 +- acompressor filter
 +- support encoding 16-bit RLE SGI images
 +- apulsator filter
 +- sidechaingate audio filter
 +- mipsdspr1 option has been renamed to mipsdsp
 +- aemphasis filter
 +- mips32r5 option has been removed
 +- mips64r6 option has been removed
 +- DXVA2-accelerated VP9 decoding
 +- SOFAlizer: virtual binaural acoustics filter
 +- VAAPI VP9 hwaccel
 +- audio high-order multiband parametric equalizer
 +- automatic bitstream filtering
 +- showspectrumpic filter
 +- libstagefright support removed
 +- spectrumsynth filter
 +- ahistogram filter
 +- only seek with the right mouse button in ffplay
 +- toggle full screen when double-clicking with the left mouse button in ffplay
 +- afftfilt filter
 +- convolution filter
 +- libquvi support removed
 +- support for dvaudio in wav and avi
 +- libaacplus and libvo-aacenc support removed
 +- Cineform HD decoder
 +- new DCA decoder with full support for DTS-HD extensions
 +- significant performance improvements in Windows Television (WTV) demuxer
 +- nnedi deinterlacer
 +- streamselect video and astreamselect audio filter
 +- swaprect filter
 +- metadata video and ametadata audio filter
 +- SMPTE VC-2 HQ profile support for the Dirac decoder
 +- SMPTE VC-2 native encoder supporting the HQ profile
 +
 +
 +version 2.8:
 +- colorkey video filter
 +- BFSTM/BCSTM demuxer
 +- little-endian ADPCM_THP decoder
 +- Hap decoder and encoder
 +- DirectDraw Surface image/texture decoder
 +- ssim filter
 +- optional new ASF demuxer
 +- showvolume filter
 +- Many improvements to the JPEG 2000 decoder
 +- Go2Meeting decoding support
 +- adrawgraph audio and drawgraph video filter
 +- removegrain video filter
 +- Intel QSV-accelerated MPEG-2 video and HEVC encoding
 +- Intel QSV-accelerated MPEG-2 video and HEVC decoding
 +- Intel QSV-accelerated VC-1 video decoding
 +- libkvazaar HEVC encoder
 +- erosion, dilation, deflate and inflate video filters
 +- Dynamic Audio Normalizer as dynaudnorm filter
 +- Reverse video and areverse audio filter
 +- Random filter
 +- deband filter
 +- AAC fixed-point decoding
 +- sidechaincompress audio filter
 +- bitstream filter for converting HEVC from MP4 to Annex B
 +- acrossfade audio filter
 +- allyuv and allrgb video sources
 +- atadenoise video filter
 +- OS X VideoToolbox support
 +- aphasemeter filter
 +- showfreqs filter
 +- vectorscope filter
 +- waveform filter
 +- hstack and vstack filter
 +- Support DNx100 (1440x1080 at 8)
 +- VAAPI hevc hwaccel
 +- VDPAU hevc hwaccel
 +- framerate filter
 +- Switched default encoders for webm to VP9 and Opus
 +- Removed experimental flag from the JPEG 2000 encoder
 +
 +
 +version 2.7:
 +- FFT video filter
 +- TDSC decoder
 +- DTS lossless extension (XLL) decoding (not lossless, disabled by default)
 +- showwavespic filter
 +- DTS decoding through libdcadec
 +- Drop support for nvenc API before 5.0
 +- nvenc HEVC encoder
 +- Detelecine filter
 +- Intel QSV-accelerated H.264 encoding
 +- MMAL-accelerated H.264 decoding
 +- basic APNG encoder and muxer with default extension "apng"
 +- unpack DivX-style packed B-frames in MPEG-4 bitstream filter
 +- WebM Live Chunk Muxer
 +- nvenc level and tier options
 +- chorus filter
 +- Canopus HQ/HQA decoder
 +- Automatically rotate videos based on metadata in ffmpeg
 +- improved Quickdraw compatibility
 +- VP9 high bit-depth and extended colorspaces decoding support
 +- WebPAnimEncoder API when available for encoding and muxing WebP
 +- Direct3D11-accelerated decoding
 +- Support Secure Transport
 +- Multipart JPEG demuxer
 +
 +
 +version 2.6:
 +- nvenc encoder
 +- 10bit spp filter
 +- colorlevels filter
 +- RIFX format for *.wav files
  - RTP/mpegts muxer
 -- VP8 in Ogg demuxing
 +- non continuous cache protocol support
 +- tblend filter
 +- cropdetect support for non 8bpp, absolute (if limit >= 1) and relative (if limit < 1.0) threshold
 +- Camellia symmetric block cipher
  - OpenH264 encoder wrapper
 +- VOC seeking support
 +- Closed caption Decoder
 +- fspp, uspp, pp7 MPlayer postprocessing filters ported to native filters
 +- showpalette filter
 +- Twofish symmetric block cipher
  - Support DNx100 (960x720 at 8)
 -- Direct3D11-accelerated decoding
 +- eq2 filter ported from libmpcodecs as eq filter
 +- removed libmpcodecs
 +- Changed default DNxHD colour range in QuickTime .mov derivatives to mpeg range
 +- ported softpulldown filter from libmpcodecs as repeatfields filter
 +- dcshift filter
 +- RTP depacketizer for loss tolerant payload format for MP3 audio (RFC 5219)
 +- RTP depacketizer for AC3 payload format (RFC 4184)
 +- palettegen and paletteuse filters
 +- VP9 RTP payload format (draft 0) experimental depacketizer
 +- RTP depacketizer for DV (RFC 6469)
  - DXVA2-accelerated HEVC decoding
  - AAC ELD 480 decoding
  - Intel QSV-accelerated H.264 decoding
diff --cc configure
index a944bcb,2cd676a..21808ea
--- a/configure
+++ b/configure
@@@ -2392,9 -1986,11 +2392,11 @@@ loco_decoder_select="golomb
  mdec_decoder_select="blockdsp idctdsp mpegvideo"
  metasound_decoder_select="lsp mdct sinewin"
  mimic_decoder_select="blockdsp bswapdsp hpeldsp idctdsp"
 -mjpeg_decoder_select="blockdsp hpeldsp idctdsp jpegtables"
 +mjpeg_decoder_select="blockdsp hpeldsp exif idctdsp jpegtables"
  mjpeg_encoder_select="aandcttables jpegtables mpegvideoenc"
  mjpegb_decoder_select="mjpeg_decoder"
+ mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
+ mjpeg_vaapi_encoder_select="vaapi_encode jpegtables"
  mlp_decoder_select="mlp_parser"
  motionpixels_decoder_select="bswapdsp"
  mp1_decoder_select="mpegaudio"
diff --cc libavcodec/vaapi_encode_mjpeg.c
index 0000000,3ab3ab1..ef944d1
mode 000000,100644..100644
--- a/libavcodec/vaapi_encode_mjpeg.c
+++ b/libavcodec/vaapi_encode_mjpeg.c
@@@ -1,0 -1,420 +1,420 @@@
+ /*
 - * This file is part of Libav.
++ * This file is part of FFmpeg.
+  *
 - * Libav is free software; you can redistribute it and/or
++ * 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.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * 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 Libav; if not, write to the Free Software
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #include <va/va.h>
+ #include <va/va_enc_jpeg.h>
+ 
+ #include "libavutil/avassert.h"
+ #include "libavutil/common.h"
+ #include "libavutil/internal.h"
+ #include "libavutil/opt.h"
+ #include "libavutil/pixfmt.h"
+ 
+ #include "avcodec.h"
+ #include "internal.h"
+ #include "jpegtables.h"
+ #include "mjpeg.h"
+ #include "put_bits.h"
+ #include "vaapi_encode.h"
+ 
+ 
+ // Standard JPEG quantisation tables, in zigzag order.
+ static const unsigned char vaapi_encode_mjpeg_quant_luminance[64] = {
+     16,  11,  12,  14,  12,  10,  16,  14,
+     13,  14,  18,  17,  16,  19,  24,  40,
+     26,  24,  22,  22,  24,  49,  35,  37,
+     29,  40,  58,  51,  61,  60,  57,  51,
+     56,  55,  64,  72,  92,  78,  64,  68,
+     87,  69,  55,  56,  80, 109,  81,  87,
+     95,  98, 103, 104, 103,  62,  77, 113,
+    121, 112, 100, 120,  92, 101, 103,  99,
+ };
+ static const unsigned char vaapi_encode_mjpeg_quant_chrominance[64] = {
+     17,  18,  18,  24,  21,  24,  47,  26,
+     26,  47,  99,  66,  56,  66,  99,  99,
+     99,  99,  99,  99,  99,  99,  99,  99,
+     99,  99,  99,  99,  99,  99,  99,  99,
+     99,  99,  99,  99,  99,  99,  99,  99,
+     99,  99,  99,  99,  99,  99,  99,  99,
+     99,  99,  99,  99,  99,  99,  99,  99,
+     99,  99,  99,  99,  99,  99,  99,  99,
+ };
+ 
+ typedef struct VAAPIEncodeMJPEGContext {
+     int quality;
+     int component_subsample_h[3];
+     int component_subsample_v[3];
+ 
+     VAQMatrixBufferJPEG quant_tables;
+     VAHuffmanTableBufferJPEGBaseline huffman_tables;
+ } VAAPIEncodeMJPEGContext;
+ 
+ static av_cold void vaapi_encode_mjpeg_copy_huffman(unsigned char *dst_lengths,
+                                                     unsigned char *dst_values,
+                                                     const unsigned char *src_lengths,
+                                                     const unsigned char *src_values)
+ {
+     int i, mt;
+ 
+     ++src_lengths;
+ 
+     mt = 0;
+     for (i = 0; i < 16; i++)
+         mt += (dst_lengths[i] = src_lengths[i]);
+ 
+     for (i = 0; i < mt; i++)
+         dst_values[i] = src_values[i];
+ }
+ 
+ static av_cold void vaapi_encode_mjpeg_init_tables(AVCodecContext *avctx)
+ {
+     VAAPIEncodeContext                *ctx = avctx->priv_data;
+     VAAPIEncodeMJPEGContext          *priv = ctx->priv_data;
+     VAQMatrixBufferJPEG             *quant = &priv->quant_tables;
+     VAHuffmanTableBufferJPEGBaseline *huff = &priv->huffman_tables;
+     int i;
+ 
+     quant->load_lum_quantiser_matrix = 1;
+     quant->load_chroma_quantiser_matrix = 1;
+ 
+     for (i = 0; i < 64; i++) {
+         quant->lum_quantiser_matrix[i] =
+             vaapi_encode_mjpeg_quant_luminance[i];
+         quant->chroma_quantiser_matrix[i] =
+             vaapi_encode_mjpeg_quant_chrominance[i];
+     }
+ 
+     huff->load_huffman_table[0] = 1;
+     vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[0].num_dc_codes,
+                                     huff->huffman_table[0].dc_values,
+                                     avpriv_mjpeg_bits_dc_luminance,
+                                     avpriv_mjpeg_val_dc);
+     vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[0].num_ac_codes,
+                                     huff->huffman_table[0].ac_values,
+                                     avpriv_mjpeg_bits_ac_luminance,
+                                     avpriv_mjpeg_val_ac_luminance);
+     memset(huff->huffman_table[0].pad, 0, sizeof(huff->huffman_table[0].pad));
+ 
+     huff->load_huffman_table[1] = 1;
+     vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[1].num_dc_codes,
+                                     huff->huffman_table[1].dc_values,
+                                     avpriv_mjpeg_bits_dc_chrominance,
+                                     avpriv_mjpeg_val_dc);
+     vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[1].num_ac_codes,
+                                     huff->huffman_table[1].ac_values,
+                                     avpriv_mjpeg_bits_ac_chrominance,
+                                     avpriv_mjpeg_val_ac_chrominance);
+     memset(huff->huffman_table[1].pad, 0, sizeof(huff->huffman_table[1].pad));
+ }
+ 
+ static void vaapi_encode_mjpeg_write_marker(PutBitContext *pbc, int marker)
+ {
+     put_bits(pbc, 8, 0xff);
+     put_bits(pbc, 8, marker);
+ }
+ 
+ static int vaapi_encode_mjpeg_write_image_header(AVCodecContext *avctx,
+                                                  VAAPIEncodePicture *pic,
+                                                  VAAPIEncodeSlice *slice,
+                                                  char *data, size_t *data_len)
+ {
+     VAAPIEncodeContext               *ctx = avctx->priv_data;
+     VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params;
+     VAEncSliceParameterBufferJPEG *vslice = slice->codec_slice_params;
+     VAAPIEncodeMJPEGContext         *priv = ctx->priv_data;
+     PutBitContext pbc;
+     int t, i, quant_scale;
+ 
+     init_put_bits(&pbc, data, *data_len);
+ 
+     vaapi_encode_mjpeg_write_marker(&pbc, SOI);
+ 
+     // Quantisation table coefficients are scaled for quality by the driver,
+     // so we also need to do it ourselves here so that headers match.
+     if (priv->quality < 50)
+         quant_scale = 5000 / priv->quality;
+     else
+         quant_scale = 200 - 2 * priv->quality;
+ 
+     for (t = 0; t < 2; t++) {
+         int q;
+ 
+         vaapi_encode_mjpeg_write_marker(&pbc, DQT);
+ 
+         put_bits(&pbc, 16, 3 + 64); // Lq
+         put_bits(&pbc, 4, 0); // Pq
+         put_bits(&pbc, 4, t); // Tq
+ 
+         for (i = 0; i < 64; i++) {
+             q = i[t ? priv->quant_tables.chroma_quantiser_matrix
+                     : priv->quant_tables.lum_quantiser_matrix];
+             q = (q * quant_scale) / 100;
+             if (q < 1)   q = 1;
+             if (q > 255) q = 255;
+             put_bits(&pbc, 8, q);
+         }
+     }
+ 
+     vaapi_encode_mjpeg_write_marker(&pbc, SOF0);
+ 
+     put_bits(&pbc, 16, 8 + 3 * vpic->num_components); // Lf
+     put_bits(&pbc, 8,  vpic->sample_bit_depth); // P
+     put_bits(&pbc, 16, vpic->picture_height);   // Y
+     put_bits(&pbc, 16, vpic->picture_width);    // X
+     put_bits(&pbc, 8,  vpic->num_components);   // Nf
+ 
+     for (i = 0; i < vpic->num_components; i++) {
+         put_bits(&pbc, 8, vpic->component_id[i]); // Ci
+         put_bits(&pbc, 4, priv->component_subsample_h[i]); // Hi
+         put_bits(&pbc, 4, priv->component_subsample_v[i]); // Vi
+         put_bits(&pbc, 8, vpic->quantiser_table_selector[i]); // Tqi
+     }
+ 
+     for (t = 0; t < 4; t++) {
+         int mt;
+         unsigned char *lengths, *values;
+ 
+         vaapi_encode_mjpeg_write_marker(&pbc, DHT);
+ 
+         if ((t & 1) == 0) {
+             lengths = priv->huffman_tables.huffman_table[t / 2].num_dc_codes;
+             values  = priv->huffman_tables.huffman_table[t / 2].dc_values;
+         } else {
+             lengths = priv->huffman_tables.huffman_table[t / 2].num_ac_codes;
+             values  = priv->huffman_tables.huffman_table[t / 2].ac_values;
+         }
+ 
+         mt = 0;
+         for (i = 0; i < 16; i++)
+             mt += lengths[i];
+ 
+         put_bits(&pbc, 16, 2 + 17 + mt); // Lh
+         put_bits(&pbc, 4, t & 1); // Tc
+         put_bits(&pbc, 4, t / 2); // Th
+ 
+         for (i = 0; i < 16; i++)
+             put_bits(&pbc, 8, lengths[i]);
+         for (i = 0; i < mt; i++)
+             put_bits(&pbc, 8, values[i]);
+     }
+ 
+     vaapi_encode_mjpeg_write_marker(&pbc, SOS);
+ 
+     av_assert0(vpic->num_components == vslice->num_components);
+ 
+     put_bits(&pbc, 16, 6 + 2 * vslice->num_components); // Ls
+     put_bits(&pbc, 8,  vslice->num_components); // Ns
+ 
+     for (i = 0; i < vslice->num_components; i++) {
+         put_bits(&pbc, 8, vslice->components[i].component_selector); // Csj
+         put_bits(&pbc, 4, vslice->components[i].dc_table_selector);  // Tdj
+         put_bits(&pbc, 4, vslice->components[i].ac_table_selector);  // Taj
+     }
+ 
+     put_bits(&pbc, 8, 0); // Ss
+     put_bits(&pbc, 8, 63); // Se
+     put_bits(&pbc, 4, 0); // Ah
+     put_bits(&pbc, 4, 0); // Al
+ 
+     *data_len = put_bits_count(&pbc);
+     flush_put_bits(&pbc);
+ 
+     return 0;
+ }
+ 
+ static int vaapi_encode_mjpeg_write_extra_buffer(AVCodecContext *avctx,
+                                                  VAAPIEncodePicture *pic,
+                                                  int index, int *type,
+                                                  char *data, size_t *data_len)
+ {
+     VAAPIEncodeContext       *ctx = avctx->priv_data;
+     VAAPIEncodeMJPEGContext *priv = ctx->priv_data;
+ 
+     if (index == 0) {
+         // Write quantisation tables.
+         if (*data_len < sizeof(priv->quant_tables))
+             return AVERROR(EINVAL);
+         *type = VAQMatrixBufferType;
+         memcpy(data, &priv->quant_tables,
+                *data_len = sizeof(priv->quant_tables));
+ 
+     } else if (index == 1) {
+         // Write huffman tables.
+         if (*data_len < sizeof(priv->huffman_tables))
+             return AVERROR(EINVAL);
+         *type = VAHuffmanTableBufferType;
+         memcpy(data, &priv->huffman_tables,
+                *data_len = sizeof(priv->huffman_tables));
+ 
+     } else {
+         return AVERROR_EOF;
+     }
+     return 0;
+ }
+ 
+ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,
+                                                   VAAPIEncodePicture *pic)
+ {
+     VAAPIEncodeContext               *ctx = avctx->priv_data;
+     VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params;
+     VAAPIEncodeMJPEGContext         *priv = ctx->priv_data;
+ 
+     vpic->reconstructed_picture = pic->recon_surface;
+     vpic->coded_buf = pic->output_buffer;
+ 
+     vpic->picture_width  = ctx->input_width;
+     vpic->picture_height = ctx->input_height;
+ 
+     vpic->pic_flags.bits.profile      = 0;
+     vpic->pic_flags.bits.progressive  = 0;
+     vpic->pic_flags.bits.huffman      = 1;
+     vpic->pic_flags.bits.interleaved  = 0;
+     vpic->pic_flags.bits.differential = 0;
+ 
+     vpic->sample_bit_depth = 8;
+     vpic->num_scan = 1;
+ 
+     vpic->num_components = 3;
+ 
+     vpic->component_id[0] = 1;
+     vpic->component_id[1] = 2;
+     vpic->component_id[2] = 3;
+ 
+     priv->component_subsample_h[0] = 2;
+     priv->component_subsample_v[0] = 2;
+     priv->component_subsample_h[1] = 1;
+     priv->component_subsample_v[1] = 1;
+     priv->component_subsample_h[2] = 1;
+     priv->component_subsample_v[2] = 1;
+ 
+     vpic->quantiser_table_selector[0] = 0;
+     vpic->quantiser_table_selector[1] = 1;
+     vpic->quantiser_table_selector[2] = 1;
+ 
+     vpic->quality = priv->quality;
+ 
+     pic->nb_slices = 1;
+ 
+     return 0;
+ }
+ 
+ static int vaapi_encode_mjpeg_init_slice_params(AVCodecContext *avctx,
+                                                 VAAPIEncodePicture *pic,
+                                                 VAAPIEncodeSlice *slice)
+ {
+     VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params;
+     VAEncSliceParameterBufferJPEG *vslice = slice->codec_slice_params;
+     int i;
+ 
+     vslice->restart_interval = 0;
+ 
+     vslice->num_components = vpic->num_components;
+     for (i = 0; i < vslice->num_components; i++) {
+         vslice->components[i].component_selector = i + 1;
+         vslice->components[i].dc_table_selector = (i > 0);
+         vslice->components[i].ac_table_selector = (i > 0);
+     }
+ 
+     return 0;
+ }
+ 
+ static VAConfigAttrib vaapi_encode_mjpeg_config_attributes[] = {
+     { .type  = VAConfigAttribRTFormat,
+       .value = VA_RT_FORMAT_YUV420 },
+     { .type  = VAConfigAttribEncPackedHeaders,
+       .value = VA_ENC_PACKED_HEADER_SEQUENCE },
+ };
+ 
+ static av_cold int vaapi_encode_mjpeg_init_internal(AVCodecContext *avctx)
+ {
+     VAAPIEncodeContext       *ctx = avctx->priv_data;
+     VAAPIEncodeMJPEGContext *priv = ctx->priv_data;
+ 
+     ctx->va_profile    = VAProfileJPEGBaseline;
+     ctx->va_entrypoint = VAEntrypointEncPicture;
+ 
+     ctx->input_width    = avctx->width;
+     ctx->input_height   = avctx->height;
+     ctx->aligned_width  = FFALIGN(ctx->input_width,  8);
+     ctx->aligned_height = FFALIGN(ctx->input_height, 8);
+ 
+     ctx->config_attributes    = vaapi_encode_mjpeg_config_attributes;
+     ctx->nb_config_attributes =
+         FF_ARRAY_ELEMS(vaapi_encode_mjpeg_config_attributes);
+ 
+     priv->quality = avctx->global_quality;
+     if (priv->quality < 1 || priv->quality > 100) {
+         av_log(avctx, AV_LOG_ERROR, "Invalid quality value %d "
+                "(must be 1-100).\n", priv->quality);
+         return AVERROR(EINVAL);
+     }
+ 
+     vaapi_encode_mjpeg_init_tables(avctx);
+ 
+     return 0;
+ }
+ 
+ static VAAPIEncodeType vaapi_encode_type_mjpeg = {
+     .priv_data_size        = sizeof(VAAPIEncodeMJPEGContext),
+ 
+     .init                  = &vaapi_encode_mjpeg_init_internal,
+ 
+     .picture_params_size   = sizeof(VAEncPictureParameterBufferJPEG),
+     .init_picture_params   = &vaapi_encode_mjpeg_init_picture_params,
+ 
+     .slice_params_size     = sizeof(VAEncSliceParameterBufferJPEG),
+     .init_slice_params     = &vaapi_encode_mjpeg_init_slice_params,
+ 
+     .slice_header_type     = VAEncPackedHeaderRawData,
+     .write_slice_header    = &vaapi_encode_mjpeg_write_image_header,
+ 
+     .write_extra_buffer    = &vaapi_encode_mjpeg_write_extra_buffer,
+ };
+ 
+ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx)
+ {
+     return ff_vaapi_encode_init(avctx, &vaapi_encode_type_mjpeg);
+ }
+ 
+ static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = {
+     { "global_quality", "80" },
+     { NULL },
+ };
+ 
+ static const AVClass vaapi_encode_mjpeg_class = {
+     .class_name = "mjpeg_vaapi",
+     .item_name  = av_default_item_name,
+     .version    = LIBAVUTIL_VERSION_INT,
+ };
+ 
+ AVCodec ff_mjpeg_vaapi_encoder = {
+     .name           = "mjpeg_vaapi",
+     .long_name      = NULL_IF_CONFIG_SMALL("MJPEG (VAAPI)"),
+     .type           = AVMEDIA_TYPE_VIDEO,
+     .id             = AV_CODEC_ID_MJPEG,
+     .priv_data_size = sizeof(VAAPIEncodeContext),
+     .init           = &vaapi_encode_mjpeg_init,
+     .encode2        = &ff_vaapi_encode2,
+     .close          = &ff_vaapi_encode_close,
+     .priv_class     = &vaapi_encode_mjpeg_class,
+     .defaults       = vaapi_encode_mjpeg_defaults,
+     .pix_fmts = (const enum AVPixelFormat[]) {
+         AV_PIX_FMT_VAAPI,
+         AV_PIX_FMT_NONE,
+     },
+ };




More information about the ffmpeg-cvslog mailing list