From patchwork Wed Aug 2 17:27:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhong Li X-Patchwork-Id: 4581 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.46.211 with SMTP id u202csp784905vsu; Tue, 1 Aug 2017 22:28:04 -0700 (PDT) X-Received: by 10.28.61.4 with SMTP id k4mr2620127wma.148.1501651684697; Tue, 01 Aug 2017 22:28:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501651684; cv=none; d=google.com; s=arc-20160816; b=HJIHNvNNRo3CoTtjMGUK+AdIYRwevFj3apIqkgB0U/5bq5dl/SpOMt4aKZk2HeopNY rMBRDRkM42fRgAi5h20griVHZ+QX4aipkMegJenxo6GU2NAwPGP4kcEHQLunppU6K0QK hUzr+MeGpIfj2MyrDc8dc8P2FQulNCsh2I2g9wX4pV5Tt2/p/0a2viJ72N5PCqUiwfG7 +XE9xT9fUUYLVTsBj5iEPVmJDaeugc1NsVTpzlzTHT2j+eUMsN6MJJa8t0tG1sJW9pd2 2APxMWmUX67JPKD21XtEciHpEdjPUX9EljpaN484cYr3UdvdpZuhZrJyAnX+LyuLnfQO zPVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:delivered-to :arc-authentication-results; bh=817fjplYxUUF3iH36sLL68MIaaumM/1E+ABri4u9RjI=; b=VzGpcSrJQxc74m1BZ6CBg9tkETZdpBFNr+M9mawmkvJzdF7P5N6EyJPIJ8mc2yLSuK yadPrhDiBI180o92AMwXuwQdnag4FF2f/Wlw1LyIlBN5qmsJ+V5o5iK9smL2+g/Ffkzi 01JKYocddMbfsZcO4nXQcDW0WDz7QEF68GFcw6/V4Ix7Zb0DuKNr3Zg5rXyQK6Ia+EJv rrAuTZtmFhqWIiMOZPuwOBuKaMrnduTyvqtNvP9X9ljTy5U9vbBZ9AErwPJT67FXM1ch ffZtLZGY8Sv8OGB52clB64sPf3N/Cb8LmW49uLB5n8L19ka7gLH3wR/DRmpfyKzYEqRp EFLQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 137si2554220wmh.138.2017.08.01.22.28.04; Tue, 01 Aug 2017 22:28:04 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A650C68A32E; Wed, 2 Aug 2017 08:27:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6973968A30F for ; Wed, 2 Aug 2017 08:27:51 +0300 (EEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga104.jf.intel.com with ESMTP; 01 Aug 2017 22:27:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,309,1498546800"; d="scan'208";a="118486598" Received: from unknown (HELO localhost.localdomain.sh.intel.com) ([10.239.13.23]) by orsmga002.jf.intel.com with ESMTP; 01 Aug 2017 22:27:51 -0700 From: Zhong Li To: ffmpeg-devel@ffmpeg.org Date: Wed, 2 Aug 2017 13:27:09 -0400 Message-Id: <1501694829-13716-1-git-send-email-zhong.li@intel.com> X-Mailer: git-send-email 1.8.3.1 Subject: [FFmpeg-devel] [PATCH V2] doc/examples: Add a qsv encoder example X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Zhong Li , sw@jkqxz.net, jun.zhao@intel.com, nfxjfg@googlemail.com MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" It is an evolution from the exmaple "encode_video.c" to support qsv encoder. V1->V2: Split to a separated qsv encoding example, instead of a patch based on encode_video.c Signed-off-by: Zhong Li --- configure | 2 + doc/Makefile | 1 + doc/examples/qsvenc.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 doc/examples/qsvenc.c diff --git a/configure b/configure index 66c7b94..676cd85 100755 --- a/configure +++ b/configure @@ -1472,6 +1472,7 @@ EXAMPLE_LIST=" metadata_example muxing_example qsvdec_example + qsvenc_example remuxing_example resampling_audio_example scaling_video_example @@ -3213,6 +3214,7 @@ hw_decode_example_deps="avcodec avformat avutil" metadata_example_deps="avformat avutil" muxing_example_deps="avcodec avformat avutil swscale" qsvdec_example_deps="avcodec avutil libmfx h264_qsv_decoder" +qsvenc_example_deps="avcodec avutil libmfx" remuxing_example_deps="avcodec avformat avutil" resampling_audio_example_deps="avutil swresample" scaling_video_example_deps="avutil swscale" diff --git a/doc/Makefile b/doc/Makefile index b670f0b..ed41763 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -52,6 +52,7 @@ DOC_EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata DOC_EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec +DOC_EXAMPLES-$(CONFIG_QSVENC_EXAMPLE) += qsvenc DOC_EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing DOC_EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio DOC_EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video diff --git a/doc/examples/qsvenc.c b/doc/examples/qsvenc.c new file mode 100644 index 0000000..3b94cc8 --- /dev/null +++ b/doc/examples/qsvenc.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2017 Fabrice Bellard, Zhong Li + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * @file + * Intel QSV-accelerated encoding example + * + * @example qsvenc.c + */ + +#include +#include +#include + +#include + +#include +#include +#include "libavutil/buffer.h" +#include "libavutil/hwcontext.h" + +static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt, + FILE *outfile) +{ + int ret; + + /* send the frame to the encoder */ + if (frame) + printf("Send frame %3"PRId64"\n", frame->pts); + + ret = avcodec_send_frame(enc_ctx, frame); + if (ret < 0) { + fprintf(stderr, "Error sending a frame for encoding\n"); + exit(1); + } + + while (ret >= 0) { + ret = avcodec_receive_packet(enc_ctx, pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return; + else if (ret < 0) { + fprintf(stderr, "Error during encoding\n"); + exit(1); + } + + printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size); + fwrite(pkt->data, 1, pkt->size, outfile); + av_packet_unref(pkt); + } +} + +int main(int argc, char **argv) +{ + const char *filename, *codec_name; + const AVCodec *codec; + AVCodecContext *c= NULL; + int i, ret, x, y; + FILE *f; + AVFrame *frame; + AVPacket *pkt; + AVBufferRef *encode_device = NULL; + + if (argc <= 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(0); + } + filename = argv[1]; + codec_name = argv[2]; + + if (!strstr(codec_name, "qsv")) { + fprintf(stderr, "no qsv codec found\n"); + exit(0); + } + + avcodec_register_all(); + + /* open the qsv hardware device */ + ret = av_hwdevice_ctx_create(&encode_device, AV_HWDEVICE_TYPE_QSV, + NULL, NULL, 0); + if (ret < 0) { + fprintf(stderr, "Cannot open the hardware device\n"); + exit(1); + } + + /* find the encoder */ + codec = avcodec_find_encoder_by_name(codec_name); + if (!codec) { + fprintf(stderr, "Codec '%s' not found\n", codec_name); + exit(1); + } + + c = avcodec_alloc_context3(codec); + if (!c) { + fprintf(stderr, "Could not allocate video codec context\n"); + exit(1); + } + + pkt = av_packet_alloc(); + if (!pkt) + exit(1); + + /* put sample parameters */ + c->bit_rate = 400000; + /* resolution must be a multiple of two */ + c->width = 352; + c->height = 288; + /* frames per second */ + c->time_base = (AVRational){1, 25}; + c->framerate = (AVRational){25, 1}; + + /* emit one intra frame every ten frames + * check frame pict_type before passing frame + * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I + * then gop_size is ignored and the output of encoder + * will always be I frame irrespective to gop_size + */ + c->gop_size = 10; + c->max_b_frames = 1; + c->pix_fmt = AV_PIX_FMT_NV12; + c->hw_device_ctx = av_buffer_ref(encode_device); + + /* open it */ + ret = avcodec_open2(c, codec, NULL); + if (ret < 0) { + fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret)); + exit(1); + } + + f = fopen(filename, "wb"); + if (!f) { + fprintf(stderr, "Could not open %s\n", filename); + exit(1); + } + + frame = av_frame_alloc(); + if (!frame) { + fprintf(stderr, "Could not allocate video frame\n"); + exit(1); + } + frame->format = c->pix_fmt; + frame->width = c->width; + frame->height = c->height; + + ret = av_frame_get_buffer(frame, 32); + if (ret < 0) { + fprintf(stderr, "Could not allocate the video frame data\n"); + exit(1); + } + + /* encode 1 second of video */ + for (i = 0; i < 25; i++) { + fflush(stdout); + + /* make sure the frame data is writable */ + ret = av_frame_make_writable(frame); + if (ret < 0) + exit(1); + + /* prepare a dummy image */ + /* Y */ + for (y = 0; y < c->height; y++) { + for (x = 0; x < c->width; x++) { + frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3; + } + } + + /* Cb and Cr */ + for (y = 0; y < c->height/2; y++) { + for (x = 0; x < c->width/2; x++) { + frame->data[1][y * frame->linesize[1] + 2 * x] = 128 + y + i * 2; + frame->data[1][y * frame->linesize[1] + 2 * x + 1] = 64 + x + i * 5; + } + } + + frame->pts = i; + + /* encode the image */ + encode(c, frame, pkt, f); + } + + /* flush the encoder */ + encode(c, NULL, pkt, f); + + fclose(f); + + avcodec_free_context(&c); + av_frame_free(&frame); + av_packet_free(&pkt); + av_buffer_unref(&encode_device); + + return 0; +}