... | ... |
@@ -153,6 +153,7 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id); |
153 | 153 |
#define MP4ESDescrTag 0x03 |
154 | 154 |
#define MP4DecConfigDescrTag 0x04 |
155 | 155 |
#define MP4DecSpecificDescrTag 0x05 |
156 |
+#define MP4SLDescrTag 0x06 |
|
156 | 157 |
|
157 | 158 |
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom); |
158 | 159 |
enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags); |
... | ... |
@@ -28,6 +28,7 @@ |
28 | 28 |
#include "libavutil/mathematics.h" |
29 | 29 |
#include "libavutil/opt.h" |
30 | 30 |
#include "libavcodec/bytestream.h" |
31 |
+#include "libavcodec/get_bits.h" |
|
31 | 32 |
#include "avformat.h" |
32 | 33 |
#include "mpegts.h" |
33 | 34 |
#include "internal.h" |
... | ... |
@@ -175,6 +176,7 @@ typedef struct PESContext { |
175 | 175 |
int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ |
176 | 176 |
uint8_t header[MAX_PES_HEADER_SIZE]; |
177 | 177 |
uint8_t *buffer; |
178 |
+ SLConfigDescr sl; |
|
178 | 179 |
} PESContext; |
179 | 180 |
|
180 | 181 |
extern AVInputFormat ff_mpegts_demuxer; |
... | ... |
@@ -658,6 +660,83 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt) |
658 | 658 |
pes->flags = 0; |
659 | 659 |
} |
660 | 660 |
|
661 |
+static uint64_t get_bits64(GetBitContext *gb, int bits) |
|
662 |
+{ |
|
663 |
+ uint64_t ret = 0; |
|
664 |
+ while (bits > 17) { |
|
665 |
+ ret <<= 17; |
|
666 |
+ ret |= get_bits(gb, 17); |
|
667 |
+ bits -= 17; |
|
668 |
+ } |
|
669 |
+ ret <<= bits; |
|
670 |
+ ret |= get_bits(gb, bits); |
|
671 |
+ return ret; |
|
672 |
+} |
|
673 |
+ |
|
674 |
+static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size) |
|
675 |
+{ |
|
676 |
+ GetBitContext gb; |
|
677 |
+ int au_start_flag = 0, au_end_flag = 0, ocr_flag = 0, idle_flag = 0; |
|
678 |
+ int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0; |
|
679 |
+ int dts_flag = -1, cts_flag = -1; |
|
680 |
+ int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE; |
|
681 |
+ init_get_bits(&gb, buf, buf_size*8); |
|
682 |
+ |
|
683 |
+ if (sl->use_au_start) |
|
684 |
+ au_start_flag = get_bits1(&gb); |
|
685 |
+ if (sl->use_au_end) |
|
686 |
+ au_end_flag = get_bits1(&gb); |
|
687 |
+ if (!sl->use_au_start && !sl->use_au_end) |
|
688 |
+ au_start_flag = au_end_flag = 1; |
|
689 |
+ if (sl->ocr_len > 0) |
|
690 |
+ ocr_flag = get_bits1(&gb); |
|
691 |
+ if (sl->use_idle) |
|
692 |
+ idle_flag = get_bits1(&gb); |
|
693 |
+ if (sl->use_padding) |
|
694 |
+ padding_flag = get_bits1(&gb); |
|
695 |
+ if (padding_flag) |
|
696 |
+ padding_bits = get_bits(&gb, 3); |
|
697 |
+ |
|
698 |
+ if (!idle_flag && (!padding_flag || padding_bits != 0)) { |
|
699 |
+ if (sl->packet_seq_num_len) |
|
700 |
+ skip_bits_long(&gb, sl->packet_seq_num_len); |
|
701 |
+ if (sl->degr_prior_len) |
|
702 |
+ if (get_bits1(&gb)) |
|
703 |
+ skip_bits(&gb, sl->degr_prior_len); |
|
704 |
+ if (ocr_flag) |
|
705 |
+ skip_bits_long(&gb, sl->ocr_len); |
|
706 |
+ if (au_start_flag) { |
|
707 |
+ if (sl->use_rand_acc_pt) |
|
708 |
+ get_bits1(&gb); |
|
709 |
+ if (sl->au_seq_num_len > 0) |
|
710 |
+ skip_bits_long(&gb, sl->au_seq_num_len); |
|
711 |
+ if (sl->use_timestamps) { |
|
712 |
+ dts_flag = get_bits1(&gb); |
|
713 |
+ cts_flag = get_bits1(&gb); |
|
714 |
+ } |
|
715 |
+ } |
|
716 |
+ if (sl->inst_bitrate_len) |
|
717 |
+ inst_bitrate_flag = get_bits1(&gb); |
|
718 |
+ if (dts_flag == 1) |
|
719 |
+ dts = get_bits64(&gb, sl->timestamp_len); |
|
720 |
+ if (cts_flag == 1) |
|
721 |
+ cts = get_bits64(&gb, sl->timestamp_len); |
|
722 |
+ if (sl->au_len > 0) |
|
723 |
+ skip_bits_long(&gb, sl->au_len); |
|
724 |
+ if (inst_bitrate_flag) |
|
725 |
+ skip_bits_long(&gb, sl->inst_bitrate_len); |
|
726 |
+ } |
|
727 |
+ |
|
728 |
+ if (dts != AV_NOPTS_VALUE) |
|
729 |
+ pes->dts = dts; |
|
730 |
+ if (cts != AV_NOPTS_VALUE) |
|
731 |
+ pes->pts = cts; |
|
732 |
+ |
|
733 |
+ av_set_pts_info(pes->st, sl->timestamp_len, 1, sl->timestamp_res); |
|
734 |
+ |
|
735 |
+ return (get_bits_count(&gb) + 7) >> 3; |
|
736 |
+} |
|
737 |
+ |
|
661 | 738 |
/* return non zero if a packet could be constructed */ |
662 | 739 |
static int mpegts_push_data(MpegTSFilter *filter, |
663 | 740 |
const uint8_t *buf, int buf_size, int is_start, |
... | ... |
@@ -809,6 +888,12 @@ static int mpegts_push_data(MpegTSFilter *filter, |
809 | 809 |
/* we got the full header. We parse it and get the payload */ |
810 | 810 |
pes->state = MPEGTS_PAYLOAD; |
811 | 811 |
pes->data_index = 0; |
812 |
+ if (pes->stream_type == 0x12) { |
|
813 |
+ int sl_header_bytes = read_sl_header(pes, &pes->sl, p, buf_size); |
|
814 |
+ pes->pes_header_size += sl_header_bytes; |
|
815 |
+ p += sl_header_bytes; |
|
816 |
+ buf_size -= sl_header_bytes; |
|
817 |
+ } |
|
812 | 818 |
} |
813 | 819 |
break; |
814 | 820 |
case MPEGTS_PAYLOAD: |
... | ... |
@@ -962,7 +1047,9 @@ static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len) |
962 | 962 |
d->active_descr->es_id = es_id; |
963 | 963 |
update_offsets(&d->pb, &off, &len); |
964 | 964 |
parse_mp4_descr(d, off, len, MP4DecConfigDescrTag); |
965 |
- //SLConfigDescriptor |
|
965 |
+ update_offsets(&d->pb, &off, &len); |
|
966 |
+ if (len > 0) |
|
967 |
+ parse_mp4_descr(d, off, len, MP4SLDescrTag); |
|
966 | 968 |
d->active_descr = NULL; |
967 | 969 |
return 0; |
968 | 970 |
} |
... | ... |
@@ -980,6 +1067,39 @@ static int parse_MP4DecConfigDescrTag(MP4DescrParseContext *d, int64_t off, int |
980 | 980 |
return 0; |
981 | 981 |
} |
982 | 982 |
|
983 |
+static int parse_MP4SLDescrTag(MP4DescrParseContext *d, int64_t off, int len) |
|
984 |
+{ |
|
985 |
+ Mp4Descr *descr = d->active_descr; |
|
986 |
+ int predefined; |
|
987 |
+ if (!descr) |
|
988 |
+ return -1; |
|
989 |
+ |
|
990 |
+ predefined = avio_r8(&d->pb); |
|
991 |
+ if (!predefined) { |
|
992 |
+ int lengths; |
|
993 |
+ int flags = avio_r8(&d->pb); |
|
994 |
+ descr->sl.use_au_start = !!(flags & 0x80); |
|
995 |
+ descr->sl.use_au_end = !!(flags & 0x40); |
|
996 |
+ descr->sl.use_rand_acc_pt = !!(flags & 0x20); |
|
997 |
+ descr->sl.use_padding = !!(flags & 0x08); |
|
998 |
+ descr->sl.use_timestamps = !!(flags & 0x04); |
|
999 |
+ descr->sl.use_idle = !!(flags & 0x02); |
|
1000 |
+ descr->sl.timestamp_res = avio_rb32(&d->pb); |
|
1001 |
+ avio_rb32(&d->pb); |
|
1002 |
+ descr->sl.timestamp_len = avio_r8(&d->pb); |
|
1003 |
+ descr->sl.ocr_len = avio_r8(&d->pb); |
|
1004 |
+ descr->sl.au_len = avio_r8(&d->pb); |
|
1005 |
+ descr->sl.inst_bitrate_len = avio_r8(&d->pb); |
|
1006 |
+ lengths = avio_rb16(&d->pb); |
|
1007 |
+ descr->sl.degr_prior_len = lengths >> 12; |
|
1008 |
+ descr->sl.au_seq_num_len = (lengths >> 7) & 0x1f; |
|
1009 |
+ descr->sl.packet_seq_num_len = (lengths >> 2) & 0x1f; |
|
1010 |
+ } else { |
|
1011 |
+ av_log_missing_feature(d->s, "Predefined SLConfigDescriptor\n", 0); |
|
1012 |
+ } |
|
1013 |
+ return 0; |
|
1014 |
+} |
|
1015 |
+ |
|
983 | 1016 |
static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, |
984 | 1017 |
int target_tag) { |
985 | 1018 |
int tag; |
... | ... |
@@ -1013,6 +1133,9 @@ static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, |
1013 | 1013 |
case MP4DecConfigDescrTag: |
1014 | 1014 |
parse_MP4DecConfigDescrTag(d, off, len1); |
1015 | 1015 |
break; |
1016 |
+ case MP4SLDescrTag: |
|
1017 |
+ parse_MP4SLDescrTag(d, off, len1); |
|
1018 |
+ break; |
|
1016 | 1019 |
} |
1017 | 1020 |
|
1018 | 1021 |
done: |
... | ... |
@@ -1047,12 +1170,23 @@ static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size, |
1047 | 1047 |
return 0; |
1048 | 1048 |
} |
1049 | 1049 |
|
1050 |
-static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, const uint8_t *p_end) |
|
1050 |
+static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) |
|
1051 | 1051 |
{ |
1052 |
+ MpegTSContext *ts = filter->u.section_filter.opaque; |
|
1053 |
+ SectionHeader h; |
|
1054 |
+ const uint8_t *p, *p_end; |
|
1052 | 1055 |
AVIOContext pb; |
1053 | 1056 |
Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }}; |
1054 | 1057 |
int mp4_descr_count = 0; |
1055 | 1058 |
int i, pid; |
1059 |
+ AVFormatContext *s = ts->stream; |
|
1060 |
+ |
|
1061 |
+ p_end = section + section_len - 4; |
|
1062 |
+ p = section; |
|
1063 |
+ if (parse_section_header(&h, &p, p_end) < 0) |
|
1064 |
+ return; |
|
1065 |
+ if (h.tid != M4OD_TID) |
|
1066 |
+ return; |
|
1056 | 1067 |
|
1057 | 1068 |
mp4_read_od(s, p, (unsigned)(p_end - p), mp4_descr, &mp4_descr_count, MAX_MP4_DESCR_COUNT); |
1058 | 1069 |
|
... | ... |
@@ -1074,6 +1208,8 @@ static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, c |
1074 | 1074 |
continue; |
1075 | 1075 |
} |
1076 | 1076 |
|
1077 |
+ pes->sl = mp4_descr[i].sl; |
|
1078 |
+ |
|
1077 | 1079 |
ffio_init_context(&pb, mp4_descr[i].dec_config_descr, |
1078 | 1080 |
mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL); |
1079 | 1081 |
ff_mp4_read_dec_config_descr(s, st, &pb); |
... | ... |
@@ -1098,25 +1234,6 @@ static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, c |
1098 | 1098 |
av_free(mp4_descr[i].dec_config_descr); |
1099 | 1099 |
} |
1100 | 1100 |
|
1101 |
-static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) |
|
1102 |
-{ |
|
1103 |
- MpegTSContext *ts = filter->u.section_filter.opaque; |
|
1104 |
- SectionHeader h1, *h = &h1; |
|
1105 |
- const uint8_t *p, *p_end; |
|
1106 |
- |
|
1107 |
- av_dlog(ts->stream, "m4SL/od:\n"); |
|
1108 |
- hex_dump_debug(ts->stream, (uint8_t *)section, section_len); |
|
1109 |
- |
|
1110 |
- p_end = section + section_len - 4; |
|
1111 |
- p = section; |
|
1112 |
- if (parse_section_header(h, &p, p_end) < 0) |
|
1113 |
- return; |
|
1114 |
- if (h->tid != M4OD_TID) |
|
1115 |
- return; |
|
1116 |
- |
|
1117 |
- SL_packet(ts->stream, ts, p, p_end); |
|
1118 |
-} |
|
1119 |
- |
|
1120 | 1101 |
int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, |
1121 | 1102 |
const uint8_t **pp, const uint8_t *desc_list_end, |
1122 | 1103 |
Mp4Descr *mp4_descr, int mp4_descr_count, int pid, |
... | ... |
@@ -66,9 +66,27 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, |
66 | 66 |
void ff_mpegts_parse_close(MpegTSContext *ts); |
67 | 67 |
|
68 | 68 |
typedef struct { |
69 |
+ int use_au_start; |
|
70 |
+ int use_au_end; |
|
71 |
+ int use_rand_acc_pt; |
|
72 |
+ int use_padding; |
|
73 |
+ int use_timestamps; |
|
74 |
+ int use_idle; |
|
75 |
+ int timestamp_res; |
|
76 |
+ int timestamp_len; |
|
77 |
+ int ocr_len; |
|
78 |
+ int au_len; |
|
79 |
+ int inst_bitrate_len; |
|
80 |
+ int degr_prior_len; |
|
81 |
+ int au_seq_num_len; |
|
82 |
+ int packet_seq_num_len; |
|
83 |
+} SLConfigDescr; |
|
84 |
+ |
|
85 |
+typedef struct { |
|
69 | 86 |
int es_id; |
70 | 87 |
int dec_config_descr_len; |
71 | 88 |
uint8_t *dec_config_descr; |
89 |
+ SLConfigDescr sl; |
|
72 | 90 |
} Mp4Descr; |
73 | 91 |
|
74 | 92 |
/** |