mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #738, parse avcc/sps/pps/asc from mp4.
This commit is contained in:
parent
9d21a8bb33
commit
253ac40312
8 changed files with 346 additions and 36 deletions
|
@ -1548,7 +1548,6 @@ srs_bool srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int*
|
|||
|
||||
struct Mp4Context
|
||||
{
|
||||
bool non_seekable;
|
||||
SrsFileReader reader;
|
||||
SrsMp4Decoder dec;
|
||||
};
|
||||
|
@ -1558,7 +1557,6 @@ srs_mp4_t srs_mp4_open_read(const char* file)
|
|||
int ret = ERROR_SUCCESS;
|
||||
|
||||
Mp4Context* mp4 = new Mp4Context();
|
||||
mp4->non_seekable = false;
|
||||
|
||||
if ((ret = mp4->reader.open(file)) != ERROR_SUCCESS) {
|
||||
srs_freep(mp4);
|
||||
|
@ -1584,11 +1582,99 @@ int srs_mp4_init_demuxer(srs_mp4_t mp4)
|
|||
return ret;
|
||||
}
|
||||
|
||||
// OK, it's legal mp4 for live streaming.
|
||||
context->non_seekable = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srs_mp4_read_sample(srs_mp4_t mp4, srs_mp4_sample_t* s)
|
||||
{
|
||||
s->sample = NULL;
|
||||
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
Mp4Context* context = (Mp4Context*)mp4;
|
||||
SrsMp4Decoder* dec = &context->dec;
|
||||
|
||||
SrsMp4HandlerType ht = SrsMp4HandlerTypeForbidden;
|
||||
if ((ret = dec->read_sample(&ht, &s->frame_type, &s->codec_type, &s->dts, &s->pts, &s->sample, &s->nb_sample)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ht == SrsMp4HandlerTypeForbidden) {
|
||||
return ERROR_MP4_ILLEGAL_HANDLER;
|
||||
}
|
||||
|
||||
if (ht == SrsMp4HandlerTypeSOUN) {
|
||||
s->codec = dec->acodec;
|
||||
s->sample_rate = dec->sample_rate;
|
||||
s->channels = dec->channels;
|
||||
s->sound_bits = dec->sound_bits;
|
||||
} else {
|
||||
s->codec = dec->vcodec;
|
||||
}
|
||||
s->handler_type = (uint32_t)ht;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void srs_mp4_free_sample(srs_mp4_sample_t* s)
|
||||
{
|
||||
srs_freepa(s->sample);
|
||||
}
|
||||
|
||||
int32_t srs_mp4_sizeof(srs_mp4_t mp4, srs_mp4_sample_t* s)
|
||||
{
|
||||
if (s->handler_type == SrsMp4HandlerTypeSOUN) {
|
||||
if (s->codec == SrsCodecAudioAAC) {
|
||||
return s->nb_sample + 2;
|
||||
}
|
||||
return s->nb_sample + 1;
|
||||
}
|
||||
|
||||
if (s->codec == SrsCodecVideoAVC) {
|
||||
return s->nb_sample + 5;
|
||||
}
|
||||
return s->nb_sample + 1;
|
||||
}
|
||||
|
||||
int srs_mp4_to_flv_tag(srs_mp4_t mp4, srs_mp4_sample_t* s, char* type, uint32_t* time, char* data, int32_t size)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
*time = s->dts;
|
||||
|
||||
SrsBuffer p(data, size);
|
||||
if (s->handler_type == SrsMp4HandlerTypeSOUN) {
|
||||
*type = SRS_RTMP_TYPE_AUDIO;
|
||||
|
||||
// E.4.2.1 AUDIODATA, flv_v10_1.pdf, page 3
|
||||
p.write_1bytes(uint8_t(s->codec << 4) | uint8_t(s->sample_rate << 2) | uint8_t(s->sound_bits << 1) | s->channels);
|
||||
if (s->codec == SrsCodecAudioAAC) {
|
||||
p.write_1bytes(uint8_t(s->codec_type == SrsCodecAudioTypeSequenceHeader? 0:1));
|
||||
}
|
||||
|
||||
p.write_bytes((char*)s->sample, s->nb_sample);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// E.4.3.1 VIDEODATA, flv_v10_1.pdf, page 5
|
||||
p.write_1bytes(uint8_t(s->frame_type<<4) | s->codec);
|
||||
if (s->codec == SrsCodecVideoAVC) {
|
||||
*type = SRS_RTMP_TYPE_VIDEO;
|
||||
|
||||
p.write_1bytes(uint8_t(s->codec_type == SrsCodecVideoAVCTypeSequenceHeader? 0:1));
|
||||
// cts = pts - dts, where dts = flvheader->timestamp.
|
||||
uint32_t cts = s->pts - s->dts;
|
||||
p.write_3bytes(cts);
|
||||
}
|
||||
p.write_bytes((char*)s->sample, s->nb_sample);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
srs_bool srs_mp4_is_eof(int error_code)
|
||||
{
|
||||
return error_code == ERROR_SYSTEM_FILE_EOF;
|
||||
}
|
||||
|
||||
struct FlvContext
|
||||
{
|
||||
|
|
|
@ -513,6 +513,39 @@ extern srs_bool srs_h264_startswith_annexb(
|
|||
*************************************************************
|
||||
*************************************************************/
|
||||
typedef void* srs_mp4_t;
|
||||
// The sample struct of mp4.
|
||||
typedef struct {
|
||||
// The handler type, it's SrsMp4HandlerType.
|
||||
uint32_t handler_type;
|
||||
|
||||
// The dts in milliseconds.
|
||||
uint32_t dts;
|
||||
// The codec type.
|
||||
// video: SrsCodecVideo.
|
||||
// audio: SrsCodecAudio.
|
||||
uint16_t codec;
|
||||
// The codec type:
|
||||
// video: SrsCodecVideoAVCType.
|
||||
// audio: SrsCodecAudioType.
|
||||
uint16_t codec_type;
|
||||
|
||||
// The video pts in milliseconds. Ignore for audio.
|
||||
uint32_t pts;
|
||||
// The video frame type, it's SrsCodecVideoAVCFrame.
|
||||
uint16_t frame_type;
|
||||
|
||||
// The audio sample rate, it's SrsCodecAudioSampleRate.
|
||||
uint8_t sample_rate;
|
||||
// The audio sound bits, it's SrsCodecAudioSampleSize.
|
||||
uint8_t sound_bits;
|
||||
// The audio sound type, it's SrsCodecAudioSoundType.
|
||||
uint8_t channels;
|
||||
|
||||
// The size of sample payload in bytes.
|
||||
uint32_t nb_sample;
|
||||
// The output sample data, user must free it by srs_mp4_free_sample.
|
||||
uint8_t* sample;
|
||||
} srs_mp4_sample_t;
|
||||
/* Open mp4 file for muxer(write) or demuxer(read). */
|
||||
extern srs_mp4_t srs_mp4_open_read(const char* file);
|
||||
extern void srs_mp4_close(srs_mp4_t mp4);
|
||||
|
@ -522,6 +555,27 @@ extern void srs_mp4_close(srs_mp4_t mp4);
|
|||
* For the live streaming, we must feed stream frame by frame.
|
||||
*/
|
||||
extern int srs_mp4_init_demuxer(srs_mp4_t mp4);
|
||||
/**
|
||||
* Read a sample form mp4.
|
||||
* @remark User can use srs_mp4_sample_to_flv_tag to convert mp4 sampel to flv tag.
|
||||
* Use the srs_mp4_to_flv_tag_size to calc the flv tag data size to alloc.
|
||||
*/
|
||||
extern int srs_mp4_read_sample(srs_mp4_t mp4, srs_mp4_sample_t* sample);
|
||||
/**
|
||||
* Free the allocated mp4 sample.
|
||||
*/
|
||||
extern void srs_mp4_free_sample(srs_mp4_sample_t* sample);
|
||||
/**
|
||||
* Calc the size of flv tag, for the mp4 sample to convert to.
|
||||
*/
|
||||
extern int32_t srs_mp4_sizeof(srs_mp4_t mp4, srs_mp4_sample_t* sample);
|
||||
/**
|
||||
* Covert mp4 sample to flv tag.
|
||||
*/
|
||||
extern int srs_mp4_to_flv_tag(srs_mp4_t mp4, srs_mp4_sample_t* sample, char* type, uint32_t* time, char* data, int32_t size);
|
||||
/* error code */
|
||||
/* whether the error code indicates EOF */
|
||||
extern srs_bool srs_mp4_is_eof(int error_code);
|
||||
|
||||
/*************************************************************
|
||||
**************************************************************
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue