1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

add flv injecter, add flv codec to librtmp.

This commit is contained in:
winlin 2014-05-28 15:37:06 +08:00
parent 99cfbaaad9
commit 608083d42f
13 changed files with 443 additions and 37 deletions

View file

@ -39,7 +39,7 @@ using namespace std;
#include <srs_kernel_utility.hpp>
#include <srs_app_http_hooks.hpp>
#include <srs_app_codec.hpp>
#include <srs_app_flv.hpp>
#include <srs_kernel_flv.hpp>
SrsFlvSegment::SrsFlvSegment()
{

View file

@ -40,7 +40,7 @@ using namespace std;
#include <srs_core_autofree.hpp>
#include <srs_app_json.hpp>
#include <srs_app_config.hpp>
#include <srs_app_flv.hpp>
#include <srs_kernel_flv.hpp>
#define SRS_HTTP_DEFAULT_PAGE "index.html"

View file

@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR "0"
#define VERSION_MINOR "9"
#define VERSION_REVISION "120"
#define VERSION_REVISION "121"
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
// server info.
#define RTMP_SIG_SRS_KEY "SRS"

View file

@ -118,6 +118,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_SYSTEM_FILE_RENAME 429
#define ERROR_SYSTEM_CREATE_PIPE 430
#define ERROR_SYSTEM_FILE_SEEK 431
#define ERROR_SYSTEM_FLV_HEADER 432
// see librtmp.
// failed when open ssl create the dh

View file

@ -21,22 +21,17 @@ 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_flv.hpp>
#include <srs_kernel_flv.hpp>
#include <fcntl.h>
#include <sstream>
using namespace std;
#include <srs_app_config.hpp>
#include <srs_kernel_log.hpp>
#include <srs_kernel_error.hpp>
#include <srs_protocol_rtmp.hpp>
#include <srs_protocol_rtmp_stack.hpp>
#include <srs_app_source.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_app_http_hooks.hpp>
#include <srs_app_codec.hpp>
#define SRS_FLV_TAG_HEADER_SIZE 11
#define SRS_FLV_PREVIOUS_TAG_SIZE 4
@ -509,3 +504,109 @@ int SrsFlvFastDecoder::lseek(int64_t offset)
return ret;
}
SrsFlvDecoder::SrsFlvDecoder()
{
_fs = NULL;
tag_stream = new SrsStream();
}
SrsFlvDecoder::~SrsFlvDecoder()
{
srs_freep(tag_stream);
}
int SrsFlvDecoder::initialize(SrsFileStream* fs)
{
int ret = ERROR_SUCCESS;
_fs = fs;
return ret;
}
int SrsFlvDecoder::read_header(char header[9])
{
int ret = ERROR_SUCCESS;
if ((ret = _fs->read(header, 9, NULL)) != ERROR_SUCCESS) {
return ret;
}
char* h = header;
if (h[0] != 'F' || h[1] != 'L' || h[2] != 'V') {
ret = ERROR_SYSTEM_FLV_HEADER;
srs_warn("flv header must start with FLV. ret=%d", ret);
return ret;
}
return ret;
}
int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* ptime)
{
int ret = ERROR_SUCCESS;
char th[11]; // tag header
// read tag header
if ((ret = _fs->read(th, 11, NULL)) != ERROR_SUCCESS) {
if (ret != ERROR_SYSTEM_FILE_EOF) {
srs_error("read flv tag header failed. ret=%d", ret);
}
return ret;
}
// Reserved UB [2]
// Filter UB [1]
// TagType UB [5]
*ptype = (int)(th[0] & 0x1F);
// DataSize UI24
char* pp = (char*)pdata_size;
pp[2] = th[1];
pp[1] = th[2];
pp[0] = th[3];
// Timestamp UI24
pp = (char*)ptime;
pp[2] = th[4];
pp[1] = th[5];
pp[0] = th[6];
// TimestampExtended UI8
pp[3] = th[7];
return ret;
}
int SrsFlvDecoder::read_tag_data(char* data, int32_t size)
{
int ret = ERROR_SUCCESS;
if ((ret = _fs->read(data, size, NULL)) != ERROR_SUCCESS) {
if (ret != ERROR_SYSTEM_FILE_EOF) {
srs_error("read flv tag header failed. ret=%d", ret);
}
return ret;
}
return ret;
}
int SrsFlvDecoder::read_previous_tag_size(char ts[4])
{
int ret = ERROR_SUCCESS;
// ignore 4bytes tag size.
if ((ret = _fs->read(ts, 4, NULL)) != ERROR_SUCCESS) {
if (ret != ERROR_SYSTEM_FILE_EOF) {
srs_error("read flv previous tag size failed. ret=%d", ret);
}
return ret;
}
return ret;
}

View file

@ -25,7 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SRS_APP_FLV_HPP
/*
#include <srs_app_flv.hpp>
#include <srs_kernel_flv.hpp>
*/
#include <srs_core.hpp>
@ -142,4 +142,29 @@ public:
virtual int lseek(int64_t offset);
};
/**
* decode flv file.
*/
class SrsFlvDecoder
{
private:
SrsFileStream* _fs;
private:
SrsStream* tag_stream;
public:
SrsFlvDecoder();
virtual ~SrsFlvDecoder();
public:
/**
* initialize the underlayer file stream,
* user can initialize multiple times to decode multiple flv files.
*/
virtual int initialize(SrsFileStream* fs);
public:
virtual int read_header(char header[9]);
virtual int read_tag_header(char* ptype, int32_t* pdata_size, u_int32_t* ptime);
virtual int read_tag_data(char* data, int32_t size);
virtual int read_previous_tag_size(char ts[4]);
};
#endif

View file

@ -39,6 +39,7 @@ using namespace std;
#include <srs_kernel_utility.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_protocol_amf0.hpp>
#include <srs_kernel_flv.hpp>
// if user want to define log, define the folowing macro.
#ifndef SRS_RTMP_USER_DEFINED_LOG
@ -382,6 +383,124 @@ int64_t srs_get_time_ms()
return srs_get_system_time_ms();
}
struct FlvContext
{
SrsFileStream fs;
SrsFlvEncoder enc;
SrsFlvDecoder dec;
};
srs_flv_t srs_flv_open_read(const char* file)
{
int ret = ERROR_SUCCESS;
FlvContext* flv = new FlvContext();
if ((ret = flv->fs.open_read(file)) != ERROR_SUCCESS) {
srs_freep(flv);
return NULL;
}
if ((ret = flv->enc.initialize(&flv->fs)) != ERROR_SUCCESS) {
srs_freep(flv);
return NULL;
}
if ((ret = flv->dec.initialize(&flv->fs)) != ERROR_SUCCESS) {
srs_freep(flv);
return NULL;
}
return flv;
}
srs_flv_t srs_flv_open_write(const char* file)
{
int ret = ERROR_SUCCESS;
FlvContext* flv = new FlvContext();
if ((ret = flv->fs.open_write(file)) != ERROR_SUCCESS) {
srs_freep(flv);
return NULL;
}
if ((ret = flv->enc.initialize(&flv->fs)) != ERROR_SUCCESS) {
srs_freep(flv);
return NULL;
}
if ((ret = flv->dec.initialize(&flv->fs)) != ERROR_SUCCESS) {
srs_freep(flv);
return NULL;
}
return flv;
}
void srs_flv_close(srs_flv_t flv)
{
FlvContext* context = (FlvContext*)flv;
srs_freep(context);
}
int srs_flv_read_header(srs_flv_t flv, char header[9])
{
int ret = ERROR_SUCCESS;
FlvContext* context = (FlvContext*)flv;
if ((ret = context->dec.read_header(header)) != ERROR_SUCCESS) {
return ret;
}
char ts[4]; // tag size
if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, u_int32_t* ptime)
{
int ret = ERROR_SUCCESS;
FlvContext* context = (FlvContext*)flv;
if ((ret = context->dec.read_tag_header(ptype, pdata_size, ptime)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size)
{
int ret = ERROR_SUCCESS;
FlvContext* context = (FlvContext*)flv;
if ((ret = context->dec.read_tag_data(data, size)) != ERROR_SUCCESS) {
return ret;
}
char ts[4]; // tag size
if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
int64_t srs_flv_tellg(srs_flv_t flv)
{
FlvContext* context = (FlvContext*)flv;
return context->fs.tellg();
}
flv_bool srs_flv_is_eof(int error_code)
{
return error_code == ERROR_SYSTEM_FILE_EOF;
}
srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed)
{
int ret = ERROR_SUCCESS;

View file

@ -151,6 +151,25 @@ int srs_version_revision();
*/
int64_t srs_get_time_ms();
/**
* flv codec
*/
typedef void* srs_flv_t;
typedef int flv_bool;
srs_flv_t srs_flv_open_read(const char* file);
srs_flv_t srs_flv_open_write(const char* file);
void srs_flv_close(srs_flv_t flv);
/* read the flv header. 9bytes header. drop the 4bytes zero previous tag size */
int srs_flv_read_header(srs_flv_t flv, char header[9]);
/* read the flv tag header, 1bytes tag, 3bytes data_size, 4bytes time, 3bytes stream id. */
int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, u_int32_t* ptime);
/* read the tag data. drop the 4bytes previous tag size */
int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size);
/* file stream tellg to get offset */
int64_t srs_flv_tellg(srs_flv_t flv);
/* whether the error code indicates EOF */
flv_bool srs_flv_is_eof(int error_code);
/**
* amf0 codec
*/
@ -184,7 +203,12 @@ srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index);
/* strict array value converter */
int srs_amf0_strict_array_property_count(srs_amf0_t amf0);
srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index);
/* human readable print */
/**
* human readable print
* @param pdata, output the heap data,
* user must use srs_amf0_free_bytes to free it.
* @return return the *pdata for print.
*/
char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize);
#ifdef __cplusplus

View file

@ -19,6 +19,8 @@ file
..\kernel\srs_kernel_buffer.cpp,
..\kernel\srs_kernel_error.hpp,
..\kernel\srs_kernel_error.cpp,
..\kernel\srs_kernel_flv.hpp,
..\kernel\srs_kernel_flv.cpp,
..\kernel\srs_kernel_log.hpp,
..\kernel\srs_kernel_log.cpp,
..\kernel\srs_kernel_stream.hpp,
@ -57,8 +59,6 @@ file
..\app\srs_app_encoder.cpp,
..\app\srs_app_ffmpeg.hpp,
..\app\srs_app_ffmpeg.cpp,
..\app\srs_app_flv.hpp,
..\app\srs_app_flv.cpp,
..\app\srs_app_forward.hpp,
..\app\srs_app_forward.cpp,
..\app\srs_app_heartbeat.hpp,
@ -112,6 +112,7 @@ file
..\utest\srs_utest_handshake.cpp,
research readonly separator,
..\..\research\librtmp\srs_flv_codec.h,
..\..\research\librtmp\srs_flv_injecter.c,
..\..\research\librtmp\srs_flv_parser.c,
..\..\research\librtmp\srs_ingest_flv.c,
..\..\research\librtmp\srs_ingest_rtmp.c,