Remove the old H264 code now that a new H.264 packetizer has been implemented.
R=pbos@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/15109004
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@6847 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/rtp_rtcp/source/H264/bitstream_builder.cc b/modules/rtp_rtcp/source/H264/bitstream_builder.cc
deleted file mode 100644
index 3551782..0000000
--- a/modules/rtp_rtcp/source/H264/bitstream_builder.cc
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "bitstream_builder.h"
-
-#include <string.h>
-
-namespace webrtc {
-BitstreamBuilder::BitstreamBuilder(uint8_t* data, const uint32_t dataSize) :
- _data(data),
- _dataSize(dataSize),
- _byteOffset(0),
- _bitOffset(0)
-{
- memset(data, 0, dataSize);
-}
-
-uint32_t
-BitstreamBuilder::Length() const
-{
- return _byteOffset+ (_bitOffset?1:0);
-}
-
-int32_t
-BitstreamBuilder::Add1Bit(const uint8_t bit)
-{
- // sanity
- if(_bitOffset + 1 > 8)
- {
- if(_dataSize < Length()+1)
- {
- // not enough space in buffer
- return -1;
- }
- }
- Add1BitWithoutSanity(bit);
- return 0;
-}
-
-void
-BitstreamBuilder::Add1BitWithoutSanity(const uint8_t bit)
-{
- if(bit & 0x1)
- {
- _data[_byteOffset] += (1 << (7-_bitOffset));
- }
-
- if(_bitOffset == 7)
- {
- // last bit in byte
- _bitOffset = 0;
- _byteOffset++;
- } else
- {
- _bitOffset++;
- }
-}
-
-int32_t
-BitstreamBuilder::Add2Bits(const uint8_t bits)
-{
- // sanity
- if(_bitOffset + 2 > 8)
- {
- if(_dataSize < Length()+1)
- {
- // not enough space in buffer
- return -1;
- }
- }
- Add1BitWithoutSanity(bits >> 1);
- Add1BitWithoutSanity(bits);
- return 0;
-}
-
-int32_t
-BitstreamBuilder::Add3Bits(const uint8_t bits)
-{
- // sanity
- if(_bitOffset + 3 > 8)
- {
- if(_dataSize < Length()+1)
- {
- // not enough space in buffer
- return -1;
- }
- }
- Add1BitWithoutSanity(bits >> 2);
- Add1BitWithoutSanity(bits >> 1);
- Add1BitWithoutSanity(bits);
- return 0;
-}
-
-int32_t
-BitstreamBuilder::Add4Bits(const uint8_t bits)
-{
- // sanity
- if(_bitOffset + 4 > 8)
- {
- if(_dataSize < Length()+1)
- {
- // not enough space in buffer
- return -1;
- }
- }
- Add1BitWithoutSanity(bits >> 3);
- Add1BitWithoutSanity(bits >> 2);
- Add1BitWithoutSanity(bits >> 1);
- Add1BitWithoutSanity(bits);
- return 0;
-}
-
-int32_t
-BitstreamBuilder::Add5Bits(const uint8_t bits)
-{
- // sanity
- if(_bitOffset + 5 > 8)
- {
- if(_dataSize < Length()+1)
- {
- // not enough space in buffer
- return -1;
- }
- }
- Add1BitWithoutSanity(bits >> 4);
- Add1BitWithoutSanity(bits >> 3);
- Add1BitWithoutSanity(bits >> 2);
- Add1BitWithoutSanity(bits >> 1);
- Add1BitWithoutSanity(bits);
- return 0;
-}
-
-int32_t
-BitstreamBuilder::Add6Bits(const uint8_t bits)
-{
- // sanity
- if(_bitOffset + 6 > 8)
- {
- if(_dataSize < Length()+1)
- {
- // not enough space in buffer
- return -1;
- }
- }
- Add1BitWithoutSanity(bits >> 5);
- Add1BitWithoutSanity(bits >> 4);
- Add1BitWithoutSanity(bits >> 3);
- Add1BitWithoutSanity(bits >> 2);
- Add1BitWithoutSanity(bits >> 1);
- Add1BitWithoutSanity(bits);
- return 0;
-}
-
-int32_t
-BitstreamBuilder::Add7Bits(const uint8_t bits)
-{
- // sanity
- if(_bitOffset + 7 > 8)
- {
- if(_dataSize < Length()+1)
- {
- // not enough space in buffer
- return -1;
- }
- }
- Add1BitWithoutSanity(bits >> 6);
- Add1BitWithoutSanity(bits >> 5);
- Add1BitWithoutSanity(bits >> 4);
- Add1BitWithoutSanity(bits >> 3);
- Add1BitWithoutSanity(bits >> 2);
- Add1BitWithoutSanity(bits >> 1);
- Add1BitWithoutSanity(bits);
- return 0;
-}
-
-int32_t
-BitstreamBuilder::Add8Bits(const uint8_t bits)
-{
- // sanity
- if(_dataSize < Length()+1)
- {
- // not enough space in buffer
- return -1;
- }
- if(_bitOffset == 0)
- {
- _data[_byteOffset] = bits;
- } else
- {
- _data[_byteOffset] += (bits >> _bitOffset);
- _data[_byteOffset+1] += (bits << (8-_bitOffset));
- }
- _byteOffset++;
- return 0;
-}
-
-int32_t
-BitstreamBuilder::Add16Bits(const uint16_t bits)
-{
- // sanity
- if(_dataSize < Length()+2)
- {
- // not enough space in buffer
- return -1;
- }
- if(_bitOffset == 0)
- {
- _data[_byteOffset] = (uint8_t)(bits >> 8);
- _data[_byteOffset+1] = (uint8_t)(bits);
- } else
- {
- _data[_byteOffset] += (uint8_t)(bits >> (_bitOffset + 8));
- _data[_byteOffset+1] += (uint8_t)(bits >> _bitOffset);
- _data[_byteOffset+2] += (uint8_t)(bits << (8-_bitOffset));
- }
- _byteOffset += 2;
- return 0;
-}
-
-int32_t
-BitstreamBuilder::Add24Bits(const uint32_t bits)
-{
- // sanity
- if(_dataSize < Length()+3)
- {
- // not enough space in buffer
- return -1;
- }
- if(_bitOffset == 0)
- {
- _data[_byteOffset] = (uint8_t)(bits >> 16);
- _data[_byteOffset+1] = (uint8_t)(bits >> 8);
- _data[_byteOffset+2] = (uint8_t)(bits);
- } else
- {
- _data[_byteOffset] += (uint8_t)(bits >> (_bitOffset+16));
- _data[_byteOffset+1] += (uint8_t)(bits >> (_bitOffset+8));
- _data[_byteOffset+2] += (uint8_t)(bits >> (_bitOffset));
- _data[_byteOffset+3] += (uint8_t)(bits << (8-_bitOffset));
- }
- _byteOffset += 3;
- return 0;
-}
-
-int32_t
-BitstreamBuilder::Add32Bits(const uint32_t bits)
-{
- // sanity
- if(_dataSize < Length()+4)
- {
- // not enough space in buffer
- return -1;
- }
- if(_bitOffset == 0)
- {
- _data[_byteOffset] = (uint8_t)(bits >> 24);
- _data[_byteOffset+1] = (uint8_t)(bits >> 16);
- _data[_byteOffset+2] = (uint8_t)(bits >> 8);
- _data[_byteOffset+3] = (uint8_t)(bits);
- } else
- {
- _data[_byteOffset] += (uint8_t)(bits >> (_bitOffset+24));
- _data[_byteOffset+1] += (uint8_t)(bits >> (_bitOffset+16));
- _data[_byteOffset+2] += (uint8_t)(bits >> (_bitOffset+8));
- _data[_byteOffset+3] += (uint8_t)(bits >> (_bitOffset));
- _data[_byteOffset+4] += (uint8_t)(bits << (8-_bitOffset));
- }
- _byteOffset += 4;
- return 0;
-}
-
-// Exp-Golomb codes
-/*
- with "prefix" and "suffix" bits and assignment to codeNum ranges (informative)
- Bit string form Range of codeNum
- 1 0
- 0 1 x0 1..2 2bits-1
- 0 0 1 x1 x0 3..6 3bits-1
- 0 0 0 1 x2 x1 x0 7..14 4bits-1
- 0 0 0 0 1 x3 x2 x1 x0 15..30
- 0 0 0 0 0 1 x4 x3 x2 x1 x0 31..62
-*/
-int32_t
-BitstreamBuilder::AddUE(const uint32_t value)
-{
- // un-rolled on 8 bit base to avoid too deep if else chain
- if(value < 0x0000ffff)
- {
- if(value < 0x000000ff)
- {
- if(value == 0)
- {
- if(AddPrefix(0) != 0)
- {
- return -1;
- }
- } else if(value < 3)
- {
- if(AddPrefix(1) != 0)
- {
- return -1;
- }
- AddSuffix(1, value-1);
- } else if(value < 7)
- {
- if(AddPrefix(2) != 0)
- {
- return -1;
- }
- AddSuffix(2, value-3);
- } else if(value < 15)
- {
- if(AddPrefix(3) != 0)
- {
- return -1;
- }
- AddSuffix(3, value-7);
- } else if(value < 31)
- {
- if(AddPrefix(4) != 0)
- {
- return -1;
- }
- AddSuffix(4, value-15);
- } else if(value < 63)
- {
- if(AddPrefix(5) != 0)
- {
- return -1;
- }
- AddSuffix(5, value-31);
- } else if(value < 127)
- {
- if(AddPrefix(6) != 0)
- {
- return -1;
- }
- AddSuffix(6, value-63);
- } else
- {
- if(AddPrefix(7) != 0)
- {
- return -1;
- }
- AddSuffix(7, value-127);
- }
- }else
- {
- if(value < 0x000001ff)
- {
- if(AddPrefix(8) != 0)
- {
- return -1;
- }
- AddSuffix(8, value-0x000000ff);
- } else if(value < 0x000003ff)
- {
- if(AddPrefix(9) != 0)
- {
- return -1;
- }
- AddSuffix(9, value-0x000001ff);
- } else if(value < 0x000007ff)
- {
- if(AddPrefix(10) != 0)
- {
- return -1;
- }
- AddSuffix(10, value-0x000003ff);
- } else if(value < 0x00000fff)
- {
- if(AddPrefix(11) != 0)
- {
- return -1;
- }
- AddSuffix(1, value-0x000007ff);
- } else if(value < 0x00001fff)
- {
- if(AddPrefix(12) != 0)
- {
- return -1;
- }
- AddSuffix(12, value-0x00000fff);
- } else if(value < 0x00003fff)
- {
- if(AddPrefix(13) != 0)
- {
- return -1;
- }
- AddSuffix(13, value-0x00001fff);
- } else if(value < 0x00007fff)
- {
- if(AddPrefix(14) != 0)
- {
- return -1;
- }
- AddSuffix(14, value-0x00003fff);
- } else
- {
- if(AddPrefix(15) != 0)
- {
- return -1;
- }
- AddSuffix(15, value-0x00007fff);
- }
- }
- }else
- {
- if(value < 0x00ffffff)
- {
- if(value < 0x0001ffff)
- {
- if(AddPrefix(16) != 0)
- {
- return -1;
- }
- AddSuffix(16, value-0x0000ffff);
- } else if(value < 0x0003ffff)
- {
- if(AddPrefix(17) != 0)
- {
- return -1;
- }
- AddSuffix(17, value-0x0001ffff);
- } else if(value < 0x0007ffff)
- {
- if(AddPrefix(18) != 0)
- {
- return -1;
- }
- AddSuffix(18, value-0x0003ffff);
- } else if(value < 0x000fffff)
- {
- if(AddPrefix(19) != 0)
- {
- return -1;
- }
- AddSuffix(19, value-0x0007ffff);
- } else if(value < 0x001fffff)
- {
- if(AddPrefix(20) != 0)
- {
- return -1;
- }
- AddSuffix(20, value-0x000fffff);
- } else if(value < 0x003fffff)
- {
- if(AddPrefix(21) != 0)
- {
- return -1;
- }
- AddSuffix(21, value-0x001fffff);
- } else if(value < 0x007fffff)
- {
- if(AddPrefix(22) != 0)
- {
- return -1;
- }
- AddSuffix(22, value-0x003fffff);
- } else
- {
- if(AddPrefix(23) != 0)
- {
- return -1;
- }
- AddSuffix(23, value-0x007fffff);
- }
- } else
- {
- if(value < 0x01ffffff)
- {
- if(AddPrefix(24) != 0)
- {
- return -1;
- }
- AddSuffix(24, value-0x00ffffff);
- } else if(value < 0x03ffffff)
- {
- if(AddPrefix(25) != 0)
- {
- return -1;
- }
- AddSuffix(25, value-0x01ffffff);
- } else if(value < 0x07ffffff)
- {
- if(AddPrefix(26) != 0)
- {
- return -1;
- }
- AddSuffix(26, value-0x03ffffff);
- } else if(value < 0x0fffffff)
- {
- if(AddPrefix(27) != 0)
- {
- return -1;
- }
- AddSuffix(27, value-0x07ffffff);
- } else if(value < 0x1fffffff)
- {
- if(AddPrefix(28) != 0)
- {
- return -1;
- }
- AddSuffix(28, value-0x0fffffff);
- } else if(value < 0x3fffffff)
- {
- if(AddPrefix(29) != 0)
- {
- return -1;
- }
- AddSuffix(29, value-0x1fffffff);
- } else if(value < 0x7fffffff)
- {
- if(AddPrefix(30) != 0)
- {
- return -1;
- }
- AddSuffix(30, value-0x3fffffff);
- } else if(value < 0xffffffff)
- {
- if(AddPrefix(31) != 0)
- {
- return -1;
- }
- AddSuffix(31, value-0x7ffffff);
- } else
- {
- if(AddPrefix(32) != 0)
- {
- return -1;
- }
- AddSuffix(32, 0); // exactly 0xffffffff
- }
- }
- }
- return 0;
-}
-
-int32_t
-BitstreamBuilder::AddPrefix(const uint8_t numZeros)
-{
- // sanity for the sufix too
- uint32_t numBitsToAdd = numZeros * 2 + 1;
- if(((_dataSize - _byteOffset) *8 + 8-_bitOffset) < numBitsToAdd)
- {
- return -1;
- }
-
- // add numZeros
- for (uint32_t i = 0; i < numZeros; i++)
- {
- Add1Bit(0);
- }
- Add1Bit(1);
- return 0;
-}
-
-void
-BitstreamBuilder::AddSuffix(const uint8_t numBits, const uint32_t rest)
-{
- // most significant bit first
- for(int32_t i = numBits - 1; i >= 0; i--)
- {
- if(( rest >> i) & 0x1)
- {
- Add1Bit(1);
- }else
- {
- Add1Bit(0);
- }
- }
-}
-} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/H264/bitstream_builder.h b/modules/rtp_rtcp/source/H264/bitstream_builder.h
deleted file mode 100644
index bf1efaf..0000000
--- a/modules/rtp_rtcp/source/H264/bitstream_builder.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_BITSTREAM_BUILDER_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_BITSTREAM_BUILDER_H_
-
-#include "webrtc/typedefs.h"
-
-namespace webrtc {
-class BitstreamBuilder
-{
-public:
- BitstreamBuilder(uint8_t* data, const uint32_t dataSize);
-
- uint32_t Length() const;
-
- int32_t Add1Bit(const uint8_t bit);
- int32_t Add2Bits(const uint8_t bits);
- int32_t Add3Bits(const uint8_t bits);
- int32_t Add4Bits(const uint8_t bits);
- int32_t Add5Bits(const uint8_t bits);
- int32_t Add6Bits(const uint8_t bits);
- int32_t Add7Bits(const uint8_t bits);
- int32_t Add8Bits(const uint8_t bits);
- int32_t Add16Bits(const uint16_t bits);
- int32_t Add24Bits(const uint32_t bits);
- int32_t Add32Bits(const uint32_t bits);
-
- // Exp-Golomb codes
- int32_t AddUE(const uint32_t value);
-
-private:
- int32_t AddPrefix(const uint8_t numZeros);
- void AddSuffix(const uint8_t numBits, const uint32_t rest);
- void Add1BitWithoutSanity(const uint8_t bit);
-
- uint8_t* _data;
- uint32_t _dataSize;
-
- uint32_t _byteOffset;
- uint8_t _bitOffset;
-};
-} // namespace webrtc
-
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_BITSTREAM_BUILDER_H_
diff --git a/modules/rtp_rtcp/source/H264/bitstream_parser.cc b/modules/rtp_rtcp/source/H264/bitstream_parser.cc
deleted file mode 100644
index d6505d2..0000000
--- a/modules/rtp_rtcp/source/H264/bitstream_parser.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "bitstream_parser.h"
-
-namespace webrtc {
-BitstreamParser::BitstreamParser(const uint8_t* data, const uint32_t dataLength) :
- _data(data),
- _dataLength(dataLength),
- _byteOffset(0),
- _bitOffset(0)
-{
-}
- // todo should we have any error codes from this?
-
-uint8_t
-BitstreamParser::Get1Bit()
-{
- uint8_t retVal = 0x1 & (_data[_byteOffset] >> (7-_bitOffset++));
-
- // prepare next byte
- if(_bitOffset == 8)
- {
- _bitOffset = 0;
- _byteOffset++;
- }
- return retVal;
-}
-
-uint8_t
-BitstreamParser::Get2Bits()
-{
- uint8_t retVal = (Get1Bit() << 1);
- retVal += Get1Bit();
- return retVal;
-}
-
-uint8_t
-BitstreamParser::Get3Bits()
-{
- uint8_t retVal = (Get1Bit() << 2);
- retVal += (Get1Bit() << 1);
- retVal += Get1Bit();
- return retVal;
-}
-
-uint8_t
-BitstreamParser::Get4Bits()
-{
- uint8_t retVal = (Get1Bit() << 3);
- retVal += (Get1Bit() << 2);
- retVal += (Get1Bit() << 1);
- retVal += Get1Bit();
- return retVal;
-}
-
-uint8_t
-BitstreamParser::Get5Bits()
-{
- uint8_t retVal = (Get1Bit() << 4);
- retVal += (Get1Bit() << 3);
- retVal += (Get1Bit() << 2);
- retVal += (Get1Bit() << 1);
- retVal += Get1Bit();
- return retVal;
-}
-
-uint8_t
-BitstreamParser::Get6Bits()
-{
- uint8_t retVal = (Get1Bit() << 5);
- retVal += (Get1Bit() << 4);
- retVal += (Get1Bit() << 3);
- retVal += (Get1Bit() << 2);
- retVal += (Get1Bit() << 1);
- retVal += Get1Bit();
- return retVal;
-}
-
-uint8_t
-BitstreamParser::Get7Bits()
-{
- uint8_t retVal = (Get1Bit() << 6);
- retVal += (Get1Bit() << 5);
- retVal += (Get1Bit() << 4);
- retVal += (Get1Bit() << 3);
- retVal += (Get1Bit() << 2);
- retVal += (Get1Bit() << 1);
- retVal += Get1Bit();
- return retVal;
-}
-
-uint8_t
-BitstreamParser::Get8Bits()
-{
- uint16_t retVal;
-
- if(_bitOffset != 0)
- {
- // read 16 bits
- retVal = (_data[_byteOffset] << 8)+ (_data[_byteOffset+1]) ;
- retVal = retVal >> (8-_bitOffset);
- } else
- {
- retVal = _data[_byteOffset];
- }
- _byteOffset++;
- return (uint8_t)retVal;
-}
-
-uint16_t
-BitstreamParser::Get16Bits()
-{
- uint32_t retVal;
-
- if(_bitOffset != 0)
- {
- // read 24 bits
- retVal = (_data[_byteOffset] << 16) + (_data[_byteOffset+1] << 8) + (_data[_byteOffset+2]);
- retVal = retVal >> (8-_bitOffset);
- }else
- {
- // read 16 bits
- retVal = (_data[_byteOffset] << 8) + (_data[_byteOffset+1]) ;
- }
- _byteOffset += 2;
- return (uint16_t)retVal;
-}
-
-uint32_t
-BitstreamParser::Get24Bits()
-{
- uint32_t retVal;
-
- if(_bitOffset != 0)
- {
- // read 32 bits
- retVal = (_data[_byteOffset] << 24) + (_data[_byteOffset+1] << 16) + (_data[_byteOffset+2] << 8) + (_data[_byteOffset+3]);
- retVal = retVal >> (8-_bitOffset);
- }else
- {
- // read 24 bits
- retVal = (_data[_byteOffset] << 16) + (_data[_byteOffset+1] << 8) + (_data[_byteOffset+2]) ;
- }
- _byteOffset += 3;
- return retVal & 0x00ffffff; // we need to clean up the high 8 bits
-}
-
-uint32_t
-BitstreamParser::Get32Bits()
-{
- uint32_t retVal;
-
- if(_bitOffset != 0)
- {
- // read 40 bits
- uint64_t tempVal = _data[_byteOffset];
- tempVal <<= 8;
- tempVal += _data[_byteOffset+1];
- tempVal <<= 8;
- tempVal += _data[_byteOffset+2];
- tempVal <<= 8;
- tempVal += _data[_byteOffset+3];
- tempVal <<= 8;
- tempVal += _data[_byteOffset+4];
- tempVal >>= (8-_bitOffset);
-
- retVal = uint32_t(tempVal);
- }else
- {
- // read 32 bits
- retVal = (_data[_byteOffset]<< 24) + (_data[_byteOffset+1] << 16) + (_data[_byteOffset+2] << 8) + (_data[_byteOffset+3]) ;
- }
- _byteOffset += 4;
- return retVal;
-}
-
-// Exp-Golomb codes
-/*
- with "prefix" and "suffix" bits and assignment to codeNum ranges (informative)
- Bit string form Range of codeNum
- 1 0
- 0 1 x0 1..2
- 0 0 1 x1 x0 3..6
- 0 0 0 1 x2 x1 x0 7..14
- 0 0 0 0 1 x3 x2 x1 x0 15..30
- 0 0 0 0 0 1 x4 x3 x2 x1 x0 31..62
-*/
-
-uint32_t
-BitstreamParser::GetUE()
-{
- uint32_t retVal = 0;
- uint8_t numLeadingZeros = 0;
-
- while (Get1Bit() != 1)
- {
- numLeadingZeros++;
- }
- // prefix
- retVal = (1 << numLeadingZeros) - 1;
-
- // suffix
- while (numLeadingZeros)
- {
- retVal += (Get1Bit() << --numLeadingZeros);
- }
- return retVal;
-}
-} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/H264/bitstream_parser.h b/modules/rtp_rtcp/source/H264/bitstream_parser.h
deleted file mode 100644
index 6e3d307..0000000
--- a/modules/rtp_rtcp/source/H264/bitstream_parser.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_BITSTREAM_PARSER_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_BITSTREAM_PARSER_H_
-
-#include "webrtc/typedefs.h"
-
-namespace webrtc {
-class BitstreamParser
-{
-public:
- BitstreamParser(const uint8_t* data, const uint32_t dataLength);
-
- uint8_t Get1Bit();
- uint8_t Get2Bits();
- uint8_t Get3Bits();
- uint8_t Get4Bits();
- uint8_t Get5Bits();
- uint8_t Get6Bits();
- uint8_t Get7Bits();
- uint8_t Get8Bits();
- uint16_t Get16Bits();
- uint32_t Get24Bits();
- uint32_t Get32Bits();
-
- // Exp-Golomb codes
- uint32_t GetUE();
-
-private:
- const uint8_t* _data;
- const uint32_t _dataLength;
-
- uint32_t _byteOffset;
- uint8_t _bitOffset;
-};
-} // namespace webrtc
-
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_BITSTREAM_PARSER_H_
diff --git a/modules/rtp_rtcp/source/H264/h264_information.cc b/modules/rtp_rtcp/source/H264/h264_information.cc
deleted file mode 100644
index ddb34eb..0000000
--- a/modules/rtp_rtcp/source/H264/h264_information.cc
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <string.h>
-#include "h264_information.h"
-
-//#define DEBUG_SEI_MESSAGE 1
-
-#ifdef DEBUG_SEI_MESSAGE
- #include "bitstream_parser.h"
- #include <stdio.h>
- #include <math.h>
-
- uint32_t BitRateBPS(uint16_t x )
- {
- return (x & 0x3fff) * uint32_t(pow(10.0f,(2 + (x >> 14))));
- }
-
-#endif
-
-namespace webrtc {
-H264Information::H264Information(const bool SVC)
- : _SVC(SVC)
-
-{
-}
-
-H264Information::~H264Information()
-{
-
-}
-
-void
-H264Information::Reset()
-{
- _parsedLength = 0;
- _remLength = 0;
- _length = 0;
- _info.numNALUs = 0;
- _info.numLayers = 0;
-
- memset(_info.startCodeSize, 0, sizeof(_info.startCodeSize));
- memset(_info.payloadSize, 0, sizeof(_info.payloadSize));
- memset(_info.NRI, 0, sizeof(_info.NRI));
- memset(_info.type, 0, sizeof(_info.type));
- memset(_info.accLayerSize, 0, sizeof(_info.accLayerSize));
-
- for (int32_t i = 0; i < KMaxNumberOfNALUs; i++)
- {
- _info.SVCheader[i].idr = 0;
- _info.SVCheader[i].priorityID = 0;
- _info.SVCheader[i].interLayerPred = 0;
- _info.SVCheader[i].dependencyID = 0;
- _info.SVCheader[i].qualityID = 0;
- _info.SVCheader[i].temporalID = 0;
- _info.SVCheader[i].useRefBasePic = 0;
- _info.SVCheader[i].discardable = 0;
- _info.SVCheader[i].output = 0;
-
- _info.PACSI[i].X = 0;
- _info.PACSI[i].Y = 0;
-// _info.PACSI[i].T = 0;
- _info.PACSI[i].A = 0;
- _info.PACSI[i].P = 0;
- _info.PACSI[i].C = 0;
- _info.PACSI[i].S = 0;
- _info.PACSI[i].E = 0;
- _info.PACSI[i].TL0picIDx = 0;
- _info.PACSI[i].IDRpicID = 0;
- _info.PACSI[i].DONC = 0;
- _info.PACSI[i].numSEINALUs = 0;
- _info.PACSI[i].NALlength = 5;
- }
-}
-
-/*******************************************************************************
- * int32_t GetInfo(const uint8_t* ptrEncodedBuffer,
- * const uint32_t length,
- * const H264Info*& ptrInfo);
- *
- * Gets information from an encoded stream.
- *
- * Input:
- * - ptrEncodedBuffer : Pointer to encoded stream.
- * - length : Length in bytes of encoded stream.
- *
- * Output:
- * - ptrInfo : Pointer to struct with H.264 info.
- *
- * Return value:
- * - 0 : ok
- * - (-1) : Error
- */
-int32_t
-H264Information::GetInfo(const uint8_t* ptrEncodedBuffer,
- const uint32_t length,
- const H264Info*& ptrInfo)
-{
- if (!ptrEncodedBuffer || length < 4)
- {
- return -1;
- }
-
- if (!HasInfo(length))
- {
- if (-1 == FindInfo(ptrEncodedBuffer, length))
- {
- Reset();
- return -1;
- }
- }
- ptrInfo = &_info;
- return 0;
-}
-
-RtpVideoCodecTypes
-H264Information::Type()
-{
- if(_SVC)
- {
- return RTP_H264_SVCVideo;
- }
- return RTP_H264Video;
-}
-
-
-/*******************************************************************************
- * bool HasInfo(const uint32_t length);
- *
- * Checks if information has already been stored for this encoded stream.
- *
- * Input:
- * - length : Length in bytes of encoded stream.
- *
- * Return value:
- * - true (false) : Information has (not) been stored.
- */
-
-bool
-H264Information::HasInfo(const uint32_t length)
-{
- if (!_info.numNALUs)
- {
- return false;
- }
-
- // has info, make sure current length matches info length
- if (length != _length)
- {
- Reset();
- return false;
- }
-
- return true;
-}
-
-/*******************************************************************************
- * int32_t FindInfo(const uint8_t* ptrEncodedBuffer,
- * const uint32_t length);
- *
- * Parses the encoded stream.
- *
- * Input:
- * - ptrEncodedBuffer : Pointer to encoded stream.
- * - length : Length in bytes of encoded stream.
- *
- * Return value:
- * - 0 : ok
- * - (-1) : Error
- */
-int32_t
-H264Information::FindInfo(const uint8_t* ptrEncodedBuffer, const uint32_t length)
-{
- _ptrData = ptrEncodedBuffer;
- _length = length;
- _parsedLength = 0;
- _remLength = length;
-
- do
- {
- // Get start code length
- if (FindNALUStartCodeSize() == -1)
- {
- Reset();
- return -1;
- }
-
- // Get NAL unit payload size
- int32_t foundLast = FindNALU();
- if (foundLast == -1)
- {
- Reset();
- return -1;
- }
-
- // Validate parsed length
- if (_parsedLength > _length)
- {
- Reset();
- return -1;
- }
-
- // Get NRI
- GetNRI();
-
- // Get type
- if (FindNALUType() == -1)
- {
- Reset();
- return -1;
- }
-
- // Set layer start end bit
- SetLayerSEBit(foundLast);
-
-
- // Last NAL unit found?
- if (foundLast == 1)
- {
- if (_parsedLength != _length)
- {
- Reset();
- return -1;
- }
- _info.numNALUs++;
- return SetLayerLengths();
- }
-
- // Next NAL unit
- _ptrData += (_info.startCodeSize[_info.numNALUs] + _info.payloadSize[_info.numNALUs]);
- _remLength -= (_info.startCodeSize[_info.numNALUs] + _info.payloadSize[_info.numNALUs]);
- _info.numNALUs++;
-
- // Validate memory allocation
- if (_info.numNALUs >= KMaxNumberOfNALUs)
- {
- Reset();
- return -1;
- }
- }
- while(true);
-
- return 0;
-}
-
-/*******************************************************************************
- * int32_t FindNALUStartCodeSize();
- *
- * Finds the start code length of the current NAL unit.
- *
- * Output:
- * - _info.startCodeSize[currentNALU] : Start code length in bytes of NAL unit.
- *
- * Return value:
- * - 0 : ok
- * - (-1) : Error
- */
-int32_t
-H264Information::FindNALUStartCodeSize()
-{
- // NAL unit start code. Ex. {0,0,1} or {0,0,0,1}
- for (uint32_t i = 2; i < _remLength; i++)
- {
- if (_ptrData[i] == 1 && _ptrData[i - 1] == 0 && _ptrData[i - 2] == 0)
- {
- _info.startCodeSize[_info.numNALUs] = uint8_t(i + 1);
- return 0;
- }
- }
- return -1;
-}
-
-/*******************************************************************************
- * int32_t FindNALU();
- *
- * Finds the length of the current NAL unit.
- *
- * Output:
- * - _info.payloadSize[currentNALU] : Payload length in bytes of NAL unit
- * (start code length not included).
- * - _parsedLength : Current parsed length in bytes.
- *
- * Return value:
- * - 1 : ok. Last NAL unit found.
- * - 0 : ok
- * - (-1) : Error
- */
-int32_t
-H264Information::FindNALU()
-{
- for (uint32_t i = _info.startCodeSize[_info.numNALUs]; i < _remLength - 2; i += 2)
- {
- if (_ptrData[i] == 0)
- {
- int32_t size = 0;
- if ((_ptrData[i + 1] == 1 && _ptrData[i - 1] == 0) ||
- (_ptrData[i + 2] == 1 && _ptrData[i + 1] == 0))
- {
- // Found a header
- // Reduce size by preceding zeroes
- while (_ptrData[i - 1] == 0)
- {
- i--;
- }
- size = i;
- }
- if (size > 0)
- {
- _info.payloadSize[_info.numNALUs] = size - _info.startCodeSize[_info.numNALUs];
- _parsedLength += _info.startCodeSize[_info.numNALUs] + _info.payloadSize[_info.numNALUs];
- return 0;
- }
- }
- }
- // Last NAL unit
- _info.payloadSize[_info.numNALUs] = _remLength - _info.startCodeSize[_info.numNALUs];
- if (_info.payloadSize[_info.numNALUs] > 0)
- {
- _parsedLength += _info.startCodeSize[_info.numNALUs] + _info.payloadSize[_info.numNALUs];
- return 1;
- }
- return -1;
-}
-
-/*******************************************************************************
- * void GetNRI();
- *
- * Finds the NRI of the current NAL unit.
- *
- * Output:
- * - _info.NRI[currentNALU] : NRI of NAL unit.
- *
- * Return value:
- * - 0 : ok
- * - (-1) : Error
- */
-void
-H264Information::GetNRI()
-{
- // NAL unit header (1 byte)
- // ---------------------------------
- // | start code |F|NRI| Type |
- // ---------------------------------
-
- // NRI (2 bits) - nal_ref_idc. '00' - the NAL unit is not used to reconstruct reference pictures.
- // >00 - the NAL unit is required to reconstruct reference pictures
- // in the same layer, or contains a parameter set.
-
-
- const uint8_t type = _ptrData[_info.startCodeSize[_info.numNALUs]] & 0x1f;
-
- // NALU type of 5, 7 and 8 shoud have NRI to b011
- if( type == 5 ||
- type == 7 ||
- type == 8)
- {
- _info.NRI[_info.numNALUs] = 0x60;
- }else
- {
- _info.NRI[_info.numNALUs] = _ptrData[_info.startCodeSize[_info.numNALUs]] & 0x60;
- }
-}
-
-
-/*******************************************************************************
- * int32_t FindNALUType();
- *
- * Finds the type of the current NAL unit.
- *
- * Output:
- * - _info.type[currentNALU] : Type of NAL unit
- *
- * Return value:
- * - 0 : ok
- * - (-1) : Error
- */
-int32_t
-H264Information::FindNALUType()
-{
- // NAL unit header (1 byte)
- // ---------------------------------
- // | start code |F|NRI| Type |
- // ---------------------------------
-
- _info.type[_info.numNALUs] = _ptrData[_info.startCodeSize[_info.numNALUs]] & 0x1f;
-
- if (_info.type[_info.numNALUs] == 0)
- {
- return -1;
- }
-
- // SVC NAL units, extended header
- if (ParseSVCNALUHeader() == -1)
- {
- return -1;
- }
-
- return 0;
-}
-
-/*******************************************************************************
- * int32_t ParseSVCNALUHeader();
- *
- * Finds the extended header of the current NAL unit. Included for NAL unit types 14 and 20.
- *
- * Output:
- * - _info.SVCheader[currentNALU] : SVC header of NAL unit.
- *
- * Return value:
- * - 0 : ok
- * - (-1) : Error
- */
-int32_t
-H264Information::ParseSVCNALUHeader()
-{
- if (_info.type[_info.numNALUs] == 5)
- {
- _info.SVCheader[_info.numNALUs].idr = 1;
- }
- if (_info.type[_info.numNALUs] == 6)
- {
- uint32_t seiPayloadSize;
- do
- {
- // SEI message
- seiPayloadSize = 0;
-
- uint32_t curByte = _info.startCodeSize[_info.numNALUs] + 1;
- const uint32_t seiStartOffset = curByte;
-
- uint32_t seiPayloadType = 0;
- while(_ptrData[curByte] == 0xff)
- {
- seiPayloadType += 255;
- curByte++;
- }
- seiPayloadType += _ptrData[curByte++];
-
- while(_ptrData[curByte] == 0xff)
- {
- seiPayloadSize += 255;
- curByte++;
- }
- seiPayloadSize += _ptrData[curByte++];
-
- if(_info.payloadSize[_info.numNALUs] < _info.startCodeSize[_info.numNALUs] + seiPayloadSize)
- {
- // sanity of remaining buffer
- // return 0 since no one "need" SEI messages
- assert(false);
- return 0;
- }
-
- if(seiPayloadType == 24)
- {
- // we add this to NALU 0 to be signaled in the first PACSI packet
- _info.PACSI[0].numSEINALUs = 1; // we allways add this to NALU 0 to send it in the first packet
- if(_info.PACSI[0].seiMessageLength[0] != seiPayloadSize)
- {
- _info.PACSI[0].seiMessageLength[0] = seiPayloadSize;
- delete [] _info.PACSI[0].seiMessageData[0];
- _info.PACSI[0].seiMessageData[0] = new uint8_t[seiPayloadSize];
- }
- memcpy(_info.PACSI[0].seiMessageData[0], _ptrData+seiStartOffset, seiPayloadSize);
-
- _info.PACSI[0].NALlength += seiPayloadSize + 2; // additional 2 is the length
-
-#ifdef DEBUG_SEI_MESSAGE
- const uint8_t numberOfLayers = 10;
- uint16_t avgBitrate[numberOfLayers]= {0,0,0,0,0,0,0,0,0,0};
- uint16_t maxBitrateLayer[numberOfLayers]= {0,0,0,0,0,0,0,0,0,0};
- uint16_t maxBitrateLayerRepresentation[numberOfLayers] = {0,0,0,0,0,0,0,0,0,0};
- uint16_t maxBitrareCalcWindow[numberOfLayers] = {0,0,0,0,0,0,0,0,0,0};
-
- BitstreamParser parserScalabilityInfo(_ptrData+curByte, seiPayloadSize);
-
- parserScalabilityInfo.Get1Bit(); // not used in futher parsing
- const uint8_t priority_layer_info_present = parserScalabilityInfo.Get1Bit();
- const uint8_t priority_id_setting_flag = parserScalabilityInfo.Get1Bit();
-
- uint32_t numberOfLayersMinusOne = parserScalabilityInfo.GetUE();
- for(uint32_t j = 0; j<= numberOfLayersMinusOne; j++)
- {
- printf("\nLayer ID:%d \n",parserScalabilityInfo.GetUE());
- printf("Priority ID:%d \n", parserScalabilityInfo.Get6Bits());
- printf("Discardable:%d \n", parserScalabilityInfo.Get1Bit());
-
- printf("Dependency ID:%d \n", parserScalabilityInfo.Get3Bits());
- printf("Quality ID:%d \n", parserScalabilityInfo.Get4Bits());
- printf("Temporal ID:%d \n", parserScalabilityInfo.Get3Bits());
-
- const uint8_t sub_pic_layer_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t sub_region_layer_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t iroi_division_info_present_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t profile_level_info_present_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t bitrate_info_present_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t frm_rate_info_present_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t frm_size_info_present_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t layer_dependency_info_present_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t parameter_sets_info_present_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t bitstream_restriction_info_present_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t exact_inter_layer_pred_flag = parserScalabilityInfo.Get1Bit(); // not used in futher parsing
-
- if(sub_pic_layer_flag || iroi_division_info_present_flag)
- {
- parserScalabilityInfo.Get1Bit();
- }
- const uint8_t layer_conversion_flag = parserScalabilityInfo.Get1Bit();
- const uint8_t layer_output_flag = parserScalabilityInfo.Get1Bit(); // not used in futher parsing
-
- if(profile_level_info_present_flag)
- {
- parserScalabilityInfo.Get24Bits();
- }
- if(bitrate_info_present_flag)
- {
- // this is what we want
- avgBitrate[j] = parserScalabilityInfo.Get16Bits();
- maxBitrateLayer[j] = parserScalabilityInfo.Get16Bits();
- maxBitrateLayerRepresentation[j] = parserScalabilityInfo.Get16Bits();
- maxBitrareCalcWindow[j] = parserScalabilityInfo.Get16Bits();
-
- printf("\tAvg:%d\n", BitRateBPS(avgBitrate[j]));
- printf("\tmaxBitrate:%d\n", BitRateBPS(maxBitrateLayer[j]));
- printf("\tmaxBitrate rep:%d\n", BitRateBPS(maxBitrateLayerRepresentation[j]));
- printf("\tCalcWindow:%d\n", maxBitrareCalcWindow[j]);
- }
- if(frm_rate_info_present_flag)
- {
- printf("\tFrame rate constant:%d\n", parserScalabilityInfo.Get2Bits()); // 0 = not constant, 1 = constant, 2 = maybe...
- printf("\tFrame rate avg:%d\n", parserScalabilityInfo.Get16Bits()/256);
- }
- if(frm_size_info_present_flag || iroi_division_info_present_flag)
- {
- printf("\tFrame Width:%d\n",(parserScalabilityInfo.GetUE()+1)*16);
- printf("\tFrame Height:%d\n",(parserScalabilityInfo.GetUE()+1)*16);
- }
- if(sub_region_layer_flag)
- {
- parserScalabilityInfo.GetUE();
- if(parserScalabilityInfo.Get1Bit())
- {
- parserScalabilityInfo.Get16Bits();
- parserScalabilityInfo.Get16Bits();
- parserScalabilityInfo.Get16Bits();
- parserScalabilityInfo.Get16Bits();
- }
- }
- if(sub_pic_layer_flag)
- {
- parserScalabilityInfo.GetUE();
- }
- if(iroi_division_info_present_flag)
- {
- if(parserScalabilityInfo.Get1Bit())
- {
- parserScalabilityInfo.GetUE();
- parserScalabilityInfo.GetUE();
- }else
- {
- const uint32_t numRoisMinusOne = parserScalabilityInfo.GetUE();
- for(uint32_t k = 0; k <= numRoisMinusOne; k++)
- {
- parserScalabilityInfo.GetUE();
- parserScalabilityInfo.GetUE();
- parserScalabilityInfo.GetUE();
- }
- }
- }
- if(layer_dependency_info_present_flag)
- {
- const uint32_t numDirectlyDependentLayers = parserScalabilityInfo.GetUE();
- for(uint32_t k = 0; k < numDirectlyDependentLayers; k++)
- {
- parserScalabilityInfo.GetUE();
- }
- } else
- {
- parserScalabilityInfo.GetUE();
- }
- if(parameter_sets_info_present_flag)
- {
- const uint32_t numSeqParameterSetMinusOne = parserScalabilityInfo.GetUE();
- for(uint32_t k = 0; k <= numSeqParameterSetMinusOne; k++)
- {
- parserScalabilityInfo.GetUE();
- }
- const uint32_t numSubsetSeqParameterSetMinusOne = parserScalabilityInfo.GetUE();
- for(uint32_t l = 0; l <= numSubsetSeqParameterSetMinusOne; l++)
- {
- parserScalabilityInfo.GetUE();
- }
- const uint32_t numPicParameterSetMinusOne = parserScalabilityInfo.GetUE();
- for(uint32_t m = 0; m <= numPicParameterSetMinusOne; m++)
- {
- parserScalabilityInfo.GetUE();
- }
- }else
- {
- parserScalabilityInfo.GetUE();
- }
- if(bitstream_restriction_info_present_flag)
- {
- parserScalabilityInfo.Get1Bit();
- parserScalabilityInfo.GetUE();
- parserScalabilityInfo.GetUE();
- parserScalabilityInfo.GetUE();
- parserScalabilityInfo.GetUE();
- parserScalabilityInfo.GetUE();
- parserScalabilityInfo.GetUE();
- }
- if(layer_conversion_flag)
- {
- parserScalabilityInfo.GetUE();
- for(uint32_t k = 0; k <2;k++)
- {
- if(parserScalabilityInfo.Get1Bit())
- {
- parserScalabilityInfo.Get24Bits();
- parserScalabilityInfo.Get16Bits();
- parserScalabilityInfo.Get16Bits();
- }
- }
- }
- }
- if(priority_layer_info_present)
- {
- const uint32_t prNumDidMinusOne = parserScalabilityInfo.GetUE();
- for(uint32_t k = 0; k <= prNumDidMinusOne;k++)
- {
- parserScalabilityInfo.Get3Bits();
- const uint32_t prNumMinusOne = parserScalabilityInfo.GetUE();
- for(uint32_t l = 0; l <= prNumMinusOne; l++)
- {
- parserScalabilityInfo.GetUE();
- parserScalabilityInfo.Get24Bits();
- parserScalabilityInfo.Get16Bits();
- parserScalabilityInfo.Get16Bits();
- }
- }
- }
- if(priority_id_setting_flag)
- {
- uint8_t priorityIdSettingUri;
- uint32_t priorityIdSettingUriIdx = 0;
- do
- {
- priorityIdSettingUri = parserScalabilityInfo.Get8Bits();
- } while (priorityIdSettingUri != 0);
- }
-#endif
- } else
- {
- // not seiPayloadType 24 ignore
- }
- //check if we have more SEI in NALU
- } while (_info.payloadSize[_info.numNALUs] > _info.startCodeSize[_info.numNALUs] + seiPayloadSize);
- }
-
- // Extended NAL unit header (3 bytes).
- // +---------------+---------------+---------------+
- // |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // |R|I| PRID |N| DID | QID | TID |U|D|O| RR|
- // +---------------+---------------+---------------+
-
- // R - Reserved for future extensions (MUST be 1). Receivers SHOULD ignore the value of R.
- // I - Is layer representation an IDR layer (1) or not (0).
- // PRID - Priority identifier for the NAL unit.
- // N - Specifies whether inter-layer prediction may be used for decoding the coded slice (1) or not (0).
- // DID - Indicates the inter-layer coding dependency level of a layer representation.
- // QID - Indicates the quality level of an MGS layer representation.
- // TID - Indicates the temporal level of a layer representation.
- // U - Use only reference base pictures during the inter prediction process (1) or not (0).
- // D - Discardable flag.
- // O - Output_flag. Affects the decoded picture output process as defined in Annex C of [H.264].
- // RR - Reserved_three_2bits (MUST be '11'). Receivers SHOULD ignore the value of RR.
-
- if (_info.type[_info.numNALUs] == 14 ||
- _info.type[_info.numNALUs] == 20)
- {
- uint32_t curByte = _info.startCodeSize[_info.numNALUs] + 1;
-
- if (_remLength < curByte + 3)
- {
- return -1;
- }
-
- _info.SVCheader[_info.numNALUs].idr = (_ptrData[curByte] >> 6) & 0x01;
- _info.SVCheader[_info.numNALUs].priorityID = (_ptrData[curByte++] & 0x3F);
-
- _info.SVCheader[_info.numNALUs].interLayerPred = (_ptrData[curByte] >> 7) & 0x01;
- _info.SVCheader[_info.numNALUs].dependencyID = (_ptrData[curByte] >> 4) & 0x07;
- _info.SVCheader[_info.numNALUs].qualityID = (_ptrData[curByte++] & 0x0F);
-
- _info.SVCheader[_info.numNALUs].temporalID = (_ptrData[curByte] >> 5) & 0x07;
- _info.SVCheader[_info.numNALUs].useRefBasePic = (_ptrData[curByte] >> 4) & 0x01;
- _info.SVCheader[_info.numNALUs].discardable = (_ptrData[curByte] >> 3) & 0x01;
- _info.SVCheader[_info.numNALUs].output = (_ptrData[curByte] >> 2) & 0x01;
-
- if (_info.type[_info.numNALUs] == 14)
- {
- // inform the next NALU
- memcpy(&(_info.SVCheader[_info.numNALUs+1]), &(_info.SVCheader[_info.numNALUs]), sizeof(_H264_SVC_NALUHeader));
- }
- }
- return 0;
-}
-
-
-/*******************************************************************************
- * void SetLayerSEBit();
- *
- * Sets start and end bits for the current NAL unit.
- *
- * Output:
- * - _info.PACSI[currentNALU].S : First NAL unit in a layer (S = 1).
- * - _info.PACSI[currentNALU].E : Last NAL unit in a layer (E = 1).
- *
- */
-void
-H264Information::SetLayerSEBit(int32_t foundLast)
-{
- if (_info.numNALUs == 0)
- {
- // First NAL unit
- _info.PACSI[_info.numNALUs].S = 1;
- }
-
- if (_info.numNALUs > 0)
- {
- if (_info.type[_info.numNALUs] != _info.type[_info.numNALUs-1] &&
- (_info.type[_info.numNALUs] == 20))
- {
- // First layer in scalable extension
- _info.PACSI[_info.numNALUs].S = 1;
- _info.PACSI[_info.numNALUs-1].E = 1;
- }
-
- if (_info.type[_info.numNALUs] == 20 && _info.type[_info.numNALUs-1] == 20)
- {
- if (_info.SVCheader[_info.numNALUs].temporalID != _info.SVCheader[_info.numNALUs-1].temporalID ||
- _info.SVCheader[_info.numNALUs].dependencyID != _info.SVCheader[_info.numNALUs-1].dependencyID ||
- _info.SVCheader[_info.numNALUs].qualityID != _info.SVCheader[_info.numNALUs-1].qualityID)
- {
- // New layer in scalable extension
- _info.PACSI[_info.numNALUs].S = 1;
- _info.PACSI[_info.numNALUs-1].E = 1;
- }
- }
- }
-
- if (foundLast)
- {
- // Last NAL unit
- _info.PACSI[_info.numNALUs].E = 1;
- }
-
-}
-
-/*******************************************************************************
- * int32_t SetLayerLengths();
- *
- * Sets the accumulated layer length.
- *
- * Output:
- * - _info.accLayerSize[currentLayer] : Size in bytes of layer: 0 - currentLayer.
- *
- * Return value:
- * - 0 : ok
- * - (-1) : Error
- *
- */
-int32_t
-H264Information::SetLayerLengths()
-{
- for (uint32_t curNALU = 0; curNALU < _info.numNALUs; curNALU++)
- {
- _info.accLayerSize[_info.numLayers] += _info.startCodeSize[curNALU] + _info.payloadSize[curNALU];
-
- if (_info.PACSI[curNALU].E == 1)
- {
- _info.numLayers++;
- if (curNALU == uint32_t(_info.numNALUs - 1))
- {
- break;
- }
- if (_info.numLayers >= KMaxNumberOfLayers)
- {
- Reset();
- return -1;
- }
- _info.accLayerSize[_info.numLayers] += _info.accLayerSize[_info.numLayers - 1];
- }
- }
-
- if (_info.numLayers < 1 && _info.numLayers > KMaxNumberOfLayers)
- {
- Reset();
- return -1;
- }
-
- if (_info.accLayerSize[_info.numLayers - 1] != int32_t(_length))
- {
- Reset();
- return -1;
- }
-
- return 0;
-}
-} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/H264/h264_information.h b/modules/rtp_rtcp/source/H264/h264_information.h
deleted file mode 100644
index 356a026..0000000
--- a/modules/rtp_rtcp/source/H264/h264_information.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_H264_INFORMATION_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_H264_INFORMATION_H_
-
-#include "VideoCodecInformation.h"
-#include "webrtc/typedefs.h"
-
-namespace webrtc {
-enum
-{
- KMaxNumberOfNALUs = 128,
- KMaxNumberOfSEINALUs = 2,
- KMaxNumberOfLayers = 16
-};
-
-struct H264_SVC_NALUHeader
-{
- H264_SVC_NALUHeader()
- :
- r(1),
- idr(0),
- priorityID(0),
- interLayerPred(0),
- dependencyID(0),
- qualityID(0),
- temporalID(0),
- useRefBasePic(0),
- discardable(0),
- output(0),
- rr(3),
- length(3)
- {
- }
- const uint8_t r;
- uint8_t idr;
- uint8_t priorityID;
- uint8_t interLayerPred;
- uint8_t dependencyID;
- uint8_t qualityID;
- uint8_t temporalID;
- uint8_t useRefBasePic;
- uint8_t discardable;
- uint8_t output;
- const uint8_t rr;
- const uint8_t length;
-};
-
-class H264_PACSI_NALU
-{
-public:
- H264_PACSI_NALU() :
- NALlength(5),
- type(30),
- X(0),
- Y(0),
-// T(0),
- A(0),
- P(0),
- C(0),
- S(0),
- E(0),
- TL0picIDx(0),
- IDRpicID(0),
- DONC(0),
- numSEINALUs(0)
- {
- memset(seiMessageLength, 0, sizeof(seiMessageLength));
- memset(seiMessageData, 0, sizeof(seiMessageData));
- }
- ~H264_PACSI_NALU()
- {
- for(int i = 0; i<KMaxNumberOfSEINALUs; i++)
- {
- if(seiMessageData[i])
- {
- delete [] seiMessageData[i];
- }
- }
- }
-
- uint32_t NALlength;
- const uint8_t type;
- uint8_t X;
- uint8_t Y;
-// uint8_t T;
- uint8_t A;
- uint8_t P;
- uint8_t C;
- uint8_t S;
- uint8_t E;
- uint8_t TL0picIDx;
- uint16_t IDRpicID;
- uint16_t DONC;
- uint32_t numSEINALUs;
- uint32_t seiMessageLength[KMaxNumberOfSEINALUs]; // we allow KMaxNumberOfSEINALUs SEI messages
- uint8_t* seiMessageData[KMaxNumberOfSEINALUs];
-};
-
-struct H264Info
-{
- H264Info()
- :
- numNALUs(0),
- numLayers(0)
- {
- memset(startCodeSize, 0, sizeof(startCodeSize));
- memset(payloadSize, 0, sizeof(payloadSize));
- memset(NRI, 0, sizeof(NRI));
- memset(type, 0, sizeof(type));
- memset(accLayerSize, 0, sizeof(accLayerSize));
- }
- uint16_t numNALUs;
- uint8_t numLayers;
- uint8_t startCodeSize[KMaxNumberOfNALUs];
- uint32_t payloadSize[KMaxNumberOfNALUs];
- uint8_t NRI[KMaxNumberOfNALUs];
- uint8_t type[KMaxNumberOfNALUs];
- H264_SVC_NALUHeader SVCheader[KMaxNumberOfNALUs];
- H264_PACSI_NALU PACSI[KMaxNumberOfNALUs];
- int32_t accLayerSize[KMaxNumberOfLayers];
-};
-
-
-class H264Information : public VideoCodecInformation
-{
-public:
- H264Information(const bool SVC);
- ~H264Information();
-
- virtual void Reset();
-
- virtual RtpVideoCodecTypes Type();
-
- virtual int32_t GetInfo(const uint8_t* ptrEncodedBuffer, const uint32_t length, const H264Info*& ptrInfo);
-
-
-protected:
- bool HasInfo(const uint32_t length);
- int32_t FindInfo(const uint8_t* ptrEncodedBuffer, const uint32_t length);
-
- void GetNRI();
- int32_t FindNALU();
- int32_t FindNALUStartCodeSize();
- int32_t FindNALUType();
-
- int32_t ParseSVCNALUHeader();
-
- void SetLayerSEBit(int32_t foundLast);
- int32_t SetLayerLengths();
-
-private:
- const bool _SVC;
- const uint8_t* _ptrData;
- uint32_t _length;
- uint32_t _parsedLength;
- uint32_t _remLength;
- H264Info _info;
-};
-} // namespace webrtc
-
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_H264_INFORMATION_H_
diff --git a/modules/rtp_rtcp/source/H264/rtp_sender_h264.cc b/modules/rtp_rtcp/source/H264/rtp_sender_h264.cc
deleted file mode 100644
index 6560209..0000000
--- a/modules/rtp_rtcp/source/H264/rtp_sender_h264.cc
+++ /dev/null
@@ -1,1289 +0,0 @@
-/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "rtp_sender_h264.h"
-
-#include "rtp_utility.h"
-
-namespace webrtc {
-RTPSenderH264::RTPSenderH264(RTPSenderInterface* rtpSender) :
- // H264
- _rtpSender(*rtpSender),
- _h264Mode(H264_SINGLE_NAL_MODE),
- _h264SendPPS_SPS(true),
- _h264SVCPayloadType(-1),
- _h264SVCRelaySequenceNumber(0),
- _h264SVCRelayTimeStamp(0),
- _h264SVCRelayLayerComplete(false),
-
- _useHighestSendLayer(false),
- _highestDependencyLayerOld(MAX_NUMBER_OF_TEMPORAL_ID-1),
- _highestDependencyQualityIDOld(MAX_NUMBER_OF_DEPENDENCY_QUALITY_ID-1),
- _highestDependencyLayer(0),
- _highestDependencyQualityID(0),
- _highestTemporalLayer(0)
-{
-}
-
-RTPSenderH264::~RTPSenderH264()
-{
-}
-
-int32_t
-RTPSenderH264::Init()
-{
- _h264SendPPS_SPS = true;
- _h264Mode = H264_SINGLE_NAL_MODE;
- return 0;
-}
-
-/*
- multi-session
- 3 modes supported
- NI-T timestamps
- NI-TC timestamps/CS-DON
- NI-C CS-DON
-
- Non-interleaved timestamp based mode (NI-T)
- Non-interleaved cross-session decoding order number (CS-DON) based mode (NI-C)
- Non-interleaved combined timestamp and CS-DON mode (NI-TC)
-
- NOT supported Interleaved CS-DON (I-C) mode.
-
- NI-T and NI-TC modes both use timestamps to recover the decoding
- order. In order to be able to do so, it is necessary for the RTP
- packet stream to contain data for all sampling instances of a given
- RTP session in all enhancement RTP sessions that depend on the given
- RTP session. The NI-C and I-C modes do not have this limitation,
- and use the CS-DON values as a means to explicitly indicate decoding
- order, either directly coded in PACSI NAL units, or inferred from
- them using the packetization rules. It is noted that the NI-TC mode
- offers both alternatives and it is up to the receiver to select
- which one to use.
-*/
-
-bool
-RTPSenderH264::AddH264SVCNALUHeader(const H264_SVC_NALUHeader& svc,
- uint8_t* databuffer,
- int32_t& curByte) const
-{
- // +---------------+---------------+---------------+
- // |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // |R|I| PRID |N| DID | QID | TID |U|D|O| RR|
- // +---------------+---------------+---------------+
-
- // R - Reserved for future extensions (MUST be 1). Receivers SHOULD ignore the value of R.
- // I - Is layer representation an IDR layer (1) or not (0).
- // PRID - Priority identifier for the NAL unit.
- // N - Specifies whether inter-layer prediction may be used for decoding the coded slice (1) or not (0).
- // DID - Indicates the int32_t:er-layer coding dependency level of a layer representation.
- // QID - Indicates the quality level of an MGS layer representation.
- // TID - Indicates the temporal level of a layer representation.
- // U - Use only reference base pictures during the int32_t:er prediction process (1) or not (0).
- // D - Discardable flag.
- // O - Output_flag. Affects the decoded picture output process as defined in Annex C of [H.264].
- // RR - Reserved_three_2bits (MUST be '11'). Receivers SHOULD ignore the value of RR.
-
- // Add header data
- databuffer[curByte++] = (svc.r << 7) + (svc.idr << 6) + (svc.priorityID & 0x3F);
- databuffer[curByte++] = (svc.interLayerPred << 7) + (svc.dependencyID << 4) + (svc.qualityID & 0x0F);
- databuffer[curByte++] = (svc.temporalID << 5) + (svc.useRefBasePic << 4) + (svc.discardable << 3) +
- (svc.output << 2) + (svc.rr & 0x03);
- return true;
-}
-
-int32_t
-RTPSenderH264::AddH264PACSINALU(const bool firstPacketInNALU,
- const bool lastPacketInNALU,
- const H264_PACSI_NALU& pacsi,
- const H264_SVC_NALUHeader& svc,
- const uint16_t DONC,
- uint8_t* databuffer,
- int32_t& curByte) const
-{
- // 0 1 2 3
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // |F|NRI|Type(30) | SVC NAL unit header |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // |X|Y|T|A|P|C|S|E| TL0PICIDX (o.)| IDRPICID (o.) |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | DONC (o.) | NAL unit size 1 |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | |
- // | SEI NAL unit 1 |
- // | |
- // | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | | NAL unit size 2 | |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- // | |
- // | SEI NAL unit 2 |
- // | +-+-+-+-+-+-+-+-+-+-+
- // | |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-
- // If present, MUST be first NAL unit in aggregation packet + there MUST be at least
- // one additional unit in the same packet! The RTPHeader and payload header are set as if the 2nd NAL unit
- // (first non-PACSI NAL unit) is encapsulated in the same packet.
- // contains scalability info common for all remaining NAL units.
-
- // todo add API to configure this required for multisession
- const bool addDONC = false;
-
- if (svc.length == 0 || pacsi.NALlength == 0)
- {
- return 0;
- }
-
- int32_t startByte = curByte;
-
- // NAL unit header
- databuffer[curByte++] = 30; // NRI will be added later
-
- // Extended SVC header
- AddH264SVCNALUHeader(svc, databuffer, curByte);
-
- // Flags
- databuffer[curByte++] = (pacsi.X << 7) +
- (pacsi.Y << 6) +
- (addDONC << 5) +
- (pacsi.A << 4) +
- (pacsi.P << 3) +
- (pacsi.C << 2) +
- firstPacketInNALU?(pacsi.S << 1):0 +
- lastPacketInNALU?(pacsi.E):0;
-
- // Optional fields
- if (pacsi.Y)
- {
- databuffer[curByte++] = pacsi.TL0picIDx;
- databuffer[curByte++] = (uint8_t)(pacsi.IDRpicID >> 8);
- databuffer[curByte++] = (uint8_t)(pacsi.IDRpicID);
- }
- // Decoding order number
- if (addDONC) // pacsi.T
- {
- databuffer[curByte++] = (uint8_t)(DONC >> 8);
- databuffer[curByte++] = (uint8_t)(DONC);
- }
-
- // SEI NALU
- if(firstPacketInNALU) // IMPROVEMENT duplicate it to make sure it arrives...
- {
- // we only set this for NALU 0 to make sure we send it only once per frame
- for (uint32_t i = 0; i < pacsi.numSEINALUs; i++)
- {
- // NALU size
- databuffer[curByte++] = (uint8_t)(pacsi.seiMessageLength[i] >> 8);
- databuffer[curByte++] = (uint8_t)(pacsi.seiMessageLength[i]);
-
- // NALU data
- memcpy(databuffer + curByte, pacsi.seiMessageData[i], pacsi.seiMessageLength[i]);
- curByte += pacsi.seiMessageLength[i];
- }
- }
- return curByte - startByte;
-}
-
-int32_t
-RTPSenderH264::SetH264RelaySequenceNumber(const uint16_t seqNum)
-{
- _h264SVCRelaySequenceNumber = seqNum;
- return 0;
-}
-
-int32_t
-RTPSenderH264::SetH264RelayCompleteLayer(const bool complete)
-{
- _h264SVCRelayLayerComplete = complete;
- return 0;
-}
-
-/*
- 12 Filler data
-
- The only restriction of filler data NAL units within an
- access unit is that they shall not precede the first VCL
- NAL unit with the same access unit.
-*/
-int32_t
-RTPSenderH264::SendH264FillerData(const WebRtcRTPHeader* rtpHeader,
- const uint16_t bytesToSend,
- const uint32_t ssrc)
-{
- uint16_t fillerLength = bytesToSend - 12 - 1;
-
- if (fillerLength > WEBRTC_IP_PACKET_SIZE - 12 - 1)
- {
- return 0;
- }
-
- if (fillerLength == 0)
- {
- // do not send an empty packet, will not reach JB
- fillerLength = 1;
- }
-
- // send codec valid data, H.264 has defined data which is binary 1111111
- uint8_t dataBuffer[WEBRTC_IP_PACKET_SIZE];
-
- dataBuffer[0] = static_cast<uint8_t>(0x80); // version 2
- dataBuffer[1] = rtpHeader->header.payloadType;
- RtpUtility::AssignUWord16ToBuffer(
- dataBuffer + 2,
- _rtpSender.IncrementSequenceNumber()); // get the current
- // SequenceNumber and add by 1
- // after returning
- RtpUtility::AssignUWord32ToBuffer(dataBuffer + 4,
- rtpHeader->header.timestamp);
- RtpUtility::AssignUWord32ToBuffer(dataBuffer + 8, rtpHeader->header.ssrc);
-
- // set filler NALU type
- dataBuffer[12] = 12; // NRI field = 0, type 12
-
- // fill with 0xff
- memset(dataBuffer + 12 + 1, 0xff, fillerLength);
-
- return _rtpSender.SendToNetwork(dataBuffer,
- fillerLength,
- 12 + 1);
-}
-
-int32_t
-RTPSenderH264::SendH264FillerData(const uint32_t captureTimestamp,
- const uint8_t payloadType,
- const uint32_t bytes
- )
-{
-
- const uint16_t rtpHeaderLength = _rtpSender.RTPHeaderLength();
- uint16_t maxLength = _rtpSender.MaxPayloadLength() - FECPacketOverhead() - _rtpSender.RTPHeaderLength();
-
- int32_t bytesToSend=bytes;
- uint16_t fillerLength=0;
-
- uint8_t dataBuffer[WEBRTC_IP_PACKET_SIZE];
-
- while(bytesToSend>0)
- {
- fillerLength=maxLength;
- if(fillerLength<maxLength)
- {
- fillerLength = (uint16_t) bytesToSend;
- }
-
- bytesToSend-=fillerLength;
-
- if (fillerLength > WEBRTC_IP_PACKET_SIZE - 12 - 1)
- {
- return 0;
- }
-
- if (fillerLength == 0)
- {
- // do not send an empty packet, will not reach JB
- fillerLength = 1;
- }
-
- // send paded data
- // correct seq num, time stamp and payloadtype
- _rtpSender.BuildRTPheader(dataBuffer, payloadType, false,captureTimestamp, true, true);
-
- // set filler NALU type
- dataBuffer[12] = 12; // NRI field = 0, type 12
-
- // send codec valid data, H.264 has defined data which is binary 1111111
- // fill with 0xff
- memset(dataBuffer + 12 + 1, 0xff, fillerLength-1);
-
- if( _rtpSender.SendToNetwork(dataBuffer,
- fillerLength,
- 12)<0)
- {
-
- return -1;;
- }
- }
- return 0;
-}
-
-int32_t
-RTPSenderH264::SendH264SVCRelayPacket(const WebRtcRTPHeader* rtpHeader,
- const uint8_t* incomingRTPPacket,
- const uint16_t incomingRTPPacketSize,
- const uint32_t ssrc,
- const bool higestLayer)
-{
- if (rtpHeader->header.sequenceNumber != (uint16_t)(_h264SVCRelaySequenceNumber + 1))
- {
- // not continous, signal loss
- _rtpSender.IncrementSequenceNumber();
- }
- _h264SVCRelaySequenceNumber = rtpHeader->header.sequenceNumber;
-
-
- if (rtpHeader->header.timestamp != _h264SVCRelayTimeStamp)
- {
- // new frame
- _h264SVCRelayLayerComplete = false;
- }
-
- if (rtpHeader->header.timestamp == _h264SVCRelayTimeStamp &&
- _h264SVCRelayLayerComplete)
- {
- // sanity, end of layer already sent
- // Could happened for fragmented packet with missing PACSI info (PACSI packet reorded and received after packet it belongs to)
- // fragmented packet has no layer info set (default info 0)
- return 0;
- }
- _h264SVCRelayTimeStamp = rtpHeader->header.timestamp;
-
- // re-packetize H.264-SVC packets
- // we keep the timestap unchanged
- // make a copy and only change the SSRC and seqNum
-
- uint8_t dataBuffer[WEBRTC_IP_PACKET_SIZE];
- memcpy(dataBuffer, incomingRTPPacket, incomingRTPPacketSize);
-
- // _sequenceNumber initiated in Init()
- // _ssrc initiated in constructor
-
- // re-write payload type
- if(_h264SVCPayloadType != -1)
- {
- dataBuffer[1] &= kRtpMarkerBitMask;
- dataBuffer[1] += _h264SVCPayloadType;
- }
-
- // _sequenceNumber will not work for re-ordering by NACK from original sender
- // engine responsible for this
- RtpUtility::AssignUWord16ToBuffer(
- dataBuffer + 2,
- _rtpSender.IncrementSequenceNumber()); // get the current
- // SequenceNumber and add by 1
- // after returning
- // RtpUtility::AssignUWord32ToBuffer(dataBuffer+8, ssrc);
-
- // how do we know it's the last relayed packet in a frame?
- // 1) packets arrive in order, the engine manages that
- // 2) highest layer that we relay
- // 3) the end bit is set for the highest layer
-
- if(higestLayer && rtpHeader->type.Video.codecHeader.H264.relayE)
- {
- // set marker bit
- dataBuffer[1] |= kRtpMarkerBitMask;
-
- // set relayed layer as complete
- _h264SVCRelayLayerComplete = true;
- }
- return _rtpSender.SendToNetwork(dataBuffer,
- incomingRTPPacketSize - rtpHeader->header.headerLength,
- rtpHeader->header.headerLength);
-}
-
-int32_t
-RTPSenderH264::SendH264_STAP_A(const FrameType frameType,
- const H264Info* ptrH264Info,
- uint16_t &idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- bool& switchToFUA,
- int32_t &payloadBytesToSend,
- const uint8_t*& data,
- const uint16_t rtpHeaderLength)
-{
- const int32_t H264_NALU_LENGTH = 2;
-
- uint16_t h264HeaderLength = 1; // normal header length
- uint16_t maxPayloadLengthSTAP_A = _rtpSender.MaxPayloadLength() -
- FECPacketOverhead() - rtpHeaderLength -
- h264HeaderLength - H264_NALU_LENGTH;
-
- int32_t dataOffset = rtpHeaderLength + h264HeaderLength;
- uint8_t NRI = 0;
- uint16_t payloadBytesInPacket = 0;
- uint8_t dataBuffer[WEBRTC_IP_PACKET_SIZE];
-
- if (ptrH264Info->payloadSize[idxNALU] > maxPayloadLengthSTAP_A)
- {
- // we need to fragment NAL switch to mode FU-A
- switchToFUA = true;
- } else
- {
- // combine as many NAL units in every IP packet
- do
- {
- if(!_h264SendPPS_SPS)
- {
- // don't send NALU of type 7 and 8 SPS and PPS
- if(ptrH264Info->type[idxNALU] == 7 || ptrH264Info->type[idxNALU] == 8)
- {
- payloadBytesToSend -= ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- data += ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- idxNALU++;
- continue;
- }
- }
- if(ptrH264Info->payloadSize[idxNALU] + payloadBytesInPacket <= maxPayloadLengthSTAP_A)
- {
- if(ptrH264Info->NRI[idxNALU] > NRI)
- {
- NRI = ptrH264Info->NRI[idxNALU];
- }
- // put NAL size into packet
- dataBuffer[dataOffset] = (uint8_t)(ptrH264Info->payloadSize[idxNALU] >> 8);
- dataOffset++;
- dataBuffer[dataOffset] = (uint8_t)(ptrH264Info->payloadSize[idxNALU] & 0xff);
- dataOffset++;
- // Put payload in packet
- memcpy(&dataBuffer[dataOffset], &data[ptrH264Info->startCodeSize[idxNALU]], ptrH264Info->payloadSize[idxNALU]);
- dataOffset += ptrH264Info->payloadSize[idxNALU];
- data += ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- payloadBytesInPacket += (uint16_t)(ptrH264Info->payloadSize[idxNALU] + H264_NALU_LENGTH);
- payloadBytesToSend -= ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- } else
- {
- // we don't fitt the next NALU in this packet
- break;
- }
- idxNALU++;
- }while(payloadBytesToSend);
- }
-
- // sanity
- // don't send empty packets
- if (payloadBytesInPacket)
- {
- // add RTP header
- _rtpSender.BuildRTPheader(dataBuffer, payloadType, (payloadBytesToSend==0)?true:false, captureTimeStamp);
- dataBuffer[rtpHeaderLength] = 24 + NRI; // STAP-A == 24
- uint16_t payloadLength = payloadBytesInPacket + h264HeaderLength;
-
- if(-1 == SendVideoPacket(frameType, dataBuffer, payloadLength, rtpHeaderLength))
- {
- return -1;
- }
- }
- return 0;
-} // end STAP-A
-
-// STAP-A for H.264 SVC
-int32_t
-RTPSenderH264::SendH264_STAP_A_PACSI(const FrameType frameType,
- const H264Info* ptrH264Info,
- uint16_t &idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- bool& switchToFUA,
- int32_t &payloadBytesToSend,
- const uint8_t*& data,
- const uint16_t rtpHeaderLength,
- uint16_t& decodingOrderNumber)
-{
- const int32_t H264_NALU_LENGTH = 2;
-
- uint16_t h264HeaderLength = 1; // normal header length
- uint16_t maxPayloadLengthSTAP_A = _rtpSender.MaxPayloadLength() - FECPacketOverhead() - rtpHeaderLength - h264HeaderLength - H264_NALU_LENGTH;
- int32_t dataOffset = rtpHeaderLength + h264HeaderLength;
- uint8_t NRI = 0;
- uint16_t payloadBytesInPacket = 0;
- uint8_t dataBuffer[WEBRTC_IP_PACKET_SIZE];
- bool firstNALUNotIDR = true; //delta
-
- // Put PACSI NAL unit into packet
- int32_t lengthPACSI = 0;
- uint32_t PACSI_NALlength = ptrH264Info->PACSI[idxNALU].NALlength;
- if (PACSI_NALlength > maxPayloadLengthSTAP_A)
- {
- return -1;
- }
- dataBuffer[dataOffset++] = (uint8_t)(PACSI_NALlength >> 8);
- dataBuffer[dataOffset++] = (uint8_t)(PACSI_NALlength & 0xff);
-
- // end bit will be updated later, since another NALU in this packet might be the last
- int32_t lengthPASCINALU = AddH264PACSINALU(true,
- false,
- ptrH264Info->PACSI[idxNALU],
- ptrH264Info->SVCheader[idxNALU],
- decodingOrderNumber,
- dataBuffer,
- dataOffset);
- if (lengthPASCINALU <= 0)
- {
- return -1;
- }
- decodingOrderNumber++;
-
- lengthPACSI = H264_NALU_LENGTH + lengthPASCINALU;
- maxPayloadLengthSTAP_A -= (uint16_t)lengthPACSI;
- if (ptrH264Info->payloadSize[idxNALU] > maxPayloadLengthSTAP_A)
- {
- // we need to fragment NAL switch to mode FU-A
- switchToFUA = true;
- return 0;
- }
- if(!ptrH264Info->SVCheader[idxNALU].idr)
- {
- firstNALUNotIDR = true;
- }
-
- uint32_t layer = (ptrH264Info->SVCheader[idxNALU].dependencyID << 16)+
- (ptrH264Info->SVCheader[idxNALU].qualityID << 8) +
- ptrH264Info->SVCheader[idxNALU].temporalID;
-
- {
- // combine as many NAL units in every IP packet, with the same priorityID
- // Improvement we could allow several very small MGS NALU from different layers to be sent in one packet
-
- do
- {
- if(!_h264SendPPS_SPS)
- {
- // Don't send NALU of type 7 and 8 SPS and PPS,
- // they could be signaled outofband
- if(ptrH264Info->type[idxNALU] == 7 || ptrH264Info->type[idxNALU] == 8)
- {
- payloadBytesToSend -= ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- data += ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- idxNALU++;
- continue;
- }
- }
- // don't send NALU type 6 (SEI message) not allowed when we send it in PACSI
- if(ptrH264Info->type[idxNALU] == 6)
- {
- // SEI NALU Don't send, not allowed when we send it in PACSI
- payloadBytesToSend -= ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- data += ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- idxNALU++;
- continue;
- }
-
- const uint32_t layerNALU = (ptrH264Info->SVCheader[idxNALU].dependencyID << 16)+
- (ptrH264Info->SVCheader[idxNALU].qualityID << 8) +
- ptrH264Info->SVCheader[idxNALU].temporalID;
-
- // we need to break on a new layer
- if( ptrH264Info->payloadSize[idxNALU] + payloadBytesInPacket <= maxPayloadLengthSTAP_A &&
- layerNALU == layer)
- {
- if(ptrH264Info->NRI[idxNALU] > NRI)
- {
- NRI = ptrH264Info->NRI[idxNALU];
- }
- // put NAL size into packet
- dataBuffer[dataOffset] = (uint8_t)(ptrH264Info->payloadSize[idxNALU] >> 8);
- dataOffset++;
- dataBuffer[dataOffset] = (uint8_t)(ptrH264Info->payloadSize[idxNALU] & 0xff);
- dataOffset++;
- // Put payload in packet
- memcpy(&dataBuffer[dataOffset], &data[ptrH264Info->startCodeSize[idxNALU]], ptrH264Info->payloadSize[idxNALU]);
- dataOffset += ptrH264Info->payloadSize[idxNALU];
- data += ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- payloadBytesInPacket += (uint16_t)(ptrH264Info->payloadSize[idxNALU] + H264_NALU_LENGTH);
- payloadBytesToSend -= ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- } else
- {
- // we don't fitt the next NALU in this packet or,
- // it's the next layer
-
- // check if we should send this NALU
- // based on the layer
-
- if(_useHighestSendLayer && layerNALU != layer)
- {
- // we don't send this NALU due to it's a new layer
- // check if we should send the next or if this is the last
- const uint8_t dependencyQualityID = (ptrH264Info->SVCheader[idxNALU].dependencyID << 4) + ptrH264Info->SVCheader[idxNALU].qualityID;
-
- bool highestLayer;
- if(SendH264SVCLayer(frameType,
- ptrH264Info->SVCheader[idxNALU].temporalID,
- dependencyQualityID,
- highestLayer) == false)
- {
- // will trigger markerbit and stop sending this frame
- payloadBytesToSend = 0;
- }
- }
- break;
- }
- idxNALU++;
-
- }while(payloadBytesToSend);
- }
-
- // sanity, don't send empty packets
- if (payloadBytesInPacket)
- {
- // add RTP header
- _rtpSender.BuildRTPheader(dataBuffer, payloadType, (payloadBytesToSend==0)?true:false, captureTimeStamp);
-
- dataBuffer[rtpHeaderLength] = 24 + NRI; // STAP-A == 24
-
- // NRI for PACSI
- dataBuffer[rtpHeaderLength + H264_NALU_LENGTH + 1] &= 0x1f; // zero out NRI field
- dataBuffer[rtpHeaderLength + H264_NALU_LENGTH + 1] |= NRI;
-
- if(ptrH264Info->PACSI[idxNALU-1].E)
- {
- // update end bit
- dataBuffer[rtpHeaderLength + H264_NALU_LENGTH + 5] |= 0x01;
- }
- if(firstNALUNotIDR)
- {
- // we have to check if any of the NALU in this packet is an IDR NALU
- bool setIBit = false;
- for(int i = 0; i < idxNALU; i++)
- {
- if(ptrH264Info->SVCheader[i].idr)
- {
- setIBit = true;
- break;
- }
- }
- if(setIBit)
- {
- // update I bit
- dataBuffer[rtpHeaderLength + H264_NALU_LENGTH + 2] |= 0x40;
- }
- }
- const uint16_t payloadLength = payloadBytesInPacket + h264HeaderLength + (uint16_t)lengthPACSI;
- if(-1 == SendVideoPacket(frameType,
- dataBuffer,
- payloadLength,
- rtpHeaderLength,
- layer==0))
- {
- return -1;
- }
- }
- return 0;
-} // end STAP-A
-
-int32_t
-RTPSenderH264::SendH264_FU_A(const FrameType frameType,
- const H264Info* ptrH264Info,
- uint16_t &idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- int32_t &payloadBytesToSend,
- const uint8_t*& data,
- const uint16_t rtpHeaderLength,
- uint16_t& decodingOrderNumber,
- const bool sendSVCPACSI)
-{
-
- // FUA for the rest of the frame
- uint16_t maxPayloadLength = _rtpSender.MaxPayloadLength() - FECPacketOverhead() - rtpHeaderLength;
- uint8_t dataBuffer[WEBRTC_IP_PACKET_SIZE];
- uint32_t payloadBytesRemainingInNALU = ptrH264Info->payloadSize[idxNALU];
-
- bool isBaseLayer=false;
-
- if(payloadBytesRemainingInNALU > maxPayloadLength)
- {
- // we need to fragment NALU
- const uint16_t H264_FUA_LENGTH = 2; // FU-a H.264 header is 2 bytes
-
- if(sendSVCPACSI)
- {
- SendH264_SinglePACSI(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- true,
- false);
-
- uint32_t layer = (ptrH264Info->SVCheader[idxNALU].dependencyID << 16)+
- (ptrH264Info->SVCheader[idxNALU].qualityID << 8) +
- ptrH264Info->SVCheader[idxNALU].temporalID;
- isBaseLayer=(layer==0);
- }
-
- // First packet
- _rtpSender.BuildRTPheader(dataBuffer,payloadType, false, captureTimeStamp);
-
- uint16_t maxPayloadLengthFU_A = maxPayloadLength - H264_FUA_LENGTH ;
- uint8_t fuaIndc = 28 + ptrH264Info->NRI[idxNALU];
- dataBuffer[rtpHeaderLength] = fuaIndc; // FU-A indicator
- dataBuffer[rtpHeaderLength+1] = (uint8_t)(ptrH264Info->type[idxNALU] + 0x80)/*start*/; // FU-A header
-
- memcpy(&dataBuffer[rtpHeaderLength + H264_FUA_LENGTH], &data[ptrH264Info->startCodeSize[idxNALU]+1], maxPayloadLengthFU_A);
- uint16_t payloadLength = maxPayloadLengthFU_A + H264_FUA_LENGTH;
- if(-1 == SendVideoPacket(frameType, dataBuffer, payloadLength, rtpHeaderLength, isBaseLayer))
- {
- return -1;
- }
-
- //+1 is from the type that is coded into the FU-a header
- data += maxPayloadLengthFU_A + 1 + ptrH264Info->startCodeSize[idxNALU]; // inc data ptr
- payloadBytesToSend -= maxPayloadLengthFU_A+1+ptrH264Info->startCodeSize[idxNALU];
- payloadBytesRemainingInNALU -= maxPayloadLengthFU_A+1;
-
- // all non first/last packets
- while(payloadBytesRemainingInNALU > maxPayloadLengthFU_A)
- {
- if(sendSVCPACSI)
- {
- SendH264_SinglePACSI(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- false,
- false);
- }
-
- // prepare next header
- _rtpSender.BuildRTPheader(dataBuffer, payloadType, false, captureTimeStamp);
-
- dataBuffer[rtpHeaderLength] = (uint8_t)fuaIndc; // FU-A indicator
- dataBuffer[rtpHeaderLength+1] = ptrH264Info->type[idxNALU]; // FU-A header
-
- memcpy(&dataBuffer[rtpHeaderLength+H264_FUA_LENGTH], data, maxPayloadLengthFU_A);
- payloadLength = maxPayloadLengthFU_A + H264_FUA_LENGTH;
-
- if(-1 == SendVideoPacket(frameType, dataBuffer, payloadLength, rtpHeaderLength,isBaseLayer))
- {
- return -1;
- }
- data += maxPayloadLengthFU_A; // inc data ptr
- payloadBytesToSend -= maxPayloadLengthFU_A;
- payloadBytesRemainingInNALU -= maxPayloadLengthFU_A;
- dataBuffer[rtpHeaderLength] = fuaIndc; // FU-A indicator
- dataBuffer[rtpHeaderLength+1] = ptrH264Info->type[idxNALU]; // FU-A header
- }
- if(sendSVCPACSI)
- {
- SendH264_SinglePACSI(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- false,
- true); // last packet in NALU
-
- if(_useHighestSendLayer && idxNALU+1 < ptrH264Info->numNALUs)
- {
- // not last NALU in frame
- // check if it's the the next layer should not be sent
-
- // check if we should send the next or if this is the last
- const uint8_t dependencyQualityID = (ptrH264Info->SVCheader[idxNALU+1].dependencyID << 4) +
- ptrH264Info->SVCheader[idxNALU+1].qualityID;
-
- bool highestLayer;
- if(SendH264SVCLayer(frameType,
- ptrH264Info->SVCheader[idxNALU+1].temporalID,
- dependencyQualityID,
- highestLayer) == false)
- {
- // will trigger markerbit and stop sending this frame
- payloadBytesToSend = payloadBytesRemainingInNALU;
- }
- }
- }
- // last packet in NALU
- _rtpSender.BuildRTPheader(dataBuffer, payloadType,(payloadBytesToSend == (int32_t)payloadBytesRemainingInNALU)?true:false, captureTimeStamp);
- dataBuffer[rtpHeaderLength+1] = ptrH264Info->type[idxNALU] + 0x40/*stop*/; // FU-A header
-
- memcpy(&dataBuffer[rtpHeaderLength+H264_FUA_LENGTH], data, payloadBytesRemainingInNALU);
- payloadLength = (uint16_t)payloadBytesRemainingInNALU + H264_FUA_LENGTH;
- payloadBytesToSend -= payloadBytesRemainingInNALU;
- if(payloadBytesToSend != 0)
- {
- data += payloadBytesRemainingInNALU; // inc data ptr
- }
- idxNALU++;
- if(-1 == SendVideoPacket(frameType, dataBuffer, payloadLength, rtpHeaderLength,isBaseLayer))
- {
- return -1;
- }
- } else
- {
- // send NAL unit in singel mode
- return SendH264_SingleMode(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- payloadBytesToSend,
- data,
- rtpHeaderLength,
- sendSVCPACSI);
- }
- // end FU-a
- return 0;
-}
-
-int32_t
-RTPSenderH264::SendH264_SingleMode(const FrameType frameType,
- const H264Info* ptrH264Info,
- uint16_t &idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- int32_t &payloadBytesToSend,
- const uint8_t*& data,
- const uint16_t rtpHeaderLength,
- uint16_t& decodingOrderNumber,
- const bool sendSVCPACSI)
-{
- // no H.264 header lenght in single mode
- // we use WEBRTC_IP_PACKET_SIZE instead of the configured MTU since it's better to send fragmented UDP than not to send
- const uint16_t maxPayloadLength = WEBRTC_IP_PACKET_SIZE - _rtpSender.PacketOverHead() - FECPacketOverhead() - rtpHeaderLength;
- uint8_t dataBuffer[WEBRTC_IP_PACKET_SIZE];
- bool isBaseLayer=false;
-
- if(ptrH264Info->payloadSize[idxNALU] > maxPayloadLength)
- {
- return -3;
- }
- if(!_h264SendPPS_SPS)
- {
- // don't send NALU of type 7 and 8 SPS and PPS
- if(ptrH264Info->type[idxNALU] == 7 || ptrH264Info->type[idxNALU] == 8)
- {
- payloadBytesToSend -= ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- data += ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- idxNALU++;
- return 0;
- }
- }
- if(sendSVCPACSI)
- {
- SendH264_SinglePACSI(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- true,
- true);
-
- uint32_t layer = (ptrH264Info->SVCheader[idxNALU].dependencyID << 16)+
- (ptrH264Info->SVCheader[idxNALU].qualityID << 8) +
- ptrH264Info->SVCheader[idxNALU].temporalID;
- isBaseLayer=(layer==0);
- }
-
- // Put payload in packet
- memcpy(&dataBuffer[rtpHeaderLength], &data[ptrH264Info->startCodeSize[idxNALU]], ptrH264Info->payloadSize[idxNALU]);
-
- uint16_t payloadBytesInPacket = (uint16_t)ptrH264Info->payloadSize[idxNALU];
- payloadBytesToSend -= ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU]; // left to send
-
- //
- _rtpSender.BuildRTPheader(dataBuffer,payloadType,(payloadBytesToSend ==0)?true:false, captureTimeStamp);
-
- dataBuffer[rtpHeaderLength] &= 0x1f; // zero out NRI field
- dataBuffer[rtpHeaderLength] |= ptrH264Info->NRI[idxNALU]; // nri
- if(payloadBytesToSend > 0)
- {
- data += ptrH264Info->payloadSize[idxNALU] + ptrH264Info->startCodeSize[idxNALU];
- }
- idxNALU++;
- if(-1 == SendVideoPacket(frameType, dataBuffer, payloadBytesInPacket, rtpHeaderLength,isBaseLayer))
- {
- return -1;
- }
- return 0;
-}
-
-int32_t
-RTPSenderH264::SendH264_SinglePACSI(const FrameType frameType,
- const H264Info* ptrH264Info,
- const uint16_t idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- const bool firstPacketInNALU,
- const bool lastPacketInNALU);
-{
- // Send PACSI in single mode
- uint8_t dataBuffer[WEBRTC_IP_PACKET_SIZE];
- uint16_t rtpHeaderLength = (uint16_t)_rtpSender.BuildRTPheader(dataBuffer, payloadType,false, captureTimeStamp);
- int32_t dataOffset = rtpHeaderLength;
-
- int32_t lengthPASCINALU = AddH264PACSINALU(firstPacketInNALU,
- lastPacketInNALU,
- ptrH264Info->PACSI[idxNALU],
- ptrH264Info->SVCheader[idxNALU],
- decodingOrderNumber,
- dataBuffer,
- dataOffset);
-
- if (lengthPASCINALU <= 0)
- {
- return -1;
- }
- decodingOrderNumber++;
-
- uint16_t payloadBytesInPacket = (uint16_t)lengthPASCINALU;
-
- // Set payload header (first payload byte co-serves as the payload header)
- dataBuffer[rtpHeaderLength] &= 0x1f; // zero out NRI field
- dataBuffer[rtpHeaderLength] |= ptrH264Info->NRI[idxNALU]; // nri
-
- const uint32_t layer = (ptrH264Info->SVCheader[idxNALU].dependencyID << 16)+
- (ptrH264Info->SVCheader[idxNALU].qualityID << 8) +
- ptrH264Info->SVCheader[idxNALU].temporalID;
-
- if (-1 == SendVideoPacket(frameType, dataBuffer, payloadBytesInPacket, rtpHeaderLength,layer==0))
- {
- return -1;
- }
- return 0;
-}
-
-
-
-
-int32_t
-RTPSenderH264::SendH264SVC(const FrameType frameType,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- const uint8_t* payloadData,
- const uint32_t payloadSize,
- H264Information& h264Information,
- uint16_t& decodingOrderNumber)
-{
- int32_t payloadBytesToSend = payloadSize;
- const uint16_t rtpHeaderLength = _rtpSender.RTPHeaderLength();
-
- const H264Info* ptrH264Info = NULL;
- if (h264Information.GetInfo(payloadData,payloadSize, ptrH264Info) == -1)
- {
- return -1;
- }
- if(_useHighestSendLayer)
- {
- // we need to check if we should drop the frame
- // it could be a temporal layer (aka a temporal frame)
- const uint8_t dependencyQualityID = (ptrH264Info->SVCheader[0].dependencyID << 4) + ptrH264Info->SVCheader[0].qualityID;
-
- bool dummyHighestLayer;
- if(SendH264SVCLayer(frameType,
- ptrH264Info->SVCheader[0].temporalID,
- dependencyQualityID,
- dummyHighestLayer) == false)
- {
- // skip send this frame
- return 0;
- }
- }
-
- uint16_t idxNALU = 0;
- while (payloadBytesToSend > 0)
- {
- bool switchToFUA = false;
- if (SendH264_STAP_A_PACSI(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- switchToFUA,
- payloadBytesToSend,
- payloadData,
- rtpHeaderLength,
- decodingOrderNumber) != 0)
- {
- return -1;
- }
- if(switchToFUA)
- {
- // FU_A for this NALU
- if (SendH264_FU_A(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- payloadBytesToSend,
- payloadData,
- rtpHeaderLength,
- true) != 0)
- {
- return -1;
- }
- }
- }
- return 0;
-}
-
-int32_t
-RTPSenderH264::SetH264PacketizationMode(const H264PacketizationMode mode)
-{
- _h264Mode = mode;
- return 0;
-}
-
-int32_t
-RTPSenderH264::SetH264SendModeNALU_PPS_SPS(const bool dontSend)
-{
- _h264SendPPS_SPS = !dontSend;
- return 0;
-}
-
-bool
-RTPSenderH264::SendH264SVCLayer(const FrameType frameType,
- const uint8_t temporalID,
- const uint8_t dependencyQualityID,
- bool& higestLayer)
-{
- uint8_t dependencyID = dependencyQualityID >> 4;
-
- // keyframe required to switch between dependency layers not quality and temporal
- if( _highestDependencyLayer != _highestDependencyLayerOld)
- {
- // we want to switch dependency layer
- if(frameType == kVideoFrameKey)
- {
- // key frame we can change layer if it's correct layer
- if(_highestDependencyLayer > _highestDependencyLayerOld)
- {
- // we want to switch up
- // does this packet belong to a new layer?
-
- if( dependencyID > _highestDependencyLayerOld &&
- dependencyID <= _highestDependencyLayer)
- {
- _highestDependencyLayerOld = dependencyID;
- _highestDependencyQualityIDOld = _highestDependencyQualityID;
-
- if( dependencyID == _highestDependencyLayer &&
- dependencyQualityID == _highestDependencyQualityID)
- {
- higestLayer = true;
- }
- // relay
- return true;
- }
- }
- if(_highestDependencyLayer < _highestDependencyLayerOld)
- {
- // we want to switch down
- // does this packet belong to a low layer?
- if( dependencyID <= _highestDependencyLayer)
- {
- _highestDependencyLayerOld = dependencyID;
- _highestDependencyQualityIDOld = _highestDependencyQualityID;
- if( dependencyID == _highestDependencyLayer &&
- dependencyQualityID == _highestDependencyQualityID)
- {
- higestLayer = true;
- }
- // relay
- return true;
- }
- }
- } else
- {
- // Delta frame and we are waiting to switch dependency layer
- if(_highestDependencyLayer > _highestDependencyLayerOld)
- {
- // we want to switch up to a higher dependency layer
- // use old setting until we get a key-frame
-
- // filter based on old dependency
- // we could have allowed to add a MGS layer lower than the dependency ID
- // but then we can't know the highest layer relayed we assume that the user
- // will add one layer at a time
- if( _highestTemporalLayer < temporalID ||
- _highestDependencyLayerOld < dependencyID ||
- _highestDependencyQualityIDOld < dependencyQualityID)
- {
- // drop
- return false;
- }
- // highest layer based on old
- if( dependencyID == _highestDependencyLayerOld &&
- dependencyQualityID == _highestDependencyQualityIDOld)
- {
- higestLayer = true;
- }
- } else
- {
- // we want to switch down to a lower dependency layer,
- // use old setting, done bellow
- // drop all temporal layers while waiting for the key-frame
- if(temporalID > 0)
- {
- // drop
- return false;
- }
- // we can't drop a lower MGS layer since this might depend on it
- // however we can drop MGS layers larger than dependecyQualityId
- // with dependency from old and quality 0
- if( _highestDependencyLayerOld < dependencyID ||
- (_highestDependencyQualityIDOld & 0xf0) < dependencyQualityID)
- {
- // drop
- return false;
- }
- if( dependencyID == _highestDependencyLayerOld &&
- dependencyQualityID == (_highestDependencyQualityIDOld & 0xf0))
- {
- higestLayer = true;
- }
- }
- }
- } else
- {
- // filter based on current state
- if( _highestTemporalLayer < temporalID ||
- _highestDependencyLayer < dependencyID ||
- _highestDependencyQualityID < dependencyQualityID)
- {
- // drop
- return false;
- }
- if( dependencyID == _highestDependencyLayer &&
- dependencyQualityID == _highestDependencyQualityID)
- {
- higestLayer = true;
- }
- }
- return true;
-}
-
-int32_t
-RTPSenderH264::SetHighestSendLayer(const uint8_t dependencyQualityLayer,
- const uint8_t temporalLayer)
-{
- const uint8_t dependencyLayer = (dependencyQualityLayer >> 4);
-
- if(_highestDependencyLayerOld != _highestDependencyLayer)
- {
- // we have not switched to the new dependency yet
- } else
- {
- if(_highestDependencyLayer == dependencyLayer)
- {
- // no change of dependency
- // switch now _highestDependencyQualityIDOld
- _highestDependencyQualityIDOld = dependencyQualityLayer;
- }else
- {
- // change of dependency, update _highestDependencyQualityIDOld store as old
- _highestDependencyQualityIDOld = _highestDependencyQualityID;
- }
- }
- _useHighestSendLayer = true;
- _highestDependencyLayer = dependencyLayer;
- _highestDependencyQualityID = dependencyQualityLayer;
- _highestTemporalLayer = temporalLayer;
- return 0;
-}
-
-int32_t
-RTPSenderH264::HighestSendLayer(uint8_t& dependencyQualityLayer,
- uint8_t& temporalLayer)
-{
- if (!_useHighestSendLayer)
- {
- // No information set
- return -1;
- }
- dependencyQualityLayer = _highestDependencyQualityID;
- temporalLayer = _highestTemporalLayer;
- return 0;
-}
-/*
-* H.264
-*/
-int32_t
-RTPSenderH264::SendH264(const FrameType frameType,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- const uint8_t* payloadData,
- const uint32_t payloadSize,
- H264Information& h264Information)
-{
- int32_t payloadBytesToSend = payloadSize;
- const uint8_t* data = payloadData;
- bool switchToFUA = false;
- const uint16_t rtpHeaderLength = _rtpSender.RTPHeaderLength();
-
- const H264Info* ptrH264Info = NULL;
- if (h264Information.GetInfo(payloadData,payloadSize, ptrH264Info) == -1)
- {
- return -1;
- }
- uint16_t idxNALU = 0;
- uint16_t DONCdummy = 0;
-
- while (payloadBytesToSend > 0)
- {
- switch(_h264Mode)
- {
- case H264_NON_INTERLEAVED_MODE:
-
- if(!switchToFUA)
- {
- if(SendH264_STAP_A(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- switchToFUA,
- payloadBytesToSend,
- data,
- rtpHeaderLength) != 0)
- {
- return -1;
- }
- }
- else
- {
- // FUA for the rest of the frame
- if(SendH264_FU_A(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- payloadBytesToSend,
- data,
- rtpHeaderLength,
- DONCdummy) != 0)
- {
- return -1;
- }
- // try to go back to STAP_A
- switchToFUA = false;
- }
- break;
- case H264_SINGLE_NAL_MODE:
- {
- // modeSingleU
- if(SendH264_SingleMode(frameType,
- ptrH264Info,
- idxNALU,
- payloadType,
- captureTimeStamp,
- payloadBytesToSend,
- data,
- rtpHeaderLength,
- DONCdummy) != 0)
- {
- return -1;
- }
- break;
- }
- case H264_INTERLEAVED_MODE:
- // not supported
- assert(false);
- return -1;
- }
- }
- return 0;
-}
-} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/H264/rtp_sender_h264.h b/modules/rtp_rtcp/source/H264/rtp_sender_h264.h
deleted file mode 100644
index ea385d4..0000000
--- a/modules/rtp_rtcp/source/H264/rtp_sender_h264.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_RTP_SENDER_H264_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_RTP_SENDER_H264_H_
-
-#include "webrtc/typedefs.h"
-#include "ModuleRTPRTCPConfig.h"
-#include "rtp_rtcp_defines.h"
-#include "h264_information.h"
-
-#include "RTPSender.h"
-
-namespace webrtc {
-class RTPSenderH264
-{
-public:
- int32_t SendH264(const FrameType frameType,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- const uint8_t* payloadData,
- const uint32_t payloadSize,
- H264Information& h264Information);
-
- int32_t SendH264SVC(const FrameType frameType,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- const uint8_t* payloadData,
- const uint32_t payloadSize,
- H264Information& h264Information);
-
- // H.264 AVC
- int32_t SetH264PacketizationMode(const H264PacketizationMode mode);
-
- int32_t SetH264SendModeNALU_PPS_SPS(const bool dontSend);
-
- // H.264 SVC
- int32_t SetHighestSendLayer(const uint8_t dependencyQualityLayer,
- const uint8_t temporalLayer);
-
- int32_t HighestSendLayer(uint8_t& dependencyQualityLayer,
- uint8_t& temporalLayer);
-
-protected:
- RTPSenderH264(RTPSenderInterface* rtpSender);
- virtual ~RTPSenderH264();
-
- int32_t Init();
-
- virtual uint16_t FECPacketOverhead() const = 0;
- virtual RtpVideoCodecTypes VideoCodecType() const = 0;
-
- virtual int32_t SendVideoPacket(const FrameType frameType,
- const uint8_t* dataBuffer,
- const uint16_t payloadLength,
- const uint16_t rtpHeaderLength,
- bool baseLayerVideoPacket=false) = 0;
-
-
- bool SendH264SVCLayer(const FrameType frameType,
- const uint8_t temporalID,
- const uint8_t dependencyQualityID,
- bool& higestLayer);
-
- // H.264 SVC
- int32_t AddH264PACSINALU(const bool firstPacketInNALU,
- const bool lastPacketInNALU,
- const H264_PACSI_NALU& paci,
- const H264_SVC_NALUHeader& svc,
- const uint16_t DONC,
- uint8_t* databuffer,
- int32_t& curByte) const;
-
- int32_t SendH264FillerData(const WebRtcRTPHeader* rtpHeader,
- const uint16_t bytesToSend,
- const uint32_t ssrc);
-
- int32_t SendH264FillerData(const uint32_t captureTimestamp,
- const uint8_t payloadType,
- const uint32_t bytesToSend);
-
- int32_t SendH264SVCRelayPacket(const WebRtcRTPHeader* rtpHeader,
- const uint8_t* incomingRTPPacket,
- const uint16_t incomingRTPPacketSize,
- const uint32_t ssrc,
- const bool higestLayer);
-
- int32_t SetH264RelaySequenceNumber(const uint16_t seqNum);
-
- int32_t SetH264RelayCompleteLayer(const bool complete);
-
- // H.264
- H264PacketizationMode _h264Mode;
- bool _h264SendPPS_SPS;
-
- // H.264-SVC
- int8_t _h264SVCPayloadType;
- uint16_t _h264SVCRelaySequenceNumber;
- uint32_t _h264SVCRelayTimeStamp;
- bool _h264SVCRelayLayerComplete;
-
-
-private:
- // H.264
- int32_t SendH264_SingleMode(const FrameType frameType,
- const H264Info* ptrH264Info,
- uint16_t &idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- int32_t &payloadBytesToSend,
- const uint8_t*& data,
- const uint16_t rtpHeaderLength,
- const bool sendSVCPACSI=false);
-
- int32_t SendH264_FU_A(const FrameType frameType,
- const H264Info* ptrH264Info,
- uint16_t &idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- int32_t &payloadBytesToSend,
- const uint8_t*& data,
- const uint16_t rtpHeaderLength,
- const bool sendSVCPACSI = false);
-
- int32_t SendH264_STAP_A(const FrameType frameType,
- const H264Info* ptrH264Info,
- uint16_t &idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- bool& switchToFUA,
- int32_t &payloadBytesToSend,
- const uint8_t*& data,
- const uint16_t rtpHeaderLength);
-
- int32_t SendH264_STAP_A_PACSI(const FrameType frameType,
- const H264Info* ptrH264Info,
- uint16_t &idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- bool& switchToFUA,
- int32_t &payloadBytesToSend,
- const uint8_t*& data,
- const uint16_t rtpHeaderLengh)
-
- int32_t SendH264_SinglePACSI(const FrameType frameType,
- const H264Info* ptrH264Info,
- const uint16_t idxNALU,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- const bool firstPacketInNALU,
- const bool lastPacketInNALU);
-
- bool AddH264SVCNALUHeader(const H264_SVC_NALUHeader& svc,
- uint8_t* databuffer,
- int32_t& curByte) const;
-
- RTPSenderInterface& _rtpSender;
-
- // relay
- bool _useHighestSendLayer;
- uint8_t _highestDependencyLayerOld;
- uint8_t _highestDependencyQualityIDOld;
- uint8_t _highestDependencyLayer;
- uint8_t _highestDependencyQualityID;
- uint8_t _highestTemporalLayer;
-
-
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_H264_RTP_SENDER_H264_H_
diff --git a/video_engine/vie_channel.cc b/video_engine/vie_channel.cc
index 5b3b77f..2bec052 100644
--- a/video_engine/vie_channel.cc
+++ b/video_engine/vie_channel.cc
@@ -369,18 +369,6 @@
// Clear any previous modules.
vie_receiver_.RegisterSimulcastRtpRtcpModules(simulcast_rtp_rtcp_);
}
- // Enable this if H264 is available.
- // This sets the wanted packetization mode.
- // if (video_codec.plType == kVideoCodecH264) {
- // if (video_codec.codecSpecific.H264.packetization == kH264SingleMode) {
- // rtp_rtcp_->SetH264PacketizationMode(H264_SINGLE_NAL_MODE);
- // } else {
- // rtp_rtcp_->SetH264PacketizationMode(H264_NON_INTERLEAVED_MODE);
- // }
- // if (video_codec.codecSpecific.H264.configParametersSize > 0) {
- // rtp_rtcp_->SetH264SendModeNALU_PPS_SPS(true);
- // }
- // }
// Don't log this error, no way to check in advance if this pl_type is
// registered or not...