Changeset 729


Ignore:
Timestamp:
01/22/12 03:23:59 (4 months ago)
Author:
shiretu
Message:

-- many RTSP and mpeg-ts fixes and refactorings. The bridging is more stable and reliable now

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/builders/cmake/applications/CMakeLists.txt

    r476 r729  
    1212ADD_SUBDIRECTORY(proxypublish proxypublish) 
    1313ADD_SUBDIRECTORY(stresstest stresstest) 
    14 ADD_SUBDIRECTORY(applestreamingclient applestreamingclient) 
     14#ADD_SUBDIRECTORY(applestreamingclient applestreamingclient) 
    1515#ADD_SUBDIRECTORY(vmapp vmapp) 
    1616 
  • trunk/sources/thelib/include/protocols/rtmp/streaming/outnetrtmp4tsstream.h

    r727 r729  
    3030        bool _audioCodecSent; 
    3131        bool _videoCodecSent; 
    32         bool _spsAvailable; 
    33         uint8_t *_pSPSPPS; 
    34         uint8_t _SPSPPSLength; 
    35         uint32_t _PPSStart; 
    3632        IOBuffer _videoBuffer; 
    3733        bool _inboundStreamIsRTP; 
     
    5349        bool FeedAudioData(uint8_t *pData, uint32_t dataLength, double absoluteTimestamp); 
    5450        bool FeedVideoData(uint8_t *pData, uint32_t dataLength, double absoluteTimestamp); 
     51        bool SendVideoCodec(double absoluteTimestamp); 
     52        bool SendAudioCodec(double absoluteTimestamp); 
    5553}; 
    5654 
  • trunk/sources/thelib/include/protocols/ts/innettsstream.h

    r637 r729  
    1 /*  
     1/* 
    22 *  Copyright (c) 2010, 
    33 *  Gavriloaie Eugen-Andrei (shiretu@gmail.com) 
     
    4242        double _dtsTimeAudio; 
    4343#endif 
    44         double _deltaTimeAudio; 
    45         IOBuffer _audioBuffer; 
     44        IOBuffer _audioBucket; 
    4645        double _lastGotAudioTimestamp; 
    4746        double _lastSentAudioTimestamp; 
     
    6261        double _dtsTimeVideo; 
    6362#endif 
    64         double _deltaTimeVideo; 
    6563        uint64_t _videoPacketsCount; 
    6664        uint64_t _videoBytesCount; 
    6765        uint64_t _videoDroppedPacketsCount; 
    6866        uint64_t _videoDroppedBytesCount; 
    69         IOBuffer _currentNal; 
     67        IOBuffer _videoBucket; 
    7068 
    71         double _feedTime; 
     69        StreamCapabilities _streamCapabilities; 
    7270 
    73         uint32_t _cursor; 
    74         StreamCapabilities _streamCapabilities; 
    75         bool _firstNAL; 
     71        double _deltaTime; 
    7672 
    7773        IOBuffer _SPS; 
     
    8581        void SetAudioVideoPidDescriptors(_PIDDescriptor *pAudioPidDescriptor, 
    8682                        _PIDDescriptor *pVideoPidDescriptor); 
    87  
    88         double GetFeedTime(); 
    8983 
    9084        bool FeedData(uint8_t *pData, uint32_t length, bool packetStart, 
     
    10498        virtual void GetStats(Variant &info, uint32_t namespaceId = 0); 
    10599private: 
    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); 
    111103        void InitializeVideoCapabilities(uint8_t *pData, uint32_t length); 
    112104        void InitializeAudioCapabilities(uint8_t *pData, uint32_t length); 
  • trunk/sources/thelib/src/protocols/rtmp/streaming/outnetrtmp4tsstream.cpp

    r727 r729  
    3333        _audioCodecSent = false; 
    3434        _videoCodecSent = false; 
    35         _spsAvailable = false; 
    36         _pSPSPPS = new uint8_t[SPSPPS_MAX_LENGTH]; 
    37         _SPSPPSLength = 0; 
    38         _PPSStart = 0; 
    3935        CanDropFrames(false); 
    40  
    41  
    42         _pSPSPPS[0] = 0x17; //0x10 - key frame; 0x07 - H264_CODEC_ID 
    43         _pSPSPPS[1] = 0; //0: AVC sequence header; 1: AVC NALU; 2: AVC end of sequence 
    44         _pSPSPPS[2] = 0; //CompositionTime 
    45         _pSPSPPS[3] = 0; //CompositionTime 
    46         _pSPSPPS[4] = 0; //CompositionTime 
    47         _pSPSPPS[5] = 1; //version 
    48         _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) 
    5036 
    5137        _inboundStreamIsRTP = false; 
     
    5541 
    5642OutNetRTMP4TSStream::~OutNetRTMP4TSStream() { 
    57         delete[] _pSPSPPS; 
     43 
    5844} 
    5945 
     
    8672bool OutNetRTMP4TSStream::FeedAudioData(uint8_t *pData, uint32_t dataLength, 
    8773                double absoluteTimestamp) { 
    88         if (!_videoCodecSent) 
    89                 return true; 
    9074        //the payload here respects this format: 
    9175        //6.2  Audio Data Transport Stream, ADTS 
     
    9478        //1. Send the audio codec setup if necessary 
    9579        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                } 
    11984        } 
    12085 
     
    12287                pData[0] = 0xaf; 
    12388                pData[1] = 0x01; 
    124  
    12589                return BaseOutNetRTMPStream::FeedData( 
    12690                                pData, //pData 
     
    161125                double absoluteTimestamp) { 
    162126        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"); 
    169138                                return false; 
    170139                        } 
    171                         memcpy(_pSPSPPS + 6, pData + 1, 3); //profile,profile compat,level 
    172                         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 codec 
    181                         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 codec 
    196                         if (!BaseOutNetRTMPStream::FeedData( 
    197                                         _pSPSPPS, //pData 
    198                                         _PPSStart + 1 + 2 + dataLength, //dataLength 
    199                                         0, //processedLength 
    200                                         _PPSStart + 1 + 2 + dataLength, //totalLength 
    201                                         absoluteTimestamp, //absoluteTimestamp 
    202                                         false //isAudio 
    203                                         )) { 
    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 reference 
    215                         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 packets 
    220                         if (_lastVideoTimestamp != absoluteTimestamp) { 
    221                                 if (!BaseOutNetRTMPStream::FeedData( 
    222                                                 GETIBPOINTER(_videoBuffer), //pData 
    223                                                 GETAVAILABLEBYTESCOUNT(_videoBuffer), //dataLength 
    224                                                 0, //processedLength 
    225                                                 GETAVAILABLEBYTESCOUNT(_videoBuffer), //totalLength 
    226                                                 _lastVideoTimestamp, //absoluteTimestamp 
    227                                                 false //isAudio 
    228                                                 )) { 
    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 header 
    240                         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 data 
    257                                 _videoBuffer.ReadFromBuffer(pData, dataLength); 
    258  
    259                                 //setup the frame type 
    260                                 _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 big 
    269                         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 
     200bool 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 
     246bool 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} 
    303272#endif /* HAS_PROTOCOL_RTMP */ 
    304273 
  • trunk/sources/thelib/src/protocols/rtp/streaming/innetrtpstream.cpp

    r727 r729  
    466466 
    467467void 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//      } 
    492492} 
    493493 
  • trunk/sources/thelib/src/protocols/ts/innettsstream.cpp

    r637 r729  
    1 /*  
     1/* 
    22 *  Copyright (c) 2010, 
    33 *  Gavriloaie Eugen-Andrei (shiretu@gmail.com) 
     
    3939        _dtsTimeAudio = 0; 
    4040#endif 
    41         _deltaTimeAudio = -1; 
    4241        _lastGotAudioTimestamp = 0; 
    4342        _lastSentAudioTimestamp = 0; 
     
    5756        _dtsTimeVideo = 0; 
    5857#endif 
    59         _deltaTimeVideo = -1; 
    60  
    61         _feedTime = 0; 
    62         _cursor = 0; 
     58 
     59        _deltaTime = -1; 
    6360        _videoPacketsCount = 0; 
    6461        _videoBytesCount = 0; 
    6562        _videoDroppedPacketsCount = 0; 
    6663        _videoDroppedBytesCount = 0; 
    67  
    68         _firstNAL = true; 
    6964} 
    7065 
     
    8883} 
    8984 
    90 double InNetTSStream::GetFeedTime() { 
    91         return _feedTime; 
    92 } 
    93  
    9485//#define __FORCE_ROLL_OVER_FOR_DEBUG 30 
    9586//#define __DUMP_TIMESTAMP_INFO_FOR_DEBUG 
     
    10394#define DROP_PACKET \ 
    10495do { \ 
     96        /*WARN("Video packet dropped!!!");*/ \ 
    10597        if(!isAudio) { \ 
    106                 /*WARN("Video packet dropped!!!");*/ \ 
    107                 _currentNal.IgnoreAll(); \ 
    108                 _cursor = 0; \ 
    109                 _firstNAL = true; \ 
     98                _videoBucket.IgnoreAll(); \ 
     99        } else { \ 
     100                _audioBucket.IgnoreAll(); \ 
    110101        } \ 
    111102        uint64_t &droppedPacketsCount = isAudio ? _audioDroppedPacketsCount : _videoDroppedPacketsCount; \ 
     
    144135        double &dtsTime = isAudio ? _dtsTimeAudio : _dtsTimeVideo; 
    145136#endif 
    146         double &deltaTime = isAudio ? _deltaTimeAudio : _deltaTimeVideo; 
    147137        double absoluteTime = 0; 
    148138        if (packetStart) { 
     139                if (isAudio) { 
     140                        if (!HandleAudioData()) 
     141                                return false; 
     142                } else { 
     143                        if (!HandleVideoData()) 
     144                                return false; 
     145                } 
    149146                if (length >= 8) { 
    150147                        uint32_t pesHeaderLength = pData[8]; 
     
    234231                        } 
    235232 
    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); 
    241237 
    242238                        pData += 9 + pesHeaderLength; 
     
    251247 
    252248        if (isAudio) 
    253                 return HandleAudioData(pData, length, ptsTime - deltaTime, packetStart); 
     249                _audioBucket.ReadFromBuffer(pData, length); 
    254250        else 
    255                 return HandleVideoData(pData, length, ptsTime - deltaTime, packetStart); 
     251                _videoBucket.ReadFromBuffer(pData, length); 
     252        return true; 
    256253} 
    257254 
     
    326323} 
    327324 
    328 bool InNetTSStream::HandleAudioData(uint8_t *pRawBuffer, uint32_t rawBufferLength, 
    329                 double timestamp, bool packetStart) { 
    330         _audioBytesCount += rawBufferLength; 
     325bool 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); 
    331339        _statsAudioPacketsCount++; 
    332340        //the payload here respects this format: 
     
    334342        //iso13818-7 page 26/206 
    335343 
    336         //1. Save the data 
    337         _audioBuffer.ReadFromBuffer(pRawBuffer, rawBufferLength); 
    338  
    339         InitializeAudioCapabilities(pRawBuffer, rawBufferLength); 
     344        InitializeAudioCapabilities(GETIBPOINTER(_audioBucket), 
     345                        GETAVAILABLEBYTESCOUNT(_audioBucket)); 
    340346 
    341347        if (_lastGotAudioTimestamp != timestamp) { 
     
    346352        for (;;) { 
    347353                //2. Get the buffer details: length and pointer 
    348                 uint32_t bufferLength = GETAVAILABLEBYTESCOUNT(_audioBuffer); 
    349                 uint8_t *pBuffer = GETIBPOINTER(_audioBuffer); 
     354                uint32_t bufferLength = GETAVAILABLEBYTESCOUNT(_audioBucket); 
     355                uint8_t *pBuffer = GETIBPOINTER(_audioBucket); 
    350356 
    351357                //3. Do we have at least 6 bytes to read the length? 
     
    355361 
    356362                if ((ENTOHSP(pBuffer)&0xfff0) != 0xfff0) { 
    357                         _audioBuffer.Ignore(1); 
     363                        _audioBucket.Ignore(1); 
    358364                        _audioDroppedBytesCount++; 
    359365                        continue; 
     
    367373                if (frameLength < 8) { 
    368374                        WARN("Bogus frameLength %u. Skip one byte", frameLength); 
    369                         FINEST("_audioBuffer:\n%s", STR(_audioBuffer)); 
    370                         _audioBuffer.Ignore(1); 
     375                        FINEST("_audioBuffer:\n%s", STR(_audioBucket)); 
     376                        _audioBucket.Ignore(1); 
    371377                        continue; 
    372378                } 
     
    389395 
    390396                //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 
     405bool InNetTSStream::HandleVideoData() { 
     406        double timestamp = _ptsTimeVideo - _deltaTime; 
     407        if (_ptsTimeVideo < 0 || _deltaTime < 0 || timestamp < 0) { 
     408                _videoBucket.IgnoreAll(); 
    440409                return true; 
    441410        } 
    442411 
    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; 
    444419        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) { 
    450428                        markerSize = 3; 
     429                        pNalEnd = pBuffer + cursor; 
    451430                        found = true; 
    452                 } else if (testValue == 1) { 
    453                         markerSize = 4; 
    454                         found = true; 
    455                 } 
    456  
     431                } 
    457432                if (!found) { 
    458                         _cursor++; 
     433                        cursor++; 
    459434                        continue; 
     435                } else { 
     436                        cursor += markerSize; 
    460437                } 
    461438                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"); 
    465451                        return false; 
    466452                } 
    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 
     458bool 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        } 
    482465        return FeedData( 
    483                         GETIBPOINTER(_currentNal), 
    484                         _cursor, 
     466                        pBuffer, 
     467                        length, 
    485468                        0, 
    486                         _cursor, 
     469                        length, 
    487470                        timestamp, 
    488471                        false); 
Note: See TracChangeset for help on using the changeset viewer.