On Thu, 8 Aug 2013 11:48:56 +0200, Luca Barbato <[email protected]> wrote:
> ---
> configure | 7 +
> libavcodec/Makefile | 3 +
> libavcodec/allcodecs.c | 1 +
> libavcodec/qsv.c | 377
> +++++++++++++++++++++++++++++++++++++++++++++++++
> libavcodec/qsv.h | 63 +++++++++
> libavcodec/qsv_h264.c | 132 +++++++++++++++++
> 6 files changed, 583 insertions(+)
> create mode 100644 libavcodec/qsv.c
> create mode 100644 libavcodec/qsv.h
> create mode 100644 libavcodec/qsv_h264.c
>
> +
> +int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
> + AVFrame *frame, int *got_frame,
> + AVPacket *avpkt)
> +{
> + mfxFrameSurface1 *insurf;
> + mfxFrameSurface1 *outsurf;
> + mfxSyncPoint sync;
> + int ret, i = 0;
> + int size = avpkt->size;
> +
> + *got_frame = 0;
> +
> + av_packet_list_put(&q->pending, &q->pending_end, avpkt);
> +
> + if (!q->wait) {
> + av_packet_list_get(&q->pending, &q->pending_end, avpkt);
> +
> + if ((ret = put_dts(q, avpkt->pts, avpkt->dts)) < 0)
> + return ret;
> +
> + q->bs.TimeStamp = avpkt->pts;
> +
> + ret = bitstream_enqueue(&q->bs, avpkt->data, avpkt->size);
> +
> + av_packet_unref(avpkt);
> +
> + if (ret < 0)
> + return ret;
> + }
> +
> + ret = MFX_ERR_MORE_SURFACE;
> +
> + while ((insurf = get_surface(q)) && ret == MFX_ERR_MORE_SURFACE) {
> + ret = MFXVideoDECODE_DecodeFrameAsync(q->session, &q->bs,
> + insurf, &outsurf, &sync);
> + }
> +
> + q->wait = 1;
> +
> + switch (ret) {
> + case MFX_ERR_MORE_DATA:
> + q->wait = 0;
> + ret = 0;
> + break;
> + case MFX_WRN_VIDEO_PARAM_CHANGED:
> + // FIXME handle the param change properly.
> + // ret = MFXVideoDECODE_QueryIOSurf(q->session, &q->qsv.param, &req);
> + // if (ret < 0)
> + // return ff_qsv_error(ret);
> + ret = 0;
> + default:
> + break;
> + }
> +
> + if (sync) {
> + int64_t dts;
> +
> + MFXVideoCORE_SyncOperation(q->session, sync, 60000);
> +
> + if ((ret = get_dts(q, outsurf->Data.TimeStamp, &dts)) < 0)
> + return ret;
> +
> + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
> + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
> + return ret;
> + }
> +
> + *got_frame = 1;
> +
> + frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp;
> + frame->pkt_dts = dts;
> +
> + frame->repeat_pict =
> + outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED;
> + frame->top_field_first =
> + outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
> + frame->interlaced_frame =
> + !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
> +
> + for (i = 0; i < frame->height; i++) {
> + memcpy(frame->data[0] + frame->linesize[0] * i,
> + outsurf->Data.Y + outsurf->Data.Pitch * i,
> + FFMIN(outsurf->Data.Pitch, frame->linesize[0]));
> + }
> + for (i = 0; i < frame->height/2; i++) {
> + memcpy(frame->data[1] + frame->linesize[1] * i,
> + outsurf->Data.UV + outsurf->Data.Pitch * i,
> + FFMIN(outsurf->Data.Pitch, frame->linesize[1]));
> + }
This is evil.
Is there no way to avoid to avoid the copy?
> +
> +static av_cold int qsv_dec_init(AVCodecContext *avctx)
> +{
> + QSVH264Context *q = avctx->priv_data;
> + mfxBitstream *bs = &q->qsv.bs;
> + int ret;
> +
> + avctx->pix_fmt = AV_PIX_FMT_NV12;
> +
> + if (!(q->bsf = av_bitstream_filter_init("h264_mp4toannexb")))
> + return AVERROR(ENOMEM);
> +
> + // Data and DataLength passed as dummy pointers
> + av_bitstream_filter_filter(q->bsf, avctx, NULL,
> + &bs->Data, &bs->DataLength,
> + NULL, 0, 0);
> +
> + //FIXME feed it a fake IDR directly
> + bs->Data = av_malloc(avctx->extradata_size + sizeof(fake_idr));
> + bs->DataLength = avctx->extradata_size;
> +
> + memcpy(bs->Data, avctx->extradata, avctx->extradata_size);
> + memcpy(bs->Data + bs->DataLength, fake_idr, sizeof(fake_idr));
> +
> + bs->DataLength += sizeof(fake_idr);
> +
> + bs->MaxLength = bs->DataLength;
> +
> + ret = ff_qsv_init(avctx, &q->qsv);
> + if (ret < 0)
> + av_bitstream_filter_close(q->bsf);
leaking Data?
> +
> +AVCodec ff_h264_qsv_decoder = {
> + .name = "h264_qsv",
> + .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC /
> MPEG-4 part 10 (Intel Quick Sync Video acceleration)"),
> + .priv_data_size = sizeof(QSVH264Context),
> + .type = AVMEDIA_TYPE_VIDEO,
> + .id = AV_CODEC_ID_H264,
> + .init = qsv_dec_init,
> + .decode = qsv_dec_frame,
> + .flush = qsv_dec_flush,
> + .close = qsv_dec_close,
> + .capabilities = CODEC_CAP_DELAY | CODEC_CAP_PKT_TS,
missing DR
--
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel