| 
																	
																	
																		
																	
																	
																 | 
																@@ -20,127 +20,74 @@ | 
															
														
														
													
														
															
																 | 
																 | 
																#include <stdlib.h> | 
																 | 
																 | 
																#include <stdlib.h> | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																#include "libavutil/dict.h" | 
																 | 
																 | 
																#include "libavutil/dict.h" | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include "libavutil/hwcontext.h" | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																#include "libavutil/hwcontext_qsv.h" | 
															
														
														
													
														
															
																 | 
																 | 
																#include "libavutil/mem.h" | 
																 | 
																 | 
																#include "libavutil/mem.h" | 
															
														
														
													
														
															
																 | 
																 | 
																#include "libavutil/opt.h" | 
																 | 
																 | 
																#include "libavutil/opt.h" | 
															
														
														
													
														
															
																 | 
																 | 
																#include "libavcodec/qsv.h" | 
																 | 
																 | 
																#include "libavcodec/qsv.h" | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																#include "ffmpeg.h" | 
																 | 
																 | 
																#include "ffmpeg.h" | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																typedef struct QSVContext { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    OutputStream *ost; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    mfxSession session; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    mfxExtOpaqueSurfaceAlloc opaque_alloc; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    AVBufferRef             *opaque_surfaces_buf; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    uint8_t           *surface_used; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    mfxFrameSurface1 **surface_ptrs; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    int nb_surfaces; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    mfxExtBuffer *ext_buffers[1]; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																} QSVContext; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																static void buffer_release(void *opaque, uint8_t *data) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																{ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    *(uint8_t*)opaque = 0; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																static int qsv_get_buffer(AVCodecContext *s, AVFrame *frame, int flags) | 
																 | 
																 | 
																static int qsv_get_buffer(AVCodecContext *s, AVFrame *frame, int flags) | 
															
														
														
													
														
															
																 | 
																 | 
																{ | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																    InputStream *ist = s->opaque; | 
																 | 
																 | 
																    InputStream *ist = s->opaque; | 
															
														
														
													
														
															
																 | 
																 | 
																    QSVContext  *qsv = ist->hwaccel_ctx; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    int i; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    for (i = 0; i < qsv->nb_surfaces; i++) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        if (qsv->surface_used[i]) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            continue; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        frame->buf[0] = av_buffer_create((uint8_t*)qsv->surface_ptrs[i], sizeof(*qsv->surface_ptrs[i]), | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                                         buffer_release, &qsv->surface_used[i], 0); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        if (!frame->buf[0]) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            return AVERROR(ENOMEM); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        frame->data[3]       = (uint8_t*)qsv->surface_ptrs[i]; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        qsv->surface_used[i] = 1; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        return 0; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    return AVERROR(ENOMEM); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																static int init_opaque_surf(QSVContext *qsv) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																{ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    AVQSVContext *hwctx_enc = qsv->ost->enc_ctx->hwaccel_context; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    mfxFrameSurface1 *surfaces; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    int i; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->nb_surfaces = hwctx_enc->nb_opaque_surfaces; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->opaque_surfaces_buf = av_buffer_ref(hwctx_enc->opaque_surfaces); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->surface_ptrs        = av_mallocz_array(qsv->nb_surfaces, sizeof(*qsv->surface_ptrs)); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->surface_used        = av_mallocz_array(qsv->nb_surfaces, sizeof(*qsv->surface_used)); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    if (!qsv->opaque_surfaces_buf || !qsv->surface_ptrs || !qsv->surface_used) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        return AVERROR(ENOMEM); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    surfaces = (mfxFrameSurface1*)qsv->opaque_surfaces_buf->data; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    for (i = 0; i < qsv->nb_surfaces; i++) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        qsv->surface_ptrs[i] = surfaces + i; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->opaque_alloc.Out.Surfaces   = qsv->surface_ptrs; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->opaque_alloc.Out.NumSurface = qsv->nb_surfaces; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->opaque_alloc.Out.Type       = hwctx_enc->opaque_alloc_type; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->opaque_alloc.Header.BufferSz = sizeof(qsv->opaque_alloc); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->ext_buffers[0]               = (mfxExtBuffer*)&qsv->opaque_alloc; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    return 0; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    return av_hwframe_get_buffer(ist->hw_frames_ctx, frame, 0); | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																static void qsv_uninit(AVCodecContext *s) | 
																 | 
																 | 
																static void qsv_uninit(AVCodecContext *s) | 
															
														
														
													
														
															
																 | 
																 | 
																{ | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																    InputStream *ist = s->opaque; | 
																 | 
																 | 
																    InputStream *ist = s->opaque; | 
															
														
														
													
														
															
																 | 
																 | 
																    QSVContext  *qsv = ist->hwaccel_ctx; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    av_buffer_unref(&ist->hw_frames_ctx); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    av_freep(&qsv->ost->enc_ctx->hwaccel_context); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    av_freep(&s->hwaccel_context); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																static int qsv_device_init(InputStream *ist) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    int err; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    av_buffer_unref(&qsv->opaque_surfaces_buf); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    av_freep(&qsv->surface_used); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    av_freep(&qsv->surface_ptrs); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV, | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																                                 ist->hwaccel_device, NULL, 0); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if (err < 0) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        av_log(NULL, AV_LOG_ERROR, "Error creating a QSV device\n"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return err; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    av_freep(&qsv); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    return 0; | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																int qsv_init(AVCodecContext *s) | 
																 | 
																 | 
																int qsv_init(AVCodecContext *s) | 
															
														
														
													
														
															
																 | 
																 | 
																{ | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																    InputStream *ist = s->opaque; | 
																 | 
																 | 
																    InputStream *ist = s->opaque; | 
															
														
														
													
														
															
																 | 
																 | 
																    QSVContext  *qsv = ist->hwaccel_ctx; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    AVQSVContext *hwctx_dec; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    AVHWFramesContext *frames_ctx; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    AVQSVFramesContext *frames_hwctx; | 
															
														
														
													
														
															
																 | 
																 | 
																    int ret; | 
																 | 
																 | 
																    int ret; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    if (!qsv) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        av_log(NULL, AV_LOG_ERROR, "QSV transcoding is not initialized. " | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																               "-hwaccel qsv should only be used for one-to-one QSV transcoding " | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																               "with no filters.\n"); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        return AVERROR_BUG; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if (!hw_device_ctx) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        ret = qsv_device_init(ist); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (ret < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            return ret; | 
															
														
														
													
														
															
																 | 
																 | 
																    } | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    ret = init_opaque_surf(qsv); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    if (ret < 0) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        return ret; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx_dec = av_qsv_alloc_context(); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    if (!hwctx_dec) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    av_buffer_unref(&ist->hw_frames_ctx); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if (!ist->hw_frames_ctx) | 
															
														
														
													
														
															
																 | 
																 | 
																        return AVERROR(ENOMEM); | 
																 | 
																 | 
																        return AVERROR(ENOMEM); | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx_dec->session        = qsv->session; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx_dec->iopattern      = MFX_IOPATTERN_OUT_OPAQUE_MEMORY; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx_dec->ext_buffers    = qsv->ext_buffers; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx_dec->nb_ext_buffers = FF_ARRAY_ELEMS(qsv->ext_buffers); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    frames_ctx   = (AVHWFramesContext*)ist->hw_frames_ctx->data; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    frames_hwctx = frames_ctx->hwctx; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    frames_ctx->width             = FFALIGN(s->coded_width,  32); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    frames_ctx->height            = FFALIGN(s->coded_height, 32); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    frames_ctx->format            = AV_PIX_FMT_QSV; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    frames_ctx->sw_format         = s->sw_pix_fmt; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    frames_ctx->initial_pool_size = 64; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    frames_hwctx->frame_type      = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    av_freep(&s->hwaccel_context); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    s->hwaccel_context = hwctx_dec; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    ret = av_hwframe_ctx_init(ist->hw_frames_ctx); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if (ret < 0) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n"); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        return ret; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    ist->hwaccel_get_buffer = qsv_get_buffer; | 
																 | 
																 | 
																    ist->hwaccel_get_buffer = qsv_get_buffer; | 
															
														
														
													
														
															
																 | 
																 | 
																    ist->hwaccel_uninit     = qsv_uninit; | 
																 | 
																 | 
																    ist->hwaccel_uninit     = qsv_uninit; | 
															
														
														
													
												
													
														
															
																| 
																	
																	
																	
																		
																	
																 | 
																@@ -148,53 +95,15 @@ int qsv_init(AVCodecContext *s) | 
															
														
														
													
														
															
																 | 
																 | 
																    return 0; | 
																 | 
																 | 
																    return 0; | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																} | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																static mfxIMPL choose_implementation(const InputStream *ist) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																{ | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    static const struct { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        const char *name; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        mfxIMPL     impl; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    } impl_map[] = { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        { "auto",     MFX_IMPL_AUTO         }, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        { "sw",       MFX_IMPL_SOFTWARE     }, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        { "hw",       MFX_IMPL_HARDWARE     }, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        { "auto_any", MFX_IMPL_AUTO_ANY     }, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        { "hw_any",   MFX_IMPL_HARDWARE_ANY }, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        { "hw2",      MFX_IMPL_HARDWARE2    }, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        { "hw3",      MFX_IMPL_HARDWARE3    }, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        { "hw4",      MFX_IMPL_HARDWARE4    }, | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    }; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    mfxIMPL impl = MFX_IMPL_AUTO_ANY; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    int i; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    if (ist->hwaccel_device) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        for (i = 0; i < FF_ARRAY_ELEMS(impl_map); i++) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            if (!strcmp(ist->hwaccel_device, impl_map[i].name)) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                impl = impl_map[i].impl; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                break; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        if (i == FF_ARRAY_ELEMS(impl_map)) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																            impl = strtol(ist->hwaccel_device, NULL, 0); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    } | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    return impl; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																int qsv_transcode_init(OutputStream *ost) | 
																 | 
																 | 
																int qsv_transcode_init(OutputStream *ost) | 
															
														
														
													
														
															
																 | 
																 | 
																{ | 
																 | 
																 | 
																{ | 
															
														
														
													
														
															
																 | 
																 | 
																    InputStream *ist; | 
																 | 
																 | 
																    InputStream *ist; | 
															
														
														
													
														
															
																 | 
																 | 
																    const enum AVPixelFormat *pix_fmt; | 
																 | 
																 | 
																    const enum AVPixelFormat *pix_fmt; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    AVDictionaryEntry *e; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    const AVOption *opt; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    int flags = 0; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    int err, i; | 
																 | 
																 | 
																    int err, i; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    QSVContext *qsv = NULL; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    AVQSVContext *hwctx = NULL; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    mfxIMPL impl; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    mfxVersion ver = { { 3, 1 } }; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    AVBufferRef *encode_frames_ref = NULL; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    AVHWFramesContext *encode_frames; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    AVQSVFramesContext *qsv_frames; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    /* check if the encoder supports QSV */ | 
																 | 
																 | 
																    /* check if the encoder supports QSV */ | 
															
														
														
													
														
															
																 | 
																 | 
																    if (!ost->enc->pix_fmts) | 
																 | 
																 | 
																    if (!ost->enc->pix_fmts) | 
															
														
														
													
												
													
														
															
																| 
																	
																		
																	
																	
																		
																	
																	
																 | 
																@@ -225,43 +134,45 @@ int qsv_transcode_init(OutputStream *ost) | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    av_log(NULL, AV_LOG_VERBOSE, "Setting up QSV transcoding\n"); | 
																 | 
																 | 
																    av_log(NULL, AV_LOG_VERBOSE, "Setting up QSV transcoding\n"); | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv   = av_mallocz(sizeof(*qsv)); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx = av_qsv_alloc_context(); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    if (!qsv || !hwctx) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        goto fail; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if (!hw_device_ctx) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        err = qsv_device_init(ist); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        if (err < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    impl = choose_implementation(ist); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // This creates a dummy hw_frames_ctx for the encoder to be | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // suitably initialised.  It only contains one real frame, so | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    // hopefully doesn't waste too much memory. | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    err = MFXInit(impl, &ver, &qsv->session); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    if (err != MFX_ERR_NONE) { | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        av_log(NULL, AV_LOG_ERROR, "Error initializing an MFX session: %d\n", err); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    encode_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if (!encode_frames_ref) { | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        err = AVERROR(ENOMEM); | 
															
														
														
													
														
															
																 | 
																 | 
																        goto fail; | 
																 | 
																 | 
																        goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																    } | 
																 | 
																 | 
																    } | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    encode_frames = (AVHWFramesContext*)encode_frames_ref->data; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    qsv_frames = encode_frames->hwctx; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    e = av_dict_get(ost->encoder_opts, "flags", NULL, 0); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    opt = av_opt_find(ost->enc_ctx, "flags", NULL, 0, 0); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    if (e && opt) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        av_opt_eval_flags(ost->enc_ctx, opt, e->value, &flags); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    encode_frames->width     = FFALIGN(ist->resample_width,  32); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    encode_frames->height    = FFALIGN(ist->resample_height, 32); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    encode_frames->format    = AV_PIX_FMT_QSV; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    encode_frames->sw_format = AV_PIX_FMT_NV12; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    encode_frames->initial_pool_size = 1; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    qsv->ost = ost; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    qsv_frames->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx->session                = qsv->session; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx->iopattern              = MFX_IOPATTERN_IN_OPAQUE_MEMORY; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx->opaque_alloc           = 1; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    hwctx->nb_opaque_surfaces     = 16; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    err = av_hwframe_ctx_init(encode_frames_ref); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    if (err < 0) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        goto fail; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    ost->hwaccel_ctx              = qsv; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    ost->enc_ctx->hwaccel_context = hwctx; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    ost->enc_ctx->pix_fmt         = AV_PIX_FMT_QSV; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    ist->dec_ctx->pix_fmt       = AV_PIX_FMT_QSV; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    ist->resample_pix_fmt       = AV_PIX_FMT_QSV; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    ist->hwaccel_ctx              = qsv; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    ist->dec_ctx->pix_fmt         = AV_PIX_FMT_QSV; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    ist->resample_pix_fmt         = AV_PIX_FMT_QSV; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    ost->enc_ctx->pix_fmt       = AV_PIX_FMT_QSV; | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    ost->enc_ctx->hw_frames_ctx = encode_frames_ref; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																    return 0; | 
																 | 
																 | 
																    return 0; | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																fail: | 
																 | 
																 | 
																fail: | 
															
														
														
													
														
															
																 | 
																 | 
																    av_freep(&hwctx); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    av_freep(&qsv); | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    return AVERROR_UNKNOWN; | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    av_buffer_unref(&encode_frames_ref); | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    return err; | 
															
														
														
													
														
															
																 | 
																 | 
																} | 
																 | 
																 | 
																} |