From bc9960069b94ee7b0a7cd3425c1d989636238274 Mon Sep 17 00:00:00 2001 From: pingkai Date: Thu, 6 Feb 2020 16:12:09 +0800 Subject: [PATCH] refactor(demuxer): add set meta api Signed-off-by: pingkai --- framework/codec/Apple/AppleVideoToolBox.h | 2 +- framework/demuxer/DemuxerMetaInfo.h | 21 +++++++++ framework/demuxer/IDemuxer.h | 10 +++- framework/demuxer/avFormatDemuxer.cpp | 21 ++++++--- framework/utils/AFMediaType.h | 54 +++++++++++++++------- framework/utils/ffmpeg_utils.c | 56 ++++++++++++++++++++++- framework/utils/ffmpeg_utils.h | 3 ++ 7 files changed, 142 insertions(+), 25 deletions(-) create mode 100644 framework/demuxer/DemuxerMetaInfo.h diff --git a/framework/codec/Apple/AppleVideoToolBox.h b/framework/codec/Apple/AppleVideoToolBox.h index 2a5863885..07f65e42e 100644 --- a/framework/codec/Apple/AppleVideoToolBox.h +++ b/framework/codec/Apple/AppleVideoToolBox.h @@ -106,7 +106,7 @@ namespace Cicada{ bool mThrowPacket{false}; std::mutex mActiveStatusMutex; bool mActive{true}; - pix_fmt mVTOutFmt = AF_PIX_FMT_NONE; + AFPixelFormat mVTOutFmt = AF_PIX_FMT_NONE; std::unique_ptr mPInMeta{nullptr}; std::queue> mRecoveryQueue{}; std::queue> mRecoveringQueue{}; diff --git a/framework/demuxer/DemuxerMetaInfo.h b/framework/demuxer/DemuxerMetaInfo.h new file mode 100644 index 000000000..eae2713a5 --- /dev/null +++ b/framework/demuxer/DemuxerMetaInfo.h @@ -0,0 +1,21 @@ +// +// Created by moqi on 2020/2/6. +// + +#ifndef CICADAMEDIA_DEMUXERMETAINFO_H +#define CICADAMEDIA_DEMUXERMETAINFO_H + +#include +#include +#include + +namespace Cicada { + class DemuxerMetaInfo { + public: + uint64_t id; + std::vector> meta; + }; +} + + +#endif //CICADAMEDIA_DEMUXERMETAINFO_H diff --git a/framework/demuxer/IDemuxer.h b/framework/demuxer/IDemuxer.h index cf0046007..35ba5c04e 100644 --- a/framework/demuxer/IDemuxer.h +++ b/framework/demuxer/IDemuxer.h @@ -17,8 +17,9 @@ #include #include #include +#include "DemuxerMetaInfo.h" -namespace Cicada{ +namespace Cicada { typedef enum demuxer_type { demuxer_type_unknown = 0, demuxer_type_playlist, @@ -45,6 +46,11 @@ namespace Cicada{ void SetDataCallBack(demuxer_callback_read read, demuxer_callback_seek seek, demuxer_callback_open open, demuxer_callback_interrupt_data inter, void *arg); + void setMeta(DemuxerMetaInfo *metaInfo) + { + mMetaInfo = metaInfo; + } + virtual int Open() = 0; @@ -156,6 +162,8 @@ namespace Cicada{ bool mMergeVideoHeader = false; bool mMergerAudioHeader = false; + + DemuxerMetaInfo *mMetaInfo = nullptr; }; } diff --git a/framework/demuxer/avFormatDemuxer.cpp b/framework/demuxer/avFormatDemuxer.cpp index fc880734c..0a45e410a 100644 --- a/framework/demuxer/avFormatDemuxer.cpp +++ b/framework/demuxer/avFormatDemuxer.cpp @@ -96,10 +96,6 @@ namespace Cicada { av_dict_set_int(&mInputOpts, "safe", 0, 0); av_dict_set(&mInputOpts, "protocol_whitelist", "file,http,https,tcp,tls", 0); - - - - /*If a url with mp4 ext name, but is not a mp4 file, the mp4 demuxer will be matched * by ext name , mp4 demuxer will try to find moov box, it will ignore the return value * of the avio_*, and don't check interrupt flag, if the url is a network file, here will @@ -150,6 +146,19 @@ namespace Cicada { // TODO: add a opt to set fps probe mCtx->fps_probe_size = 0; // TODO: only find ts and flv's info? + + if (mMetaInfo) { + for (int i = 0; i < mCtx->nb_streams; ++i) { + if (i >= mMetaInfo->meta.size()) { + break; + } + + set_stream_meta(mCtx->streams[i], (Stream_meta *) *mMetaInfo->meta[i].get()); + } + + mCtx->max_ts_probe = 0; + } + ret = avformat_find_stream_info(mCtx, nullptr); if (mInterrupted) { @@ -220,8 +229,8 @@ namespace Cicada { err = av_read_frame(mCtx, pkt); if (err < 0) { - if (err != AVERROR(EAGAIN)) { - if (mCtx->pb && (mCtx->pb->error != AVERROR_EXIT)) { + if (err != AVERROR(EAGAIN) && mCtx->pb->error != AVERROR_EXIT) { + if (mCtx->pb) { av_log(NULL, AV_LOG_WARNING, "%s:%d: %s, ctx->pb->error=%d\n", __FILE__, __LINE__, getErrorString(err), mCtx->pb->error); } diff --git a/framework/utils/AFMediaType.h b/framework/utils/AFMediaType.h index 853b282c3..935d47ef5 100755 --- a/framework/utils/AFMediaType.h +++ b/framework/utils/AFMediaType.h @@ -44,8 +44,8 @@ enum AFCodecID { AF_CODEC_ID_VP9, // AF_CODEC_ID_MJPEG, // AF_CODEC_ID_H263, - AF_CODEC_ID_HEVC, AF_CODEC_ID_AV1, + AF_CODEC_ID_HEVC, AF_CODEC_ID_AAC, AF_CODEC_ID_AC3, @@ -97,6 +97,41 @@ enum AFSampleFormat { AF_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically }; +enum AFPixelFormat { + AF_PIX_FMT_NONE = -1, + AF_PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) + AF_PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr + AF_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... + AF_PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... + AF_PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + AF_PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) + AF_PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) + AF_PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) + AF_PIX_FMT_GRAY8, ///< Y , 8bpp + AF_PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb + AF_PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb + AF_PIX_FMT_PAL8, ///< 8 bits with AV_PIX_FMT_RGB32 palette + AF_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range + AF_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range + AF_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range + AF_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 + AF_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 + AF_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) + AF_PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + AF_PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) + AF_PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) + AF_PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits + AF_PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) + AF_PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) + AF_PIX_FMT_NV21, ///< as above, but U and V bytes are swapped + + AF_PIX_FMT_D3D11 = 900, + AF_PIX_FMT_DXVA2_VLD, + + AF_PIX_FMT_APPLE_PIXEL_BUFFER = 1000, + AF_PIX_FMT_CICADA_AF,//framework VideoFrame + AF_PIX_FMT_CICADA_MEDIA_CODEC,//Android mediacodec buffer index +}; typedef enum InterlacedType_t { InterlacedType_UNKNOWN = -1, @@ -181,6 +216,7 @@ typedef struct { int displayWidth; int displayHeight; double avg_fps; + enum AFPixelFormat pixel_fmt; int pid; int no_program; @@ -198,20 +234,6 @@ typedef struct { } Stream_meta; -enum pix_fmt { - AF_PIX_FMT_NONE = -1, - AF_PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) - AF_PIX_FMT_YUVJ420P = 12, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range - AF_PIX_FMT_YUVJ422P, - - AF_PIX_FMT_D3D11, - AF_PIX_FMT_DXVA2_VLD, - - AF_PIX_FMT_APPLE_PIXEL_BUFFER = 1000, - AF_PIX_FMT_CICADA_AF,//framework VideoFrame - AF_PIX_FMT_CICADA_MEDIA_CODEC,//Android mediacodec buffer index -}; - enum color_space { COLOR_SPACE_UNSPECIFIED = 0, COLOR_SPACE_BT709 = 1, @@ -243,7 +265,7 @@ enum dec_flag { dec_flag_direct, dec_flag_adaptive, // adjust setting to output frames as soon as possiable. - dec_flag_output_frame_asap, + dec_flag_output_frame_asap, }; #define DECFLAG_DUMMY 1u << dec_flag_dummy #define DECFLAG_HW (1u << dec_flag_hw) diff --git a/framework/utils/ffmpeg_utils.c b/framework/utils/ffmpeg_utils.c index 819867556..7a37bd339 100644 --- a/framework/utils/ffmpeg_utils.c +++ b/framework/utils/ffmpeg_utils.c @@ -358,7 +358,7 @@ enum AVCodecID CodecID2AVCodecID(enum AFCodecID codec) typedef struct pix_fmt_pair_t { - enum pix_fmt klId; + enum AFPixelFormat klId; enum AVPixelFormat avId; } pix_fmt_pair; @@ -419,6 +419,59 @@ int AVColorRange2AF(enum AVColorRange range) } } +int set_stream_meta(struct AVStream *pStream, Stream_meta *meta) +{ + AVCodecParameters *codecpar = pStream->codecpar; + + switch (meta->type) { + case STREAM_TYPE_VIDEO: + if (meta->height > 0 && meta->width > 0) { + codecpar->height = meta->height; + codecpar->width = meta->width; + } + + if (meta->pixel_fmt >= 0) { + codecpar->format = meta->pixel_fmt; + } + + break; + + case STREAM_TYPE_AUDIO: + if (meta->channels > 0) { + codecpar->channels = meta->channels; + } + + if (meta->samplerate > 0) { + codecpar->sample_rate = meta->samplerate; + } + + if (meta->sample_fmt > 0) { + codecpar->format = meta->sample_fmt; + } + + if (meta->frame_size > 0) { + codecpar->frame_size = meta->frame_size; + } + + break; + + default: + break; + } + + if (meta->extradata_size > 0 && meta->extradata) { + if (codecpar->extradata) { + free(codecpar->extradata); + } + + codecpar->extradata = av_mallocz(meta->extradata_size + AVPROBE_PADDING_SIZE); + memcpy(codecpar->extradata, meta->extradata, meta->extradata_size); + codecpar->extradata_size = meta->extradata_size; + } + + return 0; +} + int get_stream_meta(struct AVStream *pStream, Stream_meta *meta) { enum AVMediaType codec_type = pStream->codecpar->codec_type; @@ -466,6 +519,7 @@ int get_stream_meta(struct AVStream *pStream, Stream_meta *meta) meta->width = pStream->codecpar->width; meta->height = pStream->codecpar->height; meta->profile = pStream->codecpar->profile; + meta->pixel_fmt = pStream->codecpar->format; if (meta->codec == AF_CODEC_ID_H264) { meta->interlaced = InterlacedType_UNKNOWN; diff --git a/framework/utils/ffmpeg_utils.h b/framework/utils/ffmpeg_utils.h index f9ebb45dc..2bc3bf2bd 100644 --- a/framework/utils/ffmpeg_utils.h +++ b/framework/utils/ffmpeg_utils.h @@ -37,6 +37,9 @@ enum AFCodecID AVCodec2CicadaCodec(enum AVCodecID codec); enum AVCodecID CodecID2AVCodecID(enum AFCodecID codec); + +int set_stream_meta(struct AVStream *pStream, Stream_meta *meta); + int get_stream_meta(struct AVStream *pStream, Stream_meta *meta); int AVPixFmt2Cicada(enum AVPixelFormat fmt);