winlin

detect the video/audio codec, only cache the h264/aac sequence header

@@ -86,7 +86,7 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server" @@ -86,7 +86,7 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server"
86 "srs_core_error" "srs_core_conn" "srs_core_client" 86 "srs_core_error" "srs_core_conn" "srs_core_client"
87 "srs_core_rtmp" "srs_core_socket" "srs_core_buffer" 87 "srs_core_rtmp" "srs_core_socket" "srs_core_buffer"
88 "srs_core_auto_free" "srs_core_protocol" "srs_core_amf0" 88 "srs_core_auto_free" "srs_core_protocol" "srs_core_amf0"
89 - "srs_core_stream" "srs_core_source") 89 + "srs_core_stream" "srs_core_source" "srs_core_codec")
90 MODULE_DIR="src/core" . auto/modules.sh 90 MODULE_DIR="src/core" . auto/modules.sh
91 CORE_OBJS="${MODULE_OBJS[@]}" 91 CORE_OBJS="${MODULE_OBJS[@]}"
92 92
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_codec.hpp>
  25 +
  26 +SrsCodec::SrsCodec()
  27 +{
  28 +}
  29 +
  30 +SrsCodec::~SrsCodec()
  31 +{
  32 +}
  33 +
  34 +bool SrsCodec::video_is_sequence_header(int8_t* data, int size)
  35 +{
  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)
  51 +
  52 + // sequence header only for h264
  53 + if (!video_is_h264(data, size)) {
  54 + return false;
  55 + }
  56 +
  57 + // 2bytes required.
  58 + if (size < 2) {
  59 + return false;
  60 + }
  61 +
  62 + char frame_type = *(char*)data;
  63 + frame_type = (frame_type >> 4) & 0x0F;
  64 +
  65 + char avc_packet_type = *(char*)(data + 1);
  66 +
  67 + return frame_type == 1 && avc_packet_type == 0;
  68 +}
  69 +
  70 +bool SrsCodec::audio_is_sequence_header(int8_t* data, int size)
  71 +{
  72 + // AACPacketType IF SoundFormat == 10 UI8
  73 + // The following values are defined:
  74 + // 0 = AAC sequence header
  75 + // 1 = AAC raw
  76 +
  77 + // sequence header only for aac
  78 + if (!audio_is_aac(data, size)) {
  79 + return false;
  80 + }
  81 +
  82 + // 2bytes required.
  83 + if (size < 2) {
  84 + return false;
  85 + }
  86 +
  87 + char aac_packet_type = *(char*)(data + 1);
  88 +
  89 + return aac_packet_type == 0;
  90 +}
  91 +
  92 +bool SrsCodec::video_is_h264(int8_t* data, int size)
  93 +{
  94 + // E.4.3.1 VIDEODATA
  95 + // CodecID UB [4]
  96 + // Codec Identifier. The following values are defined:
  97 + // 2 = Sorenson H.263
  98 + // 3 = Screen video
  99 + // 4 = On2 VP6
  100 + // 5 = On2 VP6 with alpha channel
  101 + // 6 = Screen video version 2
  102 + // 7 = AVC
  103 +
  104 + // 1bytes required.
  105 + if (size < 1) {
  106 + return false;
  107 + }
  108 +
  109 + char codec_id = *(char*)data;
  110 + codec_id = codec_id & 0x0F;
  111 +
  112 + return codec_id == 7;
  113 +}
  114 +
  115 +bool SrsCodec::audio_is_aac(int8_t* data, int size)
  116 +{
  117 + // SoundFormat UB [4]
  118 + // Format of SoundData. The following values are defined:
  119 + // 0 = Linear PCM, platform endian
  120 + // 1 = ADPCM
  121 + // 2 = MP3
  122 + // 3 = Linear PCM, little endian
  123 + // 4 = Nellymoser 16 kHz mono
  124 + // 5 = Nellymoser 8 kHz mono
  125 + // 6 = Nellymoser
  126 + // 7 = G.711 A-law logarithmic PCM
  127 + // 8 = G.711 mu-law logarithmic PCM
  128 + // 9 = reserved
  129 + // 10 = AAC
  130 + // 11 = Speex
  131 + // 14 = MP3 8 kHz
  132 + // 15 = Device-specific sound
  133 + // Formats 7, 8, 14, and 15 are reserved.
  134 + // AAC is supported in Flash Player 9,0,115,0 and higher.
  135 + // Speex is supported in Flash Player 10 and higher.
  136 +
  137 + // 1bytes required.
  138 + if (size < 1) {
  139 + return false;
  140 + }
  141 +
  142 + char sound_format = *(char*)data;
  143 + sound_format = (sound_format >> 4) & 0x0F;
  144 +
  145 + return sound_format == 10;
  146 +}
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_CORE_CODEC_HPP
  25 +#define SRS_CORE_CODEC_HPP
  26 +
  27 +/*
  28 +#include <srs_core_codec.hpp>
  29 +*/
  30 +
  31 +#include <srs_core.hpp>
  32 +
  33 +/**
  34 +* Annex E. The FLV File Format
  35 +*/
  36 +class SrsCodec
  37 +{
  38 +public:
  39 + SrsCodec();
  40 + virtual ~SrsCodec();
  41 +public:
  42 + virtual bool video_is_sequence_header(int8_t* data, int size);
  43 + virtual bool audio_is_sequence_header(int8_t* data, int size);
  44 +private:
  45 + virtual bool video_is_h264(int8_t* data, int size);
  46 + virtual bool audio_is_aac(int8_t* data, int size);
  47 +};
  48 +
  49 +#endif
@@ -173,7 +173,7 @@ int SrsRtmp::handshake() @@ -173,7 +173,7 @@ int SrsRtmp::handshake()
173 ssize_t nsize; 173 ssize_t nsize;
174 SrsSocket skt(stfd); 174 SrsSocket skt(stfd);
175 175
176 - // TODO: complex handshake for h264 codec. 176 + // TODO: complex handshake for h264/aac codec.
177 char* c0c1 = new char[1537]; 177 char* c0c1 = new char[1537];
178 SrsAutoFree(char, c0c1, true); 178 SrsAutoFree(char, c0c1, true);
179 if ((ret = skt.read_fully(c0c1, 1537, &nsize)) != ERROR_SUCCESS) { 179 if ((ret = skt.read_fully(c0c1, 1537, &nsize)) != ERROR_SUCCESS) {
@@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #include <srs_core_protocol.hpp> 29 #include <srs_core_protocol.hpp>
30 #include <srs_core_auto_free.hpp> 30 #include <srs_core_auto_free.hpp>
31 #include <srs_core_amf0.hpp> 31 #include <srs_core_amf0.hpp>
  32 +#include <srs_core_codec.hpp>
32 33
33 #define CONST_MAX_JITTER_MS 500 34 #define CONST_MAX_JITTER_MS 500
34 #define DEFAULT_FRAME_TIME_MS 10 35 #define DEFAULT_FRAME_TIME_MS 10
@@ -135,6 +136,7 @@ SrsSource::SrsSource(std::string _stream_url) @@ -135,6 +136,7 @@ SrsSource::SrsSource(std::string _stream_url)
135 cache_metadata = NULL; 136 cache_metadata = NULL;
136 cache_sh_video = NULL; 137 cache_sh_video = NULL;
137 cache_sh_audio = NULL; 138 cache_sh_audio = NULL;
  139 + codec = new SrsCodec();
138 } 140 }
139 141
140 SrsSource::~SrsSource() 142 SrsSource::~SrsSource()
@@ -149,6 +151,8 @@ SrsSource::~SrsSource() @@ -149,6 +151,8 @@ SrsSource::~SrsSource()
149 srs_freep(cache_metadata); 151 srs_freep(cache_metadata);
150 srs_freep(cache_sh_video); 152 srs_freep(cache_sh_video);
151 srs_freep(cache_sh_audio); 153 srs_freep(cache_sh_audio);
  154 +
  155 + srs_freep(codec);
152 } 156 }
153 157
154 int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata) 158 int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata)
@@ -227,9 +231,8 @@ int SrsSource::on_audio(SrsCommonMessage* audio) @@ -227,9 +231,8 @@ int SrsSource::on_audio(SrsCommonMessage* audio)
227 } 231 }
228 srs_info("dispatch audio success."); 232 srs_info("dispatch audio success.");
229 233
230 - // TODO: always update the sh.  
231 - // TODO: cache last gop.  
232 - if (!cache_sh_audio) { 234 + // cache the sequence header if h264
  235 + if (codec->audio_is_sequence_header(msg->payload, msg->size)) {
233 srs_freep(cache_sh_audio); 236 srs_freep(cache_sh_audio);
234 cache_sh_audio = msg->copy(); 237 cache_sh_audio = msg->copy();
235 } 238 }
@@ -264,9 +267,8 @@ int SrsSource::on_video(SrsCommonMessage* video) @@ -264,9 +267,8 @@ int SrsSource::on_video(SrsCommonMessage* video)
264 } 267 }
265 srs_info("dispatch video success."); 268 srs_info("dispatch video success.");
266 269
267 - // TODO: always update the sh.  
268 - // TODO: cache last gop.  
269 - if (!cache_sh_video) { 270 + // cache the sequence header if h264
  271 + if (codec->video_is_sequence_header(msg->payload, msg->size)) {
270 srs_freep(cache_sh_video); 272 srs_freep(cache_sh_video);
271 cache_sh_video = msg->copy(); 273 cache_sh_video = msg->copy();
272 } 274 }
@@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -34,6 +34,7 @@ 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;
37 class SrsSource; 38 class SrsSource;
38 class SrsCommonMessage; 39 class SrsCommonMessage;
39 class SrsOnMetaDataPacket; 40 class SrsOnMetaDataPacket;
@@ -82,6 +83,7 @@ public: @@ -82,6 +83,7 @@ public:
82 */ 83 */
83 static SrsSource* find(std::string stream_url); 84 static SrsSource* find(std::string stream_url);
84 private: 85 private:
  86 + SrsCodec* codec;
85 std::string stream_url; 87 std::string stream_url;
86 std::vector<SrsConsumer*> consumers; 88 std::vector<SrsConsumer*> consumers;
87 private: 89 private:
@@ -16,6 +16,8 @@ file @@ -16,6 +16,8 @@ file
16 ..\core\srs_core_client.cpp, 16 ..\core\srs_core_client.cpp,
17 ..\core\srs_core_source.hpp, 17 ..\core\srs_core_source.hpp,
18 ..\core\srs_core_source.cpp, 18 ..\core\srs_core_source.cpp,
  19 + ..\core\srs_core_codec.hpp,
  20 + ..\core\srs_core_codec.cpp,
19 ..\core\srs_core_rtmp.hpp, 21 ..\core\srs_core_rtmp.hpp,
20 ..\core\srs_core_rtmp.cpp, 22 ..\core\srs_core_rtmp.cpp,
21 ..\core\srs_core_protocol.hpp, 23 ..\core\srs_core_protocol.hpp,