winlin

finger out the ts audio/video package for AACADTS and H264NAL

  1 +ts-audio-video-analysis.ts is generated by nginx-rtmp.
  2 +
1 AUDIO 0x0F ISO/IEC 13818-7 Audio with ADTS transport syntax 3 AUDIO 0x0F ISO/IEC 13818-7 Audio with ADTS transport syntax
2 110x xxxx ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC 14496-3 audio stream number x xxxx 4 110x xxxx ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC 14496-3 audio stream number x xxxx
3 (gdb) p /x pkt.payload[0].pmt[0].at(1)[0] 5 (gdb) p /x pkt.payload[0].pmt[0].at(1)[0]
@@ -146,6 +148,28 @@ FLV header? @@ -146,6 +148,28 @@ FLV header?
146 0x60b340: 0xeb 0x07 0xb7 0xfc 0xc2 0x24 0x8d 0xfa 148 0x60b340: 0xeb 0x07 0xb7 0xfc 0xc2 0x24 0x8d 0xfa
147 0x60b348: 0xc0 0xaf 0x2a 0x76 0x53 0xc4 0x2d 0x80 149 0x60b348: 0xc0 0xaf 0x2a 0x76 0x53 0xc4 0x2d 0x80
148 0x60b350: 0x8f 0xc8 0xba 0x2e 0x2b 0xb7 0x18 0x9f 150 0x60b350: 0x8f 0xc8 0xba 0x2e 0x2b 0xb7 0x18 0x9f
  151 +
  152 +
  153 +TS的数据如下:
  154 +(gdb) x /35795xb msg->packet_data
  155 +0x00 0x00 0x00 0x01
  156 +0x09 0xf0
  157 +
  158 +0x00 0x00 0x00 0x01
  159 +0x67 0x64 0x00 0x28 0xac 0xd1
  160 +0x60b310: 0xc0 0x50 0x05 0xbb 0xff 0x00 0x2d 0x00
  161 +0x60b318: 0x22 0x10 0x00 0x00 0x03 0x00 0x10 0x00
  162 +0x60b320: 0x00 0x03 0x03 0x08 0xf1 0x83 0x11 0xe0
  163 +
  164 +0x00 0x00 0x00 0x01
  165 +0x68 0xe9 0xab 0x2c 0x8b
  166 +
  167 +0x00 0x00 0x01
  168 +0x65 0x88 0x84 0x00
  169 +0x60b338: 0x42 0xbf 0x4e 0x19 0x2a 0x00 0x0b 0xa7
  170 +0x60b340: 0xeb 0x07 0xb7 0xfc 0xc2 0x24 0x8d 0xfa
  171 +0x60b348: 0xc0 0xaf 0x2a 0x76 0x53 0xc4 0x2d 0x80
  172 +0x60b350: 0x8f 0xc8 0xba 0x2e 0x2b 0xb7 0x18 0x9f
149 0x60b358: 0xba 0x47 0x10 0x8b 0xc7 0x93 0x92 0x89 173 0x60b358: 0xba 0x47 0x10 0x8b 0xc7 0x93 0x92 0x89
150 0x60b360: 0x00 0x2d 0xdf 0x3b 0xcb 0x51 0xfe 0x27 174 0x60b360: 0x00 0x2d 0xdf 0x3b 0xcb 0x51 0xfe 0x27
151 0x60b368: 0x13 0xe3 0x29 0x48 0x71 0xf7 0x70 0x07 175 0x60b368: 0x13 0xe3 0x29 0x48 0x71 0xf7 0x70 0x07
@@ -170,13 +194,34 @@ FLV header? @@ -170,13 +194,34 @@ FLV header?
170 0x60b400: 0x0a 0xea 0x86 0x93 0xce 0x90 0xe7 0x9b 194 0x60b400: 0x0a 0xea 0x86 0x93 0xce 0x90 0xe7 0x9b
171 0x60b408: 0x75 0x92 0x0d 0x6f 0xfa 0xa2 0xac 0x26 195 0x60b408: 0x75 0x92 0x0d 0x6f 0xfa 0xa2 0xac 0x26
172 0x60b410: 0xae 0xb1 0xc3 0x4c 0xab 0x92 0xc6 0xae 196 0x60b410: 0xae 0xb1 0xc3 0x4c 0xab 0x92 0xc6 0xae
173 -0x60b418: 0x7a 0xcf 0xfa 0x0c 0xe7 0xc4 0x00 0x62  
174 -0x60b420: 0xc3 0xc8 0x49 0xbd 0x5e 0xb0 0xd3 0x4f  
175 -0x60b428: 0xb2 0x60 0xf4 0x53 0xe8 0xba 0xa0 0xf3  
176 -0x60b430: 0xe5 0xb4 0xf4 0xb1 0x15 0x9d 0x28 0x4f  
177 -0x60b438: 0x7f 0xc9 0x0a 0x50 0x90 0x4a 0xc3 0x19  
178 -0x60b440: 0xeb 0x50 0xee 0xde 0xe4 0x7d 0xed 0x69  
179 -0x60b448: 0x37 0x50 0x5d 0x0f 0x26 0x8b 0x96 0x57  
180 -0x60b450: 0x3e 0x5c 0x5f 0x68 0xbf 0xb8 0xb0 0xcb  
181 -0x60b458: 0x90 0x9c 0xb2 0x18 0x23 0x1f 0x62 0xa5  
182 -0x60b460: 0x6f 0x37 0x9f 0x3a  
  197 +
  198 +TS的第二个视频包数据如下:
  199 +(gdb) x /4108xb 0x60b300
  200 +0x00 0x00 0x00 0x01
  201 +0x09 0xf0
  202 +
  203 +0x00 0x00 0x01
  204 +0x41 0x9a 0x28 0xc8 0x4a 0xbf 0xe8
  205 +0x60b310: 0x06 0x44 0x30 0x05 0xea 0xd8 0x86 0xa5
  206 +0x60b318: 0xee 0x75 0xab 0x30 0xc8 0x7a 0x5c 0xe3
  207 +0x60b320: 0xc7 0x4a 0xdb 0xf6 0xe0 0x08 0xbe 0xc4
  208 +0x60b328: 0xb0 0xe4 0x5d 0xe7 0x95 0xf3 0x65 0x4e
  209 +0x60b330: 0x00 0xed 0xdb 0xd1 0x5e 0xc3 0xb8 0x34
  210 +0x60b338: 0x3d 0xd3 0xfe 0x46 0x5b 0xfd 0xd9 0xf0
  211 +0x60b340: 0xa0 0x5d 0xa4 0xa8 0x3d 0x44 0x97 0x58
  212 +0x60b348: 0x20 0xd5 0x41 0xb2 0x49 0x72 0xd0 0x9b
  213 +0x60b350: 0xa2 0xa7 0xbf 0xba 0x9c 0xa8 0x10 0x58
  214 +0x60b358: 0x07 0x47 0xf4 0xe5 0xe8 0x5d 0xf2 0x0d
  215 +0x60b360: 0xfe 0x51 0x26 0x8a 0x6a 0x76 0xb8 0x35
  216 +0x60b368: 0x04 0xfe 0x01 0xb4 0xec 0x67 0xd5 0x1f
  217 +0x60b370: 0xb0 0x66 0x0b 0x7e 0x52 0x58 0x38 0x1c
  218 +0x60b378: 0xf3 0x4c 0x92 0xe8 0x38 0xc3 0x7e 0x5b
  219 +0x60b380: 0xd6 0x17 0x47 0x49 0xba 0xae 0x6e 0xa0
  220 +0x60b388: 0xd8 0xfd 0x16 0xdb 0x85 0xd1 0x81 0x6e
  221 +0x60b390: 0x43 0x17 0x82 0xb9 0x39 0xb0 0xa8 0xe8
  222 +0x60b398: 0x00 0x56 0x52 0x5e 0xfd 0xad 0x5a 0x43
  223 +0x60b3a0: 0x32 0x7a 0x4e 0xed 0xd7 0xb2 0x1b 0x4d
  224 +0x60b3a8: 0x78 0x9e 0xad 0x4e 0x97 0x37 0x2c 0xbb
  225 +0x60b3b0: 0xf3 0x99 0x45 0xee 0xce 0xc7 0x1f 0xeb
  226 +0x60b3b8: 0x43 0x37 0xfd 0x67 0x34 0x97 0xcc 0x8c
  227 +0x60b3c0: 0xc5 0xec 0x86 0xb0 0x57 0xb4 0x83 0xa9
@@ -1636,11 +1636,171 @@ int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* la @@ -1636,11 +1636,171 @@ int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* la
1636 } 1636 }
1637 1637
1638 /** 1638 /**
1639 -* Annex B Byte stream format 1639 +* Table 7-1 – NAL unit type codes, page 61.
  1640 +*/
  1641 +enum TSH264NalUnitType
  1642 +{
  1643 + TSH264NalUnitTypeUnspecified = 0,
  1644 + TSH264NalUnitTypeCodedSlice = 1,
  1645 + TSH264NalUnitTypeCodedSliceDataPartitionA = 2,
  1646 + TSH264NalUnitTypeCodedSliceDataPartitionB = 3,
  1647 + TSH264NalUnitTypeCodedSliceDataPartitionC = 4,
  1648 + TSH264NalUnitTypeCodedSliceOfAnIDRPicture = 5,
  1649 + TSH264NalUnitTypeSEI = 6,
  1650 + /**
  1651 + * 7.3.2.1 Sequence parameter set RBSP syntax
  1652 + * seq_parameter_set_rbsp(), in page 45
  1653 + */
  1654 + TSH264NalUnitTypeSequenceParameterSet = 7,
  1655 + /**
  1656 + * 7.3.2.2 Picture parameter set RBSP syntax
  1657 + * pic_parameter_set_rbsp(), in page 46
  1658 + */
  1659 + TSH264NalUnitTypePictureParameterSet = 8,
  1660 + /**
  1661 + * 7.3.2.4 Picture delimiter RBSP syntax
  1662 + * pic_delimiter_rbsp(), in page 47
  1663 + */
  1664 + TSH264NalUnitTypePictureDelimiter = 9,
  1665 + TSH264NalUnitTypeEndOfSequence = 10,
  1666 + TSH264NalUnitTypeEndOfStream = 11,
  1667 + TSH264NalUnitTypeFillerData = 12,
  1668 + TSH264NalUnitTypeReservedStart = 13,
  1669 + TSH264NalUnitTypeReservedEnd = 23,
  1670 + TSH264NalUnitTypeUnspecifiedStart = 24,
  1671 + TSH264NalUnitTypeUnspecifiedEnd = 31,
  1672 +};
  1673 +
  1674 +/**
  1675 +* Table 7-2 – Meaning of pic_type, page 69.
  1676 +*/
  1677 +enum TSH264PicType
  1678 +{
  1679 + TSH264PicTypeI = 0,
  1680 + TSH264PicTypeIP = 1,
  1681 + TSH264PicTypeIPB = 2,
  1682 + TSH264PicTypeSI = 3,
  1683 + TSH264PicTypeSISP = 4,
  1684 + TSH264PicTypeISI = 5,
  1685 + TSH264PicTypeISIPSP = 6,
  1686 + TSH264PicTypeISIPSPB = 7,
  1687 +};
  1688 +
  1689 +/**
  1690 +* Annex B Byte stream format, in page 211.
1640 */ 1691 */
1641 class TSH264Codec 1692 class TSH264Codec
1642 { 1693 {
1643 public: 1694 public:
  1695 + int8_t forbidden_zero_bit; //1bit
  1696 + int8_t nal_ref_idc; //2bits
  1697 + TSH264NalUnitType nal_unit_type; //5bits
  1698 +
  1699 + // for nal_unit_type == TSH264NalUnitTypePictureDelimiter
  1700 + TSH264PicType pic_type; //3bits
  1701 +
  1702 + u_int8_t* raw_data;
  1703 + int size;
  1704 +
  1705 + TSH264Codec()
  1706 + {
  1707 + forbidden_zero_bit = 0;
  1708 + nal_ref_idc = 0;
  1709 + nal_unit_type = TSH264NalUnitTypeUnspecified;
  1710 + pic_type = TSH264PicTypeI;
  1711 + size = 0;
  1712 + raw_data = NULL;
  1713 + }
  1714 +
  1715 + u_int8_t at(int index)
  1716 + {
  1717 + if (index >= size) {
  1718 + return 0;
  1719 + }
  1720 + return raw_data[index];
  1721 + }
  1722 +
  1723 + int parse(TSMessage* msg, char* last, char*& p)
  1724 + {
  1725 + int ret = 0;
  1726 +
  1727 + while (next_int(p, 3) != 0x000001) {
  1728 + char ch = *p++;
  1729 + if (ch != 0x00) {
  1730 + trace("ts+h264 parse msg failed, "
  1731 + "expect 0x00 before start-code. actual is: %#x", (u_int8_t)ch);
  1732 + return -1;
  1733 + }
  1734 + }
  1735 +
  1736 + if (p >= last) {
  1737 + trace("ts+h264 parse msg finished, no start-code.");
  1738 + return ret;
  1739 + }
  1740 +
  1741 + // start_code_prefix_one_3bytes /* equal to 0x000001 */
  1742 + p += 3;
  1743 +
  1744 + raw_data = (u_int8_t*)p;
  1745 + while (p < last) {
  1746 + if (match_start_code_prefix(p)) {
  1747 + break;
  1748 + }
  1749 + p++;
  1750 + }
  1751 + size = (u_int8_t*)p - raw_data;
  1752 +
  1753 + trace("ts+h264 parse msg finished");
  1754 + return ret;
  1755 +
  1756 + // nal_unit( NumBytesInNALunit ) specified in page 44.
  1757 + // where f(1) specified in page 43.
  1758 + int8_t _nal_unit_type = *p++;
  1759 +
  1760 + forbidden_zero_bit = (_nal_unit_type >> 7) &0x01;
  1761 + nal_ref_idc = (_nal_unit_type >> 5) &0x03;
  1762 + _nal_unit_type &= 0x1f;
  1763 +
  1764 + nal_unit_type = (TSH264NalUnitType)_nal_unit_type;
  1765 +
  1766 + if (nal_unit_type == TSH264NalUnitTypePictureDelimiter) {
  1767 + /**
  1768 + * 7.3.2.4 Picture delimiter RBSP syntax
  1769 + * pic_delimiter_rbsp(), in page 47
  1770 + */
  1771 + } else if (nal_unit_type == TSH264NalUnitTypeSequenceParameterSet) {
  1772 + /**
  1773 + * 7.3.2.1 Sequence parameter set RBSP syntax
  1774 + * seq_parameter_set_rbsp(), in page 45
  1775 + */
  1776 + } else if (nal_unit_type == TSH264NalUnitTypePictureParameterSet) {
  1777 + /**
  1778 + * 7.3.2.2 Picture parameter set RBSP syntax
  1779 + * pic_parameter_set_rbsp(), in page 46
  1780 + */
  1781 + }
  1782 +
  1783 + return ret;
  1784 + }
  1785 +
  1786 + bool match_start_code_prefix(char*p)
  1787 + {
  1788 + return p[0] == 0x00 && p[1] == 0x00 && (p[2] == 0x00 || p[2] == 0x01);
  1789 + }
  1790 +
  1791 + int32_t next_int(char* p, int bytes)
  1792 + {
  1793 + srs_assert(bytes <= sizeof(int32_t));
  1794 +
  1795 + int32_t value = 0;
  1796 + char* pp = (char*)&value;
  1797 +
  1798 + for (int i = 0; i < bytes; i++) {
  1799 + *(pp + bytes - 1 - i) = *(p + i);
  1800 + }
  1801 +
  1802 + return value;
  1803 + }
1644 }; 1804 };
1645 1805
1646 /** 1806 /**
@@ -1696,6 +1856,14 @@ public: @@ -1696,6 +1856,14 @@ public:
1696 raw_data = NULL; 1856 raw_data = NULL;
1697 } 1857 }
1698 1858
  1859 + u_int8_t at(int index)
  1860 + {
  1861 + if (index >= size) {
  1862 + return 0;
  1863 + }
  1864 + return raw_data[index];
  1865 + }
  1866 +
1699 int parse(TSMessage* msg, char*& p) 1867 int parse(TSMessage* msg, char*& p)
1700 { 1868 {
1701 int ret = 0; 1869 int ret = 0;
@@ -1775,21 +1943,33 @@ public: @@ -1775,21 +1943,33 @@ public:
1775 1943
1776 int consume(TSMessage* msg) 1944 int consume(TSMessage* msg)
1777 { 1945 {
1778 - int ret = 0; 1946 + int ret = 0;
  1947 +
  1948 + char* p = msg->packet_data;
  1949 + char* last = msg->packet_data + msg->packet_data_size;
1779 1950
1780 if (!msg->is_video()) { 1951 if (!msg->is_video()) {
1781 // parse AAC audio. 1952 // parse AAC audio.
1782 - char* p = msg->packet_data;  
1783 - while (p < msg->packet_data + msg->packet_data_size) { 1953 + while (p < last) {
1784 TSAacAdts aac; 1954 TSAacAdts aac;
1785 if ((ret = aac.parse(msg, p)) != 0) { 1955 if ((ret = aac.parse(msg, p)) != 0) {
1786 return ret; 1956 return ret;
1787 } 1957 }
1788 trace("ts+aac audio raw data parsed, size: %d, 0x%02x 0x%02x 0x%02x 0x%02x", 1958 trace("ts+aac audio raw data parsed, size: %d, 0x%02x 0x%02x 0x%02x 0x%02x",
1789 - aac.size, aac.raw_data[0], aac.raw_data[1], aac.raw_data[2], aac.raw_data[3]); 1959 + aac.size, aac.at(0), aac.at(1), aac.at(2), aac.at(3));
1790 // TODO: process audio. 1960 // TODO: process audio.
1791 } 1961 }
1792 } else { 1962 } else {
  1963 + // parse H264 video.
  1964 + while (p < last) {
  1965 + TSH264Codec h264;
  1966 + if ((ret = h264.parse(msg, last, p)) != 0) {
  1967 + return ret;
  1968 + }
  1969 + trace("ts+h264 video raw data parsed, size: %d, 0x%02x 0x%02x 0x%02x 0x%02x",
  1970 + h264.size, h264.at(0), h264.at(1), h264.at(2), h264.at(3));
  1971 + // TODO: process video.
  1972 + }
1793 } 1973 }
1794 1974
1795 return ret; 1975 return ret;