+static AVStream *find_matching_stream(MpegTSContext *ts, int pid,
+ int stream_identifier, int pmt_stream_idx)
+{
+ AVFormatContext *s = ts->stream;
+ int i;
+ AVStream *found = NULL;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ if (stream_identifier != -1) { /* match based on "stream identifier descriptor" if present */
+ if (st->stream_identifier == stream_identifier+1) {
+ found = st;
+ break;
+ }
+ } else if (st->pmt_stream_idx == pmt_stream_idx) { /* match based on position within the PMT */
+ found = st;
+ break;
+ }
+ }
+
+ if (found) {
+ av_log(ts->stream, AV_LOG_VERBOSE,
+ "re-using existing %s stream %d (pid=0x%x) for new pid=0x%x\n",
+ av_get_media_type_string(found->codecpar->codec_type),
+ i, found->id, pid);
+ }
+
+ return found;
+}
+
+static int parse_stream_identifier_desc(const uint8_t *p, const uint8_t *p_end)
+{
+ const uint8_t **pp = &p;
+ const uint8_t *desc_list_end;
+ const uint8_t *desc_end;
+ int desc_list_len;
+ int desc_len, desc_tag;
+
+ desc_list_len = get16(pp, p_end);
+ if (desc_list_len < 0)
+ return -1;
+ desc_list_len &= 0xfff;
+ desc_list_end = p + desc_list_len;
+ if (desc_list_end > p_end)
+ return -1;
+
+ while (1) {
+ desc_tag = get8(pp, desc_list_end);
+ if (desc_tag < 0)
+ return -1;
+ desc_len = get8(pp, desc_list_end);
+ if (desc_len < 0)
+ return -1;
+ desc_end = *pp + desc_len;
+ if (desc_end > desc_list_end)
+ return -1;
+
+ if (desc_tag == 0x52) {
+ return get8(pp, desc_end);
+ }
+ *pp = desc_end;
+ }
+
+ return -1;
+}
+