From patchwork Sun May 3 00:35:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhao, Gang" X-Patchwork-Id: 19448 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 1A50D44B48A for ; Sun, 3 May 2020 03:36:15 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E85CB68BEE3; Sun, 3 May 2020 03:36:14 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f195.google.com (mail-pg1-f195.google.com [209.85.215.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C23F568BB3F for ; Sun, 3 May 2020 03:36:07 +0300 (EEST) Received: by mail-pg1-f195.google.com with SMTP id n11so6657886pgl.9 for ; Sat, 02 May 2020 17:36:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=B4UhCg6cyfDsKIhjykf7NbkMK10wvD27E8op1UnSVEA=; b=uOFpsLf2VtBiMUS08/hlpwSzkhqUQNO59OzEJGrHcLeCrXVIvc+BY46YQfzWv1Fj1Q oyPJi8ubeQyR6utdwN9ySFCOH3/WmuB/OBNSFVyO1NVgE9fAw96aSLw9avwhzU4frnw/ MmLVfMR+6G805Y+kTrMW3KLDiLWRTwVUTMOSIQxdMIOmoRH3JGUGIgmBtmXhEPsMY9u/ az2tG4oVk+fVlbqM65TuM95bJ+EerzATX0d7JwljeVWEDoj4dupy66Z3WXPOdpIxLstO VDDA7Uxz+xDHriXsVskAmRCP4PLYPgYkgxHLeeA1DzXf+UGgV0XR4LYwkB9l+V1n71y/ Zvsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=B4UhCg6cyfDsKIhjykf7NbkMK10wvD27E8op1UnSVEA=; b=uM4kPvtywT894YC2tiUYBYCAV2Tcw8FwUBQXs+ET3IW1dVF0qUnYKN49vW0cwFmqzL hDOTzNs8Qv4aqwiqhhnBWpCxlHzZyt4mESy4t6k0oxqFZ/BQA/nWBomi8ump9udugZSe KZEUKUdDRAqZ4vw8y1zqPqByEdYyeaLWiO7wLP33ZXbiXV0JOu4XxE+o3yAsQgPmECCc RIQCMXwMaIbN9FVwxx4wrB5KA/zh2RTlm88G5s5d9lU9BH0v+n9msu3X2yQECYQEbkDE KO2oB5aEsMI+CFAHF3YvrWlsJddscJYn2WKwFXnZdasRreY5eA+YOqoLDfEZ2RTaLzt0 2auQ== X-Gm-Message-State: AGi0PuYaPtydyINC6FlN7GHMl048UZo85QES9QZUgjXKbAIH3tSm/gx6 eFGSX5u9cAhjaaZecvzSEyxLDNocIA4= X-Google-Smtp-Source: APiQypJD2yDXiSoSEAzp8DKJiFDYrQTMa4ICZdFDJ6G/sZ5uRdfB25uVptb+dhi+KnplIo7dFU7iZw== X-Received: by 2002:a63:1961:: with SMTP id 33mr11245134pgz.282.1588466165316; Sat, 02 May 2020 17:36:05 -0700 (PDT) Received: from localhost.localdomain ([2600:3c01::f03c:91ff:feee:c20d]) by smtp.gmail.com with ESMTPSA id s9sm5482244pfc.179.2020.05.02.17.36.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 May 2020 17:36:04 -0700 (PDT) From: "Zhao, Gang" To: Date: Sun, 3 May 2020 08:35:33 +0800 Message-Id: <2c1d5f037490551da69ddec59088969fd6d85de0.1588464875.git.gang.zhao.42@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200502101825.2qbsze2xptt4ra2j@phare.normalesup.org> References: <20200502101825.2qbsze2xptt4ra2j@phare.normalesup.org> Subject: [FFmpeg-devel] [PATCH v2] doc/examples/transcoding: update to new encode/decode API 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Zhao, Gang --- Changes from v1: Rephrased the commit log to better describe what this patch does. Removed calling of av_log_set_level(AV_LOG_DEBUG) which is used for debugging. This patch doesn't depend on other patches and can be applied separately. Tested that the new code generated the same file as before by running ./doc/examples/transcoding_g my_samples/transcoding.mp4 my_samples/transcoding.avi doc/examples/transcoding.c | 105 +++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 51 deletions(-) diff --git doc/examples/transcoding.c doc/examples/transcoding.c index e48837cbd2..faa36c68e7 100644 --- doc/examples/transcoding.c +++ doc/examples/transcoding.c @@ -402,39 +402,50 @@ static int init_filters(void) return 0; } -static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame) { +static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index) { int ret; - int got_frame_local; AVPacket enc_pkt; - int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) = - (ifmt_ctx->streams[stream_index]->codecpar->codec_type == - AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2; - - if (!got_frame) - got_frame = &got_frame_local; av_log(NULL, AV_LOG_INFO, "Encoding frame\n"); /* encode filtered frame */ enc_pkt.data = NULL; enc_pkt.size = 0; av_init_packet(&enc_pkt); - ret = enc_func(stream_ctx[stream_index].enc_ctx, &enc_pkt, - filt_frame, got_frame); - av_frame_free(&filt_frame); - if (ret < 0) - return ret; - if (!(*got_frame)) - return 0; - /* prepare packet for muxing */ - enc_pkt.stream_index = stream_index; - av_packet_rescale_ts(&enc_pkt, - stream_ctx[stream_index].enc_ctx->time_base, - ofmt_ctx->streams[stream_index]->time_base); + /* send the frame for encoding */ + ret = avcodec_send_frame(stream_ctx[stream_index].enc_ctx, filt_frame); + if (ret < 0) { + fprintf(stderr, "(%s:%d) Error sending the frame to the encoder: %s\n", + __FUNCTION__, __LINE__, av_err2str(ret)); + exit(1); + } + + /* read all the available output packets (in general there may be any + * number of them */ + while (ret >= 0) { + ret = avcodec_receive_packet(stream_ctx[stream_index].enc_ctx, &enc_pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + /* return OK. Should call avcodec_send_frame again to get more packets */ + ret = 0; + break; + } + else if (ret < 0) { + fprintf(stderr, "Error encoding audio frame\n"); + exit(1); + } + + /* prepare packet for muxing */ + enc_pkt.stream_index = stream_index; + av_packet_rescale_ts(&enc_pkt, + stream_ctx[stream_index].enc_ctx->time_base, + ofmt_ctx->streams[stream_index]->time_base); + + av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n"); + /* mux encoded frame */ + ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt); + } - av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n"); - /* mux encoded frame */ - ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt); + av_frame_free(&filt_frame); return ret; } @@ -474,7 +485,7 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) } filt_frame->pict_type = AV_PICTURE_TYPE_NONE; - ret = encode_write_frame(filt_frame, stream_index, NULL); + ret = encode_write_frame(filt_frame, stream_index); if (ret < 0) break; } @@ -484,22 +495,12 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) static int flush_encoder(unsigned int stream_index) { - int ret; - int got_frame; - if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities & AV_CODEC_CAP_DELAY)) return 0; - while (1) { - av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index); - ret = encode_write_frame(NULL, stream_index, &got_frame); - if (ret < 0) - break; - if (!got_frame) - return 0; - } - return ret; + av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index); + return encode_write_frame(NULL, stream_index); } int main(int argc, char **argv) @@ -507,11 +508,8 @@ int main(int argc, char **argv) int ret; AVPacket packet = { .data = NULL, .size = 0 }; AVFrame *frame = NULL; - enum AVMediaType type; unsigned int stream_index; unsigned int i; - int got_frame; - int (*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *); if (argc != 3) { av_log(NULL, AV_LOG_ERROR, "Usage: %s \n", argv[0]); @@ -530,7 +528,6 @@ int main(int argc, char **argv) if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0) break; stream_index = packet.stream_index; - type = ifmt_ctx->streams[packet.stream_index]->codecpar->codec_type; av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n", stream_index); @@ -544,24 +541,30 @@ int main(int argc, char **argv) av_packet_rescale_ts(&packet, ifmt_ctx->streams[stream_index]->time_base, stream_ctx[stream_index].dec_ctx->time_base); - dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 : - avcodec_decode_audio4; - ret = dec_func(stream_ctx[stream_index].dec_ctx, frame, - &got_frame, &packet); + + /* send the packet for decoding */ + ret = avcodec_send_packet(stream_ctx[stream_index].dec_ctx, &packet); if (ret < 0) { - av_frame_free(&frame); - av_log(NULL, AV_LOG_ERROR, "Decoding failed\n"); - break; + fprintf(stderr, "(%s:%d) Error sending the packet to the encoder: %s\n", + __FUNCTION__, __LINE__, av_err2str(ret)); + exit(1); } - if (got_frame) { + /* read all the available output frames (in general there may be any + * number of them */ + while (ret >= 0) { + ret = avcodec_receive_frame(stream_ctx[stream_index].dec_ctx, frame); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + break; + else if (ret < 0) { + fprintf(stderr, "Error encoding audio frame\n"); + exit(1); + } + frame->pts = frame->best_effort_timestamp; ret = filter_encode_write_frame(frame, stream_index); - av_frame_free(&frame); if (ret < 0) goto end; - } else { - av_frame_free(&frame); } } else { /* remux this frame without reencoding */