Skip to content

Commit

Permalink
for ossrs#293, add aac encoder for http aac stream.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Jan 18, 2015
1 parent 77e43d1 commit c023354
Show file tree
Hide file tree
Showing 8 changed files with 525 additions and 27 deletions.
2 changes: 1 addition & 1 deletion trunk/configure
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ 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_consts" "srs_kernel_aac")
KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh
KERNEL_OBJS="${MODULE_OBJS[@]}"
#
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/app/srs_app_http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ int SrsGoHttpFileServer::serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
}

if (true) {
ssize_t pos;
size_t pos;
std::string ext = fullpath;
if ((pos = ext.rfind(".")) != string::npos) {
ext = ext.substr(pos);
Expand Down
147 changes: 126 additions & 21 deletions trunk/src/app/srs_app_http_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ using namespace std;
#include <srs_protocol_rtmp.hpp>
#include <srs_app_source.hpp>
#include <srs_protocol_msg_array.hpp>
#include <srs_kernel_aac.hpp>

SrsVodStream::SrsVodStream(string root_dir)
: SrsGoHttpFileServer(root_dir)
Expand Down Expand Up @@ -138,35 +139,120 @@ int SrsVodStream::serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
return ret;
}

SrsFlvStreamWriter::SrsFlvStreamWriter(ISrsGoHttpResponseWriter* w)
ISrsStreamEncoder::ISrsStreamEncoder()
{
}

ISrsStreamEncoder::~ISrsStreamEncoder()
{
}

SrsFlvStreamEncoder::SrsFlvStreamEncoder()
{
enc = new SrsFlvEncoder();
}

SrsFlvStreamEncoder::~SrsFlvStreamEncoder()
{
srs_freep(enc);
}

int SrsFlvStreamEncoder::initialize(SrsFileWriter* w)
{
int ret = ERROR_SUCCESS;

if ((ret = enc->initialize(w)) != ERROR_SUCCESS) {
return ret;
}

// write flv header.
if ((ret = enc->write_header()) != ERROR_SUCCESS) {
return ret;
}

return ret;
}

int SrsFlvStreamEncoder::write_audio(int64_t timestamp, char* data, int size)
{
return enc->write_audio(timestamp, data, size);
}

int SrsFlvStreamEncoder::write_video(int64_t timestamp, char* data, int size)
{
return enc->write_video(timestamp, data, size);
}

int SrsFlvStreamEncoder::write_metadata(int64_t timestamp, char* data, int size)
{
return enc->write_metadata(timestamp, data, size);
}

SrsAacStreamEncoder::SrsAacStreamEncoder()
{
enc = new SrsAacEncoder();
}

SrsAacStreamEncoder::~SrsAacStreamEncoder()
{
srs_freep(enc);
}

int SrsAacStreamEncoder::initialize(SrsFileWriter* w)
{
int ret = ERROR_SUCCESS;

if ((ret = enc->initialize(w)) != ERROR_SUCCESS) {
return ret;
}

return ret;
}

int SrsAacStreamEncoder::write_audio(int64_t timestamp, char* data, int size)
{
return enc->write_audio(timestamp, data, size);
}

int SrsAacStreamEncoder::write_video(int64_t timestamp, char* data, int size)
{
return enc->write_video(timestamp, data, size);
}

int SrsAacStreamEncoder::write_metadata(int64_t timestamp, char* data, int size)
{
return enc->write_metadata(timestamp, data, size);
}

SrsStreamWriter::SrsStreamWriter(ISrsGoHttpResponseWriter* w)
{
writer = w;
}

SrsFlvStreamWriter::~SrsFlvStreamWriter()
SrsStreamWriter::~SrsStreamWriter()
{
}

int SrsFlvStreamWriter::open(std::string /*file*/)
int SrsStreamWriter::open(std::string /*file*/)
{
return ERROR_SUCCESS;
}

void SrsFlvStreamWriter::close()
void SrsStreamWriter::close()
{
}

bool SrsFlvStreamWriter::is_open()
bool SrsStreamWriter::is_open()
{
return true;
}

int64_t SrsFlvStreamWriter::tellg()
int64_t SrsStreamWriter::tellg()
{
return 0;
}

int SrsFlvStreamWriter::write(void* buf, size_t count, ssize_t* pnwrite)
int SrsStreamWriter::write(void* buf, size_t count, ssize_t* pnwrite)
{
if (pnwrite) {
*pnwrite = count;
Expand All @@ -189,6 +275,20 @@ int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
{
int ret = ERROR_SUCCESS;

bool serve_flv_streaming = false;
bool serve_aac_streaming = false;

srs_assert(entry);
if (srs_string_ends_with(entry->pattern, ".flv")) {
serve_flv_streaming = true;
} else if (srs_string_ends_with(entry->pattern, ".aac")) {
serve_aac_streaming = true;
} else {
ret = ERROR_HTTP_LIVE_STREAM_EXT;
srs_error("http: unsupported pattern %s", entry->pattern.c_str());
return ret;
}

// create consumer of souce.
SrsConsumer* consumer = NULL;
if ((ret = source->create_consumer(consumer)) != ERROR_SUCCESS) {
Expand All @@ -201,20 +301,25 @@ int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
SrsMessageArray msgs(SRS_PERF_MW_MSGS);
// TODO: FIMXE: add pithy print.

// write http header for ts.
// write http header for streaming.
w->header()->set_content_length((int64_t)2 * 1024 * 1024 * 1024);
w->header()->set_content_type("video/x-flv");
if (serve_flv_streaming) {
w->header()->set_content_type("video/x-flv");
}
if (serve_aac_streaming) {
w->header()->set_content_type("audio/x-aac");
}

// the memory writer.
SrsFlvStreamWriter writer(w);
SrsStreamWriter writer(w);

SrsFlvEncoder enc;
if ((ret = enc.initialize(&writer)) != ERROR_SUCCESS) {
return ret;
ISrsStreamEncoder* enc = NULL;
if (serve_flv_streaming) {
enc = new SrsFlvStreamEncoder();
}
SrsAutoFree(ISrsStreamEncoder, enc);

// write flv header.
if ((ret = enc.write_header()) != ERROR_SUCCESS) {
if ((ret = enc->initialize(&writer)) != ERROR_SUCCESS) {
return ret;
}

Expand All @@ -223,23 +328,23 @@ int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
// each msg in msgs.msgs must be free, for the SrsMessageArray never free them.
int count = 0;
if ((ret = consumer->dump_packets(&msgs, count)) != ERROR_SUCCESS) {
srs_error("get messages from consumer failed. ret=%d", ret);
srs_error("http: get messages from consumer failed. ret=%d", ret);
return ret;
}

if (count <= 0) {
srs_info("mw sleep %dms for no msg", mw_sleep);
srs_info("http: mw sleep %dms for no msg", mw_sleep);
// directly use sleep, donot use consumer wait.
st_usleep(SRS_CONSTS_RTMP_PULSE_TIMEOUT_US);

// ignore when nothing got.
continue;
}
srs_info("got %d msgs, min=%d, mw=%d", count,
srs_info("http: got %d msgs, min=%d, mw=%d", count,
SRS_PERF_MW_MIN_MSGS, SRS_CONSTS_RTMP_PULSE_TIMEOUT_US / 1000);

// sendout all messages.
ret = send_messages(&enc, msgs.msgs, count);
ret = streaming_send_messages(enc, msgs.msgs, count);

// free the messages.
for (int i = 0; i < count; i++) {
Expand All @@ -250,7 +355,7 @@ int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
// check send error code.
if (ret != ERROR_SUCCESS) {
if (!srs_is_client_gracefully_close(ret)) {
srs_error("send messages to client failed. ret=%d", ret);
srs_error("http: send messages to client failed. ret=%d", ret);
}
return ret;
}
Expand All @@ -259,7 +364,7 @@ int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
return ret;
}

int SrsLiveStream::send_messages(SrsFlvEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs)
int SrsLiveStream::streaming_send_messages(ISrsStreamEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs)
{
int ret = ERROR_SUCCESS;

Expand Down
58 changes: 54 additions & 4 deletions trunk/src/app/srs_app_http_conn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class SrsSource;
class SrsRequest;
class SrsStSocket;
class SrsAacEncoder;
class SrsFlvEncoder;
class SrsHttpParser;
class SrsHttpMessage;
Expand All @@ -62,16 +63,65 @@ class SrsVodStream : public SrsGoHttpFileServer
virtual int serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int offset);
};

/**
* the stream encoder in some codec, for example, flv or aac.
*/
class ISrsStreamEncoder
{
public:
ISrsStreamEncoder();
virtual ~ISrsStreamEncoder();
public:
virtual int initialize(SrsFileWriter* w) = 0;
virtual int write_audio(int64_t timestamp, char* data, int size) = 0;
virtual int write_video(int64_t timestamp, char* data, int size) = 0;
virtual int write_metadata(int64_t timestamp, char* data, int size) = 0;
};

/**
* the flv stream encoder, remux rtmp stream to flv stream.
*/
class SrsFlvStreamEncoder : public ISrsStreamEncoder
{
private:
SrsFlvEncoder* enc;
public:
SrsFlvStreamEncoder();
virtual ~SrsFlvStreamEncoder();
public:
virtual int initialize(SrsFileWriter* w);
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);
};

/**
* the aac stream encoder, remux rtmp stream to aac stream.
*/
class SrsAacStreamEncoder : public ISrsStreamEncoder
{
private:
SrsAacEncoder* enc;
public:
SrsAacStreamEncoder();
virtual ~SrsAacStreamEncoder();
public:
virtual int initialize(SrsFileWriter* w);
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);
};

/**
* write stream to http response direclty.
*/
class SrsFlvStreamWriter : public SrsFileWriter
class SrsStreamWriter : public SrsFileWriter
{
private:
ISrsGoHttpResponseWriter* writer;
public:
SrsFlvStreamWriter(ISrsGoHttpResponseWriter* w);
virtual ~SrsFlvStreamWriter();
SrsStreamWriter(ISrsGoHttpResponseWriter* w);
virtual ~SrsStreamWriter();
public:
virtual int open(std::string file);
virtual void close();
Expand All @@ -97,7 +147,7 @@ class SrsLiveStream : public ISrsGoHttpHandler
public:
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
private:
virtual int send_messages(SrsFlvEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs);
virtual int streaming_send_messages(ISrsStreamEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs);
};

/**
Expand Down
Loading

0 comments on commit c023354

Please sign in to comment.