diff options
author | Anton Khirnov <anton@khirnov.net> | 2016-08-09 12:05:49 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2016-11-07 12:47:46 +0100 |
commit | 404e51478ecad060249d5b9bee6ab39a8a9d8c1c (patch) | |
tree | 942d55c8d20e5741ef4f17551dbe2959c4978238 | |
parent | e8bbacbf529049c401bfeea70d5e0b5d2c8b6de6 (diff) | |
download | ffmpeg-404e51478ecad060249d5b9bee6ab39a8a9d8c1c.tar.gz |
qsv{dec,enc}: always use an internal mfxFrameSurface1
For encoding, this avoids modifying the input surface, which we are not
allowed to do.
This will also be useful in the following commits.
Signed-off-by: Maxym Dmytrychenko <maxym.dmytrychenko@intel.com>
-rw-r--r-- | libavcodec/qsv_internal.h | 5 | ||||
-rw-r--r-- | libavcodec/qsvdec.c | 32 | ||||
-rw-r--r-- | libavcodec/qsvenc.c | 32 |
3 files changed, 36 insertions, 33 deletions
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 41f4c3ddf6..5b015a619d 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -38,11 +38,10 @@ typedef struct QSVFrame { AVFrame *frame; - mfxFrameSurface1 *surface; - - mfxFrameSurface1 surface_internal; + mfxFrameSurface1 surface; int queued; + int used; struct QSVFrame *next; } QSVFrame; diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 81c63b1292..8353d252d2 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -179,17 +179,17 @@ 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 = &frame->surface_internal; + 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->used = 1; + return 0; } @@ -197,8 +197,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 +215,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 +241,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 +250,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; } @@ -346,7 +346,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 +364,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; } diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index ba07db6e99..3d99e846e3 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -813,9 +813,9 @@ static void clear_unused_frames(QSVEncContext *q) { QSVFrame *cur = q->work_frames; while (cur) { - if (cur->surface && !cur->surface->Data.Locked) { - cur->surface = NULL; + if (cur->used && !cur->surface.Data.Locked) { av_frame_unref(cur->frame); + cur->used = 0; } cur = cur->next; } @@ -830,8 +830,9 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f) frame = q->work_frames; last = &q->work_frames; while (frame) { - if (!frame->surface) { + if (!frame->used) { *f = frame; + frame->used = 1; return 0; } @@ -850,6 +851,7 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f) *last = frame; *f = frame; + frame->used = 1; return 0; } @@ -869,7 +871,7 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, if (ret < 0) return ret; - qf->surface = (mfxFrameSurface1*)qf->frame->data[3]; + qf->surface = *(mfxFrameSurface1*)qf->frame->data[3]; } else { /* make a copy if the input is not padded as libmfx requires */ if (frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) { @@ -893,29 +895,27 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, return ret; } - qf->surface_internal.Info = q->param.mfx.FrameInfo; + qf->surface.Info = q->param.mfx.FrameInfo; - qf->surface_internal.Info.PicStruct = + qf->surface.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; + qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED; else if (frame->repeat_pict == 2) - qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING; + qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING; else if (frame->repeat_pict == 4) - qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING; + qf->surface.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 = &qf->surface_internal; + qf->surface.Data.PitchLow = qf->frame->linesize[0]; + qf->surface.Data.Y = qf->frame->data[0]; + qf->surface.Data.UV = qf->frame->data[1]; } - qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000}); + qf->surface.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000}); - *surface = qf->surface; + *surface = &qf->surface; return 0; } |