1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-14 20:31:56 +00:00

for bug #293, http ts stream, move the avc codec from app to kernel.

This commit is contained in:
winlin 2015-01-22 17:08:38 +08:00
parent dc6299171f
commit 913f98b902
17 changed files with 309 additions and 134 deletions

5
trunk/configure vendored
View file

@ -365,7 +365,8 @@ MODULE_DEPENDS=("CORE")
ModuleLibIncs=(${SRS_OBJS_DIR})
MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_stream"
"srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_file"
"srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3")
"srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts"
"srs_kernel_avc")
KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh
KERNEL_OBJS="${MODULE_OBJS[@]}"
#
@ -388,7 +389,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
"srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config"
"srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks"
"srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge"
"srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_avc_aac"
"srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client"
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic")
APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh
APP_OBJS="${MODULE_OBJS[@]}"

View file

@ -20,6 +20,8 @@ file
kernel readonly separator,
../../src/kernel/srs_kernel_aac.hpp,
../../src/kernel/srs_kernel_aac.cpp,
../../src/kernel/srs_kernel_avc.hpp,
../../src/kernel/srs_kernel_avc.cpp,
../../src/kernel/srs_kernel_codec.hpp,
../../src/kernel/srs_kernel_codec.cpp,
../../src/kernel/srs_kernel_consts.hpp,
@ -36,6 +38,8 @@ file
../../src/kernel/srs_kernel_mp3.cpp,
../../src/kernel/srs_kernel_stream.hpp,
../../src/kernel/srs_kernel_stream.cpp,
../../src/kernel/srs_kernel_ts.cpp,
../../src/kernel/srs_kernel_ts.hpp,
../../src/kernel/srs_kernel_utility.hpp,
../../src/kernel/srs_kernel_utility.cpp,
rtmp-protocol readonly separator,
@ -56,8 +60,6 @@ file
../../src/rtmp/srs_protocol_utility.hpp,
../../src/rtmp/srs_protocol_utility.cpp,
app readonly separator,
../../src/app/srs_app_avc_aac.hpp,
../../src/app/srs_app_avc_aac.cpp,
../../src/app/srs_app_bandwidth.hpp,
../../src/app/srs_app_bandwidth.cpp,
../../src/app/srs_app_conn.hpp,

View file

@ -109,6 +109,7 @@
<ClInclude Include="..\..\src\kernel\srs_kernel_log.hpp" />
<ClInclude Include="..\..\src\kernel\srs_kernel_mp3.hpp" />
<ClInclude Include="..\..\src\kernel\srs_kernel_stream.hpp" />
<ClInclude Include="..\..\src\kernel\srs_kernel_ts.hpp" />
<ClInclude Include="..\..\src\kernel\srs_kernel_utility.hpp" />
<ClInclude Include="..\..\src\libs\srs_librtmp.hpp" />
<ClInclude Include="..\..\src\libs\srs_lib_bandwidth.hpp" />
@ -182,6 +183,7 @@
<ClCompile Include="..\..\src\kernel\srs_kernel_log.cpp" />
<ClCompile Include="..\..\src\kernel\srs_kernel_mp3.cpp" />
<ClCompile Include="..\..\src\kernel\srs_kernel_stream.cpp" />
<ClCompile Include="..\..\src\kernel\srs_kernel_ts.cpp" />
<ClCompile Include="..\..\src\kernel\srs_kernel_utility.cpp" />
<ClCompile Include="..\..\src\libs\srs_librtmp.cpp" />
<ClCompile Include="..\..\src\libs\srs_lib_bandwidth.cpp" />

View file

@ -217,6 +217,9 @@
<ClCompile Include="..\..\research\librtmp\srs_aac_raw_publish.c">
<Filter>librtmp</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kernel\srs_kernel_ts.cpp">
<Filter>srs</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\app\srs_app_avc_aac.hpp">
@ -396,6 +399,9 @@
<ClInclude Include="..\..\src\libs\srs_lib_simple_socket.hpp">
<Filter>librtmp</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kernel\srs_kernel_ts.hpp">
<Filter>srs</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="research">

View file

@ -66,7 +66,7 @@ using namespace std;
#include <srs_protocol_rtmp.hpp>
#include <srs_app_pithy_print.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_app_avc_aac.hpp>
#include <srs_kernel_avc.hpp>
#include <srs_kernel_file.hpp>
#include <srs_protocol_buffer.hpp>
@ -1424,10 +1424,6 @@ int SrsHls::on_meta_data(SrsAmf0Object* metadata)
return ret;
}
if ((ret = codec->metadata_demux(metadata)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}

View file

@ -275,8 +275,6 @@ SrsGoHttpFileServer::~SrsGoHttpFileServer()
int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
{
int ret = ERROR_SUCCESS;
string upath = r->path();
// add default pages.
@ -760,6 +758,9 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size)
if (content_length == -1) {
hdr->set("Transfer-Encoding", "chunked");
}
// keep alive to make vlc happy.
hdr->set("Connection", "Keep-Alive");
// write headers
hdr->write(ss);

View file

@ -46,6 +46,7 @@ using namespace std;
#include <srs_protocol_msg_array.hpp>
#include <srs_kernel_aac.hpp>
#include <srs_kernel_mp3.hpp>
#include <srs_kernel_ts.hpp>
SrsVodStream::SrsVodStream(string root_dir)
: SrsGoHttpFileServer(root_dir)
@ -246,6 +247,54 @@ ISrsStreamEncoder::~ISrsStreamEncoder()
{
}
SrsTsStreamEncoder::SrsTsStreamEncoder()
{
enc = new SrsTsEncoder();
}
SrsTsStreamEncoder::~SrsTsStreamEncoder()
{
srs_freep(enc);
}
int SrsTsStreamEncoder::initialize(SrsFileWriter* w, SrsStreamCache* /*c*/)
{
int ret = ERROR_SUCCESS;
if ((ret = enc->initialize(w)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
int SrsTsStreamEncoder::write_audio(int64_t timestamp, char* data, int size)
{
return enc->write_audio(timestamp, data, size);
}
int SrsTsStreamEncoder::write_video(int64_t timestamp, char* data, int size)
{
return enc->write_video(timestamp, data, size);
}
int SrsTsStreamEncoder::write_metadata(int64_t /*timestamp*/, char* /*data*/, int /*size*/)
{
return ERROR_SUCCESS;
}
bool SrsTsStreamEncoder::has_cache()
{
// for ts stream, use gop cache of SrsSource is ok.
return false;
}
int SrsTsStreamEncoder::dump_cache(SrsConsumer* /*consumer*/)
{
// for ts stream, ignore cache.
return ERROR_SUCCESS;
}
SrsFlvStreamEncoder::SrsFlvStreamEncoder()
{
enc = new SrsFlvEncoder();
@ -471,6 +520,9 @@ int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
} else if (srs_string_ends_with(entry->pattern, ".mp3")) {
w->header()->set_content_type("audio/mpeg");
enc = new SrsMp3StreamEncoder();
} else if (srs_string_ends_with(entry->pattern, ".ts")) {
w->header()->set_content_type("video/MP2T");
enc = new SrsTsStreamEncoder();
} else {
ret = ERROR_HTTP_LIVE_STREAM_EXT;
srs_error("http: unsupported pattern %s", entry->pattern.c_str());

View file

@ -43,6 +43,7 @@ class SrsSource;
class SrsRequest;
class SrsConsumer;
class SrsStSocket;
class SrsTsEncoder;
class SrsAacEncoder;
class SrsMp3Encoder;
class SrsFlvEncoder;
@ -144,6 +145,26 @@ public:
virtual int dump_cache(SrsConsumer* consumer);
};
/**
* the ts stream encoder, remux rtmp stream to ts stream.
*/
class SrsTsStreamEncoder : public ISrsStreamEncoder
{
private:
SrsTsEncoder* enc;
public:
SrsTsStreamEncoder();
virtual ~SrsTsStreamEncoder();
public:
virtual int initialize(SrsFileWriter* w, SrsStreamCache* c);
virtual int write_audio(int64_t timestamp, char* data, int size);
virtual int write_video(int64_t timestamp, char* data, int size);
virtual int write_metadata(int64_t timestamp, char* data, int size);
public:
virtual bool has_cache();
virtual int dump_cache(SrsConsumer* consumer);
};
/**
* the aac stream encoder, remux rtmp stream to aac stream.
*/

View file

@ -40,7 +40,7 @@ using namespace std;
#include <srs_kernel_stream.hpp>
#include <srs_app_edge.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_app_avc_aac.hpp>
#include <srs_kernel_avc.hpp>
#include <srs_protocol_msg_array.hpp>
#define CONST_MAX_JITTER_MS 500

View file

@ -21,14 +21,12 @@ 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_avc_aac.hpp>
#include <srs_kernel_avc.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_protocol_amf0.hpp>
#include <srs_app_utility.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_kernel_utility.hpp>
SrsCodecSampleUnit::SrsCodecSampleUnit()
{
@ -120,51 +118,6 @@ SrsAvcAacCodec::~SrsAvcAacCodec()
srs_freep(pictureParameterSetNALUnit);
}
int SrsAvcAacCodec::metadata_demux(SrsAmf0Object* metadata)
{
int ret = ERROR_SUCCESS;
srs_assert(metadata);
SrsAmf0Object* obj = metadata;
// finger out the codec info from metadata if possible.
SrsAmf0Any* prop = NULL;
if ((prop = obj->get_property("duration")) != NULL && prop->is_number()) {
duration = (int)prop->to_number();
}
if ((prop = obj->get_property("width")) != NULL && prop->is_number()) {
width = (int)prop->to_number();
}
if ((prop = obj->get_property("height")) != NULL && prop->is_number()) {
height = (int)prop->to_number();
}
if ((prop = obj->get_property("framerate")) != NULL && prop->is_number()) {
frame_rate = (int)prop->to_number();
}
if ((prop = obj->get_property("videocodecid")) != NULL && prop->is_number()) {
video_codec_id = (int)prop->to_number();
}
if ((prop = obj->get_property("videodatarate")) != NULL && prop->is_number()) {
video_data_rate = (int)(1000 * prop->to_number());
}
if ((prop = obj->get_property("audiocodecid")) != NULL && prop->is_number()) {
audio_codec_id = (int)prop->to_number();
}
if ((prop = obj->get_property("audiodatarate")) != NULL && prop->is_number()) {
audio_data_rate = (int)(1000 * prop->to_number());
}
// ignore the following, for each flv/rtmp packet contains them:
// audiosamplerate, sample->sound_rate
// audiosamplesize, sample->sound_size
// stereo, sample->sound_type
return ret;
}
int SrsAvcAacCodec::audio_aac_demux(char* data, int size, SrsCodecSample* sample)
{
int ret = ERROR_SUCCESS;

View file

@ -21,11 +21,11 @@ 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_AVC_AAC_HPP
#define SRS_APP_AVC_AAC_HPP
#ifndef SRS_KERNEL_AVC_HPP
#define SRS_KERNEL_AVC_HPP
/*
#include <srs_app_avc_aac.hpp>
#include <srs_kernel_avc.hpp>
*/
#include <srs_core.hpp>
@ -238,12 +238,6 @@ public:
virtual ~SrsAvcAacCodec();
// the following function used for hls to build the sample and codec.
public:
/**
* demux the metadata, to to get the stream info,
* for instance, the width/height, sample rate.
* @param metadata, the metadata amf0 object. assert not NULL.
*/
virtual int metadata_demux(SrsAmf0Object* metadata);
/**
* demux the audio packet in aac codec.
* the packet mux in FLV/RTMP format defined in flv specification.

View file

@ -0,0 +1,80 @@
/*
The MIT License (MIT)
Copyright (c) 2013-2015 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_kernel_ts.hpp>
// for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213
#ifndef _WIN32
#include <unistd.h>
#endif
#include <fcntl.h>
#include <sstream>
using namespace std;
#include <srs_kernel_log.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_kernel_file.hpp>
SrsTsEncoder::SrsTsEncoder()
{
_fs = NULL;
tag_stream = new SrsStream();
}
SrsTsEncoder::~SrsTsEncoder()
{
srs_freep(tag_stream);
}
int SrsTsEncoder::initialize(SrsFileWriter* fs)
{
int ret = ERROR_SUCCESS;
srs_assert(fs);
if (!fs->is_open()) {
ret = ERROR_KERNEL_FLV_STREAM_CLOSED;
srs_warn("stream is not open for encoder. ret=%d", ret);
return ret;
}
_fs = fs;
return ret;
}
int SrsTsEncoder::write_audio(int64_t timestamp, char* data, int size)
{
int ret = ERROR_SUCCESS;
return ret;
}
int SrsTsEncoder::write_video(int64_t timestamp, char* data, int size)
{
int ret = ERROR_SUCCESS;
return ret;
}

View file

@ -0,0 +1,65 @@
/*
The MIT License (MIT)
Copyright (c) 2013-2015 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_KERNEL_TS_HPP
#define SRS_KERNEL_TS_HPP
/*
#include <srs_kernel_ts.hpp>
*/
#include <srs_core.hpp>
#include <string>
class SrsStream;
class SrsFileWriter;
class SrsFileReader;
/**
* encode data to ts file.
*/
class SrsTsEncoder
{
private:
SrsFileWriter* _fs;
private:
SrsStream* tag_stream;
public:
SrsTsEncoder();
virtual ~SrsTsEncoder();
public:
/**
* initialize the underlayer file stream.
*/
virtual int initialize(SrsFileWriter* fs);
public:
/**
* write audio/video packet.
* @remark assert data is not NULL.
*/
virtual int write_audio(int64_t timestamp, char* data, int size);
virtual int write_video(int64_t timestamp, char* data, int size);
};
#endif

View file

@ -39,6 +39,7 @@ using namespace std;
#include <srs_kernel_log.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_stream.hpp>
// this value must:
// equals to (SRS_SYS_CYCLE_INTERVAL*SRS_SYS_TIME_RESOLUTION_MS_TIMES)*1000
@ -278,3 +279,50 @@ int srs_create_dir_recursively(string dir)
return ret;
}
bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code)
{
char* bytes = stream->data() + stream->pos();
char* p = bytes;
for (;;) {
if (!stream->require(p - bytes + 3)) {
return false;
}
// not match
if (p[0] != (char)0x00 || p[1] != (char)0x00) {
return false;
}
// match N[00] 00 00 01, where N>=0
if (p[2] == (char)0x01) {
if (pnb_start_code) {
*pnb_start_code = (int)(p - bytes) + 3;
}
return true;
}
p++;
}
return false;
}
bool srs_aac_startswith_adts(SrsStream* stream)
{
char* bytes = stream->data() + stream->pos();
char* p = bytes;
if (!stream->require(p - bytes + 2)) {
return false;
}
// matched 12bits 0xFFF,
// @remark, we must cast the 0xff to char to compare.
if (p[0] != (char)0xff || (char)(p[1] & 0xf0) != (char)0xf0) {
return false;
}
return true;
}

View file

@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string>
class SrsStream;
// compare
#define srs_min(a, b) (((a) < (b))? (a) : (b))
#define srs_max(a, b) (((a) < (b))? (b) : (a))
@ -62,5 +64,21 @@ extern bool srs_string_ends_with(std::string str, std::string flag);
// create dir recursively
extern int srs_create_dir_recursively(std::string dir);
/**
* whether stream starts with the avc NALU in "AnnexB"
* from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
* start code must be "N[00] 00 00 01" where N>=0
* @param pnb_start_code output the size of start code, must >=3.
* NULL to ignore.
*/
extern bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code = NULL);
/**
* whether stream starts with the aac ADTS
* from aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75, 1.A.2.2 ADTS.
* start code must be '1111 1111 1111'B, that is 0xFFF
*/
extern bool srs_aac_startswith_adts(SrsStream* stream);
#endif

View file

@ -157,53 +157,6 @@ bool srs_bytes_equals(void* pa, void* pb, int size)
return true;
}
bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code)
{
char* bytes = stream->data() + stream->pos();
char* p = bytes;
for (;;) {
if (!stream->require(p - bytes + 3)) {
return false;
}
// not match
if (p[0] != (char)0x00 || p[1] != (char)0x00) {
return false;
}
// match N[00] 00 00 01, where N>=0
if (p[2] == (char)0x01) {
if (pnb_start_code) {
*pnb_start_code = (int)(p - bytes) + 3;
}
return true;
}
p++;
}
return false;
}
bool srs_aac_startswith_adts(SrsStream* stream)
{
char* bytes = stream->data() + stream->pos();
char* p = bytes;
if (!stream->require(p - bytes + 2)) {
return false;
}
// matched 12bits 0xFFF,
// @remark, we must cast the 0xff to char to compare.
if (p[0] != (char)0xff || (char)(p[1] & 0xf0) != (char)0xf0) {
return false;
}
return true;
}
int srs_chunk_header_c0(
int perfer_cid, u_int32_t timestamp, int32_t payload_length,
int8_t message_type, int32_t stream_id,

View file

@ -33,7 +33,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_kernel_consts.hpp>
class SrsStream;
class SrsMessageHeader;
/**
@ -88,22 +87,6 @@ extern std::string srs_generate_tc_url(
*/
extern bool srs_bytes_equals(void* pa, void* pb, int size);
/**
* whether stream starts with the avc NALU in "AnnexB"
* from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
* start code must be "N[00] 00 00 01" where N>=0
* @param pnb_start_code output the size of start code, must >=3.
* NULL to ignore.
*/
extern bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code = NULL);
/**
* whether stream starts with the aac ADTS
* from aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75, 1.A.2.2 ADTS.
* start code must be '1111 1111 1111'B, that is 0xFFF
*/
extern bool srs_aac_startswith_adts(SrsStream* stream);
/**
* generate the c0 chunk header for msg.
* @param cache, the cache to write header.