Merge commit '72b7441a10f578a1d0be7083d8f5adf6a01921c2'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 28 Mar 2015 00:33:27 +0000 (01:33 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 28 Mar 2015 00:33:27 +0000 (01:33 +0100)
* commit '72b7441a10f578a1d0be7083d8f5adf6a01921c2':
  lavc: add Intel libmfx-based H.264 encoder

Conflicts:
Changelog
libavcodec/version.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
Changelog
configure
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/qsv_internal.h
libavcodec/qsvdec.h
libavcodec/qsvenc.c
libavcodec/qsvenc.h
libavcodec/qsvenc_h264.c
libavcodec/version.h

diff --cc Changelog
+++ b/Changelog
@@@ -2,43 -2,16 +2,44 @@@ 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
 +- FFT video filter
 +- TDSC decoder
 +- DTS lossless extension (XLL) decoding (not lossless, disabled by default)
 +- showwavespic filter
 +- libdcadec wrapper
 +- Drop support for nvenc API before 5.0
 +- nvenc H265 encoder
 +- Detelecine filter
++- Intel QSV-accelerated H.264 encoding
 +
 +
 +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@8)
 +- 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
+++ b/configure
@@@ -2072,9 -1760,10 +2073,10 @@@ me_cmp_select="fdctdsp idctdsp pixblock
  mpeg_er_select="error_resilience"
  mpegaudio_select="mpegaudiodsp"
  mpegaudiodsp_select="dct"
 -mpegvideo_select="blockdsp hpeldsp idctdsp me_cmp videodsp"
 +mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp me_cmp videodsp"
  mpegvideoenc_select="me_cmp mpegvideo pixblockdsp qpeldsp"
  qsvdec_select="qsv"
+ qsvenc_select="qsv"
  
  # decoders / encoders
  aac_decoder_select="imdct15 mdct sinewin"
@@@ -2150,9 -1833,11 +2152,11 @@@ h264_decoder_select="cabac golomb h264c
  h264_decoder_suggest="error_resilience"
  h264_qsv_decoder_deps="libmfx"
  h264_qsv_decoder_select="h264_mp4toannexb_bsf h264_parser qsvdec h264_qsv_hwaccel"
+ h264_qsv_encoder_deps="libmfx"
+ h264_qsv_encoder_select="qsvenc"
  hevc_decoder_select="bswapdsp cabac golomb videodsp"
 -huffyuv_decoder_select="bswapdsp huffyuvdsp"
 -huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp"
 +huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
 +huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llviddsp"
  iac_decoder_select="imc_decoder"
  imc_decoder_select="bswapdsp fft mdct sinewin"
  indeo3_decoder_select="hpeldsp"
@@@ -268,8 -224,8 +269,9 @@@ OBJS-$(CONFIG_H264_DECODER)            
                                            h264_direct.o h264_loopfilter.o  \
                                            h264_mb.o h264_picture.o h264_ps.o \
                                            h264_refs.o h264_sei.o h264_slice.o
 +OBJS-$(CONFIG_H264_VDA_DECODER)        += vda_h264_dec.o
  OBJS-$(CONFIG_H264_QSV_DECODER)        += qsvdec_h264.o
+ OBJS-$(CONFIG_H264_QSV_ENCODER)        += qsvenc_h264.o
  OBJS-$(CONFIG_HEVC_DECODER)            += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \
                                            hevc_cabac.o hevc_refs.o hevcpred.o    \
                                            hevcdsp.o hevc_filter.o
Simple merge
Simple merge
Simple merge
index 0000000,2830b0d..bcf3d73
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,444 +1,444 @@@
 - * This file is part of Libav.
+ /*
+  * Intel MediaSDK QSV encoder utility functions
+  *
+  * copyright (c) 2013 Yukinori Yamazoe
+  * copyright (c) 2015 Anton Khirnov
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * 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.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * 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 <string.h>
+ #include <sys/types.h>
+ #include <mfx/mfxvideo.h>
+ #include "libavutil/common.h"
+ #include "libavutil/mem.h"
+ #include "libavutil/log.h"
+ #include "libavutil/time.h"
+ #include "libavutil/imgutils.h"
+ #include "avcodec.h"
+ #include "internal.h"
+ #include "qsv.h"
+ #include "qsv_internal.h"
+ #include "qsvenc.h"
+ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
+ {
+     const char *ratecontrol_desc;
+     float quant;
+     int ret;
+     ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
+     if (ret < 0)
+         return AVERROR_BUG;
+     q->param.mfx.CodecId = ret;
+     if (avctx->level > 0)
+         q->param.mfx.CodecLevel = avctx->level;
+     q->param.mfx.CodecProfile       = q->profile;
+     q->param.mfx.TargetUsage        = q->preset;
+     q->param.mfx.GopPicSize         = FFMAX(0, avctx->gop_size);
+     q->param.mfx.GopRefDist         = FFMAX(-1, avctx->max_b_frames) + 1;
+     q->param.mfx.GopOptFlag         = avctx->flags & CODEC_FLAG_CLOSED_GOP ?
+                                       MFX_GOP_CLOSED : 0;
+     q->param.mfx.IdrInterval        = q->idr_interval;
+     q->param.mfx.NumSlice           = avctx->slices;
+     q->param.mfx.NumRefFrame        = FFMAX(0, avctx->refs);
+     q->param.mfx.EncodedOrder       = 0;
+     q->param.mfx.BufferSizeInKB     = 0;
+     q->param.mfx.FrameInfo.FourCC         = MFX_FOURCC_NV12;
+     q->param.mfx.FrameInfo.Width          = FFALIGN(avctx->width, 16);
+     q->param.mfx.FrameInfo.Height         = FFALIGN(avctx->height, 32);
+     q->param.mfx.FrameInfo.CropX          = 0;
+     q->param.mfx.FrameInfo.CropY          = 0;
+     q->param.mfx.FrameInfo.CropW          = avctx->width;
+     q->param.mfx.FrameInfo.CropH          = avctx->height;
+     q->param.mfx.FrameInfo.AspectRatioW   = avctx->sample_aspect_ratio.num;
+     q->param.mfx.FrameInfo.AspectRatioH   = avctx->sample_aspect_ratio.den;
+     q->param.mfx.FrameInfo.PicStruct      = MFX_PICSTRUCT_PROGRESSIVE;
+     q->param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
+     q->param.mfx.FrameInfo.BitDepthLuma   = 8;
+     q->param.mfx.FrameInfo.BitDepthChroma = 8;
+     if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
+         q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
+         q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
+     } else {
+         q->param.mfx.FrameInfo.FrameRateExtN  = avctx->time_base.den;
+         q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
+     }
+     if (avctx->flags & CODEC_FLAG_QSCALE) {
+         q->param.mfx.RateControlMethod = MFX_RATECONTROL_CQP;
+         ratecontrol_desc = "constant quantization parameter (CQP)";
+     } else if (avctx->rc_max_rate == avctx->bit_rate) {
+         q->param.mfx.RateControlMethod = MFX_RATECONTROL_CBR;
+         ratecontrol_desc = "constant bitrate (CBR)";
+     } else if (!avctx->rc_max_rate) {
+         q->param.mfx.RateControlMethod = MFX_RATECONTROL_AVBR;
+         ratecontrol_desc = "average variable bitrate (AVBR)";
+     } else {
+         q->param.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
+         ratecontrol_desc = "variable bitrate (VBR)";
+     }
+     av_log(avctx, AV_LOG_VERBOSE, "Using the %s ratecontrol method\n", ratecontrol_desc);
+     switch (q->param.mfx.RateControlMethod) {
+     case MFX_RATECONTROL_CBR:
+     case MFX_RATECONTROL_VBR:
+         q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000;
+         q->param.mfx.TargetKbps       = avctx->bit_rate / 1000;
+         q->param.mfx.MaxKbps          = avctx->bit_rate / 1000;
+         break;
+     case MFX_RATECONTROL_CQP:
+         quant = avctx->global_quality / FF_QP2LAMBDA;
+         q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
+         q->param.mfx.QPP = av_clip(quant, 0, 51);
+         q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
+         break;
+     case MFX_RATECONTROL_AVBR:
+         q->param.mfx.TargetKbps  = avctx->bit_rate / 1000;
+         q->param.mfx.Convergence = q->avbr_convergence;
+         q->param.mfx.Accuracy    = q->avbr_accuracy;
+         break;
+     }
+     q->extco.Header.BufferId      = MFX_EXTBUFF_CODING_OPTION;
+     q->extco.Header.BufferSz      = sizeof(q->extco);
+     q->extco.CAVLC                = avctx->coder_type == FF_CODER_TYPE_VLC ?
+                                     MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
+     q->extparam[0] = (mfxExtBuffer *)&q->extco;
+     q->param.ExtParam    = q->extparam;
+     q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam);
+     return 0;
+ }
+ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
+ {
+     uint8_t sps_buf[128];
+     uint8_t pps_buf[128];
+     mfxExtCodingOptionSPSPPS extradata = {
+         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
+         .Header.BufferSz = sizeof(extradata),
+         .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
+         .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
+     };
+     mfxExtBuffer *ext_buffers[] = {
+         (mfxExtBuffer*)&extradata,
+     };
+     int ret;
+     q->param.ExtParam    = ext_buffers;
+     q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
+     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
+     if (ret < 0)
+         return ff_qsv_error(ret);
+     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
+     if (!extradata.SPSBufSize || !extradata.PPSBufSize) {
+         av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
+         return AVERROR_UNKNOWN;
+     }
+     avctx->extradata = av_malloc(extradata.SPSBufSize + extradata.PPSBufSize +
+                                  FF_INPUT_BUFFER_PADDING_SIZE);
+     if (!avctx->extradata)
+         return AVERROR(ENOMEM);
+     memcpy(avctx->extradata,                        sps_buf, extradata.SPSBufSize);
+     memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
+     avctx->extradata_size = extradata.SPSBufSize + extradata.PPSBufSize;
+     memset(avctx->extradata + avctx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+     return 0;
+ }
+ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
+ {
+     int ret;
+     q->param.IOPattern  = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
+     q->param.AsyncDepth = q->async_depth;
+     if (avctx->hwaccel_context) {
+         AVQSVContext *qsv = avctx->hwaccel_context;
+         q->session         = qsv->session;
+         q->param.IOPattern = qsv->iopattern;
+     }
+     if (!q->session) {
+         ret = ff_qsv_init_internal_session(avctx, &q->internal_session);
+         if (ret < 0)
+             return ret;
+         q->session = q->internal_session;
+     }
+     ret = init_video_param(avctx, q);
+     if (ret < 0)
+         return ret;
+     ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
+     if (ret < 0) {
+         av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
+         return ff_qsv_error(ret);
+     }
+     ret = MFXVideoENCODE_Init(q->session, &q->param);
+     if (ret < 0) {
+         av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
+         return ff_qsv_error(ret);
+     }
+     ret = qsv_retrieve_enc_params(avctx, q);
+     if (ret < 0) {
+         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
+         return ret;
+     }
+     avctx->coded_frame = av_frame_alloc();
+     if (!avctx->coded_frame)
+         return AVERROR(ENOMEM);
+     q->avctx = avctx;
+     return 0;
+ }
+ static void clear_unused_frames(QSVEncContext *q)
+ {
+     QSVFrame *cur = q->work_frames;
+     while (cur) {
+         if (cur->surface && !cur->surface->Data.Locked) {
+             cur->surface = NULL;
+             av_frame_unref(cur->frame);
+         }
+         cur = cur->next;
+     }
+ }
+ static int get_free_frame(QSVEncContext *q, QSVFrame **f)
+ {
+     QSVFrame *frame, **last;
+     clear_unused_frames(q);
+     frame = q->work_frames;
+     last  = &q->work_frames;
+     while (frame) {
+         if (!frame->surface) {
+             *f = frame;
+             return 0;
+         }
+         last  = &frame->next;
+         frame = frame->next;
+     }
+     frame = av_mallocz(sizeof(*frame));
+     if (!frame)
+         return AVERROR(ENOMEM);
+     frame->frame = av_frame_alloc();
+     if (!frame->frame) {
+         av_freep(&frame);
+         return AVERROR(ENOMEM);
+     }
+     *last = frame;
+     *f = frame;
+     return 0;
+ }
+ static int submit_frame(QSVEncContext *q, const AVFrame *frame,
+                         mfxFrameSurface1 **surface)
+ {
+     QSVFrame *qf;
+     int ret;
+     ret = get_free_frame(q, &qf);
+     if (ret < 0)
+         return ret;
+     if (frame->format == AV_PIX_FMT_QSV) {
+         ret = av_frame_ref(qf->frame, frame);
+         if (ret < 0)
+             return ret;
+         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
+         *surface = qf->surface;
+         return 0;
+     }
+     /* make a copy if the input is not padded as libmfx requires */
+     if (frame->height & 31 || frame->linesize[0] & 15) {
+         qf->frame->height = FFALIGN(frame->height, 32);
+         qf->frame->width  = FFALIGN(frame->width, 16);
+         ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
+         if (ret < 0)
+             return ret;
+         qf->frame->height = frame->height;
+         qf->frame->width  = frame->width;
+         ret = av_frame_copy(qf->frame, frame);
+         if (ret < 0) {
+             av_frame_unref(qf->frame);
+             return ret;
+         }
+     } else {
+         ret = av_frame_ref(qf->frame, frame);
+         if (ret < 0)
+             return ret;
+     }
+     qf->surface_internal.Info = q->param.mfx.FrameInfo;
+     qf->surface_internal.Info.PicStruct =
+         !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
+         frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
+                                    MFX_PICSTRUCT_FIELD_BFF;
+     if (frame->repeat_pict == 1)
+         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
+     else if (frame->repeat_pict == 2)
+         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
+     else if (frame->repeat_pict == 4)
+         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
+     qf->surface_internal.Data.PitchLow  = qf->frame->linesize[0];
+     qf->surface_internal.Data.Y         = qf->frame->data[0];
+     qf->surface_internal.Data.UV        = qf->frame->data[1];
+     qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
+     qf->surface = &qf->surface_internal;
+     *surface = qf->surface;
+     return 0;
+ }
+ static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
+ {
+     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
+         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
+             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
+             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
+             av_log(avctx, AV_LOG_WARNING,
+                    "Interlaced coding is supported"
+                    " at Main/High Profile Level 2.1-4.1\n");
+     }
+ }
+ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
+                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
+ {
+     mfxBitstream bs = { { { 0 } } };
+     mfxFrameSurface1 *surf = NULL;
+     mfxSyncPoint sync      = NULL;
+     int ret;
+     if (frame) {
+         ret = submit_frame(q, frame, &surf);
+         if (ret < 0) {
+             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
+             return ret;
+         }
+     }
+     ret = ff_alloc_packet(pkt, q->packet_size);
+     if (ret < 0) {
+         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
+         return ret;
+     }
+     bs.Data      = pkt->data;
+     bs.MaxLength = pkt->size;
+     do {
+         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, &bs, &sync);
+         if (ret == MFX_WRN_DEVICE_BUSY)
+             av_usleep(1);
+     } while (ret > 0);
+     if (ret < 0)
+         return (ret == MFX_ERR_MORE_DATA) ? 0 : ff_qsv_error(ret);
+     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame)
+         print_interlace_msg(avctx, q);
+     if (sync) {
+         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
+         if (bs.FrameType & MFX_FRAMETYPE_I || bs.FrameType & MFX_FRAMETYPE_xI)
+             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+         else if (bs.FrameType & MFX_FRAMETYPE_P || bs.FrameType & MFX_FRAMETYPE_xP)
+             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
+         else if (bs.FrameType & MFX_FRAMETYPE_B || bs.FrameType & MFX_FRAMETYPE_xB)
+             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
+         pkt->dts  = av_rescale_q(bs.DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
+         pkt->pts  = av_rescale_q(bs.TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
+         pkt->size = bs.DataLength;
+         if (bs.FrameType & MFX_FRAMETYPE_IDR ||
+             bs.FrameType & MFX_FRAMETYPE_xIDR)
+             pkt->flags |= AV_PKT_FLAG_KEY;
+         *got_packet = 1;
+     }
+     return 0;
+ }
+ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
+ {
+     QSVFrame *cur;
+     MFXVideoENCODE_Close(q->session);
+     if (q->internal_session)
+         MFXClose(q->internal_session);
+     q->session          = NULL;
+     q->internal_session = NULL;
+     cur = q->work_frames;
+     while (cur) {
+         q->work_frames = cur->next;
+         av_frame_free(&cur->frame);
+         av_freep(&cur);
+         cur = q->work_frames;
+     }
+     av_frame_free(&avctx->coded_frame);
+     return 0;
+ }
index 0000000,05d268a..9f7f8cc
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,68 +1,68 @@@
 - * This file is part of Libav.
+ /*
+  * Intel MediaSDK QSV encoder utility functions
+  *
+  * copyright (c) 2013 Yukinori Yamazoe
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * 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.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * 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
+  */
+ #ifndef AVCODEC_QSVENC_H
+ #define AVCODEC_QSVENC_H
+ #include <stdint.h>
+ #include <sys/types.h>
+ #include <mfx/mfxvideo.h>
+ #include "libavutil/avutil.h"
+ #include "avcodec.h"
+ #include "qsv_internal.h"
+ typedef struct QSVEncContext {
+     AVCodecContext *avctx;
+     QSVFrame *work_frames;
+     mfxSession session;
+     mfxSession internal_session;
+     int packet_size;
+     mfxVideoParam param;
+     mfxFrameAllocRequest req;
+     mfxExtCodingOption  extco;
+     mfxExtBuffer *extparam[1];
+     // options set by the caller
+     int async_depth;
+     int idr_interval;
+     int profile;
+     int preset;
+     int avbr_accuracy;
+     int avbr_convergence;
+ } QSVEncContext;
+ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
+ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
+                   AVPacket *pkt, const AVFrame *frame, int *got_packet);
+ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q);
+ #endif /* AVCODEC_QSVENC_H */
index 0000000,441ede8..d0b9b03
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,121 +1,121 @@@
 - * This file is part of Libav.
+ /*
+  * Intel MediaSDK QSV based H.264 enccoder
+  *
+  * copyright (c) 2013 Yukinori Yamazoe
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * 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.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * 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 <stdint.h>
+ #include <sys/types.h>
+ #include <mfx/mfxvideo.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 QSVH264EncContext {
+     AVClass *class;
+     QSVEncContext qsv;
+ } QSVH264EncContext;
+ static av_cold int qsv_enc_init(AVCodecContext *avctx)
+ {
+     QSVH264EncContext *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)
+ {
+     QSVH264EncContext *q = avctx->priv_data;
+     return ff_qsv_encode(avctx, &q->qsv, pkt, frame, got_packet);
+ }
+ static av_cold int qsv_enc_close(AVCodecContext *avctx)
+ {
+     QSVH264EncContext *q = avctx->priv_data;
+     return ff_qsv_enc_close(avctx, &q->qsv);
+ }
+ #define OFFSET(x) offsetof(QSVH264EncContext, x)
+ #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+ static const AVOption options[] = {
+     { "async_depth", "Maximum processing parallelism", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 0, INT_MAX, VE },
+     { "idr_interval", "Distance (in I-frames) between IDR frames", OFFSET(qsv.idr_interval), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
+     { "avbr_accuracy",    "Accuracy of the AVBR ratecontrol",    OFFSET(qsv.avbr_accuracy),    AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
+     { "avbr_convergence", "Convergence of the AVBR ratecontrol", OFFSET(qsv.avbr_convergence), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
+     { "profile", NULL, OFFSET(qsv.profile), AV_OPT_TYPE_INT, { .i64 = MFX_PROFILE_UNKNOWN }, 0, INT_MAX, VE, "profile" },
+     { "unknown" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_UNKNOWN      }, INT_MIN, INT_MAX,     VE, "profile" },
+     { "baseline", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_AVC_BASELINE }, INT_MIN, INT_MAX,     VE, "profile" },
+     { "main"    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_AVC_MAIN     }, INT_MIN, INT_MAX,     VE, "profile" },
+     { "high"    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_AVC_HIGH     }, INT_MIN, INT_MAX,     VE, "profile" },
+     { "preset", NULL, OFFSET(qsv.preset), AV_OPT_TYPE_INT, { .i64 = MFX_TARGETUSAGE_BALANCED }, 0, 7,   VE, "preset" },
+     { "fast",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_SPEED  },   INT_MIN, INT_MAX, VE, "preset" },
+     { "medium", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BALANCED  },     INT_MIN, INT_MAX, VE, "preset" },
+     { "slow",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_BEST_QUALITY  }, INT_MIN, INT_MAX, VE, "preset" },
+     { NULL },
+ };
+ static const AVClass class = {
+     .class_name = "h264_qsv encoder",
+     .item_name  = av_default_item_name,
+     .option     = options,
+     .version    = LIBAVUTIL_VERSION_INT,
+ };
+ static const AVCodecDefault qsv_enc_defaults[] = {
+     { "b",         "1M"    },
+     { "refs",      "0"     },
+     // same as the x264 default
+     { "g",         "250"   },
+     { "bf",        "3"     },
+     { "coder",     "ac"    },
+     { "flags",     "+cgop" },
+     { NULL },
+ };
+ AVCodec ff_h264_qsv_encoder = {
+     .name           = "h264_qsv",
+     .long_name      = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration)"),
+     .priv_data_size = sizeof(QSVH264EncContext),
+     .type           = AVMEDIA_TYPE_VIDEO,
+     .id             = AV_CODEC_ID_H264,
+     .init           = qsv_enc_init,
+     .encode2        = qsv_enc_frame,
+     .close          = qsv_enc_close,
+     .capabilities   = CODEC_CAP_DELAY,
+     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
+                                                     AV_PIX_FMT_QSV,
+                                                     AV_PIX_FMT_NONE },
+     .priv_class     = &class,
+     .defaults       = qsv_enc_defaults,
+ };
@@@ -29,8 -29,8 +29,8 @@@
  #include "libavutil/version.h"
  
  #define LIBAVCODEC_VERSION_MAJOR 56
- #define LIBAVCODEC_VERSION_MINOR  30
 -#define LIBAVCODEC_VERSION_MINOR 20
 -#define LIBAVCODEC_VERSION_MICRO  0
++#define LIBAVCODEC_VERSION_MINOR  31
 +#define LIBAVCODEC_VERSION_MICRO 100
  
  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                 LIBAVCODEC_VERSION_MINOR, \