]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/qsvdec.c
atrac3plus: Convert to the new bitstream reader
[ffmpeg] / libavcodec / qsvdec.c
index 4802932ea7c92c87e75625aef5240017def60a72..b6fead0b8428b65dcb17d84893d022621eca4f27 100644 (file)
@@ -90,7 +90,7 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
     const AVPixFmtDescriptor *desc;
     mfxSession session = NULL;
     int iopattern = 0;
-    mfxVideoParam param = { { 0 } };
+    mfxVideoParam param = { 0 };
     int frame_width  = avctx->coded_width;
     int frame_height = avctx->coded_height;
     int ret;
@@ -106,7 +106,7 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
             return AVERROR(ENOMEM);
     }
 
-    if (avctx->hwaccel_context) {
+    if (avctx->pix_fmt == AV_PIX_FMT_QSV && avctx->hwaccel_context) {
         AVQSVContext *user_ctx = avctx->hwaccel_context;
         session           = user_ctx->session;
         iopattern         = user_ctx->iopattern;
@@ -144,8 +144,8 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
         return ret;
 
     param.mfx.CodecId      = ret;
-    param.mfx.CodecProfile = avctx->profile;
-    param.mfx.CodecLevel   = avctx->level;
+    param.mfx.CodecProfile = ff_qsv_profile_to_mfx(avctx->codec_id, avctx->profile);
+    param.mfx.CodecLevel   = avctx->level == FF_LEVEL_UNKNOWN ? MFX_LEVEL_UNKNOWN : avctx->level;
 
     param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;
     param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
@@ -155,6 +155,21 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
     param.mfx.FrameInfo.Height         = frame_height;
     param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
 
+    switch (avctx->field_order) {
+    case AV_FIELD_PROGRESSIVE:
+        param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
+        break;
+    case AV_FIELD_TT:
+        param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
+        break;
+    case AV_FIELD_BB:
+        param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_BFF;
+        break;
+    default:
+        param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_UNKNOWN;
+        break;
+    }
+
     param.IOPattern   = q->iopattern;
     param.AsyncDepth  = q->async_depth;
     param.ExtParam    = q->ext_buffers;
@@ -179,17 +194,25 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame)
         return ret;
 
     if (frame->frame->format == AV_PIX_FMT_QSV) {
-        frame->surface = (mfxFrameSurface1*)frame->frame->data[3];
+        frame->surface = *(mfxFrameSurface1*)frame->frame->data[3];
     } else {
-        frame->surface_internal.Info = q->frame_info;
+        frame->surface.Info = q->frame_info;
 
-        frame->surface_internal.Data.PitchLow = frame->frame->linesize[0];
-        frame->surface_internal.Data.Y        = frame->frame->data[0];
-        frame->surface_internal.Data.UV       = frame->frame->data[1];
+        frame->surface.Data.PitchLow = frame->frame->linesize[0];
+        frame->surface.Data.Y        = frame->frame->data[0];
+        frame->surface.Data.UV       = frame->frame->data[1];
+    }
 
-        frame->surface = &frame->surface_internal;
+    if (q->frames_ctx.mids) {
+        ret = ff_qsv_find_surface_idx(&q->frames_ctx, frame);
+        if (ret < 0)
+            return ret;
+
+        frame->surface.Data.MemId = &q->frames_ctx.mids[ret];
     }
 
+    frame->used = 1;
+
     return 0;
 }
 
@@ -197,8 +220,8 @@ static void qsv_clear_unused_frames(QSVContext *q)
 {
     QSVFrame *cur = q->work_frames;
     while (cur) {
-        if (cur->surface && !cur->surface->Data.Locked && !cur->queued) {
-            cur->surface = NULL;
+        if (cur->used && !cur->surface.Data.Locked && !cur->queued) {
+            cur->used = 0;
             av_frame_unref(cur->frame);
         }
         cur = cur->next;
@@ -215,11 +238,11 @@ static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **
     frame = q->work_frames;
     last  = &q->work_frames;
     while (frame) {
-        if (!frame->surface) {
+        if (!frame->used) {
             ret = alloc_frame(avctx, q, frame);
             if (ret < 0)
                 return ret;
-            *surf = frame->surface;
+            *surf = &frame->surface;
             return 0;
         }
 
@@ -241,7 +264,7 @@ static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **
     if (ret < 0)
         return ret;
 
-    *surf = frame->surface;
+    *surf = &frame->surface;
 
     return 0;
 }
@@ -250,7 +273,7 @@ static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
 {
     QSVFrame *cur = q->work_frames;
     while (cur) {
-        if (surf == cur->surface)
+        if (surf == &cur->surface)
             return cur;
         cur = cur->next;
     }
@@ -305,8 +328,12 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
     /* make sure we do not enter an infinite loop if the SDK
      * did not consume any data and did not return anything */
     if (!*sync && !bs.DataOffset) {
-        av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");
         bs.DataOffset = avpkt->size;
+        ++q->zero_consume_run;
+        if (q->zero_consume_run > 1)
+            ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data");
+    } else {
+        q->zero_consume_run = 0;
     }
 
     if (*sync) {
@@ -346,7 +373,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
         if (ret < 0)
             return ret;
 
-        outsurf = out_frame->surface;
+        outsurf = &out_frame->surface;
 
 #if FF_API_PKT_PTS
 FF_DISABLE_DEPRECATION_WARNINGS
@@ -364,6 +391,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
         frame->interlaced_frame =
             !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
 
+        /* update the surface properties */
+        if (avctx->pix_fmt == AV_PIX_FMT_QSV)
+            ((mfxFrameSurface1*)frame->data[3])->Info = outsurf->Info;
+
         *got_frame = 1;
     }
 
@@ -404,8 +435,7 @@ int ff_qsv_decode_close(QSVContext *q)
         MFXClose(q->internal_session);
 
     av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
-    av_freep(&q->frames_ctx.mids);
-    q->frames_ctx.nb_mids = 0;
+    av_buffer_unref(&q->frames_ctx.mids_buf);
 
     return 0;
 }
@@ -474,6 +504,7 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q,
         avctx->height       = q->parser->height;
         avctx->coded_width  = q->parser->coded_width;
         avctx->coded_height = q->parser->coded_height;
+        avctx->field_order  = q->parser->field_order;
         avctx->level        = q->avctx_internal->level;
         avctx->profile      = q->avctx_internal->profile;