mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-06 12:39:26 +08:00
各协议全面支持vp8/vp9/av1编码,ertmp新增支持opus编码 (#4498)
实现功能: - rtp 增加vp8,vp9和av1编码支持 - 实现MP4录像所需的extra_data接口 - 扩展rtmp增加对opus、vp8、vp9和av1的支持 已知问题: - 开启enhance rtmp后,ffmpeg暂时不支持播放vp8编码格式,其他格式的支持 - vp9和av1开始播放时容易遇到卡顿情况,过几秒后好了,原因暂时未知 --------- Co-authored-by: xia-chu <771730766@qq.com>
This commit is contained in:
94
ext-codec/OpusRtmp.cpp
Normal file
94
ext-codec/OpusRtmp.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT-like license that can be found in the
|
||||
* LICENSE file in the root of the source tree. All contributing project authors
|
||||
* may be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "OpusRtmp.h"
|
||||
#include "Rtmp/utils.h"
|
||||
#include "Common/config.h"
|
||||
#include "Extension/Factory.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
void OpusRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt) {
|
||||
auto data = pkt->data();
|
||||
int size = pkt->size();
|
||||
auto flags = (uint8_t)data[0];
|
||||
auto codec = (RtmpAudioCodec)(flags >> 4);
|
||||
auto type = flags & 0x0F;
|
||||
data++; size--;
|
||||
if (codec == RtmpAudioCodec::FOURCC) {
|
||||
// @todo parse enhance audio header and check fourcc
|
||||
data += 4;
|
||||
size -= 4;
|
||||
if (type == (uint8_t)RtmpPacketType::PacketTypeSequenceStart) {
|
||||
getTrack()->setExtraData((uint8_t *)data, size);
|
||||
} else {
|
||||
outputFrame(data, size, pkt->time_stamp, pkt->time_stamp);
|
||||
}
|
||||
} else {
|
||||
outputFrame(data, size, pkt->time_stamp, pkt->time_stamp);
|
||||
}
|
||||
}
|
||||
|
||||
void OpusRtmpDecoder::outputFrame(const char *data, size_t size, uint32_t dts, uint32_t pts) {
|
||||
RtmpCodec::inputFrame(Factory::getFrameFromPtr(getTrack()->getCodecId(), data, size, dts, pts));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
OpusRtmpEncoder::OpusRtmpEncoder(const Track::Ptr &track) : RtmpCodec(track) {
|
||||
_enhanced = mINI::Instance()[Rtmp::kEnhanced];
|
||||
}
|
||||
|
||||
bool OpusRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||
auto packet = RtmpPacket::create();
|
||||
if (_enhanced) {
|
||||
uint8_t flags = ((uint8_t)RtmpAudioCodec::FOURCC << 4) | (uint8_t)RtmpPacketType::PacketTypeCodedFrames;
|
||||
packet->buffer.push_back(flags);
|
||||
packet->buffer.append("Opus", 4);
|
||||
} else {
|
||||
uint8_t flags = getAudioRtmpFlags(getTrack());
|
||||
packet->buffer.push_back(flags);
|
||||
}
|
||||
packet->buffer.append(frame->data(), frame->size());
|
||||
packet->body_size = packet->buffer.size();
|
||||
packet->time_stamp = frame->dts();
|
||||
packet->chunk_id = CHUNK_AUDIO;
|
||||
packet->stream_index = STREAM_MEDIA;
|
||||
packet->type_id = MSG_AUDIO;
|
||||
// Output rtmp packet
|
||||
RtmpCodec::inputRtmp(packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpusRtmpEncoder::makeConfigPacket() {
|
||||
auto extra_data = getTrack()->getExtraData();
|
||||
if (!extra_data || !extra_data->size())
|
||||
return;
|
||||
auto pkt = RtmpPacket::create();
|
||||
if (_enhanced) {
|
||||
uint8_t flags = ((uint8_t)RtmpAudioCodec::FOURCC << 4) | (uint8_t)RtmpPacketType::PacketTypeSequenceStart;
|
||||
pkt->buffer.push_back(flags);
|
||||
pkt->buffer.append("Opus", 4);
|
||||
} else {
|
||||
uint8_t flags = getAudioRtmpFlags(getTrack());
|
||||
pkt->buffer.push_back(flags);
|
||||
}
|
||||
pkt->buffer.append(extra_data->data(), extra_data->size());
|
||||
pkt->body_size = pkt->buffer.size();
|
||||
pkt->chunk_id = CHUNK_AUDIO;
|
||||
pkt->stream_index = STREAM_MEDIA;
|
||||
pkt->time_stamp = 0;
|
||||
pkt->type_id = MSG_AUDIO;
|
||||
RtmpCodec::inputRtmp(pkt);
|
||||
}
|
||||
|
||||
} // namespace mediakit
|
||||
Reference in New Issue
Block a user