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 | 80 ++++++++++++++++++++++++++-------------- 1 files changed, 52 insertions(+), 28 deletions(-) diff --git a/csrc/ffmpeg/format/FormatOut.cpp b/csrc/ffmpeg/format/FormatOut.cpp index d686d8e..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" @@ -106,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_; @@ -181,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()); @@ -193,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(){ @@ -345,18 +343,10 @@ } flag = openResource(filename, 2); - - if(flag){ - AVDictionary *avdic = NULL; - char option_key[]="movflags"; - char option_value[]="frag_keyframe+empty_moov"; - av_dict_set(&avdic,option_key,option_value,0); - flag = writeHeader(&avdic); - av_dict_free(&avdic); - } - if (v){ - if (v->codecpar->codec_id == AV_CODEC_ID_H264){ +// 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){ @@ -371,6 +361,17 @@ } } } +// h264 mp4toannexb + + if(flag){ + AVDictionary *avdic = NULL; + char option_key[]="movflags"; + char option_value[]="frag_keyframe+empty_moov"; + av_dict_set(&avdic,option_key,option_value,0); + flag = writeHeader(&avdic); + av_dict_free(&avdic); + } + return flag; } @@ -476,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); @@ -493,18 +495,40 @@ bool FormatOut::writeFrameInternal(AVPacket *pkt, bool interleaved){ - // h264_mp4toanatax - if (bsf_h264){ - if (av_bsf_send_packet(bsf_h264, pkt) < 0){ - logIt("bsf_h264 send packet failed"); - return true; - } - int ret; - while((ret = av_bsf_receive_packet(bsf_h264, pkt)) == 0){ - if (!write_frame(ctx_, pkt, interleaved)) return false; + 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; + } + } + } } - if (ret == AVERROR(EAGAIN)) return true; + 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