winlin

enhanced avc decode, parse the sps get width+height. 2.0.156.

@@ -562,7 +562,8 @@ Supported operating systems and hardware: @@ -562,7 +562,8 @@ Supported operating systems and hardware:
562 562
563 ### SRS 2.0 history 563 ### SRS 2.0 history
564 564
565 -* v2.0, 2015-03-30, for [#372](https://github.com/winlinvip/simple-rtmp-server/issues/372), support transform vhost of edge 2.0.155. 565 +* v2.0, 2015-04-03, enhanced avc decode, parse the sps get width+height. 2.0.156.
  566 +* v2.0, 2015-04-03, for [#372](https://github.com/winlinvip/simple-rtmp-server/issues/372), support transform vhost of edge 2.0.155.
566 * v2.0, 2015-03-30, for [#366](https://github.com/winlinvip/simple-rtmp-server/issues/366), config hls to disable cleanup of ts. 2.0.154. 567 * v2.0, 2015-03-30, for [#366](https://github.com/winlinvip/simple-rtmp-server/issues/366), config hls to disable cleanup of ts. 2.0.154.
567 * v2.0, 2015-03-31, support server cycle handler. 2.0.153. 568 * v2.0, 2015-03-31, support server cycle handler. 2.0.153.
568 * v2.0, 2015-03-31, support on_hls for http hooks. 2.0.152. 569 * v2.0, 2015-03-31, support on_hls for http hooks. 2.0.152.
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 155 34 +#define VERSION_REVISION 156
35 35
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"
@@ -31,6 +31,7 @@ using namespace std; @@ -31,6 +31,7 @@ using namespace std;
31 #include <srs_kernel_log.hpp> 31 #include <srs_kernel_log.hpp>
32 #include <srs_kernel_stream.hpp> 32 #include <srs_kernel_stream.hpp>
33 #include <srs_kernel_utility.hpp> 33 #include <srs_kernel_utility.hpp>
  34 +#include <srs_core_autofree.hpp>
34 35
35 string srs_codec_video2str(SrsCodecVideo codec) 36 string srs_codec_video2str(SrsCodecVideo codec)
36 { 37 {
@@ -713,7 +714,8 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream) @@ -713,7 +714,8 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream)
713 return ret; 714 return ret;
714 } 715 }
715 716
716 - // 1 sps 717 + // 1 sps, 7.3.2.1 Sequence parameter set RBSP syntax
  718 + // H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
717 if (!stream->require(1)) { 719 if (!stream->require(1)) {
718 ret = ERROR_HLS_DECODE_ERROR; 720 ret = ERROR_HLS_DECODE_ERROR;
719 srs_error("avc decode sequenc header sps failed. ret=%d", ret); 721 srs_error("avc decode sequenc header sps failed. ret=%d", ret);
@@ -740,8 +742,7 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream) @@ -740,8 +742,7 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream)
740 if (sequenceParameterSetLength > 0) { 742 if (sequenceParameterSetLength > 0) {
741 srs_freep(sequenceParameterSetNALUnit); 743 srs_freep(sequenceParameterSetNALUnit);
742 sequenceParameterSetNALUnit = new char[sequenceParameterSetLength]; 744 sequenceParameterSetNALUnit = new char[sequenceParameterSetLength];
743 - memcpy(sequenceParameterSetNALUnit, stream->data() + stream->pos(), sequenceParameterSetLength);  
744 - stream->skip(sequenceParameterSetLength); 745 + stream->read_bytes(sequenceParameterSetNALUnit, sequenceParameterSetLength);
745 } 746 }
746 // 1 pps 747 // 1 pps
747 if (!stream->require(1)) { 748 if (!stream->require(1)) {
@@ -770,10 +771,242 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream) @@ -770,10 +771,242 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream)
770 if (pictureParameterSetLength > 0) { 771 if (pictureParameterSetLength > 0) {
771 srs_freep(pictureParameterSetNALUnit); 772 srs_freep(pictureParameterSetNALUnit);
772 pictureParameterSetNALUnit = new char[pictureParameterSetLength]; 773 pictureParameterSetNALUnit = new char[pictureParameterSetLength];
773 - memcpy(pictureParameterSetNALUnit, stream->data() + stream->pos(), pictureParameterSetLength);  
774 - stream->skip(pictureParameterSetLength); 774 + stream->read_bytes(pictureParameterSetNALUnit, pictureParameterSetLength);
775 } 775 }
776 776
  777 + return avc_demux_sps();
  778 +}
  779 +
  780 +int SrsAvcAacCodec::avc_demux_sps()
  781 +{
  782 + int ret = ERROR_SUCCESS;
  783 +
  784 + if (!sequenceParameterSetLength) {
  785 + return ret;
  786 + }
  787 +
  788 + SrsStream stream;
  789 + if ((ret = stream.initialize(sequenceParameterSetNALUnit, sequenceParameterSetLength)) != ERROR_SUCCESS) {
  790 + return ret;
  791 + }
  792 +
  793 + // for NALU, 7.3.1 NAL unit syntax
  794 + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
  795 + if (!stream.require(1)) {
  796 + ret = ERROR_HLS_DECODE_ERROR;
  797 + srs_error("avc decode sps failed. ret=%d", ret);
  798 + return ret;
  799 + }
  800 + int8_t nutv = stream.read_1bytes();
  801 +
  802 + // forbidden_zero_bit shall be equal to 0.
  803 + int8_t forbidden_zero_bit = (nutv >> 7) & 0x01;
  804 + if (forbidden_zero_bit) {
  805 + ret = ERROR_HLS_DECODE_ERROR;
  806 + srs_error("forbidden_zero_bit shall be equal to 0. ret=%d", ret);
  807 + return ret;
  808 + }
  809 +
  810 + // nal_ref_idc not equal to 0 specifies that the content of the NAL unit contains a sequence parameter set or a picture
  811 + // parameter set or a slice of a reference picture or a slice data partition of a reference picture.
  812 + int8_t nal_ref_idc = (nutv >> 5) & 0x03;
  813 + if (!nal_ref_idc) {
  814 + ret = ERROR_HLS_DECODE_ERROR;
  815 + srs_error("for sps, nal_ref_idc shall be not be equal to 0. ret=%d", ret);
  816 + return ret;
  817 + }
  818 +
  819 + // nal_unit_type specifies the type of RBSP data structure contained in the NAL unit as specified in Table 7-1.
  820 + // VCL NAL units are specified as those NAL units having nal_unit_type equal to 1, 2, 3, 4, 5, or 12.
  821 + // All remaining NAL units are called non-VCL NAL units.
  822 + int8_t nal_unit_type = nutv & 0x1f;
  823 + if (nal_unit_type != 7) {
  824 + ret = ERROR_HLS_DECODE_ERROR;
  825 + srs_error("for sps, nal_unit_type shall be equal to 7. ret=%d", ret);
  826 + return ret;
  827 + }
  828 +
  829 + // decode the rbsp from sps.
  830 + // rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
  831 + int8_t* rbsp = new int8_t[sequenceParameterSetLength];
  832 + SrsAutoFree(int8_t, rbsp);
  833 +
  834 + int nb_rbsp = 0;
  835 + while (!stream.empty()) {
  836 + rbsp[nb_rbsp] = stream.read_1bytes();
  837 +
  838 + // XX 00 00 03 XX, the 03 byte should be drop.
  839 + if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
  840 + continue;
  841 + }
  842 +
  843 + nb_rbsp++;
  844 + }
  845 +
  846 + return avc_demux_sps_rbsp((char*)rbsp, nb_rbsp);
  847 +}
  848 +
  849 +
  850 +int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
  851 +{
  852 + int ret = ERROR_SUCCESS;
  853 +
  854 + // reparse the rbsp.
  855 + SrsStream stream;
  856 + if ((ret = stream.initialize(rbsp, nb_rbsp)) != ERROR_SUCCESS) {
  857 + return ret;
  858 + }
  859 +
  860 + // for SPS, 7.3.2.1.1 Sequence parameter set data syntax
  861 + // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62.
  862 + if (!stream.require(3)) {
  863 + ret = ERROR_HLS_DECODE_ERROR;
  864 + srs_error("sps shall atleast 3bytes. ret=%d", ret);
  865 + return ret;
  866 + }
  867 + u_int8_t profile_idc = stream.read_1bytes();
  868 + if (!profile_idc) {
  869 + ret = ERROR_HLS_DECODE_ERROR;
  870 + srs_error("sps the profile_idc invalid. ret=%d", ret);
  871 + return ret;
  872 + }
  873 +
  874 + int8_t flags = stream.read_1bytes();
  875 + if (flags & 0x03) {
  876 + ret = ERROR_HLS_DECODE_ERROR;
  877 + srs_error("sps the flags invalid. ret=%d", ret);
  878 + return ret;
  879 + }
  880 +
  881 + u_int8_t level_idc = stream.read_1bytes();
  882 + if (!level_idc) {
  883 + ret = ERROR_HLS_DECODE_ERROR;
  884 + srs_error("sps the level_idc invalid. ret=%d", ret);
  885 + return ret;
  886 + }
  887 +
  888 + SrsBitStream bs;
  889 + if ((ret = bs.initialize(&stream)) != ERROR_SUCCESS) {
  890 + return ret;
  891 + }
  892 +
  893 + int64_t seq_parameter_set_id = -1;
  894 + if ((ret = srs_avc_nalu_read_uev(&bs, seq_parameter_set_id)) != ERROR_SUCCESS) {
  895 + return ret;
  896 + }
  897 + if (seq_parameter_set_id < 0) {
  898 + ret = ERROR_HLS_DECODE_ERROR;
  899 + srs_error("sps the seq_parameter_set_id invalid. ret=%d", ret);
  900 + return ret;
  901 + }
  902 + srs_info("sps parse profile=%d, level=%d, sps_id=%d", profile_idc, level_idc, seq_parameter_set_id);
  903 +
  904 + if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244
  905 + || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118
  906 + || profile_idc == 128
  907 + ) {
  908 + int64_t chroma_format_idc = -1;
  909 + if ((ret = srs_avc_nalu_read_uev(&bs, chroma_format_idc)) != ERROR_SUCCESS) {
  910 + return ret;
  911 + }
  912 + if (chroma_format_idc == 3) {
  913 + int8_t separate_colour_plane_flag = -1;
  914 + if ((ret = srs_avc_nalu_read_bit(&bs, separate_colour_plane_flag)) != ERROR_SUCCESS) {
  915 + return ret;
  916 + }
  917 + }
  918 +
  919 + int64_t bit_depth_luma_minus8 = -1;
  920 + if ((ret = srs_avc_nalu_read_uev(&bs, bit_depth_luma_minus8)) != ERROR_SUCCESS) {
  921 + return ret;
  922 + }
  923 +
  924 + int64_t bit_depth_chroma_minus8 = -1;
  925 + if ((ret = srs_avc_nalu_read_uev(&bs, bit_depth_chroma_minus8)) != ERROR_SUCCESS) {
  926 + return ret;
  927 + }
  928 +
  929 + int8_t qpprime_y_zero_transform_bypass_flag = -1;
  930 + if ((ret = srs_avc_nalu_read_bit(&bs, qpprime_y_zero_transform_bypass_flag)) != ERROR_SUCCESS) {
  931 + return ret;
  932 + }
  933 +
  934 + int8_t seq_scaling_matrix_present_flag = -1;
  935 + if ((ret = srs_avc_nalu_read_bit(&bs, seq_scaling_matrix_present_flag)) != ERROR_SUCCESS) {
  936 + return ret;
  937 + }
  938 + if (seq_scaling_matrix_present_flag) {
  939 + ret = ERROR_HLS_DECODE_ERROR;
  940 + srs_error("sps the seq_scaling_matrix_present_flag invalid. ret=%d", ret);
  941 + return ret;
  942 + }
  943 + }
  944 +
  945 + int64_t log2_max_frame_num_minus4 = -1;
  946 + if ((ret = srs_avc_nalu_read_uev(&bs, log2_max_frame_num_minus4)) != ERROR_SUCCESS) {
  947 + return ret;
  948 + }
  949 +
  950 + int64_t pic_order_cnt_type = -1;
  951 + if ((ret = srs_avc_nalu_read_uev(&bs, pic_order_cnt_type)) != ERROR_SUCCESS) {
  952 + return ret;
  953 + }
  954 +
  955 + if (pic_order_cnt_type == 0) {
  956 + int64_t log2_max_pic_order_cnt_lsb_minus4 = -1;
  957 + if ((ret = srs_avc_nalu_read_uev(&bs, log2_max_pic_order_cnt_lsb_minus4)) != ERROR_SUCCESS) {
  958 + return ret;
  959 + }
  960 + } else if (pic_order_cnt_type == 1) {
  961 + int8_t delta_pic_order_always_zero_flag = -1;
  962 + if ((ret = srs_avc_nalu_read_bit(&bs, delta_pic_order_always_zero_flag)) != ERROR_SUCCESS) {
  963 + return ret;
  964 + }
  965 +
  966 + int64_t offset_for_non_ref_pic = -1;
  967 + if ((ret = srs_avc_nalu_read_uev(&bs, offset_for_non_ref_pic)) != ERROR_SUCCESS) {
  968 + return ret;
  969 + }
  970 +
  971 + int64_t offset_for_top_to_bottom_field = -1;
  972 + if ((ret = srs_avc_nalu_read_uev(&bs, offset_for_top_to_bottom_field)) != ERROR_SUCCESS) {
  973 + return ret;
  974 + }
  975 +
  976 + int64_t num_ref_frames_in_pic_order_cnt_cycle = -1;
  977 + if ((ret = srs_avc_nalu_read_uev(&bs, num_ref_frames_in_pic_order_cnt_cycle)) != ERROR_SUCCESS) {
  978 + return ret;
  979 + }
  980 + if (num_ref_frames_in_pic_order_cnt_cycle) {
  981 + ret = ERROR_HLS_DECODE_ERROR;
  982 + srs_error("sps the num_ref_frames_in_pic_order_cnt_cycle invalid. ret=%d", ret);
  983 + return ret;
  984 + }
  985 + }
  986 +
  987 + int64_t max_num_ref_frames = -1;
  988 + if ((ret = srs_avc_nalu_read_uev(&bs, max_num_ref_frames)) != ERROR_SUCCESS) {
  989 + return ret;
  990 + }
  991 +
  992 + int8_t gaps_in_frame_num_value_allowed_flag = -1;
  993 + if ((ret = srs_avc_nalu_read_bit(&bs, gaps_in_frame_num_value_allowed_flag)) != ERROR_SUCCESS) {
  994 + return ret;
  995 + }
  996 +
  997 + int64_t pic_width_in_mbs_minus1 = -1;
  998 + if ((ret = srs_avc_nalu_read_uev(&bs, pic_width_in_mbs_minus1)) != ERROR_SUCCESS) {
  999 + return ret;
  1000 + }
  1001 +
  1002 + int64_t pic_height_in_map_units_minus1 = -1;
  1003 + if ((ret = srs_avc_nalu_read_uev(&bs, pic_height_in_map_units_minus1)) != ERROR_SUCCESS) {
  1004 + return ret;
  1005 + }
  1006 +
  1007 + width = (int)(pic_width_in_mbs_minus1 + 1) * 16;
  1008 + height = (int)(pic_height_in_map_units_minus1 + 1) * 16;
  1009 +
777 return ret; 1010 return ret;
778 } 1011 }
779 1012
@@ -581,6 +581,11 @@ private: @@ -581,6 +581,11 @@ private:
581 */ 581 */
582 virtual int avc_demux_sps_pps(SrsStream* stream); 582 virtual int avc_demux_sps_pps(SrsStream* stream);
583 /** 583 /**
  584 + * decode the sps rbsp stream.
  585 + */
  586 + virtual int avc_demux_sps();
  587 + virtual int avc_demux_sps_rbsp(char* rbsp, int nb_rbsp);
  588 + /**
584 * demux the avc NALU in "AnnexB" 589 * demux the avc NALU in "AnnexB"
585 * from H.264-AVC-ISO_IEC_14496-10.pdf, page 211. 590 * from H.264-AVC-ISO_IEC_14496-10.pdf, page 211.
586 */ 591 */
@@ -215,7 +215,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -215,7 +215,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
215 #define ERROR_HTTP_DVR_CREATE_REQUEST 3053 215 #define ERROR_HTTP_DVR_CREATE_REQUEST 3053
216 #define ERROR_HTTP_DVR_NO_TAEGET 3054 216 #define ERROR_HTTP_DVR_NO_TAEGET 3054
217 #define ERROR_ADTS_ID_NOT_AAC 3055 217 #define ERROR_ADTS_ID_NOT_AAC 3055
218 -  
219 // HDS error code 218 // HDS error code
220 #define ERROR_HDS_OPEN_F4M_FAILED 3056 219 #define ERROR_HDS_OPEN_F4M_FAILED 3056
221 #define ERROR_HDS_WRITE_F4M_FAILED 3057 220 #define ERROR_HDS_WRITE_F4M_FAILED 3057
@@ -254,6 +253,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -254,6 +253,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
254 #define ERROR_STREAM_CASTER_FLV_TAG 4024 253 #define ERROR_STREAM_CASTER_FLV_TAG 4024
255 #define ERROR_HTTP_RESPONSE_EOF 4025 254 #define ERROR_HTTP_RESPONSE_EOF 4025
256 #define ERROR_HTTP_INVALID_CHUNK_HEADER 4026 255 #define ERROR_HTTP_INVALID_CHUNK_HEADER 4026
  256 +#define ERROR_AVC_NALU_UEV 4027
257 257
258 /////////////////////////////////////////////////////// 258 ///////////////////////////////////////////////////////
259 // user-define error. 259 // user-define error.
@@ -252,4 +252,38 @@ void SrsStream::write_bytes(char* data, int size) @@ -252,4 +252,38 @@ void SrsStream::write_bytes(char* data, int size)
252 p += size; 252 p += size;
253 } 253 }
254 254
  255 +SrsBitStream::SrsBitStream()
  256 +{
  257 + cb = 0;
  258 + cb_left = 0;
  259 + stream = NULL;
  260 +}
  261 +
  262 +SrsBitStream::~SrsBitStream()
  263 +{
  264 +}
  265 +
  266 +int SrsBitStream::initialize(SrsStream* s) {
  267 + stream = s;
  268 + return ERROR_SUCCESS;
  269 +}
  270 +
  271 +bool SrsBitStream::empty() {
  272 + if (cb_left) {
  273 + return false;
  274 + }
  275 + return stream->empty();
  276 +}
  277 +
  278 +int8_t SrsBitStream::read_bit() {
  279 + if (!cb_left) {
  280 + srs_assert(!stream->empty());
  281 + cb = stream->read_1bytes();
  282 + cb_left = 8;
  283 + }
  284 +
  285 + int8_t v = (cb >> (cb_left - 1)) & 0x01;
  286 + cb_left--;
  287 + return v;
  288 +}
255 289
@@ -154,4 +154,22 @@ public: @@ -154,4 +154,22 @@ public:
154 virtual void write_bytes(char* data, int size); 154 virtual void write_bytes(char* data, int size);
155 }; 155 };
156 156
  157 +/**
  158 + * the bit stream.
  159 + */
  160 +class SrsBitStream
  161 +{
  162 +private:
  163 + int8_t cb;
  164 + u_int8_t cb_left;
  165 + SrsStream* stream;
  166 +public:
  167 + SrsBitStream();
  168 + virtual ~SrsBitStream();
  169 +public:
  170 + virtual int initialize(SrsStream* s);
  171 + virtual bool empty();
  172 + virtual int8_t read_bit();
  173 +};
  174 +
157 #endif 175 #endif
@@ -46,6 +46,53 @@ using namespace std; @@ -46,6 +46,53 @@ using namespace std;
46 // @see SRS_SYS_TIME_RESOLUTION_MS_TIMES 46 // @see SRS_SYS_TIME_RESOLUTION_MS_TIMES
47 #define SYS_TIME_RESOLUTION_US 300*1000 47 #define SYS_TIME_RESOLUTION_US 300*1000
48 48
  49 +int srs_avc_nalu_read_uev(SrsBitStream* stream, int64_t& v)
  50 +{
  51 + int ret = ERROR_SUCCESS;
  52 +
  53 + if (stream->empty()) {
  54 + return ERROR_AVC_NALU_UEV;
  55 + }
  56 +
  57 + // ue(v) in 9.1 Parsing process for Exp-Golomb codes
  58 + // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 227.
  59 + // Syntax elements coded as ue(v), me(v), or se(v) are Exp-Golomb-coded.
  60 + // leadingZeroBits = -1;
  61 + // for( b = 0; !b; leadingZeroBits++ )
  62 + // b = read_bits( 1 )
  63 + // The variable codeNum is then assigned as follows:
  64 + // codeNum = (2<<leadingZeroBits) – 1 + read_bits( leadingZeroBits )
  65 + int leadingZeroBits = -1;
  66 + for (int8_t b = 0; !b && !stream->empty(); leadingZeroBits++) {
  67 + b = stream->read_bit();
  68 + }
  69 +
  70 + if (leadingZeroBits >= 64) {
  71 + return ERROR_AVC_NALU_UEV;
  72 + }
  73 +
  74 + v = (1 << leadingZeroBits) - 1;
  75 + for (int i = 0; i < leadingZeroBits; i++) {
  76 + int64_t b = stream->read_bit();
  77 + v += b << (leadingZeroBits - 1);
  78 + }
  79 +
  80 + return ret;
  81 +}
  82 +
  83 +int srs_avc_nalu_read_bit(SrsBitStream* stream, int8_t& v)
  84 +{
  85 + int ret = ERROR_SUCCESS;
  86 +
  87 + if (stream->empty()) {
  88 + return ERROR_AVC_NALU_UEV;
  89 + }
  90 +
  91 + v = stream->read_bit();
  92 +
  93 + return ret;
  94 +}
  95 +
49 static int64_t _srs_system_time_us_cache = 0; 96 static int64_t _srs_system_time_us_cache = 0;
50 static int64_t _srs_system_time_startup_time = 0; 97 static int64_t _srs_system_time_startup_time = 0;
51 98
@@ -33,11 +33,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -33,11 +33,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 #include <string> 33 #include <string>
34 34
35 class SrsStream; 35 class SrsStream;
  36 +class SrsBitStream;
36 37
37 // compare 38 // compare
38 #define srs_min(a, b) (((a) < (b))? (a) : (b)) 39 #define srs_min(a, b) (((a) < (b))? (a) : (b))
39 #define srs_max(a, b) (((a) < (b))? (b) : (a)) 40 #define srs_max(a, b) (((a) < (b))? (b) : (a))
40 41
  42 +// read nalu uev.
  43 +extern int srs_avc_nalu_read_uev(SrsBitStream* stream, int64_t& v);
  44 +extern int srs_avc_nalu_read_bit(SrsBitStream* stream, int8_t& v);
  45 +
41 // get current system time in ms, use cache to avoid performance problem 46 // get current system time in ms, use cache to avoid performance problem
42 extern int64_t srs_get_system_time_ms(); 47 extern int64_t srs_get_system_time_ms();
43 extern int64_t srs_get_system_startup_time_ms(); 48 extern int64_t srs_get_system_startup_time_ms();