1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

for #738, write mp4 samples.

This commit is contained in:
winlin 2017-02-05 09:15:46 +08:00
parent e24674e9cf
commit 733ba73d54
8 changed files with 87 additions and 19 deletions

View file

@ -26,9 +26,13 @@
#include "../../objs/include/srs_librtmp.h" #include "../../objs/include/srs_librtmp.h"
int64_t tools_main_entrance_startup_time;
int proxy(srs_mp4_t mp4, srs_rtmp_t ortmp); int proxy(srs_mp4_t mp4, srs_rtmp_t ortmp);
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
// main function
tools_main_entrance_startup_time = srs_utils_time_ms();
printf("Ingest mp4 file and publish to RTMP server like FFMPEG.\n"); printf("Ingest mp4 file and publish to RTMP server like FFMPEG.\n");
printf("SRS(OSSRS) client librtmp library.\n"); printf("SRS(OSSRS) client librtmp library.\n");
printf("Version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); printf("Version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
@ -129,7 +133,6 @@ int connect_oc(srs_rtmp_t ortmp)
#define RE_PULSE_MS 300 #define RE_PULSE_MS 300
#define RE_PULSE_JITTER_MS 3000 #define RE_PULSE_JITTER_MS 3000
int64_t tools_main_entrance_startup_time;
int64_t re_create() int64_t re_create()
{ {

View file

@ -4462,7 +4462,7 @@ bool SrsConfig::get_gop_cache(string vhost)
} }
conf = conf->get("play"); conf = conf->get("play");
if (!conf || conf->arg0().empty()) { if (!conf) {
return SRS_PERF_GOP_CACHE; return SRS_PERF_GOP_CACHE;
} }
@ -4484,7 +4484,7 @@ bool SrsConfig::get_debug_srs_upnode(string vhost)
} }
conf = conf->get("cluster"); conf = conf->get("cluster");
if (!conf || conf->arg0().empty()) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
@ -4506,7 +4506,7 @@ bool SrsConfig::get_atc(string vhost)
} }
conf = conf->get("play"); conf = conf->get("play");
if (!conf || conf->arg0().empty()) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
@ -4528,7 +4528,7 @@ bool SrsConfig::get_atc_auto(string vhost)
} }
conf = conf->get("play"); conf = conf->get("play");
if (!conf || conf->arg0().empty()) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
@ -4550,7 +4550,7 @@ int SrsConfig::get_time_jitter(string vhost)
} }
conf = conf->get("play"); conf = conf->get("play");
if (!conf || conf->arg0().empty()) { if (!conf) {
return _srs_time_jitter_string2int(DEFAULT); return _srs_time_jitter_string2int(DEFAULT);
} }
@ -4572,7 +4572,7 @@ bool SrsConfig::get_mix_correct(string vhost)
} }
conf = conf->get("play"); conf = conf->get("play");
if (!conf || conf->arg0().empty()) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
@ -4594,7 +4594,7 @@ double SrsConfig::get_queue_length(string vhost)
} }
conf = conf->get("play"); conf = conf->get("play");
if (!conf || conf->arg0().empty()) { if (!conf) {
return DEFAULT; return DEFAULT;
} }
@ -4807,7 +4807,7 @@ int SrsConfig::get_mw_sleep_ms(string vhost)
} }
conf = conf->get("play"); conf = conf->get("play");
if (!conf || conf->arg0().empty()) { if (!conf) {
return SRS_PERF_MW_SLEEP; return SRS_PERF_MW_SLEEP;
} }

View file

@ -288,7 +288,7 @@ SrsPublishRecvThread::~SrsPublishRecvThread()
st_cond_destroy(error); st_cond_destroy(error);
} }
int SrsPublishRecvThread::wait(int timeout_ms) int SrsPublishRecvThread::wait(uint64_t timeout_ms)
{ {
if (recv_error_code != ERROR_SUCCESS) { if (recv_error_code != ERROR_SUCCESS) {
return recv_error_code; return recv_error_code;

View file

@ -196,7 +196,7 @@ public:
/** /**
* wait for error for some timeout. * wait for error for some timeout.
*/ */
virtual int wait(int timeout_ms); virtual int wait(uint64_t timeout_ms);
virtual int64_t nb_msgs(); virtual int64_t nb_msgs();
virtual int error_code(); virtual int error_code();
virtual void set_cid(int v); virtual void set_cid(int v);

View file

@ -68,7 +68,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// the following is the timeout for rtmp protocol, // the following is the timeout for rtmp protocol,
// to avoid death connection. // to avoid death connection.
// Never timeout in ms. // Never timeout in ms
// @remake Rename from SRS_CONSTS_NO_TIMEOUT
// @see ST_UTIME_NO_TIMEOUT
#define SRS_CONSTS_NO_TMMS ((int64_t) -1LL) #define SRS_CONSTS_NO_TMMS ((int64_t) -1LL)
// the common io timeout, for both recv and send. // the common io timeout, for both recv and send.

View file

@ -3184,12 +3184,12 @@ SrsMp4Sample::~SrsMp4Sample()
srs_freepa(data); srs_freepa(data);
} }
uint32_t SrsMp4Sample::get_dts() uint32_t SrsMp4Sample::dts_ms()
{ {
return (uint32_t)(dts * 1000 / tbn); return (uint32_t)(dts * 1000 / tbn);
} }
uint32_t SrsMp4Sample::get_pts() uint32_t SrsMp4Sample::pts_ms()
{ {
return (uint32_t)(pts * 1000 / tbn); return (uint32_t)(pts * 1000 / tbn);
} }
@ -3237,6 +3237,14 @@ int SrsMp4SampleManager::load(SrsMp4MovieBox* moov)
return ret; return ret;
} }
SrsMp4Sample* SrsMp4SampleManager::at(uint32_t index)
{
if (index >= samples.size() - 1) {
return NULL;
}
return samples.at(index);
}
int SrsMp4SampleManager::do_load(map<uint64_t, SrsMp4Sample*>& tses, SrsMp4MovieBox* moov) int SrsMp4SampleManager::do_load(map<uint64_t, SrsMp4Sample*>& tses, SrsMp4MovieBox* moov)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
@ -3349,6 +3357,10 @@ int SrsMp4SampleManager::load_trak(map<uint64_t, SrsMp4Sample*>& tses, SrsCodecF
} }
} }
// Only set the sample size, read data from io when needed.
sample->nb_data = sample_size;
sample->data = NULL;
previous = sample; previous = sample;
tses[sample->offset] = sample; tses[sample->offset] = sample;
} }
@ -3379,6 +3391,8 @@ SrsMp4Decoder::SrsMp4Decoder()
sound_bits = SrsCodecAudioSampleSizeForbidden; sound_bits = SrsCodecAudioSampleSizeForbidden;
channels = SrsCodecAudioSoundTypeForbidden; channels = SrsCodecAudioSoundTypeForbidden;
samples = new SrsMp4SampleManager(); samples = new SrsMp4SampleManager();
current_index = 0;
current_offset = 0;
} }
SrsMp4Decoder::~SrsMp4Decoder() SrsMp4Decoder::~SrsMp4Decoder()
@ -3437,7 +3451,7 @@ int SrsMp4Decoder::initialize(ISrsReadSeeker* rs)
// Set the offset to the mdat. // Set the offset to the mdat.
if (offset >= 0) { if (offset >= 0) {
return rsio->lseek(offset, SEEK_SET, NULL); return rsio->lseek(offset, SEEK_SET, &current_offset);
} }
return ret; return ret;
@ -3478,6 +3492,46 @@ int SrsMp4Decoder::read_sample(SrsMp4HandlerType* pht,
return ret; return ret;
} }
SrsMp4Sample* ps = samples->at(current_index++);
if (!ps) {
return ERROR_SYSTEM_FILE_EOF;
}
if (ps->type == SrsCodecFlvTagVideo) {
*pht = SrsMp4HandlerTypeVIDE;
*pct = SrsCodecVideoAVCTypeNALU;
} else {
*pht = SrsMp4HandlerTypeSOUN;
*pct = SrsCodecAudioTypeRawData;
}
*pdts = ps->dts_ms();
*ppts = ps->pts_ms();
*pft = ps->frame_type;
if (ps->type == SrsCodecFlvTagAudio) {
*pdts = ps->dts_ms() + 34;
*ppts = ps->pts_ms() + 34;
}
// Read sample from io, for we never preload the samples(too large).
if (ps->offset != current_offset) {
if ((ret = rsio->lseek(ps->offset, SEEK_SET, &current_offset)) != ERROR_SUCCESS) {
return ret;
}
}
uint32_t nb_sample = ps->nb_data;
uint8_t* sample = new uint8_t[nb_sample];
// TODO: FIXME: Use fully read.
if ((ret = rsio->read(sample, nb_sample, NULL)) != ERROR_SUCCESS) {
srs_freepa(sample);
return ret;
}
*psample = sample;
*pnb_sample = nb_sample;
current_offset += nb_sample;
return ret; return ret;
} }

View file

@ -1435,9 +1435,9 @@ public:
virtual ~SrsMp4Sample(); virtual ~SrsMp4Sample();
public: public:
// Get the dts in ms. // Get the dts in ms.
virtual uint32_t get_dts(); virtual uint32_t dts_ms();
// Get the pts in ms. // Get the pts in ms.
virtual uint32_t get_pts(); virtual uint32_t pts_ms();
}; };
/** /**
@ -1464,6 +1464,11 @@ public:
* There must be atleast one track. * There must be atleast one track.
*/ */
virtual int load(SrsMp4MovieBox* moov); virtual int load(SrsMp4MovieBox* moov);
/**
* Get the sample at index position.
* @remark NULL if exceed the max index.
*/
virtual SrsMp4Sample* at(uint32_t index);
private: private:
virtual int do_load(std::map<uint64_t, SrsMp4Sample*>& tses, SrsMp4MovieBox* moov); virtual int do_load(std::map<uint64_t, SrsMp4Sample*>& tses, SrsMp4MovieBox* moov);
private: private:
@ -1484,7 +1489,11 @@ class SrsMp4Decoder
private: private:
// The major brand of decoder, parse from ftyp. // The major brand of decoder, parse from ftyp.
SrsMp4BoxBrand brand; SrsMp4BoxBrand brand;
// The samples build from moov.
SrsMp4SampleManager* samples; SrsMp4SampleManager* samples;
// The current written sample information.
uint32_t current_index;
off_t current_offset;
public: public:
// The video codec of first track, generally there is zero or one track. // The video codec of first track, generally there is zero or one track.
// Forbidden if no video stream. // Forbidden if no video stream.

View file

@ -94,7 +94,7 @@ public:
public: public:
/** /**
* Set the timeout tm in ms for recv bytes from peer. * Set the timeout tm in ms for recv bytes from peer.
* @remark Use SRS_CONSTS_NO_TIMEOUT to never timeout. * @remark Use SRS_CONSTS_NO_TMMS to never timeout.
*/ */
virtual void set_recv_timeout(int64_t tm) = 0; virtual void set_recv_timeout(int64_t tm) = 0;
/** /**
@ -122,7 +122,7 @@ public:
public: public:
/** /**
* Set the timeout tm in ms for send bytes to peer. * Set the timeout tm in ms for send bytes to peer.
* @remark Use SRS_CONSTS_NO_TIMEOUT to never timeout. * @remark Use SRS_CONSTS_NO_TMMS to never timeout.
*/ */
virtual void set_send_timeout(int64_t tm) = 0; virtual void set_send_timeout(int64_t tm) = 0;
/** /**