正在显示
3 个修改的文件
包含
108 行增加
和
2 行删除
| @@ -145,6 +145,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -145,6 +145,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 145 | #define ERROR_RTSP_TOKEN_NOT_NORMAL 2042 | 145 | #define ERROR_RTSP_TOKEN_NOT_NORMAL 2042 |
| 146 | #define ERROR_RTSP_REQUEST_HEADER_EOF 2043 | 146 | #define ERROR_RTSP_REQUEST_HEADER_EOF 2043 |
| 147 | #define ERROR_RTP_HEADER_CORRUPT 2044 | 147 | #define ERROR_RTP_HEADER_CORRUPT 2044 |
| 148 | +#define ERROR_RTP_TYPE96_CORRUPT 2045 | ||
| 149 | +#define ERROR_RTP_TYPE97_CORRUPT 2046 | ||
| 148 | // | 150 | // |
| 149 | // system control message, | 151 | // system control message, |
| 150 | // not an error, but special control logic. | 152 | // not an error, but special control logic. |
| @@ -35,6 +35,7 @@ using namespace std; | @@ -35,6 +35,7 @@ using namespace std; | ||
| 35 | #include <srs_core_autofree.hpp> | 35 | #include <srs_core_autofree.hpp> |
| 36 | #include <srs_kernel_utility.hpp> | 36 | #include <srs_kernel_utility.hpp> |
| 37 | #include <srs_kernel_stream.hpp> | 37 | #include <srs_kernel_stream.hpp> |
| 38 | +#include <srs_kernel_codec.hpp> | ||
| 38 | 39 | ||
| 39 | #ifdef SRS_AUTO_STREAM_CASTER | 40 | #ifdef SRS_AUTO_STREAM_CASTER |
| 40 | 41 | ||
| @@ -133,6 +134,7 @@ SrsRtpPacket::SrsRtpPacket() | @@ -133,6 +134,7 @@ SrsRtpPacket::SrsRtpPacket() | ||
| 133 | ssrc = 0; | 134 | ssrc = 0; |
| 134 | 135 | ||
| 135 | payload = new SrsSimpleBuffer(); | 136 | payload = new SrsSimpleBuffer(); |
| 137 | + audio_samples = new SrsCodecSample(); | ||
| 136 | chunked = false; | 138 | chunked = false; |
| 137 | completed = false; | 139 | completed = false; |
| 138 | } | 140 | } |
| @@ -140,6 +142,7 @@ SrsRtpPacket::SrsRtpPacket() | @@ -140,6 +142,7 @@ SrsRtpPacket::SrsRtpPacket() | ||
| 140 | SrsRtpPacket::~SrsRtpPacket() | 142 | SrsRtpPacket::~SrsRtpPacket() |
| 141 | { | 143 | { |
| 142 | srs_freep(payload); | 144 | srs_freep(payload); |
| 145 | + srs_freep(audio_samples); | ||
| 143 | } | 146 | } |
| 144 | 147 | ||
| 145 | void SrsRtpPacket::copy(SrsRtpPacket* src) | 148 | void SrsRtpPacket::copy(SrsRtpPacket* src) |
| @@ -156,22 +159,28 @@ void SrsRtpPacket::copy(SrsRtpPacket* src) | @@ -156,22 +159,28 @@ void SrsRtpPacket::copy(SrsRtpPacket* src) | ||
| 156 | 159 | ||
| 157 | chunked = src->chunked; | 160 | chunked = src->chunked; |
| 158 | completed = src->completed; | 161 | completed = src->completed; |
| 162 | + audio_samples = new SrsCodecSample(); | ||
| 159 | } | 163 | } |
| 160 | 164 | ||
| 161 | void SrsRtpPacket::reap(SrsRtpPacket* src) | 165 | void SrsRtpPacket::reap(SrsRtpPacket* src) |
| 162 | { | 166 | { |
| 163 | copy(src); | 167 | copy(src); |
| 164 | 168 | ||
| 169 | + srs_freep(payload); | ||
| 165 | payload = src->payload; | 170 | payload = src->payload; |
| 166 | src->payload = NULL; | 171 | src->payload = NULL; |
| 172 | + | ||
| 173 | + srs_freep(audio_samples); | ||
| 174 | + audio_samples = src->audio_samples; | ||
| 175 | + src->audio_samples = NULL; | ||
| 167 | } | 176 | } |
| 168 | 177 | ||
| 169 | int SrsRtpPacket::decode(SrsStream* stream) | 178 | int SrsRtpPacket::decode(SrsStream* stream) |
| 170 | { | 179 | { |
| 171 | int ret = ERROR_SUCCESS; | 180 | int ret = ERROR_SUCCESS; |
| 172 | 181 | ||
| 173 | - // 12bytes header, atleast 2bytes content. | ||
| 174 | - if (!stream->require(14)) { | 182 | + // 12bytes header |
| 183 | + if (!stream->require(12)) { | ||
| 175 | ret = ERROR_RTP_HEADER_CORRUPT; | 184 | ret = ERROR_RTP_HEADER_CORRUPT; |
| 176 | srs_error("rtsp: rtp header corrupt. ret=%d", ret); | 185 | srs_error("rtsp: rtp header corrupt. ret=%d", ret); |
| 177 | return ret; | 186 | return ret; |
| @@ -191,6 +200,92 @@ int SrsRtpPacket::decode(SrsStream* stream) | @@ -191,6 +200,92 @@ int SrsRtpPacket::decode(SrsStream* stream) | ||
| 191 | timestamp = stream->read_4bytes(); | 200 | timestamp = stream->read_4bytes(); |
| 192 | ssrc = stream->read_4bytes(); | 201 | ssrc = stream->read_4bytes(); |
| 193 | 202 | ||
| 203 | + // video codec. | ||
| 204 | + if (payload_type == 96) { | ||
| 205 | + return decode_96(stream); | ||
| 206 | + } else if (payload_type == 97) { | ||
| 207 | + return decode_97(stream); | ||
| 208 | + } | ||
| 209 | + | ||
| 210 | + return ret; | ||
| 211 | +} | ||
| 212 | + | ||
| 213 | +int SrsRtpPacket::decode_97(SrsStream* stream) | ||
| 214 | +{ | ||
| 215 | + int ret = ERROR_SUCCESS; | ||
| 216 | + | ||
| 217 | + // atleast 2bytes content. | ||
| 218 | + if (!stream->require(2)) { | ||
| 219 | + ret = ERROR_RTP_TYPE97_CORRUPT; | ||
| 220 | + srs_error("rtsp: rtp type97 corrupt. ret=%d", ret); | ||
| 221 | + return ret; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + int8_t hasv = stream->read_1bytes(); | ||
| 225 | + int8_t lasv = stream->read_1bytes(); | ||
| 226 | + u_int16_t au_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f); | ||
| 227 | + | ||
| 228 | + if (!stream->require(au_size)) { | ||
| 229 | + ret = ERROR_RTP_TYPE97_CORRUPT; | ||
| 230 | + srs_error("rtsp: rtp type97 au_size corrupt. ret=%d", ret); | ||
| 231 | + return ret; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + int nb_samples = au_size / 2; | ||
| 235 | + int guess_sample_size = (stream->size() - stream->pos() - au_size) / nb_samples; | ||
| 236 | + int required_size = 0; | ||
| 237 | + | ||
| 238 | + // append left bytes to payload. | ||
| 239 | + payload->append( | ||
| 240 | + stream->data() + stream->pos() + au_size, | ||
| 241 | + stream->size() - stream->pos() - au_size | ||
| 242 | + ); | ||
| 243 | + char* p = payload->bytes(); | ||
| 244 | + | ||
| 245 | + for (int i = 0; i < au_size; i += 2) { | ||
| 246 | + hasv = stream->read_1bytes(); | ||
| 247 | + lasv = stream->read_1bytes(); | ||
| 248 | + | ||
| 249 | + u_int16_t sample_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f); | ||
| 250 | + if (sample_size != guess_sample_size) { | ||
| 251 | + // guess the size lost 0x100. | ||
| 252 | + if (guess_sample_size == (sample_size | 0x100)) { | ||
| 253 | + sample_size = guess_sample_size; | ||
| 254 | + } | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + char* sample = p + required_size; | ||
| 258 | + required_size += sample_size; | ||
| 259 | + | ||
| 260 | + if (!stream->require(required_size)) { | ||
| 261 | + ret = ERROR_RTP_TYPE97_CORRUPT; | ||
| 262 | + srs_error("rtsp: rtp type97 samples corrupt. ret=%d", ret); | ||
| 263 | + return ret; | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + if ((ret = audio_samples->add_sample_unit(sample, sample_size)) != ERROR_SUCCESS) { | ||
| 267 | + srs_error("rtsp: rtp type97 add sample failed. ret=%d", ret); | ||
| 268 | + return ret; | ||
| 269 | + } | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + // parsed ok. | ||
| 273 | + completed = true; | ||
| 274 | + | ||
| 275 | + return ret; | ||
| 276 | +} | ||
| 277 | + | ||
| 278 | +int SrsRtpPacket::decode_96(SrsStream* stream) | ||
| 279 | +{ | ||
| 280 | + int ret = ERROR_SUCCESS; | ||
| 281 | + | ||
| 282 | + // atleast 2bytes content. | ||
| 283 | + if (!stream->require(2)) { | ||
| 284 | + ret = ERROR_RTP_TYPE96_CORRUPT; | ||
| 285 | + srs_error("rtsp: rtp type96 corrupt. ret=%d", ret); | ||
| 286 | + return ret; | ||
| 287 | + } | ||
| 288 | + | ||
| 194 | // frame type | 289 | // frame type |
| 195 | // 0... .... reserverd | 290 | // 0... .... reserverd |
| 196 | // .11. .... NALU[0]&0x60 | 291 | // .11. .... NALU[0]&0x60 |
| @@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 39 | 39 | ||
| 40 | class SrsStream; | 40 | class SrsStream; |
| 41 | class SrsSimpleBuffer; | 41 | class SrsSimpleBuffer; |
| 42 | +class SrsCodecSample; | ||
| 42 | class ISrsProtocolReaderWriter; | 43 | class ISrsProtocolReaderWriter; |
| 43 | 44 | ||
| 44 | // rtsp specification | 45 | // rtsp specification |
| @@ -292,6 +293,11 @@ public: | @@ -292,6 +293,11 @@ public: | ||
| 292 | // normal message always completed. | 293 | // normal message always completed. |
| 293 | // while chunked completed when the last chunk arriaved. | 294 | // while chunked completed when the last chunk arriaved. |
| 294 | bool completed; | 295 | bool completed; |
| 296 | + | ||
| 297 | + /** | ||
| 298 | + * the audio samples, one rtp packets may contains multiple audio samples. | ||
| 299 | + */ | ||
| 300 | + SrsCodecSample* audio_samples; | ||
| 295 | public: | 301 | public: |
| 296 | SrsRtpPacket(); | 302 | SrsRtpPacket(); |
| 297 | virtual ~SrsRtpPacket(); | 303 | virtual ~SrsRtpPacket(); |
| @@ -308,6 +314,9 @@ public: | @@ -308,6 +314,9 @@ public: | ||
| 308 | * decode rtp packet from stream. | 314 | * decode rtp packet from stream. |
| 309 | */ | 315 | */ |
| 310 | virtual int decode(SrsStream* stream); | 316 | virtual int decode(SrsStream* stream); |
| 317 | +private: | ||
| 318 | + virtual int decode_97(SrsStream* stream); | ||
| 319 | + virtual int decode_96(SrsStream* stream); | ||
| 311 | }; | 320 | }; |
| 312 | 321 | ||
| 313 | /** | 322 | /** |
-
请 注册 或 登录 后发表评论