]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/qsvenc.c
Merge commit 'e46a6fb7732a7caef97a916a4f765ec0f779d195'
[ffmpeg] / libavcodec / qsvenc.c
index ac443c1a26541dd44884fda95036f9ecaceabd5c..2e591507a2cf5a30730c7bfa6bf2b04e73c81955 100644 (file)
@@ -347,6 +347,9 @@ static int rc_supported(QSVEncContext *q)
 
 static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
 {
+    enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ?
+                                   avctx->sw_pix_fmt : avctx->pix_fmt;
+    const AVPixFmtDescriptor *desc;
     float quant;
     int ret;
 
@@ -372,24 +375,31 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
     q->param.mfx.EncodedOrder       = 0;
     q->param.mfx.BufferSizeInKB     = 0;
 
+    desc = av_pix_fmt_desc_get(sw_format);
+    if (!desc)
+        return AVERROR_BUG;
+
+    ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC);
+
+    q->param.mfx.FrameInfo.Width          = FFALIGN(avctx->width, q->width_align);
+    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   = desc->comp[0].depth;
+    q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
+    q->param.mfx.FrameInfo.Shift          = desc->comp[0].depth > 8;
+
     if (avctx->hw_frames_ctx) {
         AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
         AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
-        q->param.mfx.FrameInfo = frames_hwctx->surfaces[0].Info;
-    } else {
-        q->param.mfx.FrameInfo.FourCC         = MFX_FOURCC_NV12;
-        q->param.mfx.FrameInfo.Width          = FFALIGN(avctx->width, q->width_align);
-        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;
+        q->param.mfx.FrameInfo.Width  = frames_hwctx->surfaces[0].Info.Width;
+        q->param.mfx.FrameInfo.Height = frames_hwctx->surfaces[0].Info.Height;
     }
 
     if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
@@ -581,7 +591,8 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
 
     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
     if (ret < 0)
-        return ff_qsv_error(ret);
+        return ff_qsv_print_error(avctx, ret,
+                                  "Error calling GetVideoParam");
 
     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
 
@@ -730,10 +741,9 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
         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);
-    }
+    if (ret < 0)
+        return ff_qsv_print_error(avctx, ret,
+                                  "Error querying the encoding parameters");
 
     if (opaque_alloc) {
         ret = qsv_init_opaque_alloc(avctx, q);
@@ -771,12 +781,12 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
     }
 
     ret = MFXVideoENCODE_Init(q->session, &q->param);
-    if (ret == MFX_WRN_PARTIAL_ACCELERATION) {
-        av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
-    } else if (ret < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
-        return ff_qsv_error(ret);
-    }
+    if (ret < 0)
+        return ff_qsv_print_error(avctx, ret,
+                                  "Error initializing the encoder");
+    else if (ret > 0)
+        ff_qsv_print_warning(avctx, ret,
+                             "Warning in encoder initialization");
 
     ret = qsv_retrieve_enc_params(avctx, q);
     if (ret < 0) {
@@ -984,11 +994,15 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
             av_usleep(500);
     } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_WRN_IN_EXECUTION);
 
+    if (ret > 0)
+        ff_qsv_print_warning(avctx, ret, "Warning during encoding");
+
     if (ret < 0) {
         av_packet_unref(&new_pkt);
         av_freep(&bs);
         av_freep(&sync);
-        return (ret == MFX_ERR_MORE_DATA) ? 0 : ff_qsv_error(ret);
+        return (ret == MFX_ERR_MORE_DATA) ?
+               0 : ff_qsv_print_error(avctx, ret, "Error during encoding");
     }
 
     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame)