mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
start coding flv->rtp
This commit is contained in:
parent
c62901a3ac
commit
2e68c375e3
6 changed files with 404 additions and 6 deletions
2
trunk/configure
vendored
2
trunk/configure
vendored
|
@ -257,7 +257,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
"srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_edge"
|
||||
"srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static"
|
||||
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
|
||||
"srs_app_mpegts_udp" "srs_app_rtc_conn" "srs_app_dtls" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call"
|
||||
"srs_app_mpegts_udp" "srs_app_rtp" "srs_app_rtc_conn" "srs_app_dtls" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call"
|
||||
"srs_app_caster_flv" "srs_app_process" "srs_app_ng_exec"
|
||||
"srs_app_hourglass" "srs_app_dash" "srs_app_fragment" "srs_app_dvr"
|
||||
"srs_app_coworkers" "srs_app_hybrid")
|
||||
|
|
|
@ -47,14 +47,14 @@ static bool is_stun(const char* data, const int size)
|
|||
return data != NULL && size > 0 && (data[0] == 0 || data[0] == 1);
|
||||
}
|
||||
|
||||
static bool is_rtp_or_rtcp(const char* data, const int size)
|
||||
static bool is_dtls(const char* data, size_t len)
|
||||
{
|
||||
return data != NULL && size > 0 && (data[0] >= 128 && data[0] <= 191);
|
||||
return (len >= 13 && (data[0] > 19 && data[0] < 64));
|
||||
}
|
||||
|
||||
static bool is_dtls(const char* data, const int size)
|
||||
static bool is_rtp_or_rtcp(const char* data, size_t len)
|
||||
{
|
||||
return data != NULL && size > 0 && (data[0] >= 20 && data[0] <= 64);
|
||||
return (len >= 12 && (data[0] & 0xC0) == 0x80);
|
||||
}
|
||||
|
||||
static string gen_random_str(int len)
|
||||
|
|
285
trunk/src/app/srs_app_rtp.cpp
Normal file
285
trunk/src/app/srs_app_rtp.cpp
Normal file
|
@ -0,0 +1,285 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2020 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <srs_app_rtp.hpp>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
#include <srs_kernel_buffer.hpp>
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_kernel_codec.hpp>
|
||||
#include <srs_kernel_flv.hpp>
|
||||
#include <srs_app_config.hpp>
|
||||
#include <srs_app_source.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_app_pithy_print.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_kernel_codec.hpp>
|
||||
#include <srs_kernel_file.hpp>
|
||||
#include <srs_app_utility.hpp>
|
||||
#include <srs_app_http_hooks.hpp>
|
||||
#include <srs_protocol_format.hpp>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
static string dump_string_hex(const char* buf, const int nb_buf, const int& max_len);
|
||||
static string dump_string_hex(const std::string& str, const int& max_len = 128)
|
||||
{
|
||||
return dump_string_hex(str.c_str(), str.size(), max_len);
|
||||
}
|
||||
|
||||
static string dump_string_hex(const char* buf, const int nb_buf, const int& max_len = 128)
|
||||
{
|
||||
char tmp_buf[1024*16];
|
||||
int len = 0;
|
||||
|
||||
for (int i = 0; i < nb_buf && i < max_len; ++i) {
|
||||
int nb = snprintf(tmp_buf + len, sizeof(tmp_buf) - len - 1, "%02X ", (uint8_t)buf[i]);
|
||||
if (nb <= 0)
|
||||
break;
|
||||
|
||||
len += nb;
|
||||
}
|
||||
tmp_buf[len] = '\0';
|
||||
|
||||
return string(tmp_buf, len);
|
||||
}
|
||||
|
||||
|
||||
SrsRtpRawFrame::SrsRtpRawFrame(char* buf, int len)
|
||||
{
|
||||
if (buf && len > 0) {
|
||||
payload = new char[len];
|
||||
size = len;
|
||||
memcpy(payload, buf, len);
|
||||
} else {
|
||||
payload = NULL;
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SrsRtpRawFrame::~SrsRtpRawFrame()
|
||||
{
|
||||
if (payload) {
|
||||
delete [] payload;
|
||||
payload = NULL;
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpRawFrame::avcc_to_annexb()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (! (payload[0] == 0x00 && payload[1] == 0x00 && payload[2] == 0x00 && payload[3] == 0x01)) {
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpRawFrame::frame_to_packet()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
if (payload == NULL || size <= 4) {
|
||||
return srs_error_wrap(err, "invalid rtp raw frame");
|
||||
}
|
||||
|
||||
avcc_to_annexb();
|
||||
|
||||
char buf[1500] = {0};
|
||||
SrsBuffer* stream = new SrsBuffer(buf, sizeof(buf));
|
||||
}
|
||||
|
||||
SrsRtpMuxer::SrsRtpMuxer()
|
||||
{
|
||||
}
|
||||
|
||||
SrsRtpMuxer::~SrsRtpMuxer()
|
||||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpMuxer::video_frame_to_packet(SrsSharedPtrMessage* shared_video, SrsFormat* format)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (shared_video->size < 5) {
|
||||
return srs_error_wrap(err, "invalid video size:%d", shared_video->size);
|
||||
}
|
||||
|
||||
SrsRtpRawFrame* rtp_raw_frame = new SrsRtpRawFrame(shared_video->payload + 5, shared_video->size - 5);
|
||||
SrsAutoFree(SrsRtpRawFrame, rtp_raw_frame);
|
||||
|
||||
rtp_raw_frame->frame_to_packet();
|
||||
|
||||
srs_trace("video dump=%s", dump_string_hex(shared_video->payload, shared_video->size).c_str());
|
||||
|
||||
//srs_avcc_to_annexb(raw, raw_len);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpMuxer::audio_frame_to_packet(SrsSharedPtrMessage* shared_video, SrsFormat* format)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsRtp::SrsRtp()
|
||||
{
|
||||
req = NULL;
|
||||
hub = NULL;
|
||||
|
||||
enabled = false;
|
||||
disposable = false;
|
||||
last_update_time = 0;
|
||||
}
|
||||
|
||||
SrsRtp::~SrsRtp()
|
||||
{
|
||||
}
|
||||
|
||||
void SrsRtp::dispose()
|
||||
{
|
||||
if (enabled) {
|
||||
on_unpublish();
|
||||
}
|
||||
}
|
||||
|
||||
srs_error_t SrsRtp::cycle()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtp::initialize(SrsOriginHub* h, SrsRequest* r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
hub = h;
|
||||
req = r;
|
||||
|
||||
rtp_muxer = new SrsRtpMuxer();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtp::on_publish()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// update the hls time, for hls_dispose.
|
||||
last_update_time = srs_get_system_time();
|
||||
|
||||
// support multiple publish.
|
||||
if (enabled) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// if enabled, open the muxer.
|
||||
enabled = true;
|
||||
|
||||
// ok, the hls can be dispose, or need to be dispose.
|
||||
disposable = true;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void SrsRtp::on_unpublish()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// support multiple unpublish.
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtp::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!enabled) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Ignore if no format->acodec, it means the codec is not parsed, or unknown codec.
|
||||
// @issue https://github.com/ossrs/srs/issues/1506#issuecomment-562079474
|
||||
if (!format->acodec) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// update the hls time, for hls_dispose.
|
||||
last_update_time = srs_get_system_time();
|
||||
|
||||
SrsSharedPtrMessage* audio = shared_audio->copy();
|
||||
SrsAutoFree(SrsSharedPtrMessage, audio);
|
||||
|
||||
// ts support audio codec: aac/mp3
|
||||
SrsAudioCodecId acodec = format->acodec->id;
|
||||
if (acodec != SrsAudioCodecIdAAC && acodec != SrsAudioCodecIdMP3) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// ignore sequence header
|
||||
srs_assert(format->audio);
|
||||
|
||||
return rtp_muxer->audio_frame_to_packet(audio, format);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtp::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (!enabled) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Ignore if no format->vcodec, it means the codec is not parsed, or unknown codec.
|
||||
// @issue https://github.com/ossrs/srs/issues/1506#issuecomment-562079474
|
||||
if (!format->vcodec) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// update the hls time, for hls_dispose.
|
||||
last_update_time = srs_get_system_time();
|
||||
|
||||
SrsSharedPtrMessage* video = shared_video->copy();
|
||||
SrsAutoFree(SrsSharedPtrMessage, video);
|
||||
|
||||
// ignore info frame,
|
||||
// @see https://github.com/ossrs/srs/issues/288#issuecomment-69863909
|
||||
srs_assert(format->video);
|
||||
return rtp_muxer->video_frame_to_packet(video, format);
|
||||
}
|
87
trunk/src/app/srs_app_rtp.hpp
Normal file
87
trunk/src/app/srs_app_rtp.hpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2020 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SRS_APP_RTP_HPP
|
||||
#define SRS_APP_RTP_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class SrsFormat;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsRequest;
|
||||
class SrsOriginHub;
|
||||
|
||||
class SrsRtpRawFrame
|
||||
{
|
||||
public:
|
||||
int64_t timestamp;
|
||||
char* payload;
|
||||
int size;
|
||||
public:
|
||||
SrsRtpRawFrame(char* buf, int len);
|
||||
virtual ~SrsRtpRawFrame();
|
||||
public:
|
||||
srs_error_t avcc_to_annexb();
|
||||
srs_error_t frame_to_packet();
|
||||
};
|
||||
|
||||
class SrsRtpMuxer
|
||||
{
|
||||
private:
|
||||
std::map<uint32_t, std::string> packet_queue;
|
||||
public:
|
||||
SrsRtpMuxer();
|
||||
virtual ~SrsRtpMuxer();
|
||||
public:
|
||||
srs_error_t video_frame_to_packet(SrsSharedPtrMessage* shared_video, SrsFormat* format);
|
||||
srs_error_t audio_frame_to_packet(SrsSharedPtrMessage* shared_video, SrsFormat* format);
|
||||
};
|
||||
|
||||
class SrsRtp
|
||||
{
|
||||
private:
|
||||
SrsRequest* req;
|
||||
bool enabled;
|
||||
bool disposable;
|
||||
srs_utime_t last_update_time;
|
||||
SrsRtpMuxer* rtp_muxer;
|
||||
SrsOriginHub* hub;
|
||||
public:
|
||||
SrsRtp();
|
||||
virtual ~SrsRtp();
|
||||
public:
|
||||
virtual void dispose();
|
||||
virtual srs_error_t cycle();
|
||||
public:
|
||||
virtual srs_error_t initialize(SrsOriginHub* h, SrsRequest* r);
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format);
|
||||
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -32,6 +32,7 @@ using namespace std;
|
|||
#include <srs_protocol_amf0.hpp>
|
||||
#include <srs_kernel_codec.hpp>
|
||||
#include <srs_app_hls.hpp>
|
||||
#include <srs_app_rtp.hpp>
|
||||
#include <srs_app_forward.hpp>
|
||||
#include <srs_app_config.hpp>
|
||||
#include <srs_app_encoder.hpp>
|
||||
|
@ -824,6 +825,7 @@ SrsOriginHub::SrsOriginHub()
|
|||
dash = new SrsDash();
|
||||
dvr = new SrsDvr();
|
||||
encoder = new SrsEncoder();
|
||||
rtp = new SrsRtp();
|
||||
#ifdef SRS_AUTO_HDS
|
||||
hds = new SrsHds();
|
||||
#endif
|
||||
|
@ -868,6 +870,10 @@ srs_error_t SrsOriginHub::initialize(SrsSource* s, SrsRequest* r)
|
|||
return srs_error_wrap(err, "format initialize");
|
||||
}
|
||||
|
||||
if ((err = rtp->initialize(this, req)) != srs_success) {
|
||||
return srs_error_wrap(err, "rtp initialize");
|
||||
}
|
||||
|
||||
if ((err = hls->initialize(this, req)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls initialize");
|
||||
}
|
||||
|
@ -965,6 +971,12 @@ srs_error_t SrsOriginHub::on_audio(SrsSharedPtrMessage* shared_audio)
|
|||
flv_sample_sizes[c->sound_size], flv_sound_types[c->sound_type],
|
||||
srs_flv_srates[c->sound_rate]);
|
||||
}
|
||||
|
||||
if ((err = rtp->on_audio(msg, format)) != srs_success) {
|
||||
srs_warn("rtp: ignore audio error %s", srs_error_desc(err).c_str());
|
||||
srs_error_reset(err);
|
||||
rtp->on_unpublish();
|
||||
}
|
||||
|
||||
if ((err = hls->on_audio(msg, format)) != srs_success) {
|
||||
// apply the error strategy for hls.
|
||||
|
@ -1058,6 +1070,12 @@ srs_error_t SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_se
|
|||
if (format->vcodec && !format->vcodec->is_avc_codec_ok()) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = rtp->on_video(msg, format)) != srs_success) {
|
||||
srs_warn("rtp: ignore video error %s", srs_error_desc(err).c_str());
|
||||
srs_error_reset(err);
|
||||
rtp->on_unpublish();
|
||||
}
|
||||
|
||||
if ((err = hls->on_video(msg, format)) != srs_success) {
|
||||
// apply the error strategy for hls.
|
||||
|
@ -1126,6 +1144,10 @@ srs_error_t SrsOriginHub::on_publish()
|
|||
return srs_error_wrap(err, "encoder publish");
|
||||
}
|
||||
|
||||
if ((err = rtp->on_publish()) != srs_success) {
|
||||
return srs_error_wrap(err, "rtp publish");
|
||||
}
|
||||
|
||||
if ((err = hls->on_publish()) != srs_success) {
|
||||
return srs_error_wrap(err, "hls publish");
|
||||
}
|
||||
|
@ -1163,6 +1185,7 @@ void SrsOriginHub::on_unpublish()
|
|||
destroy_forwarders();
|
||||
|
||||
encoder->on_unpublish();
|
||||
rtp->on_unpublish();
|
||||
hls->on_unpublish();
|
||||
dash->on_unpublish();
|
||||
dvr->on_unpublish();
|
||||
|
@ -2224,7 +2247,7 @@ srs_error_t SrsSource::on_video(SrsCommonMessage* shared_video)
|
|||
return srs_error_wrap(err, "create message");
|
||||
}
|
||||
|
||||
// directly process the audio message.
|
||||
// directly process the video message.
|
||||
if (!mix_correct) {
|
||||
return on_video_imp(&msg);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ class SrsNgExec;
|
|||
class SrsConnection;
|
||||
class SrsMessageHeader;
|
||||
class SrsHls;
|
||||
class SrsRtp;
|
||||
class SrsDvr;
|
||||
class SrsDash;
|
||||
class SrsEncoder;
|
||||
|
@ -335,6 +336,8 @@ private:
|
|||
private:
|
||||
// The format, codec information.
|
||||
SrsRtmpFormat* format;
|
||||
// rtp handler
|
||||
SrsRtp* rtp;
|
||||
// hls handler.
|
||||
SrsHls* hls;
|
||||
// The DASH encoder.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue