正在显示
3 个修改的文件
包含
172 行增加
和
9 行删除
trunk/doc/H.264-AVC-ISO_IEC_14496-10.pdf
0 → 100644
不能预览此文件类型
不能预览此文件类型
@@ -105,8 +105,8 @@ enum TSPidType | @@ -105,8 +105,8 @@ enum TSPidType | ||
105 | TSPidTypePAT, // Program associtate table | 105 | TSPidTypePAT, // Program associtate table |
106 | TSPidTypePMT, // Program map table. | 106 | TSPidTypePMT, // Program map table. |
107 | 107 | ||
108 | - TSPidTypeVideo, | ||
109 | - TSPidTypeAudio, | 108 | + TSPidTypeVideo, // only for H264 video |
109 | + TSPidTypeAudio, // only for AAC audio | ||
110 | }; | 110 | }; |
111 | 111 | ||
112 | // forward declares. | 112 | // forward declares. |
@@ -1094,13 +1094,17 @@ int TSPayloadPMT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | @@ -1094,13 +1094,17 @@ int TSPayloadPMT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t | ||
1094 | 1094 | ||
1095 | ES_info.push_back(info); | 1095 | ES_info.push_back(info); |
1096 | 1096 | ||
1097 | - // TODO: support more video type. | ||
1098 | if (info->stream_type == TSStreamTypeVideoH264) { | 1097 | if (info->stream_type == TSStreamTypeVideoH264) { |
1098 | + // TODO: support more video type. | ||
1099 | ctx->push(TSPidTypeVideo, info->elementary_PID); | 1099 | ctx->push(TSPidTypeVideo, info->elementary_PID); |
1100 | - } | ||
1101 | - // TODO: support more audio type. | ||
1102 | - if (info->stream_type == TSStreamTypeAudioAAC) { | 1100 | + trace("ts+pmt add pid: %d, type: H264 video", info->elementary_PID); |
1101 | + } else if (info->stream_type == TSStreamTypeAudioAAC) { | ||
1102 | + // TODO: support more audio type. | ||
1103 | + // see aac: 6.2 Audio Data Transport Stream, ADTS | ||
1103 | ctx->push(TSPidTypeAudio, info->elementary_PID); | 1104 | ctx->push(TSPidTypeAudio, info->elementary_PID); |
1105 | + trace("ts+pmt add pid: %d, type: AAC audio", info->elementary_PID); | ||
1106 | + } else { | ||
1107 | + trace("ts+pmt ignore the stream type: %d", info->stream_type); | ||
1104 | } | 1108 | } |
1105 | } | 1109 | } |
1106 | 1110 | ||
@@ -1626,6 +1630,158 @@ int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* la | @@ -1626,6 +1630,158 @@ int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* la | ||
1626 | return ret; | 1630 | return ret; |
1627 | } | 1631 | } |
1628 | 1632 | ||
1633 | +/** | ||
1634 | +* 6.2 Audio Data Transport Stream, ADTS | ||
1635 | +*/ | ||
1636 | +class TSAacAdts | ||
1637 | +{ | ||
1638 | +public: | ||
1639 | + // adts_fixed_header | ||
1640 | + // 2B, 16bits | ||
1641 | + int16_t syncword; //12bits | ||
1642 | + int8_t ID; //1bit | ||
1643 | + int8_t layer; //2bits | ||
1644 | + int8_t protection_absent; //1bit | ||
1645 | + // 12bits | ||
1646 | + int8_t profile; //2bit | ||
1647 | + int8_t sampling_frequency_index; //4bits | ||
1648 | + int8_t private_bit; //1bit | ||
1649 | + int8_t channel_configuration; //3bits | ||
1650 | + int8_t original_or_copy; //1bit | ||
1651 | + int8_t home; //1bit | ||
1652 | + | ||
1653 | + // adts_variable_header | ||
1654 | + // 28bits | ||
1655 | + int8_t copyright_identification_bit; //1bit | ||
1656 | + int8_t copyright_identification_start; //1bit | ||
1657 | + int16_t frame_length; //13bits | ||
1658 | + int16_t adts_buffer_fullness; //11bits | ||
1659 | + int8_t number_of_raw_data_blocks_in_frame; //2bits | ||
1660 | + | ||
1661 | + u_int8_t* raw_data; | ||
1662 | + int size; | ||
1663 | + | ||
1664 | + TSAacAdts() | ||
1665 | + { | ||
1666 | + syncword = 0; | ||
1667 | + ID = 0; | ||
1668 | + layer = 0; | ||
1669 | + protection_absent = 0; | ||
1670 | + profile = 0; | ||
1671 | + sampling_frequency_index = 0; | ||
1672 | + private_bit = 0; | ||
1673 | + channel_configuration = 0; | ||
1674 | + original_or_copy = 0; | ||
1675 | + home = 0; | ||
1676 | + copyright_identification_bit = 0; | ||
1677 | + copyright_identification_start = 0; | ||
1678 | + frame_length = 0; | ||
1679 | + adts_buffer_fullness = 0; | ||
1680 | + number_of_raw_data_blocks_in_frame = 0; | ||
1681 | + | ||
1682 | + size = 0; | ||
1683 | + raw_data = NULL; | ||
1684 | + } | ||
1685 | + | ||
1686 | + int parse(TSMessage* msg, char*& p) | ||
1687 | + { | ||
1688 | + int ret = 0; | ||
1689 | + | ||
1690 | + char* start = p; | ||
1691 | + | ||
1692 | + // adts_fixed_header | ||
1693 | + char* pp = (char*)&syncword; | ||
1694 | + pp[1] = *p++; | ||
1695 | + pp[0] = *p++; | ||
1696 | + | ||
1697 | + protection_absent = syncword & 0x01; | ||
1698 | + layer = (syncword >> 1) & 0x03; | ||
1699 | + ID = (syncword >> 3) & 0x01; | ||
1700 | + syncword = (syncword >> 4) & 0x0FFF; | ||
1701 | + | ||
1702 | + // adts_variable_header | ||
1703 | + int64_t temp = 0; | ||
1704 | + pp = (char*)&temp; | ||
1705 | + pp[4] = *p++; | ||
1706 | + pp[3] = *p++; | ||
1707 | + pp[2] = *p++; | ||
1708 | + pp[1] = *p++; | ||
1709 | + pp[0] = *p++; | ||
1710 | + | ||
1711 | + number_of_raw_data_blocks_in_frame = temp & 0x03; | ||
1712 | + temp = temp >> 2; | ||
1713 | + | ||
1714 | + adts_buffer_fullness = temp & 0x7FF; | ||
1715 | + temp = temp >> 11; | ||
1716 | + | ||
1717 | + frame_length = temp & 0x1FFF; | ||
1718 | + temp = temp >> 13; | ||
1719 | + | ||
1720 | + copyright_identification_start = temp & 0x01; | ||
1721 | + temp = temp >> 1; | ||
1722 | + | ||
1723 | + copyright_identification_bit = temp & 0x01; | ||
1724 | + temp = temp >> 1; | ||
1725 | + | ||
1726 | + // adts_fixed_header | ||
1727 | + home = temp & 0x01; | ||
1728 | + temp = temp >> 1; | ||
1729 | + | ||
1730 | + original_or_copy = temp & 0x01; | ||
1731 | + temp = temp >> 1; | ||
1732 | + | ||
1733 | + channel_configuration = temp & 0x07; | ||
1734 | + temp = temp >> 3; | ||
1735 | + | ||
1736 | + private_bit = temp & 0x01; | ||
1737 | + temp = temp >> 1; | ||
1738 | + | ||
1739 | + sampling_frequency_index = temp & 0x0F; | ||
1740 | + temp = temp >> 4; | ||
1741 | + | ||
1742 | + profile = temp & 0x03; | ||
1743 | + temp = temp >> 2; | ||
1744 | + | ||
1745 | + if (!number_of_raw_data_blocks_in_frame) { | ||
1746 | + // adts_error_check | ||
1747 | + if (!protection_absent) { | ||
1748 | + // crc_check | ||
1749 | + trace("ts+aac TODO: crc_check."); | ||
1750 | + } | ||
1751 | + // raw_data_block | ||
1752 | + raw_data = (u_int8_t*)p; | ||
1753 | + size = frame_length - (p - start); | ||
1754 | + p += size; | ||
1755 | + } else { | ||
1756 | + trace("ts+aac TODO: parse multiple blocks."); | ||
1757 | + } | ||
1758 | + | ||
1759 | + return ret; | ||
1760 | + } | ||
1761 | +}; | ||
1762 | + | ||
1763 | +int consume(TSMessage* msg) | ||
1764 | +{ | ||
1765 | + int ret = 0; | ||
1766 | + | ||
1767 | + if (!msg->is_video()) { | ||
1768 | + // parse AAC audio. | ||
1769 | + char* p = msg->packet_data; | ||
1770 | + while (p < msg->packet_data + msg->packet_data_size) { | ||
1771 | + TSAacAdts aac; | ||
1772 | + if ((ret = aac.parse(msg, p)) != 0) { | ||
1773 | + return ret; | ||
1774 | + } | ||
1775 | + trace("ts+aac audio raw data parsed, size: %d, 0x%02x 0x%02x 0x%02x 0x%02x", | ||
1776 | + aac.size, aac.raw_data[0], aac.raw_data[1], aac.raw_data[2], aac.raw_data[3]); | ||
1777 | + // TODO: process audio. | ||
1778 | + } | ||
1779 | + } else { | ||
1780 | + } | ||
1781 | + | ||
1782 | + return ret; | ||
1783 | +} | ||
1784 | + | ||
1629 | int main(int /*argc*/, char** /*argv*/) | 1785 | int main(int /*argc*/, char** /*argv*/) |
1630 | { | 1786 | { |
1631 | const char* file = "livestream-1347.ts"; | 1787 | const char* file = "livestream-1347.ts"; |
@@ -1664,10 +1820,17 @@ int main(int /*argc*/, char** /*argv*/) | @@ -1664,10 +1820,17 @@ int main(int /*argc*/, char** /*argv*/) | ||
1664 | return ret; | 1820 | return ret; |
1665 | } | 1821 | } |
1666 | 1822 | ||
1667 | - // TODO: process it. | ||
1668 | - srs_freep(msg); | ||
1669 | - | ||
1670 | offset += nread; | 1823 | offset += nread; |
1824 | + if (!msg) { | ||
1825 | + continue; | ||
1826 | + } | ||
1827 | + | ||
1828 | + if ((ret = consume(msg)) != 0) { | ||
1829 | + trace("demuxer+consume parse and consume message failed. ret=%d", ret); | ||
1830 | + break; | ||
1831 | + } | ||
1832 | + | ||
1833 | + srs_freep(msg); | ||
1671 | } | 1834 | } |
1672 | 1835 | ||
1673 | close(fd); | 1836 | close(fd); |
-
请 注册 或 登录 后发表评论