Track新增update方法,支持更新宽高采样率等信息 (#2960)

当变分辨率时候,实时更新MP4封装层的参数信息,避免出现封装层与编码(SPS)层视频宽高不一样,造成解码参数错误花屏;同时也支持更新音频采样率等信息。


---------

Co-authored-by: xia-chu <771730766@qq.com>
This commit is contained in:
fruit Juice 2023-11-07 23:36:41 +08:00 committed by GitHub
parent 77b3c4312e
commit 1609fe67d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 75 additions and 44 deletions

View File

@ -45,6 +45,7 @@ static string getTrackInfoStr(const TrackSource *track_src){
_StrPrinter codec_info;
auto tracks = track_src->getTracks(true);
for (auto &track : tracks) {
track->update();
auto codec_type = track->getTrackType();
codec_info << track->getCodecName();
switch (codec_type) {

View File

@ -67,7 +67,10 @@ static void dumpAdtsHeader(const AdtsHeader &hed, uint8_t *out) {
out[6] |= (hed.no_raw_data_blocks_in_frame & 0x03); // 2 bit
}
static void parseAacConfig(const string &config, AdtsHeader &adts) {
static bool parseAacConfig(const string &config, AdtsHeader &adts) {
if (config.size() < 2) {
return false;
}
uint8_t cfg1 = config[0];
uint8_t cfg2 = config[1];
@ -94,6 +97,7 @@ static void parseAacConfig(const string &config, AdtsHeader &adts) {
adts.aac_frame_length = 7;
adts.adts_buffer_fullness = 2047;
adts.no_raw_data_blocks_in_frame = 0;
return true;
}
#endif// ENABLE_MP4
@ -171,7 +175,9 @@ int dumpAacConfig(const string &config, size_t length, uint8_t *out, size_t out_
bool parseAacConfig(const string &config, int &samplerate, int &channels) {
#ifndef ENABLE_MP4
AdtsHeader header;
parseAacConfig(config, header);
if (!parseAacConfig(config, header)) {
return false;
}
samplerate = samplingFrequencyTable[header.sf_index];
channels = header.channel_configuration;
return true;
@ -326,11 +332,14 @@ bool AACTrack::inputFrame_l(const Frame::Ptr &frame) {
return false;
}
void AACTrack::onReady() {
if (_cfg.size() < 2) {
return;
bool AACTrack::update() {
return parseAacConfig(_cfg, _sampleRate, _channel);
}
void AACTrack::onReady() {
if (!parseAacConfig(_cfg, _sampleRate, _channel)) {
_cfg.clear();
}
parseAacConfig(_cfg, _sampleRate, _channel);
}
Track::Ptr AACTrack::clone() {
@ -342,6 +351,7 @@ Sdp::Ptr AACTrack::getSdp() {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
update();
return std::make_shared<AACSdp>(getConfig(), getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
}

View File

@ -52,6 +52,7 @@ public:
int getAudioSampleRate() const override;
int getAudioSampleBit() const override;
bool inputFrame(const Frame::Ptr &frame) override;
bool update() override;
private:
void onReady();

View File

@ -168,6 +168,10 @@ bool H264Track::inputFrame(const Frame::Ptr &frame) {
return ret;
}
bool H264Track::update() {
return getAVCInfo(_sps, _width, _height, _fps);
}
void H264Track::onReady() {
if (!getAVCInfo(_sps, _width, _height, _fps)) {
_sps.clear();

View File

@ -128,6 +128,7 @@ public:
int getVideoWidth() const override;
float getVideoFps() const override;
bool inputFrame(const Frame::Ptr &frame) override;
bool update() override;
private:
void onReady();

View File

@ -144,6 +144,10 @@ bool H265Track::inputFrame_l(const Frame::Ptr &frame) {
return ret;
}
bool H265Track::update() {
return getHEVCInfo(_vps, _sps, _width, _height, _fps);
}
void H265Track::onReady() {
if (!getHEVCInfo(_vps, _sps, _width, _height, _fps)) {
_vps.clear();

View File

@ -150,6 +150,7 @@ public:
int getVideoHeight() const override;
float getVideoFps() const override;
bool inputFrame(const Frame::Ptr &frame) override;
bool update() override;
private:
void onReady();

View File

@ -39,6 +39,11 @@ public:
*/
virtual Track::Ptr clone() = 0;
/**
* track信息sps/pps解析
*/
virtual bool update() { return false; }
/**
* sdp
* @return sdp对象

View File

@ -70,6 +70,7 @@ void PlayerProxy::setTranslationInfo()
_transtalion_info.stream_info.clear();
auto tracks = _muxer->getTracks();
for (auto &track : tracks) {
track->update();
_transtalion_info.stream_info.emplace_back();
auto &back = _transtalion_info.stream_info.back();
back.bitrate = track->getBitRate();

View File

@ -198,6 +198,7 @@ bool MP4MuxerInterface::addTrack(const Track::Ptr &track) {
return false;
}
track->update();
switch (track->getCodecId()) {
case CodecG711A:
case CodecG711U:

View File

@ -57,6 +57,7 @@ AudioMeta::AudioMeta(const AudioTrack::Ptr &audio) {
}
uint8_t getAudioRtmpFlags(const Track::Ptr &track) {
track->update();
switch (track->getTrackType()) {
case TrackAudio: {
auto audioTrack = std::dynamic_pointer_cast<AudioTrack>(track);
@ -115,6 +116,7 @@ uint8_t getAudioRtmpFlags(const Track::Ptr &track) {
void Metadata::addTrack(AMFValue &metadata, const Track::Ptr &track) {
Metadata::Ptr new_metadata;
track->update();
switch (track->getTrackType()) {
case TrackVideo: {
new_metadata = std::make_shared<VideoMeta>(std::dynamic_pointer_cast<VideoTrack>(track));