diff options
author | Anton Khirnov <anton@khirnov.net> | 2015-03-13 07:55:53 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2015-03-27 21:56:36 +0100 |
commit | b04d009b0e1a34b717f3d3bbf407aef0c742aff1 (patch) | |
tree | 9a928a89edc2ade51ae1946ec3ebe9f726e69b74 /libavcodec/qsv.c | |
parent | 1188119624e42c1b2ce5be6137d2e6c6f4f03328 (diff) | |
download | ffmpeg-b04d009b0e1a34b717f3d3bbf407aef0c742aff1.tar.gz |
qsv: rename to qsvdec
This is to avoid conflicts with the upcoming QSV encoding support.
Diffstat (limited to 'libavcodec/qsv.c')
-rw-r--r-- | libavcodec/qsv.c | 369 |
1 files changed, 0 insertions, 369 deletions
diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c deleted file mode 100644 index eef0604647..0000000000 --- a/libavcodec/qsv.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Intel MediaSDK QSV codec-independent code - * - * copyright (c) 2013 Luca Barbato - * copyright (c) 2015 Anton Khirnov <anton@khirnov.net> - * - * This file is part of Libav. - * - * Libav 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. - * - * Libav 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 Libav; 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/pixfmt.h" -#include "libavutil/time.h" - -#include "avcodec.h" -#include "internal.h" -#include "qsv_internal.h" - -int ff_qsv_error(int mfx_err) -{ - switch (mfx_err) { - case MFX_ERR_NONE: - return 0; - case MFX_ERR_MEMORY_ALLOC: - case MFX_ERR_NOT_ENOUGH_BUFFER: - return AVERROR(ENOMEM); - case MFX_ERR_INVALID_HANDLE: - return AVERROR(EINVAL); - case MFX_ERR_DEVICE_FAILED: - case MFX_ERR_DEVICE_LOST: - case MFX_ERR_LOCK_MEMORY: - return AVERROR(EIO); - case MFX_ERR_NULL_PTR: - case MFX_ERR_UNDEFINED_BEHAVIOR: - case MFX_ERR_NOT_INITIALIZED: - return AVERROR_BUG; - case MFX_ERR_UNSUPPORTED: - case MFX_ERR_NOT_FOUND: - return AVERROR(ENOSYS); - case MFX_ERR_MORE_DATA: - case MFX_ERR_MORE_SURFACE: - case MFX_ERR_MORE_BITSTREAM: - return AVERROR(EAGAIN); - case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM: - case MFX_ERR_INVALID_VIDEO_PARAM: - return AVERROR(EINVAL); - case MFX_ERR_ABORTED: - case MFX_ERR_UNKNOWN: - default: - return AVERROR_UNKNOWN; - } -} - -int ff_qsv_map_pixfmt(enum AVPixelFormat format) -{ - switch (format) { - case AV_PIX_FMT_YUV420P: - case AV_PIX_FMT_YUVJ420P: - return AV_PIX_FMT_NV12; - default: - return AVERROR(ENOSYS); - } -} - -static int codec_id_to_mfx(enum AVCodecID codec_id) -{ - switch (codec_id) { - case AV_CODEC_ID_H264: - return MFX_CODEC_AVC; - case AV_CODEC_ID_MPEG1VIDEO: - case AV_CODEC_ID_MPEG2VIDEO: - return MFX_CODEC_MPEG2; - case AV_CODEC_ID_VC1: - return MFX_CODEC_VC1; - default: - break; - } - - return AVERROR(ENOSYS); -} - -static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session) -{ - if (!session) { - if (!q->internal_session) { - mfxIMPL impl = MFX_IMPL_AUTO_ANY; - mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } }; - - const char *desc; - int ret; - - ret = MFXInit(impl, &ver, &q->internal_session); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n"); - return ff_qsv_error(ret); - } - - MFXQueryIMPL(q->internal_session, &impl); - - switch (MFX_IMPL_BASETYPE(impl)) { - case MFX_IMPL_SOFTWARE: - desc = "software"; - break; - case MFX_IMPL_HARDWARE: - case MFX_IMPL_HARDWARE2: - case MFX_IMPL_HARDWARE3: - case MFX_IMPL_HARDWARE4: - desc = "hardware accelerated"; - break; - default: - desc = "unknown"; - } - - av_log(avctx, AV_LOG_VERBOSE, - "Initialized an internal MFX session using %s implementation\n", - desc); - } - - q->session = q->internal_session; - } else { - q->session = session; - } - - /* make sure the decoder is uninitialized */ - MFXVideoDECODE_Close(q->session); - - return 0; -} - -int ff_qsv_init(AVCodecContext *avctx, QSVContext *q, mfxSession session) -{ - mfxVideoParam param = { { 0 } }; - int ret; - - ret = qsv_init_session(avctx, q, session); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error initializing an MFX session\n"); - return ret; - } - - - ret = codec_id_to_mfx(avctx->codec_id); - if (ret < 0) - return ret; - - param.mfx.CodecId = ret; - param.mfx.CodecProfile = avctx->profile; - param.mfx.CodecLevel = avctx->level; - - param.mfx.FrameInfo.BitDepthLuma = 8; - param.mfx.FrameInfo.BitDepthChroma = 8; - param.mfx.FrameInfo.Shift = 0; - param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12; - param.mfx.FrameInfo.Width = avctx->coded_width; - param.mfx.FrameInfo.Height = avctx->coded_height; - param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420; - - param.IOPattern = q->iopattern; - param.AsyncDepth = q->async_depth; - param.ExtParam = q->ext_buffers; - param.NumExtParam = q->nb_ext_buffers; - - ret = MFXVideoDECODE_Init(q->session, ¶m); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error initializing the MFX video decoder\n"); - return ff_qsv_error(ret); - } - - return 0; -} - -static int alloc_frame(AVCodecContext *avctx, QSVFrame *frame) -{ - int ret; - - ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF); - if (ret < 0) - return ret; - - if (frame->frame->format == AV_PIX_FMT_QSV) { - frame->surface = (mfxFrameSurface1*)frame->frame->data[3]; - } else { - frame->surface_internal.Info.BitDepthLuma = 8; - frame->surface_internal.Info.BitDepthChroma = 8; - frame->surface_internal.Info.FourCC = MFX_FOURCC_NV12; - frame->surface_internal.Info.Width = avctx->coded_width; - frame->surface_internal.Info.Height = avctx->coded_height; - frame->surface_internal.Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420; - - 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; - } - - return 0; -} - -static void qsv_clear_unused_frames(QSVContext *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_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf) -{ - QSVFrame *frame, **last; - int ret; - - qsv_clear_unused_frames(q); - - frame = q->work_frames; - last = &q->work_frames; - while (frame) { - if (!frame->surface) { - ret = alloc_frame(avctx, frame); - if (ret < 0) - return ret; - *surf = frame->surface; - 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; - - ret = alloc_frame(avctx, frame); - if (ret < 0) - return ret; - - *surf = frame->surface; - - return 0; -} - -static AVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf) -{ - QSVFrame *cur = q->work_frames; - while (cur) { - if (surf == cur->surface) - return cur->frame; - cur = cur->next; - } - return NULL; -} - -int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q, - AVFrame *frame, int *got_frame, - AVPacket *avpkt) -{ - mfxFrameSurface1 *insurf; - mfxFrameSurface1 *outsurf; - mfxSyncPoint sync; - mfxBitstream bs = { { { 0 } } }; - int ret; - - if (avpkt->size) { - bs.Data = avpkt->data; - bs.DataLength = avpkt->size; - bs.MaxLength = bs.DataLength; - bs.TimeStamp = avpkt->pts; - } - - do { - ret = get_surface(avctx, q, &insurf); - if (ret < 0) - return ret; - - ret = MFXVideoDECODE_DecodeFrameAsync(q->session, avpkt->size ? &bs : NULL, - insurf, &outsurf, &sync); - if (ret == MFX_WRN_DEVICE_BUSY) - av_usleep(1); - - } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE); - - if (ret != MFX_ERR_NONE && - ret != MFX_ERR_MORE_DATA && - ret != MFX_WRN_VIDEO_PARAM_CHANGED && - ret != MFX_ERR_MORE_SURFACE) { - av_log(avctx, AV_LOG_ERROR, "Error during QSV decoding.\n"); - return ff_qsv_error(ret); - } - - if (sync) { - AVFrame *src_frame; - - MFXVideoCORE_SyncOperation(q->session, sync, 60000); - - src_frame = find_frame(q, outsurf); - if (!src_frame) { - av_log(avctx, AV_LOG_ERROR, - "The returned surface does not correspond to any frame\n"); - return AVERROR_BUG; - } - - ret = av_frame_ref(frame, src_frame); - if (ret < 0) - return ret; - - frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp; - - frame->repeat_pict = - outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 : - outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 : - outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0; - frame->top_field_first = - outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF; - frame->interlaced_frame = - !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE); - - *got_frame = 1; - } - - return bs.DataOffset; -} - -int ff_qsv_close(QSVContext *q) -{ - QSVFrame *cur = q->work_frames; - - while (cur) { - q->work_frames = cur->next; - av_frame_free(&cur->frame); - av_freep(&cur); - cur = q->work_frames; - } - - if (q->internal_session) - MFXClose(q->internal_session); - - return 0; -} |