Changeset 729
- Timestamp:
- 01/22/12 03:23:59 (4 months ago)
- Location:
- trunk
- Files:
-
- 6 edited
-
builders/cmake/applications/CMakeLists.txt (modified) (1 diff)
-
sources/thelib/include/protocols/rtmp/streaming/outnetrtmp4tsstream.h (modified) (2 diffs)
-
sources/thelib/include/protocols/ts/innettsstream.h (modified) (5 diffs)
-
sources/thelib/src/protocols/rtmp/streaming/outnetrtmp4tsstream.cpp (modified) (6 diffs)
-
sources/thelib/src/protocols/rtp/streaming/innetrtpstream.cpp (modified) (1 diff)
-
sources/thelib/src/protocols/ts/innettsstream.cpp (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/builders/cmake/applications/CMakeLists.txt
r476 r729 12 12 ADD_SUBDIRECTORY(proxypublish proxypublish) 13 13 ADD_SUBDIRECTORY(stresstest stresstest) 14 ADD_SUBDIRECTORY(applestreamingclient applestreamingclient)14 #ADD_SUBDIRECTORY(applestreamingclient applestreamingclient) 15 15 #ADD_SUBDIRECTORY(vmapp vmapp) 16 16 -
trunk/sources/thelib/include/protocols/rtmp/streaming/outnetrtmp4tsstream.h
r727 r729 30 30 bool _audioCodecSent; 31 31 bool _videoCodecSent; 32 bool _spsAvailable;33 uint8_t *_pSPSPPS;34 uint8_t _SPSPPSLength;35 uint32_t _PPSStart;36 32 IOBuffer _videoBuffer; 37 33 bool _inboundStreamIsRTP; … … 53 49 bool FeedAudioData(uint8_t *pData, uint32_t dataLength, double absoluteTimestamp); 54 50 bool FeedVideoData(uint8_t *pData, uint32_t dataLength, double absoluteTimestamp); 51 bool SendVideoCodec(double absoluteTimestamp); 52 bool SendAudioCodec(double absoluteTimestamp); 55 53 }; 56 54 -
trunk/sources/thelib/include/protocols/ts/innettsstream.h
r637 r729 1 /* 1 /* 2 2 * Copyright (c) 2010, 3 3 * Gavriloaie Eugen-Andrei (shiretu@gmail.com) … … 42 42 double _dtsTimeAudio; 43 43 #endif 44 double _deltaTimeAudio; 45 IOBuffer _audioBuffer; 44 IOBuffer _audioBucket; 46 45 double _lastGotAudioTimestamp; 47 46 double _lastSentAudioTimestamp; … … 62 61 double _dtsTimeVideo; 63 62 #endif 64 double _deltaTimeVideo;65 63 uint64_t _videoPacketsCount; 66 64 uint64_t _videoBytesCount; 67 65 uint64_t _videoDroppedPacketsCount; 68 66 uint64_t _videoDroppedBytesCount; 69 IOBuffer _ currentNal;67 IOBuffer _videoBucket; 70 68 71 double _feedTime;69 StreamCapabilities _streamCapabilities; 72 70 73 uint32_t _cursor; 74 StreamCapabilities _streamCapabilities; 75 bool _firstNAL; 71 double _deltaTime; 76 72 77 73 IOBuffer _SPS; … … 85 81 void SetAudioVideoPidDescriptors(_PIDDescriptor *pAudioPidDescriptor, 86 82 _PIDDescriptor *pVideoPidDescriptor); 87 88 double GetFeedTime();89 83 90 84 bool FeedData(uint8_t *pData, uint32_t length, bool packetStart, … … 104 98 virtual void GetStats(Variant &info, uint32_t namespaceId = 0); 105 99 private: 106 bool HandleAudioData(uint8_t *pRawBuffer, uint32_t rawBufferLength, 107 double timestamp, bool packetStart); 108 bool HandleVideoData(uint8_t *pRawBuffer, uint32_t rawBufferLength, 109 double timestamp, bool packetStart); 110 bool ProcessNal(double timestamp); 100 bool HandleAudioData(); 101 bool HandleVideoData(); 102 bool ProcessNal(uint8_t *pBuffer, int32_t length, double timestamp); 111 103 void InitializeVideoCapabilities(uint8_t *pData, uint32_t length); 112 104 void InitializeAudioCapabilities(uint8_t *pData, uint32_t length); -
trunk/sources/thelib/src/protocols/rtmp/streaming/outnetrtmp4tsstream.cpp
r727 r729 33 33 _audioCodecSent = false; 34 34 _videoCodecSent = false; 35 _spsAvailable = false;36 _pSPSPPS = new uint8_t[SPSPPS_MAX_LENGTH];37 _SPSPPSLength = 0;38 _PPSStart = 0;39 35 CanDropFrames(false); 40 41 42 _pSPSPPS[0] = 0x17; //0x10 - key frame; 0x07 - H264_CODEC_ID43 _pSPSPPS[1] = 0; //0: AVC sequence header; 1: AVC NALU; 2: AVC end of sequence44 _pSPSPPS[2] = 0; //CompositionTime45 _pSPSPPS[3] = 0; //CompositionTime46 _pSPSPPS[4] = 0; //CompositionTime47 _pSPSPPS[5] = 1; //version48 _pSPSPPS[9] = 0xff; //6 bits reserved (111111) + 2 bits nal size length - 1 (11)49 _pSPSPPS[10] = 0xe1; //3 bits reserved (111) + 5 bits number of sps (00001)50 36 51 37 _inboundStreamIsRTP = false; … … 55 41 56 42 OutNetRTMP4TSStream::~OutNetRTMP4TSStream() { 57 delete[] _pSPSPPS; 43 58 44 } 59 45 … … 86 72 bool OutNetRTMP4TSStream::FeedAudioData(uint8_t *pData, uint32_t dataLength, 87 73 double absoluteTimestamp) { 88 if (!_videoCodecSent)89 return true;90 74 //the payload here respects this format: 91 75 //6.2 Audio Data Transport Stream, ADTS … … 94 78 //1. Send the audio codec setup if necessary 95 79 if (!_audioCodecSent) { 96 StreamCapabilities *pCapabilities = GetCapabilities(); 97 if ((pCapabilities != NULL) 98 && (pCapabilities->audioCodecId == CODEC_AUDIO_AAC)) { 99 IOBuffer codecSetup; 100 codecSetup.ReadFromRepeat(0xaf, 1); 101 codecSetup.ReadFromRepeat(0x00, 1); 102 codecSetup.ReadFromBuffer(pCapabilities->aac._pAAC, 103 pCapabilities->aac._aacLength); 104 105 if (!BaseOutNetRTMPStream::FeedData( 106 GETIBPOINTER(codecSetup), //pData 107 GETAVAILABLEBYTESCOUNT(codecSetup), //dataLength 108 0, //processedLength 109 GETAVAILABLEBYTESCOUNT(codecSetup), //totalLength 110 absoluteTimestamp, //absoluteTimestamp 111 true //isAudio 112 )) { 113 FATAL("Unable to send audio codec setup"); 114 return false; 115 } 116 } 117 118 _audioCodecSent = true; 80 if (!SendAudioCodec(absoluteTimestamp)) { 81 FATAL("Unable to send video codec"); 82 return false; 83 } 119 84 } 120 85 … … 122 87 pData[0] = 0xaf; 123 88 pData[1] = 0x01; 124 125 89 return BaseOutNetRTMPStream::FeedData( 126 90 pData, //pData … … 161 125 double absoluteTimestamp) { 162 126 uint8_t nalType = NALU_TYPE(pData[0]); 163 switch (nalType) { 164 case NALU_TYPE_SPS: 165 { 166 //1. Prepare the SPS part from video codec 167 if (dataLength > 128) { 168 FATAL("SPS too big"); 127 128 //1. Create timestamp reference 129 if (_lastVideoTimestamp < 0) 130 _lastVideoTimestamp = absoluteTimestamp; 131 132 //2. Send over the accumulated stuff if this is a new packet from a 133 //brand new sequence of packets 134 if (_lastVideoTimestamp != absoluteTimestamp) { 135 if (!_videoCodecSent) { 136 if (!SendVideoCodec(_lastVideoTimestamp)) { 137 FATAL("Unable to send video codec"); 169 138 return false; 170 139 } 171 memcpy(_pSPSPPS + 6, pData + 1, 3); //profile,profile compat,level172 EHTONSP(_pSPSPPS + 11, (uint16_t) dataLength);173 memcpy(_pSPSPPS + 13, pData, dataLength);174 _PPSStart = 13 + dataLength;175 _spsAvailable = true;176 return true;177 }178 case NALU_TYPE_PPS:179 {180 //2. Prepare the PPS part from video codec181 if (dataLength > 128) {182 FATAL("PPS too big");183 return false;184 }185 if (!_spsAvailable) {186 WARN("No SPS available yet");187 return true; 188 }189 190 _pSPSPPS[_PPSStart] = 1;191 EHTONSP(_pSPSPPS + _PPSStart + 1, (uint16_t) dataLength);192 memcpy(_pSPSPPS + _PPSStart + 1 + 2, pData, dataLength);193 _spsAvailable = false;194 195 //3. Send the video codec196 if (!BaseOutNetRTMPStream::FeedData(197 _pSPSPPS, //pData 198 _PPSStart + 1 + 2 + dataLength, //dataLength199 0, //processedLength200 _PPSStart + 1 + 2 + dataLength, //totalLength201 absoluteTimestamp, //absoluteTimestamp202 false //isAudio203 )) {204 FATAL("Unable to send video codec setup");205 return false;206 } 207 208 _videoCodecSent = true;209 210 return true;211 }212 default:213 {214 //1. Create timestamp reference215 if (_lastVideoTimestamp < 0)216 _lastVideoTimestamp = absoluteTimestamp;217 218 //2. Send over the accumulated stuff if this is a new packet from a 219 //brand new sequence of packets220 if (_lastVideoTimestamp != absoluteTimestamp) {221 if (!BaseOutNetRTMPStream::FeedData(222 GETIBPOINTER(_videoBuffer), //pData223 GETAVAILABLEBYTESCOUNT(_videoBuffer), //dataLength224 0, //processedLength225 GETAVAILABLEBYTESCOUNT(_videoBuffer), //totalLength226 _lastVideoTimestamp, //absoluteTimestamp 227 false //isAudio228 )) {229 FATAL("Unable to send video"); 230 return false; 231 } 232 _videoBuffer.IgnoreAll();233 _isKeyFrame = false;234 }235 _lastVideoTimestamp = absoluteTimestamp;236 237 uint8_t *pTemp = NULL;238 239 //put the 5 bytes header240 if (GETAVAILABLEBYTESCOUNT(_videoBuffer) == 0) {241 _videoBuffer.ReadFromRepeat(0, 5);242 pTemp = GETIBPOINTER(_videoBuffer);243 pTemp[1] = 0x01;244 pTemp[2] = pTemp[3] = pTemp[4] = 0;245 }246 247 if ((nalType == NALU_TYPE_IDR)248 || (nalType == NALU_TYPE_SLICE)249 || (nalType == NALU_TYPE_SEI)250 ) {251 //put the length 252 _videoBuffer.ReadFromRepeat(0, 4); 253 pTemp = GETIBPOINTER(_videoBuffer) + GETAVAILABLEBYTESCOUNT(_videoBuffer) - 4;254 EHTONLP(pTemp, dataLength);255 256 //put the data257 _videoBuffer.ReadFromBuffer(pData, dataLength); 258 259 //setup the frame type260 _isKeyFrame |= (nalType == NALU_TYPE_IDR);261 if (_isKeyFrame) {262 GETIBPOINTER(_videoBuffer)[0] = 0x17;263 } else {264 GETIBPOINTER(_videoBuffer)[0] = 0x27;265 }266 }267 268 //6. make sure the packet doesn't grow too big269 if (GETAVAILABLEBYTESCOUNT(_videoBuffer) >= 4 * 1024 * 1024) {270 WARN("Big video frame. Discard it");271 _videoBuffer.IgnoreAll(); 272 _isKeyFrame = false;273 _lastVideoTimestamp = -1; 274 }275 276 //done 277 return true; 278 }279 }280 } 281 282 //void checkData(IOBuffer &buffer) { 283 // uint8_t *pBuffer = GETIBPOINTER(buffer);284 // uint32_t length = GETAVAILABLEBYTESCOUNT(buffer);285 // uint32_t cursor = 5; 286 // uint32_t computed = 5;287 // string dbg; 288 // dbg += format("5 bytes: %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", 289 // pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3], pBuffer[4]); 290 // while (cursor < length) { 291 // uint32_t size = ENTOHLP(pBuffer + cursor); 292 // dbg += format("%s(%08"PRIx32")(%02"PRIx8"), ", 293 // STR(NALUToString(pBuffer[cursor + 4])), 294 // size, 295 // pBuffer[cursor + 4 + size - 1]); 296 // cursor += 4 + size;297 // computed += 4 + size;298 //}299 // dbg += format("\ncomputed: %"PRIu32"; available: %"PRIu32"; ok: %"PRIu8"\n", 300 // computed, length, computed == length);301 // fprintf(stdout, "%s\n", STR(dbg));302 //}140 } 141 if (!BaseOutNetRTMPStream::FeedData( 142 GETIBPOINTER(_videoBuffer), //pData 143 GETAVAILABLEBYTESCOUNT(_videoBuffer), //dataLength 144 0, //processedLength 145 GETAVAILABLEBYTESCOUNT(_videoBuffer), //totalLength 146 _lastVideoTimestamp, //absoluteTimestamp 147 false //isAudio 148 )) { 149 FATAL("Unable to send video"); 150 return false; 151 } 152 _videoBuffer.IgnoreAll(); 153 _isKeyFrame = false; 154 } 155 _lastVideoTimestamp = absoluteTimestamp; 156 157 uint8_t *pTemp = NULL; 158 159 //put the 5 bytes header 160 if (GETAVAILABLEBYTESCOUNT(_videoBuffer) == 0) { 161 _videoBuffer.ReadFromRepeat(0, 5); 162 pTemp = GETIBPOINTER(_videoBuffer); 163 pTemp[1] = 0x01; 164 pTemp[2] = pTemp[3] = pTemp[4] = 0; 165 } 166 167 if ((nalType == NALU_TYPE_IDR) 168 || (nalType == NALU_TYPE_SLICE) 169 || (nalType == NALU_TYPE_SEI) 170 ) { 171 //put the length 172 _videoBuffer.ReadFromRepeat(0, 4); 173 pTemp = GETIBPOINTER(_videoBuffer) + GETAVAILABLEBYTESCOUNT(_videoBuffer) - 4; 174 EHTONLP(pTemp, dataLength); 175 176 //put the data 177 _videoBuffer.ReadFromBuffer(pData, dataLength); 178 179 //setup the frame type 180 _isKeyFrame |= (nalType == NALU_TYPE_IDR); 181 if (_isKeyFrame) { 182 GETIBPOINTER(_videoBuffer)[0] = 0x17; 183 } else { 184 GETIBPOINTER(_videoBuffer)[0] = 0x27; 185 } 186 } 187 188 //6. make sure the packet doesn't grow too big 189 if (GETAVAILABLEBYTESCOUNT(_videoBuffer) >= 4 * 1024 * 1024) { 190 WARN("Big video frame. Discard it"); 191 _videoBuffer.IgnoreAll(); 192 _isKeyFrame = false; 193 _lastVideoTimestamp = -1; 194 } 195 196 //done 197 return true; 198 } 199 200 bool OutNetRTMP4TSStream::SendVideoCodec(double absoluteTimestamp) { 201 StreamCapabilities *pCapabilities = GetCapabilities(); 202 if (pCapabilities == NULL || pCapabilities->videoCodecId != CODEC_VIDEO_AVC) { 203 return true; 204 } 205 206 IOBuffer result; 207 208 result.ReadFromByte(0x17); //0x10 - key frame; 0x07 - H264_CODEC_ID 209 result.ReadFromByte(0); //0: AVC sequence header; 1: AVC NALU; 2: AVC end of sequence 210 result.ReadFromByte(0); //CompositionTime 211 result.ReadFromByte(0); //CompositionTime 212 result.ReadFromByte(0); //CompositionTime 213 result.ReadFromByte(1); //version 214 result.ReadFromBuffer(pCapabilities->avc._pSPS + 1, 3); //profile,profile compat,level 215 result.ReadFromByte(0xff); //6 bits reserved (111111) + 2 bits nal size length - 1 (11) 216 result.ReadFromByte(0xe1); //3 bits reserved (111) + 5 bits number of sps (00001) 217 uint16_t temp16 = EHTONS(pCapabilities->avc._spsLength); 218 result.ReadFromBuffer((uint8_t *) & temp16, 2); //SPS length 219 result.ReadFromBuffer(pCapabilities->avc._pSPS, pCapabilities->avc._spsLength); 220 221 222 result.ReadFromByte(1); 223 temp16 = EHTONS(pCapabilities->avc._ppsLength); 224 result.ReadFromBuffer((uint8_t *) & temp16, 2); //PPS length 225 result.ReadFromBuffer(pCapabilities->avc._pPPS, pCapabilities->avc._ppsLength); 226 227 228 //3. Send the video codec 229 if (!BaseOutNetRTMPStream::FeedData( 230 GETIBPOINTER(result), //pData 231 GETAVAILABLEBYTESCOUNT(result), //dataLength 232 0, //processedLength 233 GETAVAILABLEBYTESCOUNT(result), //totalLength 234 absoluteTimestamp, //absoluteTimestamp 235 false //isAudio 236 )) { 237 FATAL("Unable to send video codec setup"); 238 return false; 239 } 240 241 _videoCodecSent = true; 242 243 return true; 244 } 245 246 bool OutNetRTMP4TSStream::SendAudioCodec(double absoluteTimestamp) { 247 StreamCapabilities *pCapabilities = GetCapabilities(); 248 if ((pCapabilities == NULL) || (pCapabilities->audioCodecId != CODEC_AUDIO_AAC)) { 249 return true; 250 } 251 IOBuffer result; 252 result.ReadFromRepeat(0xaf, 1); 253 result.ReadFromRepeat(0x00, 1); 254 result.ReadFromBuffer(pCapabilities->aac._pAAC, 255 pCapabilities->aac._aacLength); 256 257 if (!BaseOutNetRTMPStream::FeedData( 258 GETIBPOINTER(result), //pData 259 GETAVAILABLEBYTESCOUNT(result), //dataLength 260 0, //processedLength 261 GETAVAILABLEBYTESCOUNT(result), //totalLength 262 absoluteTimestamp, //absoluteTimestamp 263 true //isAudio 264 )) { 265 FATAL("Unable to send audio codec setup"); 266 return false; 267 } 268 269 _audioCodecSent = true; 270 return true; 271 } 303 272 #endif /* HAS_PROTOCOL_RTMP */ 304 273 -
trunk/sources/thelib/src/protocols/rtp/streaming/innetrtpstream.cpp
r727 r729 466 466 467 467 void InNetRTPStream::FeedVideoCodecSetup(BaseOutStream* pOutStream) { 468 if (!pOutStream->FeedData(469 _capabilities.avc._pSPS,470 _capabilities.avc._spsLength,471 0,472 _capabilities.avc._spsLength,473 _videoLastTs,474 false)) {475 FATAL("Unable to feed stream");476 if (pOutStream->GetProtocol() != NULL) {477 pOutStream->GetProtocol()->EnqueueForDelete();478 }479 }480 if (!pOutStream->FeedData(481 _capabilities.avc._pPPS,482 _capabilities.avc._ppsLength,483 0,484 _capabilities.avc._ppsLength,485 _videoLastTs,486 false)) {487 FATAL("Unable to feed stream");488 if (pOutStream->GetProtocol() != NULL) {489 pOutStream->GetProtocol()->EnqueueForDelete();490 }491 }468 // if (!pOutStream->FeedData( 469 // _capabilities.avc._pSPS, 470 // _capabilities.avc._spsLength, 471 // 0, 472 // _capabilities.avc._spsLength, 473 // _videoLastTs, 474 // false)) { 475 // FATAL("Unable to feed stream"); 476 // if (pOutStream->GetProtocol() != NULL) { 477 // pOutStream->GetProtocol()->EnqueueForDelete(); 478 // } 479 // } 480 // if (!pOutStream->FeedData( 481 // _capabilities.avc._pPPS, 482 // _capabilities.avc._ppsLength, 483 // 0, 484 // _capabilities.avc._ppsLength, 485 // _videoLastTs, 486 // false)) { 487 // FATAL("Unable to feed stream"); 488 // if (pOutStream->GetProtocol() != NULL) { 489 // pOutStream->GetProtocol()->EnqueueForDelete(); 490 // } 491 // } 492 492 } 493 493 -
trunk/sources/thelib/src/protocols/ts/innettsstream.cpp
r637 r729 1 /* 1 /* 2 2 * Copyright (c) 2010, 3 3 * Gavriloaie Eugen-Andrei (shiretu@gmail.com) … … 39 39 _dtsTimeAudio = 0; 40 40 #endif 41 _deltaTimeAudio = -1;42 41 _lastGotAudioTimestamp = 0; 43 42 _lastSentAudioTimestamp = 0; … … 57 56 _dtsTimeVideo = 0; 58 57 #endif 59 _deltaTimeVideo = -1; 60 61 _feedTime = 0; 62 _cursor = 0; 58 59 _deltaTime = -1; 63 60 _videoPacketsCount = 0; 64 61 _videoBytesCount = 0; 65 62 _videoDroppedPacketsCount = 0; 66 63 _videoDroppedBytesCount = 0; 67 68 _firstNAL = true;69 64 } 70 65 … … 88 83 } 89 84 90 double InNetTSStream::GetFeedTime() {91 return _feedTime;92 }93 94 85 //#define __FORCE_ROLL_OVER_FOR_DEBUG 30 95 86 //#define __DUMP_TIMESTAMP_INFO_FOR_DEBUG … … 103 94 #define DROP_PACKET \ 104 95 do { \ 96 /*WARN("Video packet dropped!!!");*/ \ 105 97 if(!isAudio) { \ 106 /*WARN("Video packet dropped!!!");*/ \ 107 _currentNal.IgnoreAll(); \ 108 _cursor = 0; \ 109 _firstNAL = true; \ 98 _videoBucket.IgnoreAll(); \ 99 } else { \ 100 _audioBucket.IgnoreAll(); \ 110 101 } \ 111 102 uint64_t &droppedPacketsCount = isAudio ? _audioDroppedPacketsCount : _videoDroppedPacketsCount; \ … … 144 135 double &dtsTime = isAudio ? _dtsTimeAudio : _dtsTimeVideo; 145 136 #endif 146 double &deltaTime = isAudio ? _deltaTimeAudio : _deltaTimeVideo;147 137 double absoluteTime = 0; 148 138 if (packetStart) { 139 if (isAudio) { 140 if (!HandleAudioData()) 141 return false; 142 } else { 143 if (!HandleVideoData()) 144 return false; 145 } 149 146 if (length >= 8) { 150 147 uint32_t pesHeaderLength = pData[8]; … … 234 231 } 235 232 236 if (deltaTime < 0) 237 deltaTime = ptsTime; 238 239 absoluteTime = (ptsTime - deltaTime); 240 _feedTime = _feedTime < absoluteTime ? absoluteTime : _feedTime; 233 if (_deltaTime < 0) 234 _deltaTime = ptsTime; 235 236 absoluteTime = (ptsTime - _deltaTime); 241 237 242 238 pData += 9 + pesHeaderLength; … … 251 247 252 248 if (isAudio) 253 return HandleAudioData(pData, length, ptsTime - deltaTime, packetStart);249 _audioBucket.ReadFromBuffer(pData, length); 254 250 else 255 return HandleVideoData(pData, length, ptsTime - deltaTime, packetStart); 251 _videoBucket.ReadFromBuffer(pData, length); 252 return true; 256 253 } 257 254 … … 326 323 } 327 324 328 bool InNetTSStream::HandleAudioData(uint8_t *pRawBuffer, uint32_t rawBufferLength, 329 double timestamp, bool packetStart) { 330 _audioBytesCount += rawBufferLength; 325 bool InNetTSStream::HandleAudioData() { 326 if (_streamCapabilities.videoCodecId != CODEC_VIDEO_AVC) { 327 if (_pVideoPidDescriptor != NULL) { 328 _audioBucket.IgnoreAll(); 329 return true; 330 } 331 } 332 double timestamp = _ptsTimeAudio - _deltaTime; 333 if (_ptsTimeAudio < 0 || _deltaTime < 0 || timestamp < 0) { 334 _audioBucket.IgnoreAll(); 335 return true; 336 } 337 338 _audioBytesCount += GETAVAILABLEBYTESCOUNT(_audioBucket); 331 339 _statsAudioPacketsCount++; 332 340 //the payload here respects this format: … … 334 342 //iso13818-7 page 26/206 335 343 336 //1. Save the data 337 _audioBuffer.ReadFromBuffer(pRawBuffer, rawBufferLength); 338 339 InitializeAudioCapabilities(pRawBuffer, rawBufferLength); 344 InitializeAudioCapabilities(GETIBPOINTER(_audioBucket), 345 GETAVAILABLEBYTESCOUNT(_audioBucket)); 340 346 341 347 if (_lastGotAudioTimestamp != timestamp) { … … 346 352 for (;;) { 347 353 //2. Get the buffer details: length and pointer 348 uint32_t bufferLength = GETAVAILABLEBYTESCOUNT(_audioBu ffer);349 uint8_t *pBuffer = GETIBPOINTER(_audioBu ffer);354 uint32_t bufferLength = GETAVAILABLEBYTESCOUNT(_audioBucket); 355 uint8_t *pBuffer = GETIBPOINTER(_audioBucket); 350 356 351 357 //3. Do we have at least 6 bytes to read the length? … … 355 361 356 362 if ((ENTOHSP(pBuffer)&0xfff0) != 0xfff0) { 357 _audioBu ffer.Ignore(1);363 _audioBucket.Ignore(1); 358 364 _audioDroppedBytesCount++; 359 365 continue; … … 367 373 if (frameLength < 8) { 368 374 WARN("Bogus frameLength %u. Skip one byte", frameLength); 369 FINEST("_audioBuffer:\n%s", STR(_audioBu ffer));370 _audioBu ffer.Ignore(1);375 FINEST("_audioBuffer:\n%s", STR(_audioBucket)); 376 _audioBucket.Ignore(1); 371 377 continue; 372 378 } … … 389 395 390 396 //6. Ignore frameLength bytes 391 _audioBuffer.Ignore(frameLength); 392 } 393 394 return true; 395 } 396 397 bool InNetTSStream::HandleVideoData(uint8_t *pBuffer, uint32_t length, 398 double timestamp, bool packetStart) { 399 _videoBytesCount += length; 400 _videoPacketsCount++; 401 //1. Store the data inside our buffer 402 _currentNal.ReadFromBuffer(pBuffer, length); 403 404 //2. Get the initial buffer and size 405 uint32_t size = GETAVAILABLEBYTESCOUNT(_currentNal); 406 uint8_t *pNalBuffer = GETIBPOINTER(_currentNal); 407 uint32_t testValue = 0; 408 409 //3. If this is the first NAL encountered, than lock 410 //on the first byte from the first packet 411 if (_firstNAL) { 412 _cursor = 0; 413 if (size < 4) 414 return true; 415 while (_cursor < size - 4) { 416 testValue = ENTOHLP(pNalBuffer + _cursor); 417 if ((testValue >> 8) == 1) { 418 _videoDroppedBytesCount += (_cursor + 3); 419 _currentNal.Ignore(_cursor + 3); 420 _firstNAL = false; 421 _cursor = 0; 422 size = GETAVAILABLEBYTESCOUNT(_currentNal); 423 pNalBuffer = GETIBPOINTER(_currentNal); 424 break; 425 } 426 if (testValue == 1) { 427 _videoDroppedBytesCount += (_cursor + 4); 428 _currentNal.Ignore(_cursor + 4); 429 _firstNAL = false; 430 _cursor = 0; 431 size = GETAVAILABLEBYTESCOUNT(_currentNal); 432 pNalBuffer = GETIBPOINTER(_currentNal); 433 break; 434 } 435 _cursor++; 436 } 437 } 438 439 if (size < 4) { 397 _audioBucket.Ignore(frameLength); 398 } 399 400 _audioBucket.IgnoreAll(); 401 402 return true; 403 } 404 405 bool InNetTSStream::HandleVideoData() { 406 double timestamp = _ptsTimeVideo - _deltaTime; 407 if (_ptsTimeVideo < 0 || _deltaTime < 0 || timestamp < 0) { 408 _videoBucket.IgnoreAll(); 440 409 return true; 441 410 } 442 411 443 //4. Search for the next NAL boundary 412 uint32_t cursor = 0; 413 uint32_t length = GETAVAILABLEBYTESCOUNT(_videoBucket); 414 uint8_t *pBuffer = GETIBPOINTER(_videoBucket); 415 uint8_t *pNalStart = NULL; 416 uint8_t *pNalEnd = NULL; 417 uint32_t testValue; 418 uint8_t markerSize = 0; 444 419 bool found = false; 445 int8_t markerSize = 0; 446 447 while (_cursor < size - 4) { 448 testValue = ENTOHLP(pNalBuffer + _cursor); 449 if ((testValue >> 8) == 1) { 420 421 while (cursor + 4 < length) { 422 testValue = ENTOHLP(pBuffer + cursor); 423 if (testValue == 1) { 424 markerSize = 4; 425 pNalEnd = pBuffer + cursor; 426 found = true; 427 } else if ((testValue >> 8) == 1) { 450 428 markerSize = 3; 429 pNalEnd = pBuffer + cursor; 451 430 found = true; 452 } else if (testValue == 1) { 453 markerSize = 4; 454 found = true; 455 } 456 431 } 457 432 if (!found) { 458 _cursor++;433 cursor++; 459 434 continue; 435 } else { 436 cursor += markerSize; 460 437 } 461 438 found = false; 462 463 if (!ProcessNal(timestamp)) { 464 FATAL("Unable to process NALU"); 439 if (pNalStart != NULL) { 440 if (!ProcessNal(pNalStart, pNalEnd - pNalStart, timestamp)) { 441 FATAL("Unable to process NAL"); 442 return false; 443 } 444 } 445 pNalStart = pNalEnd + markerSize; 446 } 447 if (pNalStart != NULL) { 448 int32_t lastLength = length - (pNalStart - pBuffer); 449 if (!ProcessNal(pNalStart, lastLength, timestamp)) { 450 FATAL("Unable to process NAL"); 465 451 return false; 466 452 } 467 468 _currentNal.Ignore(_cursor + markerSize); 469 pNalBuffer = GETIBPOINTER(_currentNal); 470 size = GETAVAILABLEBYTESCOUNT(_currentNal); 471 _cursor = 0; 472 if (size < 4) 473 break; 474 } 475 476 return true; 477 } 478 479 bool InNetTSStream::ProcessNal(double timestamp) { 480 InitializeVideoCapabilities(GETIBPOINTER(_currentNal), _cursor); 481 //5. Feed 453 } 454 _videoBucket.IgnoreAll(); 455 return true; 456 } 457 458 bool InNetTSStream::ProcessNal(uint8_t *pBuffer, int32_t length, double timestamp) { 459 if (pBuffer == NULL || length <= 0) 460 return true; 461 InitializeVideoCapabilities(pBuffer, length); 462 if (_streamCapabilities.videoCodecId != CODEC_VIDEO_AVC) { 463 return true; 464 } 482 465 return FeedData( 483 GETIBPOINTER(_currentNal),484 _cursor,466 pBuffer, 467 length, 485 468 0, 486 _cursor,469 length, 487 470 timestamp, 488 471 false);
Note: See TracChangeset
for help on using the changeset viewer.
