From 18a05d269516a5e33d8460291c2f93e73d95adce Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期二, 26 十二月 2023 10:45:31 +0800 Subject: [PATCH] GetYUV format is NV12 --- csrc/ffmpeg/format/FormatOut.cpp | 74 +++++++++++++++++++++++++++++++++---- 1 files changed, 66 insertions(+), 8 deletions(-) diff --git a/csrc/ffmpeg/format/FormatOut.cpp b/csrc/ffmpeg/format/FormatOut.cpp index 4d6ce60..5d51aaf 100644 --- a/csrc/ffmpeg/format/FormatOut.cpp +++ b/csrc/ffmpeg/format/FormatOut.cpp @@ -10,6 +10,7 @@ #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libavutil/opt.h> +#include <libavutil/intreadwrite.h> } #include "../log/log.hpp" @@ -33,12 +34,16 @@ ,format_name_("mp4") ,in_v_stream_(NULL) ,in_a_stream_(NULL) + ,bsf_h264(NULL) + ,bsf_hevc(NULL) {} FormatOut::~FormatOut() { clear(); + if (bsf_h264) av_bsf_free(&bsf_h264); + if (bsf_hevc) av_bsf_free(&bsf_hevc); } void FormatOut::clear(){ @@ -102,8 +107,8 @@ enc_ctx_->codec_id = AV_CODEC_ID_H264; enc_ctx_->codec_type = AVMEDIA_TYPE_VIDEO; - enc_ctx_->height = (prop.height_ & 0x01) ? prop.height_-1 : prop.height_; - enc_ctx_->width = (prop.width_ & 0x01) ? prop.width_ - 1 : prop.width_; + enc_ctx_->height = prop.height_ & ~0x01; + enc_ctx_->width = prop.width_ & ~0x01; enc_ctx_->sample_aspect_ratio = prop.sample_aspect_ratio_; @@ -177,7 +182,7 @@ av_opt_set(enc_ctx_->priv_data, "tune", "zerolatency", 0); av_opt_set(enc_ctx_->priv_data, "profile", "baseline", 0); - int err =avcodec_open2(enc_ctx_, codec, NULL); + int err = avcodec_open2(enc_ctx_, codec, NULL); if( err< 0) { logIt("can't open output codec: %s", getAVErrorDesc(err).c_str()); @@ -189,14 +194,11 @@ return false; } ofmt->video_codec = codec_id; - if(ofmt->flags & AVFMT_GLOBALHEADER) - { + if(ofmt->flags & AVFMT_GLOBALHEADER){ enc_ctx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; } - return true; - } AVStream *FormatOut::getStream(){ @@ -341,7 +343,26 @@ } flag = openResource(filename, 2); - + +// h264 mp4toannexb + if (v && v->codecpar->codec_id == AV_CODEC_ID_H264) { + if (!bsf_h264){ + char p[100] = {0}; + char *sub = av_fourcc_make_string(p, v->codecpar->codec_tag); + if (strcmp(sub, "avc1") == 0){ + const AVBitStreamFilter *f = av_bsf_get_by_name("h264_mp4toannexb"); + if (f){ + if (av_bsf_alloc(f, &bsf_h264) >= 0){ + if (avcodec_parameters_copy(bsf_h264->par_in, v->codecpar) >= 0){ + if (av_bsf_init(bsf_h264) < 0) bsf_h264 = NULL; + } + } + } + } + } + } +// h264 mp4toannexb + if(flag){ AVDictionary *avdic = NULL; char option_key[]="movflags"; @@ -456,6 +477,7 @@ } static bool write_frame(AVFormatContext *ctx, AVPacket *pkt, bool interleaved){ + int ret = 0; if(interleaved){ ret = av_interleaved_write_frame(ctx, pkt); @@ -473,6 +495,42 @@ bool FormatOut::writeFrameInternal(AVPacket *pkt, bool interleaved){ + AVBSFContext *bsf = NULL; + + if (in_v_stream_ && in_v_stream_->codecpar->codec_id == AV_CODEC_ID_HEVC) { + if (pkt->size >= 5 && + AV_RB32(pkt->data) != 0x0000001 && + AV_RB24(pkt->data) != 0x000001 && + !bsf_hevc){ + + const AVBitStreamFilter *f = av_bsf_get_by_name("hevc_mp4toannexb"); + if (f){ + if (av_bsf_alloc(f, &bsf_hevc) >= 0){ + if (avcodec_parameters_copy(bsf_hevc->par_in, in_v_stream_->codecpar) >= 0){ + if (av_bsf_init(bsf_hevc) < 0) bsf_hevc = NULL; + } + } + } + } + + bsf = bsf_hevc; + logIt("use hevc AVBitStreamFilter"); + }else { + bsf = bsf_h264; + logIt("use h264 AVBitStreamFilter"); + } + + if (bsf){ + if (av_bsf_send_packet(bsf, pkt) < 0){ + logIt("bsf send packet failed"); + return true; + } + if (av_bsf_receive_packet(bsf, pkt) < 0){ + logIt("bsf recv packet failed"); + return true; + } + } + return write_frame(ctx_, pkt, interleaved); } -- Gitblit v1.8.0