|
55 | 55 | #define INIT_BUFFER_THRESHOLD_MAX_MS (8*1000)
|
56 | 56 | #define MAX_BUFFER_TIME 10000
|
57 | 57 | #define MAX_STATE_CNT 30
|
| 58 | +#define NALU_HEAD_LEN 4 |
| 59 | +#define H264_NAL_SPS 7 |
| 60 | +#define H264_NAL_PPS 8 |
58 | 61 |
|
59 | 62 | typedef struct AdaptiveConfig {
|
60 | 63 | int32_t buffer_init;
|
@@ -1902,6 +1905,105 @@ static void reset_packet(AVPacket* pkt) {
|
1902 | 1905 | }
|
1903 | 1906 | }
|
1904 | 1907 |
|
| 1908 | +static bool h264_check_sps_pps(const AVPacket* pkt) { |
| 1909 | + if (pkt && pkt->data && pkt->size >= 5) { |
| 1910 | + int offset = 0; |
| 1911 | + |
| 1912 | + while (offset >= 0 && offset + 5 <= pkt->size) { |
| 1913 | + uint8_t* nal_start = pkt->data + offset; |
| 1914 | + int nal_size = AV_RB32(nal_start); |
| 1915 | + int nal_type = nal_start[4] & 0x1f; |
| 1916 | + |
| 1917 | + if (nal_type == H264_NAL_SPS || nal_type == H264_NAL_PPS) { |
| 1918 | + return true; |
| 1919 | + } |
| 1920 | + |
| 1921 | + offset += nal_size + 4; |
| 1922 | + } |
| 1923 | + } |
| 1924 | + return false; |
| 1925 | +} |
| 1926 | + |
| 1927 | +static bool read_sps_pps_by_avcc(uint8_t* extradata, uint32_t extrasize, |
| 1928 | + uint8_t** sps, int* sps_len, |
| 1929 | + uint8_t** pps, int* pps_len) { |
| 1930 | + uint8_t* spc = extradata + 6; |
| 1931 | + uint32_t sps_size = AV_RB16(spc); |
| 1932 | + if (sps_size) { |
| 1933 | + *sps_len = sps_size; |
| 1934 | + *sps = (uint8_t*)av_mallocz(sps_size); |
| 1935 | + if (!*sps) { |
| 1936 | + return false; |
| 1937 | + } |
| 1938 | + spc += 2; |
| 1939 | + memcpy(*sps, spc, sps_size); |
| 1940 | + spc += sps_size; |
| 1941 | + } |
| 1942 | + spc += 1; |
| 1943 | + uint32_t pps_size = AV_RB16(spc); |
| 1944 | + if (pps_size) { |
| 1945 | + *pps_len = pps_size; |
| 1946 | + *pps = (uint8_t*)av_mallocz(pps_size); |
| 1947 | + if (!*pps) { |
| 1948 | + if (*sps) { |
| 1949 | + free(*sps); |
| 1950 | + } |
| 1951 | + return false; |
| 1952 | + } |
| 1953 | + spc += 2; |
| 1954 | + memcpy(*pps, spc, pps_size); |
| 1955 | + } |
| 1956 | + return true; |
| 1957 | +} |
| 1958 | + |
| 1959 | +static void insert_sps_pps_into_avpacket(AVPacket* packet, uint8_t* new_extradata, int new_extradata_size, PlayList* playlist) { |
| 1960 | + uint8_t* sps = NULL, *pps = NULL; |
| 1961 | + int sps_len = 0, pps_len = 0; |
| 1962 | + |
| 1963 | + if (read_sps_pps_by_avcc(new_extradata, new_extradata_size, &sps, &sps_len, &pps, &pps_len)) { |
| 1964 | + int size = packet->size; |
| 1965 | + if (sps) { |
| 1966 | + size += NALU_HEAD_LEN + sps_len; |
| 1967 | + } |
| 1968 | + if (pps) { |
| 1969 | + size += NALU_HEAD_LEN + pps_len; |
| 1970 | + } |
| 1971 | + if (size == packet->size) { |
| 1972 | + return; |
| 1973 | + } |
| 1974 | + AVPacket new_pack; |
| 1975 | + int res = av_new_packet(&new_pack, size); |
| 1976 | + if (res < 0) { |
| 1977 | + log_error("Failed memory allocation"); |
| 1978 | + } else { |
| 1979 | + av_packet_copy_props(&new_pack, packet); |
| 1980 | + uint8_t* data = new_pack.data; |
| 1981 | + |
| 1982 | + if (sps) { |
| 1983 | + AV_WB32(data, sps_len); |
| 1984 | + data += NALU_HEAD_LEN; |
| 1985 | + memcpy(data, sps, sps_len); |
| 1986 | + data += sps_len; |
| 1987 | + log_info("insert sps, size:%d", sps_len); |
| 1988 | + } else { |
| 1989 | + log_info("sps is null"); |
| 1990 | + } |
| 1991 | + if (pps) { |
| 1992 | + AV_WB32(data, pps_len); |
| 1993 | + data += NALU_HEAD_LEN; |
| 1994 | + memcpy(data, pps, pps_len); |
| 1995 | + data += pps_len; |
| 1996 | + log_info("insert pps, size:%d", pps_len); |
| 1997 | + } else { |
| 1998 | + log_info("pps is null"); |
| 1999 | + } |
| 2000 | + memcpy(data, packet->data, packet->size); |
| 2001 | + av_packet_unref(packet); |
| 2002 | + *packet = new_pack; |
| 2003 | + } |
| 2004 | + } |
| 2005 | +} |
| 2006 | + |
1905 | 2007 | static int las_read_packet(AVFormatContext* s, AVPacket* pkt) {
|
1906 | 2008 | LasContext* c = s->priv_data;
|
1907 | 2009 | PlayList* playlist = &c->playlist;
|
@@ -1936,6 +2038,10 @@ static int las_read_packet(AVFormatContext* s, AVPacket* pkt) {
|
1936 | 2038 | }
|
1937 | 2039 | AVCodecParameters* codec = playlist->ctx->streams[pkt->stream_index]->codecpar;
|
1938 | 2040 | if (codec->extradata) {
|
| 2041 | + if (codec->codec_id == AV_CODEC_ID_H264 |
| 2042 | + && !h264_check_sps_pps(pkt)) { |
| 2043 | + insert_sps_pps_into_avpacket(pkt, codec->extradata, codec->extradata_size, playlist); |
| 2044 | + } |
1939 | 2045 | uint8_t *side = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, codec->extradata_size);
|
1940 | 2046 | if (side) {
|
1941 | 2047 | memcpy(side, codec->extradata, codec->extradata_size);
|
|
0 commit comments