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

add avc format doc. decode the flv codec info

This commit is contained in:
winlin 2013-11-24 12:39:47 +08:00
parent b87318dec0
commit ba234e8741
10 changed files with 387 additions and 97 deletions

Binary file not shown.

View file

@ -151,6 +151,7 @@ int SrsClient::do_cycle()
// find a source to publish. // find a source to publish.
SrsSource* source = SrsSource::find(req->get_stream_url()); SrsSource* source = SrsSource::find(req->get_stream_url());
srs_assert(source != NULL); srs_assert(source != NULL);
SrsHLS* hls = source->get_hls();
bool enabled_cache = true; bool enabled_cache = true;
conf = config->get_gop_cache(req->vhost); conf = config->get_gop_cache(req->vhost);
@ -181,6 +182,7 @@ int SrsClient::do_cycle()
} }
srs_info("start to publish stream %s success", req->stream.c_str()); srs_info("start to publish stream %s success", req->stream.c_str());
ret = publish(source, true); ret = publish(source, true);
hls->on_unpublish();
source->on_unpublish(); source->on_unpublish();
return ret; return ret;
} }
@ -193,6 +195,7 @@ int SrsClient::do_cycle()
} }
srs_info("flash start to publish stream %s success", req->stream.c_str()); srs_info("flash start to publish stream %s success", req->stream.c_str());
ret = publish(source, false); ret = publish(source, false);
hls->on_unpublish();
source->on_unpublish(); source->on_unpublish();
return ret; return ret;
} }
@ -330,8 +333,15 @@ int SrsClient::publish(SrsSource* source, bool is_fmle)
srs_verbose("check publish_refer success."); srs_verbose("check publish_refer success.");
SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER); SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);
SrsHLS* hls = source->get_hls(); SrsHLS* hls = source->get_hls();
// notify the hls to prepare when publish start.
if ((ret = hls->on_publish()) != ERROR_SUCCESS) {
srs_error("hls on_publish failed. ret=%d", ret);
return ret;
}
srs_verbose("hls on_publish success.");
while (true) { while (true) {
// switch to other st-threads. // switch to other st-threads.
st_usleep(0); st_usleep(0);
@ -366,14 +376,26 @@ int SrsClient::process_publish_message(SrsSource* source, SrsHLS* hls, SrsCommon
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
// process audio packet // process audio packet
if (msg->header.is_audio() && ((ret = source->on_audio(msg)) != ERROR_SUCCESS)) { if (msg->header.is_audio()) {
srs_error("process audio message failed. ret=%d", ret); if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) {
return ret; srs_error("hls process audio message failed. ret=%d", ret);
return ret;
}
if ((ret = source->on_audio(msg)) != ERROR_SUCCESS) {
srs_error("source process audio message failed. ret=%d", ret);
return ret;
}
} }
// process video packet // process video packet
if (msg->header.is_video() && ((ret = source->on_video(msg)) != ERROR_SUCCESS)) { if (msg->header.is_video()) {
srs_error("process video message failed. ret=%d", ret); if ((ret = hls->on_video(msg)) != ERROR_SUCCESS) {
return ret; srs_error("hls process video message failed. ret=%d", ret);
return ret;
}
if ((ret = source->on_video(msg)) != ERROR_SUCCESS) {
srs_error("source process video message failed. ret=%d", ret);
return ret;
}
} }
// process onMetaData // process onMetaData
@ -386,8 +408,12 @@ int SrsClient::process_publish_message(SrsSource* source, SrsHLS* hls, SrsCommon
SrsPacket* pkt = msg->get_packet(); SrsPacket* pkt = msg->get_packet();
if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) { if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {
SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt); SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);
if ((ret = hls->on_meta_data(metadata)) != ERROR_SUCCESS) {
srs_error("hls process onMetaData message failed. ret=%d", ret);
return ret;
}
if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) { if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) {
srs_error("process onMetaData message failed. ret=%d", ret); srs_error("source process onMetaData message failed. ret=%d", ret);
return ret; return ret;
} }
srs_trace("process onMetaData message success."); srs_trace("process onMetaData message success.");

View file

@ -23,32 +23,84 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_codec.hpp> #include <srs_core_codec.hpp>
#include <srs_core_error.hpp>
#include <srs_core_stream.hpp>
SrsCodec::SrsCodec() SrsCodec::SrsCodec()
{ {
width = 0;
height = 0;
duration = 0;
frame_rate = 0;
video_data_rate = 0;
video_codec_id = 0;
audio_data_rate = 0;
audio_codec_id = 0;
aac_sample_rate = 0;
sample_rate = 0;
sample_size = 0;
audio_channels = 0;
profile = 0;
level = 0;
avc_extra_size = 0;
avc_extra_data = NULL;
aac_extra_size = 0;
aac_extra_data = NULL;
stream = new SrsStream();
} }
SrsCodec::~SrsCodec() SrsCodec::~SrsCodec()
{ {
srs_freepa(avc_extra_data);
srs_freepa(aac_extra_data);
srs_freep(stream);
}
int SrsCodec::parse_av_codec(bool is_video, int8_t* data, int size)
{
int ret = ERROR_SUCCESS;
if (!data || size <= 0) {
return ret;
}
if ((ret = stream->initialize((char*)data, size)) != ERROR_SUCCESS) {
return ret;
}
if (is_video) {
if (!stream->require(1)) {
return ret;
}
int8_t frame_type = stream->read_1bytes();
int8_t codec_id = frame_type & 0x0f;
frame_type = (frame_type >> 4) & 0x0f;
video_codec_id = codec_id;
if (codec_id != SrsCodecVideoAVC) {
return ret;
}
if (!stream->require(4)) {
return ret;
}
int8_t avc_packet_type = stream->read_1bytes();
int32_t composition_time = stream->read_3bytes();
// 5.2.4.1.1 Syntax
if (avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader) {
}
} else {
}
return ret;
} }
bool SrsCodec::video_is_keyframe(int8_t* data, int size) bool SrsCodec::video_is_keyframe(int8_t* data, int size)
{ {
// E.4.3.1 VIDEODATA
// Frame Type UB [4]
// Type of video frame. The following values are defined:
// 1 = key frame (for AVC, a seekable frame)
// 2 = inter frame (for AVC, a non-seekable frame)
// 3 = disposable inter frame (H.263 only)
// 4 = generated key frame (reserved for server use only)
// 5 = video info/command frame
//
// AVCPacketType IF CodecID == 7 UI8
// The following values are defined:
// 0 = AVC sequence header
// 1 = AVC NALU
// 2 = AVC end of sequence (lower level NALU sequence ender is
// not required or supported)
// 2bytes required. // 2bytes required.
if (size < 1) { if (size < 1) {
return false; return false;
@ -57,27 +109,11 @@ bool SrsCodec::video_is_keyframe(int8_t* data, int size)
char frame_type = *(char*)data; char frame_type = *(char*)data;
frame_type = (frame_type >> 4) & 0x0F; frame_type = (frame_type >> 4) & 0x0F;
return frame_type == 1; return frame_type == SrsCodecVideoAVCFrameKeyFrame;
} }
bool SrsCodec::video_is_sequence_header(int8_t* data, int size) bool SrsCodec::video_is_sequence_header(int8_t* data, int size)
{ {
// E.4.3.1 VIDEODATA
// Frame Type UB [4]
// Type of video frame. The following values are defined:
// 1 = key frame (for AVC, a seekable frame)
// 2 = inter frame (for AVC, a non-seekable frame)
// 3 = disposable inter frame (H.263 only)
// 4 = generated key frame (reserved for server use only)
// 5 = video info/command frame
//
// AVCPacketType IF CodecID == 7 UI8
// The following values are defined:
// 0 = AVC sequence header
// 1 = AVC NALU
// 2 = AVC end of sequence (lower level NALU sequence ender is
// not required or supported)
// sequence header only for h264 // sequence header only for h264
if (!video_is_h264(data, size)) { if (!video_is_h264(data, size)) {
return false; return false;
@ -93,16 +129,12 @@ bool SrsCodec::video_is_sequence_header(int8_t* data, int size)
char avc_packet_type = *(char*)(data + 1); char avc_packet_type = *(char*)(data + 1);
return frame_type == 1 && avc_packet_type == 0; return frame_type == SrsCodecVideoAVCFrameKeyFrame
&& avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader;
} }
bool SrsCodec::audio_is_sequence_header(int8_t* data, int size) bool SrsCodec::audio_is_sequence_header(int8_t* data, int size)
{ {
// AACPacketType IF SoundFormat == 10 UI8
// The following values are defined:
// 0 = AAC sequence header
// 1 = AAC raw
// sequence header only for aac // sequence header only for aac
if (!audio_is_aac(data, size)) { if (!audio_is_aac(data, size)) {
return false; return false;
@ -115,21 +147,11 @@ bool SrsCodec::audio_is_sequence_header(int8_t* data, int size)
char aac_packet_type = *(char*)(data + 1); char aac_packet_type = *(char*)(data + 1);
return aac_packet_type == 0; return aac_packet_type == SrsCodecAudioTypeSequenceHeader;
} }
bool SrsCodec::video_is_h264(int8_t* data, int size) bool SrsCodec::video_is_h264(int8_t* data, int size)
{ {
// E.4.3.1 VIDEODATA
// CodecID UB [4]
// Codec Identifier. The following values are defined:
// 2 = Sorenson H.263
// 3 = Screen video
// 4 = On2 VP6
// 5 = On2 VP6 with alpha channel
// 6 = Screen video version 2
// 7 = AVC
// 1bytes required. // 1bytes required.
if (size < 1) { if (size < 1) {
return false; return false;
@ -138,31 +160,11 @@ bool SrsCodec::video_is_h264(int8_t* data, int size)
char codec_id = *(char*)data; char codec_id = *(char*)data;
codec_id = codec_id & 0x0F; codec_id = codec_id & 0x0F;
return codec_id == 7; return codec_id == SrsCodecVideoAVC;
} }
bool SrsCodec::audio_is_aac(int8_t* data, int size) bool SrsCodec::audio_is_aac(int8_t* data, int size)
{ {
// SoundFormat UB [4]
// Format of SoundData. The following values are defined:
// 0 = Linear PCM, platform endian
// 1 = ADPCM
// 2 = MP3
// 3 = Linear PCM, little endian
// 4 = Nellymoser 16 kHz mono
// 5 = Nellymoser 8 kHz mono
// 6 = Nellymoser
// 7 = G.711 A-law logarithmic PCM
// 8 = G.711 mu-law logarithmic PCM
// 9 = reserved
// 10 = AAC
// 11 = Speex
// 14 = MP3 8 kHz
// 15 = Device-specific sound
// Formats 7, 8, 14, and 15 are reserved.
// AAC is supported in Flash Player 9,0,115,0 and higher.
// Speex is supported in Flash Player 10 and higher.
// 1bytes required. // 1bytes required.
if (size < 1) { if (size < 1) {
return false; return false;
@ -171,5 +173,5 @@ bool SrsCodec::audio_is_aac(int8_t* data, int size)
char sound_format = *(char*)data; char sound_format = *(char*)data;
sound_format = (sound_format >> 4) & 0x0F; sound_format = (sound_format >> 4) & 0x0F;
return sound_format == 10; return sound_format == SrsCodecAudioAAC;
} }

View file

@ -30,36 +30,170 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core.hpp> #include <srs_core.hpp>
class SrsStream;
// E.4.3.1 VIDEODATA
// CodecID UB [4]
// Codec Identifier. The following values are defined:
// 2 = Sorenson H.263
// 3 = Screen video
// 4 = On2 VP6
// 5 = On2 VP6 with alpha channel
// 6 = Screen video version 2
// 7 = AVC
enum SrsCodecVideo
{
SrsCodecVideoSorensonH263 = 2,
SrsCodecVideoScreenVideo = 3,
SrsCodecVideoOn2VP6 = 4,
SrsCodecVideoOn2VP6WithAlphaChannel = 5,
SrsCodecVideoScreenVideoVersion2 = 6,
SrsCodecVideoAVC = 7,
};
// E.4.3.1 VIDEODATA
// Frame Type UB [4]
// Type of video frame. The following values are defined:
// 1 = key frame (for AVC, a seekable frame)
// 2 = inter frame (for AVC, a non-seekable frame)
// 3 = disposable inter frame (H.263 only)
// 4 = generated key frame (reserved for server use only)
// 5 = video info/command frame
enum SrsCodecVideoAVCFrame
{
SrsCodecVideoAVCFrameKeyFrame = 1,
SrsCodecVideoAVCFrameInterFrame = 2,
SrsCodecVideoAVCFrameDisposableInterFrame = 3,
SrsCodecVideoAVCFrameGeneratedKeyFrame = 4,
SrsCodecVideoAVCFrameVideoInfoFrame = 5,
};
// AVCPacketType IF CodecID == 7 UI8
// The following values are defined:
// 0 = AVC sequence header
// 1 = AVC NALU
// 2 = AVC end of sequence (lower level NALU sequence ender is
// not required or supported)
enum SrsCodecVideoAVCType
{
SrsCodecVideoAVCTypeSequenceHeader = 0,
SrsCodecVideoAVCTypeNALU = 1,
SrsCodecVideoAVCTypeSequenceHeaderEOF = 2,
};
// SoundFormat UB [4]
// Format of SoundData. The following values are defined:
// 0 = Linear PCM, platform endian
// 1 = ADPCM
// 2 = MP3
// 3 = Linear PCM, little endian
// 4 = Nellymoser 16 kHz mono
// 5 = Nellymoser 8 kHz mono
// 6 = Nellymoser
// 7 = G.711 A-law logarithmic PCM
// 8 = G.711 mu-law logarithmic PCM
// 9 = reserved
// 10 = AAC
// 11 = Speex
// 14 = MP3 8 kHz
// 15 = Device-specific sound
// Formats 7, 8, 14, and 15 are reserved.
// AAC is supported in Flash Player 9,0,115,0 and higher.
// Speex is supported in Flash Player 10 and higher.
enum SrsCodecAudio
{
SrsCodecAudioLinearPCMPlatformEndian = 0,
SrsCodecAudioADPCM = 1,
SrsCodecAudioMP3 = 2,
SrsCodecAudioLinearPCMLittleEndian = 3,
SrsCodecAudioNellymoser16kHzMono = 4,
SrsCodecAudioNellymoser8kHzMono = 5,
SrsCodecAudioNellymoser = 6,
SrsCodecAudioReservedG711AlawLogarithmicPCM = 7,
SrsCodecAudioReservedG711MuLawLogarithmicPCM = 8,
SrsCodecAudioReserved = 9,
SrsCodecAudioAAC = 10,
SrsCodecAudioSpeex = 11,
SrsCodecAudioReservedMP3_8kHz = 14,
SrsCodecAudioReservedDeviceSpecificSound = 15,
};
// AACPacketType IF SoundFormat == 10 UI8
// The following values are defined:
// 0 = AAC sequence header
// 1 = AAC raw
enum SrsCodecAudioType
{
SrsCodecAudioTypeSequenceHeader = 0,
SrsCodecAudioTypeRawData = 1,
};
/** /**
* Annex E. The FLV File Format * Annex E. The FLV File Format
*/ */
class SrsCodec class SrsCodec
{ {
private:
SrsStream* stream;
public:
/**
* video specified
*/
int width;
int height;
int duration;
int frame_rate;
// @see: SrsCodecVideo
int video_codec_id;
int video_data_rate; // in bps
u_int8_t profile; // profile_idc, page 45.
u_int8_t level; // level_idc, page 45.
/**
* audio specified
*/
int audio_codec_id;
int audio_data_rate; // in bps
int aac_sample_rate;
int sample_rate; /* 5512, 11025, 22050, 44100 */
int sample_size; /* 1=8bit, 2=16bit */
int audio_channels; /* 1, 2 */
// the avc extra data, the AVC sequence header,
// without the flv codec header
int avc_extra_size;
char* avc_extra_data;
// the aac extra data, the AAC sequence header,
// without the flv codec header
int aac_extra_size;
char* aac_extra_data;
public: public:
SrsCodec(); SrsCodec();
virtual ~SrsCodec(); virtual ~SrsCodec();
// the following function used for hls to build the codec info.
public:
virtual int parse_av_codec(bool is_video, int8_t* data, int size);
// the following function used to finger out the flv/rtmp packet detail.
public: public:
/** /**
* only check the frame_type, not check the codec type. * only check the frame_type, not check the codec type.
*/ */
virtual bool video_is_keyframe(int8_t* data, int size); static bool video_is_keyframe(int8_t* data, int size);
/** /**
* check codec h264, keyframe, sequence header * check codec h264, keyframe, sequence header
*/ */
virtual bool video_is_sequence_header(int8_t* data, int size); static bool video_is_sequence_header(int8_t* data, int size);
/** /**
* check codec aac, sequence header * check codec aac, sequence header
*/ */
virtual bool audio_is_sequence_header(int8_t* data, int size); static bool audio_is_sequence_header(int8_t* data, int size);
/** /**
* check codec h264. * check codec h264.
*/ */
virtual bool video_is_h264(int8_t* data, int size); static bool video_is_h264(int8_t* data, int size);
private: private:
/** /**
* check codec aac. * check codec aac.
*/ */
virtual bool audio_is_aac(int8_t* data, int size); static bool audio_is_aac(int8_t* data, int size);
}; };
#endif #endif

View file

@ -23,11 +23,117 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core_hls.hpp> #include <srs_core_hls.hpp>
#include <srs_core_error.hpp>
#include <srs_core_codec.hpp>
#include <srs_core_amf0.hpp>
#include <srs_core_protocol.hpp>
SrsHLS::SrsHLS() SrsHLS::SrsHLS()
{ {
codec = new SrsCodec();
} }
SrsHLS::~SrsHLS() SrsHLS::~SrsHLS()
{ {
srs_freep(codec);
}
int SrsHLS::on_publish()
{
int ret = ERROR_SUCCESS;
return ret;
}
void SrsHLS::on_unpublish()
{
}
int SrsHLS::on_meta_data(SrsOnMetaDataPacket* metadata)
{
int ret = ERROR_SUCCESS;
if (!metadata || !metadata->metadata) {
return ret;
}
SrsAmf0Object* obj = metadata->metadata;
if (obj->size() <= 0) {
return ret;
}
// finger out the codec info from metadata if possible.
SrsAmf0Any* prop = NULL;
if ((prop = obj->get_property("duration")) != NULL && prop->is_number()) {
codec->duration = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
}
if ((prop = obj->get_property("width")) != NULL && prop->is_number()) {
codec->width = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
}
if ((prop = obj->get_property("height")) != NULL && prop->is_number()) {
codec->height = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
}
if ((prop = obj->get_property("framerate")) != NULL && prop->is_number()) {
codec->frame_rate = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
}
if ((prop = obj->get_property("videocodecid")) != NULL && prop->is_number()) {
codec->video_codec_id = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
}
if ((prop = obj->get_property("videodatarate")) != NULL && prop->is_number()) {
codec->video_data_rate = (int)(1000 * srs_amf0_convert<SrsAmf0Number>(prop)->value);
}
if ((prop = obj->get_property("audiocodecid")) != NULL && prop->is_number()) {
codec->audio_codec_id = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
}
if ((prop = obj->get_property("audiodatarate")) != NULL && prop->is_number()) {
codec->audio_data_rate = (int)(1000 * srs_amf0_convert<SrsAmf0Number>(prop)->value);
}
if ((prop = obj->get_property("audiosamplerate")) != NULL && prop->is_number()) {
codec->sample_rate = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
}
if ((prop = obj->get_property("audiosamplesize")) != NULL && prop->is_number()) {
codec->sample_size = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
if (codec->sample_size == 16) {
codec->sample_size = 2;
} else {
codec->sample_size = 1;
}
}
if ((prop = obj->get_property("stereo")) != NULL && prop->is_number()) {
if (srs_amf0_convert<SrsAmf0Boolean>(prop)->value) {
codec->audio_channels = 2;
} else {
codec->audio_channels = 1;
}
}
return ret;
}
int SrsHLS::on_audio(SrsCommonMessage* audio)
{
int ret = ERROR_SUCCESS;
if ((ret = codec->parse_av_codec(false, audio->payload, audio->size)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
int SrsHLS::on_video(SrsCommonMessage* video)
{
int ret = ERROR_SUCCESS;
if ((ret = codec->parse_av_codec(true, video->payload, video->size)) != ERROR_SUCCESS) {
return ret;
}
if (codec->video_codec_id != SrsCodecVideoAVC) {
return ret;
}
return ret;
} }

View file

@ -29,11 +29,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_core.hpp> #include <srs_core.hpp>
class SrsOnMetaDataPacket;
class SrsCommonMessage;
class SrsCodec;
class SrsHLS class SrsHLS
{ {
private:
SrsCodec* codec;
public: public:
SrsHLS(); SrsHLS();
virtual ~SrsHLS(); virtual ~SrsHLS();
public:
virtual int on_publish();
virtual void on_unpublish();
virtual int on_meta_data(SrsOnMetaDataPacket* metadata);
virtual int on_audio(SrsCommonMessage* audio);
virtual int on_video(SrsCommonMessage* video);
}; };
#endif #endif

View file

@ -53,13 +53,11 @@ SrsConsumer::SrsConsumer(SrsSource* _source)
source = _source; source = _source;
last_pkt_correct_time = last_pkt_time = 0; last_pkt_correct_time = last_pkt_time = 0;
paused = false; paused = false;
codec = new SrsCodec();
} }
SrsConsumer::~SrsConsumer() SrsConsumer::~SrsConsumer()
{ {
clear(); clear();
srs_freep(codec);
source->on_consumer_destroy(this); source->on_consumer_destroy(this);
} }
@ -141,7 +139,7 @@ void SrsConsumer::shrink()
SrsSharedPtrMessage* msg = *it; SrsSharedPtrMessage* msg = *it;
if (msg->header.is_video()) { if (msg->header.is_video()) {
has_video = true; has_video = true;
if (codec->video_is_keyframe(msg->payload, msg->size)) { if (SrsCodec::video_is_keyframe(msg->payload, msg->size)) {
iframe = it; iframe = it;
frame_to_remove = i + 1; frame_to_remove = i + 1;
} }
@ -240,7 +238,6 @@ void SrsConsumer::clear()
SrsSource::SrsSource(std::string _stream_url) SrsSource::SrsSource(std::string _stream_url)
{ {
stream_url = _stream_url; stream_url = _stream_url;
codec = new SrsCodec();
hls = new SrsHLS(); hls = new SrsHLS();
cache_metadata = cache_sh_video = cache_sh_audio = NULL; cache_metadata = cache_sh_video = cache_sh_audio = NULL;
@ -266,7 +263,6 @@ SrsSource::~SrsSource()
srs_freep(cache_sh_video); srs_freep(cache_sh_video);
srs_freep(cache_sh_audio); srs_freep(cache_sh_audio);
srs_freep(codec);
srs_freep(hls); srs_freep(hls);
} }
@ -364,7 +360,7 @@ int SrsSource::on_audio(SrsCommonMessage* audio)
srs_info("dispatch audio success."); srs_info("dispatch audio success.");
// cache the sequence header if h264 // cache the sequence header if h264
if (codec->audio_is_sequence_header(msg->payload, msg->size)) { if (SrsCodec::audio_is_sequence_header(msg->payload, msg->size)) {
srs_freep(cache_sh_audio); srs_freep(cache_sh_audio);
cache_sh_audio = msg->copy(); cache_sh_audio = msg->copy();
srs_trace("update audio sequence header success. size=%d", msg->header.payload_length); srs_trace("update audio sequence header success. size=%d", msg->header.payload_length);
@ -409,7 +405,7 @@ int SrsSource::on_video(SrsCommonMessage* video)
srs_info("dispatch video success."); srs_info("dispatch video success.");
// cache the sequence header if h264 // cache the sequence header if h264
if (codec->video_is_sequence_header(msg->payload, msg->size)) { if (SrsCodec::video_is_sequence_header(msg->payload, msg->size)) {
srs_freep(cache_sh_video); srs_freep(cache_sh_video);
cache_sh_video = msg->copy(); cache_sh_video = msg->copy();
srs_trace("update video sequence header success. size=%d", msg->header.payload_length); srs_trace("update video sequence header success. size=%d", msg->header.payload_length);
@ -521,7 +517,7 @@ int SrsSource::cache_last_gop(SrsSharedPtrMessage* msg)
} }
// clear gop cache when got key frame // clear gop cache when got key frame
if (msg->header.is_video() && codec->video_is_keyframe(msg->payload, msg->size)) { if (msg->header.is_video() && SrsCodec::video_is_keyframe(msg->payload, msg->size)) {
srs_info("clear gop cache when got keyframe. vcount=%d, count=%d", srs_info("clear gop cache when got keyframe. vcount=%d, count=%d",
cached_video_count, (int)gop_cache.size()); cached_video_count, (int)gop_cache.size());

View file

@ -34,7 +34,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <vector> #include <vector>
#include <string> #include <string>
class SrsCodec;
class SrsSource; class SrsSource;
class SrsCommonMessage; class SrsCommonMessage;
class SrsOnMetaDataPacket; class SrsOnMetaDataPacket;
@ -52,7 +51,6 @@ private:
SrsSource* source; SrsSource* source;
std::vector<SrsSharedPtrMessage*> msgs; std::vector<SrsSharedPtrMessage*> msgs;
bool paused; bool paused;
SrsCodec* codec;
public: public:
SrsConsumer(SrsSource* _source); SrsConsumer(SrsSource* _source);
virtual ~SrsConsumer(); virtual ~SrsConsumer();
@ -108,7 +106,6 @@ public:
static SrsSource* find(std::string stream_url); static SrsSource* find(std::string stream_url);
private: private:
SrsHLS* hls; SrsHLS* hls;
SrsCodec* codec;
std::string stream_url; std::string stream_url;
std::vector<SrsConsumer*> consumers; std::vector<SrsConsumer*> consumers;
// gop cache for client fast startup. // gop cache for client fast startup.

View file

@ -106,6 +106,19 @@ int16_t SrsStream::read_2bytes()
return value; return value;
} }
int32_t SrsStream::read_3bytes()
{
srs_assert(require(3));
int32_t value = 0x00;
pp = (char*)&value;
pp[2] = *p++;
pp[1] = *p++;
pp[0] = *p++;
return value;
}
int32_t SrsStream::read_4bytes() int32_t SrsStream::read_4bytes()
{ {
srs_assert(require(4)); srs_assert(require(4));

View file

@ -84,6 +84,10 @@ public:
*/ */
virtual int16_t read_2bytes(); virtual int16_t read_2bytes();
/** /**
* get 3bytes int from stream.
*/
virtual int32_t read_3bytes();
/**
* get 4bytes int from stream. * get 4bytes int from stream.
*/ */
virtual int32_t read_4bytes(); virtual int32_t read_4bytes();