winlin

add avc format doc. decode the flv codec info

不能预览此文件类型
@@ -151,6 +151,7 @@ int SrsClient::do_cycle() @@ -151,6 +151,7 @@ int SrsClient::do_cycle()
151 // find a source to publish. 151 // find a source to publish.
152 SrsSource* source = SrsSource::find(req->get_stream_url()); 152 SrsSource* source = SrsSource::find(req->get_stream_url());
153 srs_assert(source != NULL); 153 srs_assert(source != NULL);
  154 + SrsHLS* hls = source->get_hls();
154 155
155 bool enabled_cache = true; 156 bool enabled_cache = true;
156 conf = config->get_gop_cache(req->vhost); 157 conf = config->get_gop_cache(req->vhost);
@@ -181,6 +182,7 @@ int SrsClient::do_cycle() @@ -181,6 +182,7 @@ int SrsClient::do_cycle()
181 } 182 }
182 srs_info("start to publish stream %s success", req->stream.c_str()); 183 srs_info("start to publish stream %s success", req->stream.c_str());
183 ret = publish(source, true); 184 ret = publish(source, true);
  185 + hls->on_unpublish();
184 source->on_unpublish(); 186 source->on_unpublish();
185 return ret; 187 return ret;
186 } 188 }
@@ -193,6 +195,7 @@ int SrsClient::do_cycle() @@ -193,6 +195,7 @@ int SrsClient::do_cycle()
193 } 195 }
194 srs_info("flash start to publish stream %s success", req->stream.c_str()); 196 srs_info("flash start to publish stream %s success", req->stream.c_str());
195 ret = publish(source, false); 197 ret = publish(source, false);
  198 + hls->on_unpublish();
196 source->on_unpublish(); 199 source->on_unpublish();
197 return ret; 200 return ret;
198 } 201 }
@@ -330,8 +333,15 @@ int SrsClient::publish(SrsSource* source, bool is_fmle) @@ -330,8 +333,15 @@ int SrsClient::publish(SrsSource* source, bool is_fmle)
330 srs_verbose("check publish_refer success."); 333 srs_verbose("check publish_refer success.");
331 334
332 SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER); 335 SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);
333 -  
334 SrsHLS* hls = source->get_hls(); 336 SrsHLS* hls = source->get_hls();
  337 +
  338 + // notify the hls to prepare when publish start.
  339 + if ((ret = hls->on_publish()) != ERROR_SUCCESS) {
  340 + srs_error("hls on_publish failed. ret=%d", ret);
  341 + return ret;
  342 + }
  343 + srs_verbose("hls on_publish success.");
  344 +
335 while (true) { 345 while (true) {
336 // switch to other st-threads. 346 // switch to other st-threads.
337 st_usleep(0); 347 st_usleep(0);
@@ -366,14 +376,26 @@ int SrsClient::process_publish_message(SrsSource* source, SrsHLS* hls, SrsCommon @@ -366,14 +376,26 @@ int SrsClient::process_publish_message(SrsSource* source, SrsHLS* hls, SrsCommon
366 int ret = ERROR_SUCCESS; 376 int ret = ERROR_SUCCESS;
367 377
368 // process audio packet 378 // process audio packet
369 - if (msg->header.is_audio() && ((ret = source->on_audio(msg)) != ERROR_SUCCESS)) {  
370 - srs_error("process audio message failed. ret=%d", ret);  
371 - return ret; 379 + if (msg->header.is_audio()) {
  380 + if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) {
  381 + srs_error("hls process audio message failed. ret=%d", ret);
  382 + return ret;
  383 + }
  384 + if ((ret = source->on_audio(msg)) != ERROR_SUCCESS) {
  385 + srs_error("source process audio message failed. ret=%d", ret);
  386 + return ret;
  387 + }
372 } 388 }
373 // process video packet 389 // process video packet
374 - if (msg->header.is_video() && ((ret = source->on_video(msg)) != ERROR_SUCCESS)) {  
375 - srs_error("process video message failed. ret=%d", ret);  
376 - return ret; 390 + if (msg->header.is_video()) {
  391 + if ((ret = hls->on_video(msg)) != ERROR_SUCCESS) {
  392 + srs_error("hls process video message failed. ret=%d", ret);
  393 + return ret;
  394 + }
  395 + if ((ret = source->on_video(msg)) != ERROR_SUCCESS) {
  396 + srs_error("source process video message failed. ret=%d", ret);
  397 + return ret;
  398 + }
377 } 399 }
378 400
379 // process onMetaData 401 // process onMetaData
@@ -386,8 +408,12 @@ int SrsClient::process_publish_message(SrsSource* source, SrsHLS* hls, SrsCommon @@ -386,8 +408,12 @@ int SrsClient::process_publish_message(SrsSource* source, SrsHLS* hls, SrsCommon
386 SrsPacket* pkt = msg->get_packet(); 408 SrsPacket* pkt = msg->get_packet();
387 if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) { 409 if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {
388 SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt); 410 SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);
  411 + if ((ret = hls->on_meta_data(metadata)) != ERROR_SUCCESS) {
  412 + srs_error("hls process onMetaData message failed. ret=%d", ret);
  413 + return ret;
  414 + }
389 if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) { 415 if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) {
390 - srs_error("process onMetaData message failed. ret=%d", ret); 416 + srs_error("source process onMetaData message failed. ret=%d", ret);
391 return ret; 417 return ret;
392 } 418 }
393 srs_trace("process onMetaData message success."); 419 srs_trace("process onMetaData message success.");
@@ -23,32 +23,84 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,32 +23,84 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_core_codec.hpp> 24 #include <srs_core_codec.hpp>
25 25
  26 +#include <srs_core_error.hpp>
  27 +#include <srs_core_stream.hpp>
  28 +
26 SrsCodec::SrsCodec() 29 SrsCodec::SrsCodec()
27 { 30 {
  31 + width = 0;
  32 + height = 0;
  33 + duration = 0;
  34 + frame_rate = 0;
  35 + video_data_rate = 0;
  36 + video_codec_id = 0;
  37 + audio_data_rate = 0;
  38 + audio_codec_id = 0;
  39 + aac_sample_rate = 0;
  40 + sample_rate = 0;
  41 + sample_size = 0;
  42 + audio_channels = 0;
  43 + profile = 0;
  44 + level = 0;
  45 + avc_extra_size = 0;
  46 + avc_extra_data = NULL;
  47 + aac_extra_size = 0;
  48 + aac_extra_data = NULL;
  49 +
  50 + stream = new SrsStream();
28 } 51 }
29 52
30 SrsCodec::~SrsCodec() 53 SrsCodec::~SrsCodec()
31 { 54 {
  55 + srs_freepa(avc_extra_data);
  56 + srs_freepa(aac_extra_data);
  57 +
  58 + srs_freep(stream);
32 } 59 }
33 60
34 -bool SrsCodec::video_is_keyframe(int8_t* data, int size) 61 +int SrsCodec::parse_av_codec(bool is_video, int8_t* data, int size)
35 { 62 {
36 - // E.4.3.1 VIDEODATA  
37 - // Frame Type UB [4]  
38 - // Type of video frame. The following values are defined:  
39 - // 1 = key frame (for AVC, a seekable frame)  
40 - // 2 = inter frame (for AVC, a non-seekable frame)  
41 - // 3 = disposable inter frame (H.263 only)  
42 - // 4 = generated key frame (reserved for server use only)  
43 - // 5 = video info/command frame  
44 - //  
45 - // AVCPacketType IF CodecID == 7 UI8  
46 - // The following values are defined:  
47 - // 0 = AVC sequence header  
48 - // 1 = AVC NALU  
49 - // 2 = AVC end of sequence (lower level NALU sequence ender is  
50 - // not required or supported) 63 + int ret = ERROR_SUCCESS;
  64 +
  65 + if (!data || size <= 0) {
  66 + return ret;
  67 + }
  68 +
  69 + if ((ret = stream->initialize((char*)data, size)) != ERROR_SUCCESS) {
  70 + return ret;
  71 + }
  72 +
  73 + if (is_video) {
  74 + if (!stream->require(1)) {
  75 + return ret;
  76 + }
  77 +
  78 + int8_t frame_type = stream->read_1bytes();
  79 + int8_t codec_id = frame_type & 0x0f;
  80 + frame_type = (frame_type >> 4) & 0x0f;
  81 +
  82 + video_codec_id = codec_id;
  83 + if (codec_id != SrsCodecVideoAVC) {
  84 + return ret;
  85 + }
  86 +
  87 + if (!stream->require(4)) {
  88 + return ret;
  89 + }
  90 + int8_t avc_packet_type = stream->read_1bytes();
  91 + int32_t composition_time = stream->read_3bytes();
  92 +
  93 + // 5.2.4.1.1 Syntax
  94 + if (avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader) {
  95 + }
  96 + } else {
  97 + }
51 98
  99 + return ret;
  100 +}
  101 +
  102 +bool SrsCodec::video_is_keyframe(int8_t* data, int size)
  103 +{
52 // 2bytes required. 104 // 2bytes required.
53 if (size < 1) { 105 if (size < 1) {
54 return false; 106 return false;
@@ -57,27 +109,11 @@ bool SrsCodec::video_is_keyframe(int8_t* data, int size) @@ -57,27 +109,11 @@ bool SrsCodec::video_is_keyframe(int8_t* data, int size)
57 char frame_type = *(char*)data; 109 char frame_type = *(char*)data;
58 frame_type = (frame_type >> 4) & 0x0F; 110 frame_type = (frame_type >> 4) & 0x0F;
59 111
60 - return frame_type == 1; 112 + return frame_type == SrsCodecVideoAVCFrameKeyFrame;
61 } 113 }
62 114
63 bool SrsCodec::video_is_sequence_header(int8_t* data, int size) 115 bool SrsCodec::video_is_sequence_header(int8_t* data, int size)
64 { 116 {
65 - // E.4.3.1 VIDEODATA  
66 - // Frame Type UB [4]  
67 - // Type of video frame. The following values are defined:  
68 - // 1 = key frame (for AVC, a seekable frame)  
69 - // 2 = inter frame (for AVC, a non-seekable frame)  
70 - // 3 = disposable inter frame (H.263 only)  
71 - // 4 = generated key frame (reserved for server use only)  
72 - // 5 = video info/command frame  
73 - //  
74 - // AVCPacketType IF CodecID == 7 UI8  
75 - // The following values are defined:  
76 - // 0 = AVC sequence header  
77 - // 1 = AVC NALU  
78 - // 2 = AVC end of sequence (lower level NALU sequence ender is  
79 - // not required or supported)  
80 -  
81 // sequence header only for h264 117 // sequence header only for h264
82 if (!video_is_h264(data, size)) { 118 if (!video_is_h264(data, size)) {
83 return false; 119 return false;
@@ -93,16 +129,12 @@ bool SrsCodec::video_is_sequence_header(int8_t* data, int size) @@ -93,16 +129,12 @@ bool SrsCodec::video_is_sequence_header(int8_t* data, int size)
93 129
94 char avc_packet_type = *(char*)(data + 1); 130 char avc_packet_type = *(char*)(data + 1);
95 131
96 - return frame_type == 1 && avc_packet_type == 0; 132 + return frame_type == SrsCodecVideoAVCFrameKeyFrame
  133 + && avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader;
97 } 134 }
98 135
99 bool SrsCodec::audio_is_sequence_header(int8_t* data, int size) 136 bool SrsCodec::audio_is_sequence_header(int8_t* data, int size)
100 { 137 {
101 - // AACPacketType IF SoundFormat == 10 UI8  
102 - // The following values are defined:  
103 - // 0 = AAC sequence header  
104 - // 1 = AAC raw  
105 -  
106 // sequence header only for aac 138 // sequence header only for aac
107 if (!audio_is_aac(data, size)) { 139 if (!audio_is_aac(data, size)) {
108 return false; 140 return false;
@@ -115,21 +147,11 @@ bool SrsCodec::audio_is_sequence_header(int8_t* data, int size) @@ -115,21 +147,11 @@ bool SrsCodec::audio_is_sequence_header(int8_t* data, int size)
115 147
116 char aac_packet_type = *(char*)(data + 1); 148 char aac_packet_type = *(char*)(data + 1);
117 149
118 - return aac_packet_type == 0; 150 + return aac_packet_type == SrsCodecAudioTypeSequenceHeader;
119 } 151 }
120 152
121 bool SrsCodec::video_is_h264(int8_t* data, int size) 153 bool SrsCodec::video_is_h264(int8_t* data, int size)
122 { 154 {
123 - // E.4.3.1 VIDEODATA  
124 - // CodecID UB [4]  
125 - // Codec Identifier. The following values are defined:  
126 - // 2 = Sorenson H.263  
127 - // 3 = Screen video  
128 - // 4 = On2 VP6  
129 - // 5 = On2 VP6 with alpha channel  
130 - // 6 = Screen video version 2  
131 - // 7 = AVC  
132 -  
133 // 1bytes required. 155 // 1bytes required.
134 if (size < 1) { 156 if (size < 1) {
135 return false; 157 return false;
@@ -138,31 +160,11 @@ bool SrsCodec::video_is_h264(int8_t* data, int size) @@ -138,31 +160,11 @@ bool SrsCodec::video_is_h264(int8_t* data, int size)
138 char codec_id = *(char*)data; 160 char codec_id = *(char*)data;
139 codec_id = codec_id & 0x0F; 161 codec_id = codec_id & 0x0F;
140 162
141 - return codec_id == 7; 163 + return codec_id == SrsCodecVideoAVC;
142 } 164 }
143 165
144 bool SrsCodec::audio_is_aac(int8_t* data, int size) 166 bool SrsCodec::audio_is_aac(int8_t* data, int size)
145 { 167 {
146 - // SoundFormat UB [4]  
147 - // Format of SoundData. The following values are defined:  
148 - // 0 = Linear PCM, platform endian  
149 - // 1 = ADPCM  
150 - // 2 = MP3  
151 - // 3 = Linear PCM, little endian  
152 - // 4 = Nellymoser 16 kHz mono  
153 - // 5 = Nellymoser 8 kHz mono  
154 - // 6 = Nellymoser  
155 - // 7 = G.711 A-law logarithmic PCM  
156 - // 8 = G.711 mu-law logarithmic PCM  
157 - // 9 = reserved  
158 - // 10 = AAC  
159 - // 11 = Speex  
160 - // 14 = MP3 8 kHz  
161 - // 15 = Device-specific sound  
162 - // Formats 7, 8, 14, and 15 are reserved.  
163 - // AAC is supported in Flash Player 9,0,115,0 and higher.  
164 - // Speex is supported in Flash Player 10 and higher.  
165 -  
166 // 1bytes required. 168 // 1bytes required.
167 if (size < 1) { 169 if (size < 1) {
168 return false; 170 return false;
@@ -171,5 +173,5 @@ bool SrsCodec::audio_is_aac(int8_t* data, int size) @@ -171,5 +173,5 @@ bool SrsCodec::audio_is_aac(int8_t* data, int size)
171 char sound_format = *(char*)data; 173 char sound_format = *(char*)data;
172 sound_format = (sound_format >> 4) & 0x0F; 174 sound_format = (sound_format >> 4) & 0x0F;
173 175
174 - return sound_format == 10; 176 + return sound_format == SrsCodecAudioAAC;
175 } 177 }
@@ -30,36 +30,170 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,36 +30,170 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 30
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
  33 +class SrsStream;
  34 +
  35 +// E.4.3.1 VIDEODATA
  36 +// CodecID UB [4]
  37 +// Codec Identifier. The following values are defined:
  38 +// 2 = Sorenson H.263
  39 +// 3 = Screen video
  40 +// 4 = On2 VP6
  41 +// 5 = On2 VP6 with alpha channel
  42 +// 6 = Screen video version 2
  43 +// 7 = AVC
  44 +enum SrsCodecVideo
  45 +{
  46 + SrsCodecVideoSorensonH263 = 2,
  47 + SrsCodecVideoScreenVideo = 3,
  48 + SrsCodecVideoOn2VP6 = 4,
  49 + SrsCodecVideoOn2VP6WithAlphaChannel = 5,
  50 + SrsCodecVideoScreenVideoVersion2 = 6,
  51 + SrsCodecVideoAVC = 7,
  52 +};
  53 +
  54 +// E.4.3.1 VIDEODATA
  55 +// Frame Type UB [4]
  56 +// Type of video frame. The following values are defined:
  57 +// 1 = key frame (for AVC, a seekable frame)
  58 +// 2 = inter frame (for AVC, a non-seekable frame)
  59 +// 3 = disposable inter frame (H.263 only)
  60 +// 4 = generated key frame (reserved for server use only)
  61 +// 5 = video info/command frame
  62 +enum SrsCodecVideoAVCFrame
  63 +{
  64 + SrsCodecVideoAVCFrameKeyFrame = 1,
  65 + SrsCodecVideoAVCFrameInterFrame = 2,
  66 + SrsCodecVideoAVCFrameDisposableInterFrame = 3,
  67 + SrsCodecVideoAVCFrameGeneratedKeyFrame = 4,
  68 + SrsCodecVideoAVCFrameVideoInfoFrame = 5,
  69 +};
  70 +
  71 +// AVCPacketType IF CodecID == 7 UI8
  72 +// The following values are defined:
  73 +// 0 = AVC sequence header
  74 +// 1 = AVC NALU
  75 +// 2 = AVC end of sequence (lower level NALU sequence ender is
  76 +// not required or supported)
  77 +enum SrsCodecVideoAVCType
  78 +{
  79 + SrsCodecVideoAVCTypeSequenceHeader = 0,
  80 + SrsCodecVideoAVCTypeNALU = 1,
  81 + SrsCodecVideoAVCTypeSequenceHeaderEOF = 2,
  82 +};
  83 +
  84 +// SoundFormat UB [4]
  85 +// Format of SoundData. The following values are defined:
  86 +// 0 = Linear PCM, platform endian
  87 +// 1 = ADPCM
  88 +// 2 = MP3
  89 +// 3 = Linear PCM, little endian
  90 +// 4 = Nellymoser 16 kHz mono
  91 +// 5 = Nellymoser 8 kHz mono
  92 +// 6 = Nellymoser
  93 +// 7 = G.711 A-law logarithmic PCM
  94 +// 8 = G.711 mu-law logarithmic PCM
  95 +// 9 = reserved
  96 +// 10 = AAC
  97 +// 11 = Speex
  98 +// 14 = MP3 8 kHz
  99 +// 15 = Device-specific sound
  100 +// Formats 7, 8, 14, and 15 are reserved.
  101 +// AAC is supported in Flash Player 9,0,115,0 and higher.
  102 +// Speex is supported in Flash Player 10 and higher.
  103 +enum SrsCodecAudio
  104 +{
  105 + SrsCodecAudioLinearPCMPlatformEndian = 0,
  106 + SrsCodecAudioADPCM = 1,
  107 + SrsCodecAudioMP3 = 2,
  108 + SrsCodecAudioLinearPCMLittleEndian = 3,
  109 + SrsCodecAudioNellymoser16kHzMono = 4,
  110 + SrsCodecAudioNellymoser8kHzMono = 5,
  111 + SrsCodecAudioNellymoser = 6,
  112 + SrsCodecAudioReservedG711AlawLogarithmicPCM = 7,
  113 + SrsCodecAudioReservedG711MuLawLogarithmicPCM = 8,
  114 + SrsCodecAudioReserved = 9,
  115 + SrsCodecAudioAAC = 10,
  116 + SrsCodecAudioSpeex = 11,
  117 + SrsCodecAudioReservedMP3_8kHz = 14,
  118 + SrsCodecAudioReservedDeviceSpecificSound = 15,
  119 +};
  120 +
  121 +// AACPacketType IF SoundFormat == 10 UI8
  122 +// The following values are defined:
  123 +// 0 = AAC sequence header
  124 +// 1 = AAC raw
  125 +enum SrsCodecAudioType
  126 +{
  127 + SrsCodecAudioTypeSequenceHeader = 0,
  128 + SrsCodecAudioTypeRawData = 1,
  129 +};
  130 +
33 /** 131 /**
34 * Annex E. The FLV File Format 132 * Annex E. The FLV File Format
35 */ 133 */
36 class SrsCodec 134 class SrsCodec
37 { 135 {
  136 +private:
  137 + SrsStream* stream;
  138 +public:
  139 + /**
  140 + * video specified
  141 + */
  142 + int width;
  143 + int height;
  144 + int duration;
  145 + int frame_rate;
  146 + // @see: SrsCodecVideo
  147 + int video_codec_id;
  148 + int video_data_rate; // in bps
  149 + u_int8_t profile; // profile_idc, page 45.
  150 + u_int8_t level; // level_idc, page 45.
  151 + /**
  152 + * audio specified
  153 + */
  154 + int audio_codec_id;
  155 + int audio_data_rate; // in bps
  156 + int aac_sample_rate;
  157 + int sample_rate; /* 5512, 11025, 22050, 44100 */
  158 + int sample_size; /* 1=8bit, 2=16bit */
  159 + int audio_channels; /* 1, 2 */
  160 + // the avc extra data, the AVC sequence header,
  161 + // without the flv codec header
  162 + int avc_extra_size;
  163 + char* avc_extra_data;
  164 + // the aac extra data, the AAC sequence header,
  165 + // without the flv codec header
  166 + int aac_extra_size;
  167 + char* aac_extra_data;
38 public: 168 public:
39 SrsCodec(); 169 SrsCodec();
40 virtual ~SrsCodec(); 170 virtual ~SrsCodec();
  171 +// the following function used for hls to build the codec info.
  172 +public:
  173 + virtual int parse_av_codec(bool is_video, int8_t* data, int size);
  174 +// the following function used to finger out the flv/rtmp packet detail.
41 public: 175 public:
42 /** 176 /**
43 * only check the frame_type, not check the codec type. 177 * only check the frame_type, not check the codec type.
44 */ 178 */
45 - virtual bool video_is_keyframe(int8_t* data, int size); 179 + static bool video_is_keyframe(int8_t* data, int size);
46 /** 180 /**
47 * check codec h264, keyframe, sequence header 181 * check codec h264, keyframe, sequence header
48 */ 182 */
49 - virtual bool video_is_sequence_header(int8_t* data, int size); 183 + static bool video_is_sequence_header(int8_t* data, int size);
50 /** 184 /**
51 * check codec aac, sequence header 185 * check codec aac, sequence header
52 */ 186 */
53 - virtual bool audio_is_sequence_header(int8_t* data, int size); 187 + static bool audio_is_sequence_header(int8_t* data, int size);
54 /** 188 /**
55 * check codec h264. 189 * check codec h264.
56 */ 190 */
57 - virtual bool video_is_h264(int8_t* data, int size); 191 + static bool video_is_h264(int8_t* data, int size);
58 private: 192 private:
59 /** 193 /**
60 * check codec aac. 194 * check codec aac.
61 */ 195 */
62 - virtual bool audio_is_aac(int8_t* data, int size); 196 + static bool audio_is_aac(int8_t* data, int size);
63 }; 197 };
64 198
65 #endif 199 #endif
@@ -23,11 +23,117 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,11 +23,117 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_core_hls.hpp> 24 #include <srs_core_hls.hpp>
25 25
  26 +#include <srs_core_error.hpp>
  27 +#include <srs_core_codec.hpp>
  28 +#include <srs_core_amf0.hpp>
  29 +#include <srs_core_protocol.hpp>
  30 +
26 SrsHLS::SrsHLS() 31 SrsHLS::SrsHLS()
27 { 32 {
  33 + codec = new SrsCodec();
28 } 34 }
29 35
30 SrsHLS::~SrsHLS() 36 SrsHLS::~SrsHLS()
31 { 37 {
  38 + srs_freep(codec);
  39 +}
  40 +
  41 +int SrsHLS::on_publish()
  42 +{
  43 + int ret = ERROR_SUCCESS;
  44 + return ret;
  45 +}
  46 +
  47 +void SrsHLS::on_unpublish()
  48 +{
  49 +}
  50 +
  51 +int SrsHLS::on_meta_data(SrsOnMetaDataPacket* metadata)
  52 +{
  53 + int ret = ERROR_SUCCESS;
  54 +
  55 + if (!metadata || !metadata->metadata) {
  56 + return ret;
  57 + }
  58 +
  59 + SrsAmf0Object* obj = metadata->metadata;
  60 + if (obj->size() <= 0) {
  61 + return ret;
  62 + }
  63 +
  64 + // finger out the codec info from metadata if possible.
  65 + SrsAmf0Any* prop = NULL;
  66 +
  67 + if ((prop = obj->get_property("duration")) != NULL && prop->is_number()) {
  68 + codec->duration = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  69 + }
  70 + if ((prop = obj->get_property("width")) != NULL && prop->is_number()) {
  71 + codec->width = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  72 + }
  73 + if ((prop = obj->get_property("height")) != NULL && prop->is_number()) {
  74 + codec->height = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  75 + }
  76 + if ((prop = obj->get_property("framerate")) != NULL && prop->is_number()) {
  77 + codec->frame_rate = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  78 + }
  79 + if ((prop = obj->get_property("videocodecid")) != NULL && prop->is_number()) {
  80 + codec->video_codec_id = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  81 + }
  82 + if ((prop = obj->get_property("videodatarate")) != NULL && prop->is_number()) {
  83 + codec->video_data_rate = (int)(1000 * srs_amf0_convert<SrsAmf0Number>(prop)->value);
  84 + }
  85 +
  86 + if ((prop = obj->get_property("audiocodecid")) != NULL && prop->is_number()) {
  87 + codec->audio_codec_id = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  88 + }
  89 + if ((prop = obj->get_property("audiodatarate")) != NULL && prop->is_number()) {
  90 + codec->audio_data_rate = (int)(1000 * srs_amf0_convert<SrsAmf0Number>(prop)->value);
  91 + }
  92 + if ((prop = obj->get_property("audiosamplerate")) != NULL && prop->is_number()) {
  93 + codec->sample_rate = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  94 + }
  95 + if ((prop = obj->get_property("audiosamplesize")) != NULL && prop->is_number()) {
  96 + codec->sample_size = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  97 + if (codec->sample_size == 16) {
  98 + codec->sample_size = 2;
  99 + } else {
  100 + codec->sample_size = 1;
  101 + }
  102 + }
  103 + if ((prop = obj->get_property("stereo")) != NULL && prop->is_number()) {
  104 + if (srs_amf0_convert<SrsAmf0Boolean>(prop)->value) {
  105 + codec->audio_channels = 2;
  106 + } else {
  107 + codec->audio_channels = 1;
  108 + }
  109 + }
  110 +
  111 + return ret;
  112 +}
  113 +
  114 +int SrsHLS::on_audio(SrsCommonMessage* audio)
  115 +{
  116 + int ret = ERROR_SUCCESS;
  117 +
  118 + if ((ret = codec->parse_av_codec(false, audio->payload, audio->size)) != ERROR_SUCCESS) {
  119 + return ret;
  120 + }
  121 +
  122 + return ret;
  123 +}
  124 +
  125 +int SrsHLS::on_video(SrsCommonMessage* video)
  126 +{
  127 + int ret = ERROR_SUCCESS;
  128 +
  129 + if ((ret = codec->parse_av_codec(true, video->payload, video->size)) != ERROR_SUCCESS) {
  130 + return ret;
  131 + }
  132 +
  133 + if (codec->video_codec_id != SrsCodecVideoAVC) {
  134 + return ret;
  135 + }
  136 +
  137 + return ret;
32 } 138 }
33 139
@@ -29,11 +29,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -29,11 +29,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 */ 29 */
30 #include <srs_core.hpp> 30 #include <srs_core.hpp>
31 31
  32 +class SrsOnMetaDataPacket;
  33 +class SrsCommonMessage;
  34 +class SrsCodec;
  35 +
32 class SrsHLS 36 class SrsHLS
33 { 37 {
  38 +private:
  39 + SrsCodec* codec;
34 public: 40 public:
35 SrsHLS(); 41 SrsHLS();
36 virtual ~SrsHLS(); 42 virtual ~SrsHLS();
  43 +public:
  44 + virtual int on_publish();
  45 + virtual void on_unpublish();
  46 + virtual int on_meta_data(SrsOnMetaDataPacket* metadata);
  47 + virtual int on_audio(SrsCommonMessage* audio);
  48 + virtual int on_video(SrsCommonMessage* video);
37 }; 49 };
38 50
39 #endif 51 #endif
@@ -53,13 +53,11 @@ SrsConsumer::SrsConsumer(SrsSource* _source) @@ -53,13 +53,11 @@ SrsConsumer::SrsConsumer(SrsSource* _source)
53 source = _source; 53 source = _source;
54 last_pkt_correct_time = last_pkt_time = 0; 54 last_pkt_correct_time = last_pkt_time = 0;
55 paused = false; 55 paused = false;
56 - codec = new SrsCodec();  
57 } 56 }
58 57
59 SrsConsumer::~SrsConsumer() 58 SrsConsumer::~SrsConsumer()
60 { 59 {
61 - clear();  
62 - srs_freep(codec); 60 + clear();
63 61
64 source->on_consumer_destroy(this); 62 source->on_consumer_destroy(this);
65 } 63 }
@@ -141,7 +139,7 @@ void SrsConsumer::shrink() @@ -141,7 +139,7 @@ void SrsConsumer::shrink()
141 SrsSharedPtrMessage* msg = *it; 139 SrsSharedPtrMessage* msg = *it;
142 if (msg->header.is_video()) { 140 if (msg->header.is_video()) {
143 has_video = true; 141 has_video = true;
144 - if (codec->video_is_keyframe(msg->payload, msg->size)) { 142 + if (SrsCodec::video_is_keyframe(msg->payload, msg->size)) {
145 iframe = it; 143 iframe = it;
146 frame_to_remove = i + 1; 144 frame_to_remove = i + 1;
147 } 145 }
@@ -240,7 +238,6 @@ void SrsConsumer::clear() @@ -240,7 +238,6 @@ void SrsConsumer::clear()
240 SrsSource::SrsSource(std::string _stream_url) 238 SrsSource::SrsSource(std::string _stream_url)
241 { 239 {
242 stream_url = _stream_url; 240 stream_url = _stream_url;
243 - codec = new SrsCodec();  
244 hls = new SrsHLS(); 241 hls = new SrsHLS();
245 242
246 cache_metadata = cache_sh_video = cache_sh_audio = NULL; 243 cache_metadata = cache_sh_video = cache_sh_audio = NULL;
@@ -266,7 +263,6 @@ SrsSource::~SrsSource() @@ -266,7 +263,6 @@ SrsSource::~SrsSource()
266 srs_freep(cache_sh_video); 263 srs_freep(cache_sh_video);
267 srs_freep(cache_sh_audio); 264 srs_freep(cache_sh_audio);
268 265
269 - srs_freep(codec);  
270 srs_freep(hls); 266 srs_freep(hls);
271 } 267 }
272 268
@@ -364,7 +360,7 @@ int SrsSource::on_audio(SrsCommonMessage* audio) @@ -364,7 +360,7 @@ int SrsSource::on_audio(SrsCommonMessage* audio)
364 srs_info("dispatch audio success."); 360 srs_info("dispatch audio success.");
365 361
366 // cache the sequence header if h264 362 // cache the sequence header if h264
367 - if (codec->audio_is_sequence_header(msg->payload, msg->size)) { 363 + if (SrsCodec::audio_is_sequence_header(msg->payload, msg->size)) {
368 srs_freep(cache_sh_audio); 364 srs_freep(cache_sh_audio);
369 cache_sh_audio = msg->copy(); 365 cache_sh_audio = msg->copy();
370 srs_trace("update audio sequence header success. size=%d", msg->header.payload_length); 366 srs_trace("update audio sequence header success. size=%d", msg->header.payload_length);
@@ -409,7 +405,7 @@ int SrsSource::on_video(SrsCommonMessage* video) @@ -409,7 +405,7 @@ int SrsSource::on_video(SrsCommonMessage* video)
409 srs_info("dispatch video success."); 405 srs_info("dispatch video success.");
410 406
411 // cache the sequence header if h264 407 // cache the sequence header if h264
412 - if (codec->video_is_sequence_header(msg->payload, msg->size)) { 408 + if (SrsCodec::video_is_sequence_header(msg->payload, msg->size)) {
413 srs_freep(cache_sh_video); 409 srs_freep(cache_sh_video);
414 cache_sh_video = msg->copy(); 410 cache_sh_video = msg->copy();
415 srs_trace("update video sequence header success. size=%d", msg->header.payload_length); 411 srs_trace("update video sequence header success. size=%d", msg->header.payload_length);
@@ -521,7 +517,7 @@ int SrsSource::cache_last_gop(SrsSharedPtrMessage* msg) @@ -521,7 +517,7 @@ int SrsSource::cache_last_gop(SrsSharedPtrMessage* msg)
521 } 517 }
522 518
523 // clear gop cache when got key frame 519 // clear gop cache when got key frame
524 - if (msg->header.is_video() && codec->video_is_keyframe(msg->payload, msg->size)) { 520 + if (msg->header.is_video() && SrsCodec::video_is_keyframe(msg->payload, msg->size)) {
525 srs_info("clear gop cache when got keyframe. vcount=%d, count=%d", 521 srs_info("clear gop cache when got keyframe. vcount=%d, count=%d",
526 cached_video_count, (int)gop_cache.size()); 522 cached_video_count, (int)gop_cache.size());
527 523
@@ -34,7 +34,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -34,7 +34,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 #include <vector> 34 #include <vector>
35 #include <string> 35 #include <string>
36 36
37 -class SrsCodec;  
38 class SrsSource; 37 class SrsSource;
39 class SrsCommonMessage; 38 class SrsCommonMessage;
40 class SrsOnMetaDataPacket; 39 class SrsOnMetaDataPacket;
@@ -52,7 +51,6 @@ private: @@ -52,7 +51,6 @@ private:
52 SrsSource* source; 51 SrsSource* source;
53 std::vector<SrsSharedPtrMessage*> msgs; 52 std::vector<SrsSharedPtrMessage*> msgs;
54 bool paused; 53 bool paused;
55 - SrsCodec* codec;  
56 public: 54 public:
57 SrsConsumer(SrsSource* _source); 55 SrsConsumer(SrsSource* _source);
58 virtual ~SrsConsumer(); 56 virtual ~SrsConsumer();
@@ -108,7 +106,6 @@ public: @@ -108,7 +106,6 @@ public:
108 static SrsSource* find(std::string stream_url); 106 static SrsSource* find(std::string stream_url);
109 private: 107 private:
110 SrsHLS* hls; 108 SrsHLS* hls;
111 - SrsCodec* codec;  
112 std::string stream_url; 109 std::string stream_url;
113 std::vector<SrsConsumer*> consumers; 110 std::vector<SrsConsumer*> consumers;
114 // gop cache for client fast startup. 111 // gop cache for client fast startup.
@@ -106,6 +106,19 @@ int16_t SrsStream::read_2bytes() @@ -106,6 +106,19 @@ int16_t SrsStream::read_2bytes()
106 return value; 106 return value;
107 } 107 }
108 108
  109 +int32_t SrsStream::read_3bytes()
  110 +{
  111 + srs_assert(require(3));
  112 +
  113 + int32_t value = 0x00;
  114 + pp = (char*)&value;
  115 + pp[2] = *p++;
  116 + pp[1] = *p++;
  117 + pp[0] = *p++;
  118 +
  119 + return value;
  120 +}
  121 +
109 int32_t SrsStream::read_4bytes() 122 int32_t SrsStream::read_4bytes()
110 { 123 {
111 srs_assert(require(4)); 124 srs_assert(require(4));
@@ -84,6 +84,10 @@ public: @@ -84,6 +84,10 @@ public:
84 */ 84 */
85 virtual int16_t read_2bytes(); 85 virtual int16_t read_2bytes();
86 /** 86 /**
  87 + * get 3bytes int from stream.
  88 + */
  89 + virtual int32_t read_3bytes();
  90 + /**
87 * get 4bytes int from stream. 91 * get 4bytes int from stream.
88 */ 92 */
89 virtual int32_t read_4bytes(); 93 virtual int32_t read_4bytes();