正在显示
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); |
-
请 注册 或 登录 后发表评论