| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * MPEG-2 transport stream (aka DVB) demuxer | ||
| 3 | * Copyright (c) 2002-2003 Fabrice Bellard | ||
| 4 | * | ||
| 5 | * This file is part of FFmpeg. | ||
| 6 | * | ||
| 7 | * FFmpeg is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with FFmpeg; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include "config_components.h" | ||
| 23 | |||
| 24 | #include "libavutil/attributes_internal.h" | ||
| 25 | #include "libavutil/buffer.h" | ||
| 26 | #include "libavutil/crc.h" | ||
| 27 | #include "libavutil/internal.h" | ||
| 28 | #include "libavutil/intreadwrite.h" | ||
| 29 | #include "libavutil/log.h" | ||
| 30 | #include "libavutil/dict.h" | ||
| 31 | #include "libavutil/mem.h" | ||
| 32 | #include "libavutil/opt.h" | ||
| 33 | #include "libavutil/avassert.h" | ||
| 34 | #include "libavutil/dovi_meta.h" | ||
| 35 | #include "libavcodec/bytestream.h" | ||
| 36 | #include "libavcodec/defs.h" | ||
| 37 | #include "libavcodec/get_bits.h" | ||
| 38 | #include "libavcodec/opus/opus.h" | ||
| 39 | #include "avformat.h" | ||
| 40 | #include "mpegts.h" | ||
| 41 | #include "internal.h" | ||
| 42 | #include "avio_internal.h" | ||
| 43 | #include "demux.h" | ||
| 44 | #include "mpeg.h" | ||
| 45 | #include "isom.h" | ||
| 46 | #include "id3v2.h" | ||
| 47 | #if CONFIG_ICONV | ||
| 48 | #include <iconv.h> | ||
| 49 | #endif | ||
| 50 | |||
| 51 | /* maximum size in which we look for synchronization if | ||
| 52 | * synchronization is lost */ | ||
| 53 | #define MAX_RESYNC_SIZE 65536 | ||
| 54 | |||
| 55 | /* payload of a TS packet which carries no adaptation field */ | ||
| 56 | #define TS_PAYLOAD_SIZE (TS_PACKET_SIZE - 4) | ||
| 57 | |||
| 58 | #define MAX_MP4_DESCR_COUNT 16 | ||
| 59 | |||
| 60 | #define MOD_UNLIKELY(modulus, dividend, divisor, prev_dividend) \ | ||
| 61 | do { \ | ||
| 62 | if ((prev_dividend) == 0 || (dividend) - (prev_dividend) != (divisor)) \ | ||
| 63 | (modulus) = (dividend) % (divisor); \ | ||
| 64 | (prev_dividend) = (dividend); \ | ||
| 65 | } while (0) | ||
| 66 | |||
| 67 | #define PROBE_PACKET_MAX_BUF 8192 | ||
| 68 | #define PROBE_PACKET_MARGIN 5 | ||
| 69 | |||
| 70 | enum MpegTSFilterType { | ||
| 71 | MPEGTS_PES, | ||
| 72 | MPEGTS_SECTION, | ||
| 73 | MPEGTS_PCR, | ||
| 74 | }; | ||
| 75 | |||
| 76 | typedef struct MpegTSFilter MpegTSFilter; | ||
| 77 | |||
| 78 | typedef int PESCallback (MpegTSFilter *f, const uint8_t *buf, int len, | ||
| 79 | int is_start, int64_t pos); | ||
| 80 | |||
| 81 | typedef struct MpegTSPESFilter { | ||
| 82 | PESCallback *pes_cb; | ||
| 83 | void *opaque; | ||
| 84 | } MpegTSPESFilter; | ||
| 85 | |||
| 86 | typedef void SectionCallback (MpegTSFilter *f, const uint8_t *buf, int len); | ||
| 87 | |||
| 88 | typedef void SetServiceCallback (void *opaque, int ret); | ||
| 89 | |||
| 90 | typedef struct MpegTSSectionFilter { | ||
| 91 | int section_index; | ||
| 92 | int section_h_size; | ||
| 93 | int last_ver; | ||
| 94 | unsigned crc; | ||
| 95 | unsigned last_crc; | ||
| 96 | uint8_t *section_buf; | ||
| 97 | unsigned int check_crc : 1; | ||
| 98 | unsigned int end_of_section_reached : 1; | ||
| 99 | SectionCallback *section_cb; | ||
| 100 | void *opaque; | ||
| 101 | } MpegTSSectionFilter; | ||
| 102 | |||
| 103 | struct MpegTSFilter { | ||
| 104 | int pid; | ||
| 105 | int es_id; | ||
| 106 | int last_cc; /* last cc code (-1 if first packet) */ | ||
| 107 | int64_t last_pcr; | ||
| 108 | int discard; | ||
| 109 | enum MpegTSFilterType type; | ||
| 110 | union { | ||
| 111 | MpegTSPESFilter pes_filter; | ||
| 112 | MpegTSSectionFilter section_filter; | ||
| 113 | } u; | ||
| 114 | }; | ||
| 115 | |||
| 116 | struct Stream { | ||
| 117 | int idx; | ||
| 118 | int stream_identifier; | ||
| 119 | }; | ||
| 120 | |||
| 121 | #define MAX_STREAMS_PER_PROGRAM 128 | ||
| 122 | #define MAX_PIDS_PER_PROGRAM (MAX_STREAMS_PER_PROGRAM + 2) | ||
| 123 | |||
| 124 | struct StreamGroup { | ||
| 125 | enum AVStreamGroupParamsType type; | ||
| 126 | int id; | ||
| 127 | int dep_pid; /* PID of the linked dependency stream */ | ||
| 128 | unsigned int nb_streams; | ||
| 129 | AVStream *streams[MAX_STREAMS_PER_PROGRAM]; | ||
| 130 | }; | ||
| 131 | |||
| 132 | struct Program { | ||
| 133 | unsigned int id; // program id/service id | ||
| 134 | unsigned int nb_pids; | ||
| 135 | unsigned int pids[MAX_PIDS_PER_PROGRAM]; | ||
| 136 | unsigned int nb_streams; | ||
| 137 | struct Stream streams[MAX_STREAMS_PER_PROGRAM]; | ||
| 138 | unsigned int nb_stream_groups; | ||
| 139 | struct StreamGroup stream_groups[MAX_STREAMS_PER_PROGRAM]; | ||
| 140 | |||
| 141 | /** have we found pmt for this program */ | ||
| 142 | int pmt_found; | ||
| 143 | }; | ||
| 144 | |||
| 145 | struct MpegTSContext { | ||
| 146 | const AVClass *class; | ||
| 147 | /* user data */ | ||
| 148 | AVFormatContext *stream; | ||
| 149 | /** raw packet size, including FEC if present */ | ||
| 150 | int raw_packet_size; | ||
| 151 | |||
| 152 | int64_t pos47_full; | ||
| 153 | |||
| 154 | /** if true, all pids are analyzed to find streams */ | ||
| 155 | int auto_guess; | ||
| 156 | |||
| 157 | /** compute exact PCR for each transport stream packet */ | ||
| 158 | int mpeg2ts_compute_pcr; | ||
| 159 | |||
| 160 | /** fix dvb teletext pts */ | ||
| 161 | int fix_teletext_pts; | ||
| 162 | |||
| 163 | int64_t cur_pcr; /**< used to estimate the exact PCR */ | ||
| 164 | int64_t pcr_incr; /**< used to estimate the exact PCR */ | ||
| 165 | |||
| 166 | /* data needed to handle file based ts */ | ||
| 167 | /** stop parsing loop */ | ||
| 168 | int stop_parse; | ||
| 169 | /** packet containing Audio/Video data */ | ||
| 170 | AVPacket *pkt; | ||
| 171 | /** to detect seek */ | ||
| 172 | int64_t last_pos; | ||
| 173 | |||
| 174 | int skip_changes; | ||
| 175 | int skip_clear; | ||
| 176 | int skip_unknown_pmt; | ||
| 177 | |||
| 178 | int scan_all_pmts; | ||
| 179 | |||
| 180 | int resync_size; | ||
| 181 | int merge_pmt_versions; | ||
| 182 | int max_packet_size; | ||
| 183 | |||
| 184 | int id; | ||
| 185 | |||
| 186 | /******************************************/ | ||
| 187 | /* private mpegts data */ | ||
| 188 | /* scan context */ | ||
| 189 | /** structure to keep track of Program->pids mapping */ | ||
| 190 | unsigned int nb_prg; | ||
| 191 | unsigned int prg_size; ///< allocated size of prg in bytes | ||
| 192 | struct Program *prg; | ||
| 193 | |||
| 194 | int8_t crc_validity[NB_PID_MAX]; | ||
| 195 | /** filters for various streams specified by PMT + for the PAT and PMT */ | ||
| 196 | MpegTSFilter *pids[NB_PID_MAX]; | ||
| 197 | int current_pid; | ||
| 198 | |||
| 199 | AVStream *epg_stream; | ||
| 200 | AVBufferPool* pools[32]; | ||
| 201 | }; | ||
| 202 | |||
| 203 | #define MPEGTS_OPTIONS \ | ||
| 204 | { "resync_size", "set size limit for looking up a new synchronization", \ | ||
| 205 | offsetof(MpegTSContext, resync_size), AV_OPT_TYPE_INT, \ | ||
| 206 | { .i64 = MAX_RESYNC_SIZE}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, \ | ||
| 207 | { "ts_id", "transport stream id", \ | ||
| 208 | offsetof(MpegTSContext, id), AV_OPT_TYPE_INT, \ | ||
| 209 | { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY }, \ | ||
| 210 | { "ts_packetsize", "output option carrying the raw packet size", \ | ||
| 211 | offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT, \ | ||
| 212 | { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY } | ||
| 213 | |||
| 214 | static const AVOption options[] = { | ||
| 215 | MPEGTS_OPTIONS, | ||
| 216 | {"fix_teletext_pts", "try to fix pts values of dvb teletext streams", offsetof(MpegTSContext, fix_teletext_pts), AV_OPT_TYPE_BOOL, | ||
| 217 | {.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, | ||
| 218 | {"scan_all_pmts", "scan and combine all PMTs", offsetof(MpegTSContext, scan_all_pmts), AV_OPT_TYPE_BOOL, | ||
| 219 | {.i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM }, | ||
| 220 | {"skip_unknown_pmt", "skip PMTs for programs not advertised in the PAT", offsetof(MpegTSContext, skip_unknown_pmt), AV_OPT_TYPE_BOOL, | ||
| 221 | {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, | ||
| 222 | {"merge_pmt_versions", "reuse streams when PMT's version/pids change", offsetof(MpegTSContext, merge_pmt_versions), AV_OPT_TYPE_BOOL, | ||
| 223 | {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, | ||
| 224 | {"skip_changes", "skip changing / adding streams / programs", offsetof(MpegTSContext, skip_changes), AV_OPT_TYPE_BOOL, | ||
| 225 | {.i64 = 0}, 0, 1, 0 }, | ||
| 226 | {"skip_clear", "skip clearing programs", offsetof(MpegTSContext, skip_clear), AV_OPT_TYPE_BOOL, | ||
| 227 | {.i64 = 0}, 0, 1, 0 }, | ||
| 228 | {"max_packet_size", "maximum size of emitted packet", offsetof(MpegTSContext, max_packet_size), AV_OPT_TYPE_INT, | ||
| 229 | {.i64 = 204800}, TS_PAYLOAD_SIZE, INT_MAX/2, AV_OPT_FLAG_DECODING_PARAM }, | ||
| 230 | { NULL }, | ||
| 231 | }; | ||
| 232 | |||
| 233 | static const AVClass mpegts_class = { | ||
| 234 | .class_name = "mpegts demuxer", | ||
| 235 | .item_name = av_default_item_name, | ||
| 236 | .option = options, | ||
| 237 | .version = LIBAVUTIL_VERSION_INT, | ||
| 238 | }; | ||
| 239 | |||
| 240 | static const AVOption raw_options[] = { | ||
| 241 | MPEGTS_OPTIONS, | ||
| 242 | { "compute_pcr", "compute exact PCR for each transport stream packet", | ||
| 243 | offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_BOOL, | ||
| 244 | { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, | ||
| 245 | { NULL }, | ||
| 246 | }; | ||
| 247 | |||
| 248 | static const AVClass mpegtsraw_class = { | ||
| 249 | .class_name = "mpegtsraw demuxer", | ||
| 250 | .item_name = av_default_item_name, | ||
| 251 | .option = raw_options, | ||
| 252 | .version = LIBAVUTIL_VERSION_INT, | ||
| 253 | }; | ||
| 254 | |||
| 255 | /* TS stream handling */ | ||
| 256 | |||
| 257 | enum MpegTSState { | ||
| 258 | MPEGTS_HEADER = 0, | ||
| 259 | MPEGTS_PESHEADER, | ||
| 260 | MPEGTS_PESHEADER_FILL, | ||
| 261 | MPEGTS_PAYLOAD, | ||
| 262 | MPEGTS_SKIP, | ||
| 263 | }; | ||
| 264 | |||
| 265 | /* enough for PES header + length */ | ||
| 266 | #define PES_START_SIZE 6 | ||
| 267 | #define PES_HEADER_SIZE 9 | ||
| 268 | #define MAX_PES_HEADER_SIZE (9 + 255) | ||
| 269 | |||
| 270 | typedef struct PESContext { | ||
| 271 | int pid; | ||
| 272 | int pcr_pid; /**< if -1 then all packets containing PCR are considered */ | ||
| 273 | int stream_type; | ||
| 274 | MpegTSContext *ts; | ||
| 275 | AVFormatContext *stream; | ||
| 276 | AVStream *st; | ||
| 277 | AVStream *sub_st; /**< stream for the embedded AC3 stream in HDMV TrueHD */ | ||
| 278 | enum MpegTSState state; | ||
| 279 | /* used to get the format */ | ||
| 280 | int data_index; | ||
| 281 | int flags; /**< copied to the AVPacket flags */ | ||
| 282 | int PES_packet_length; | ||
| 283 | int pes_header_size; | ||
| 284 | int extended_stream_id; | ||
| 285 | uint8_t stream_id; | ||
| 286 | int64_t pts, dts; | ||
| 287 | int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ | ||
| 288 | uint8_t header[MAX_PES_HEADER_SIZE]; | ||
| 289 | AVBufferRef *buffer; | ||
| 290 | SLConfigDescr sl; | ||
| 291 | int merged_st; | ||
| 292 | } PESContext; | ||
| 293 | |||
| 294 | EXTERN const FFInputFormat ff_mpegts_demuxer; | ||
| 295 | |||
| 296 | 835 | static struct Program * get_program(MpegTSContext *ts, unsigned int programid) | |
| 297 | { | ||
| 298 | int i; | ||
| 299 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 835 times.
|
835 | if (!ts) |
| 300 | ✗ | return NULL; | |
| 301 |
2/2✓ Branch 0 taken 755 times.
✓ Branch 1 taken 80 times.
|
835 | for (i = 0; i < ts->nb_prg; i++) { |
| 302 |
1/2✓ Branch 0 taken 755 times.
✗ Branch 1 not taken.
|
755 | if (ts->prg[i].id == programid) { |
| 303 | 755 | return &ts->prg[i]; | |
| 304 | } | ||
| 305 | } | ||
| 306 | 80 | return NULL; | |
| 307 | } | ||
| 308 | |||
| 309 | 270 | static void clear_avprogram(MpegTSContext *ts, unsigned int programid) | |
| 310 | { | ||
| 311 | 270 | AVProgram *prg = NULL; | |
| 312 | int i; | ||
| 313 | |||
| 314 |
1/2✓ Branch 0 taken 270 times.
✗ Branch 1 not taken.
|
270 | for (i = 0; i < ts->stream->nb_programs; i++) |
| 315 |
1/2✓ Branch 0 taken 270 times.
✗ Branch 1 not taken.
|
270 | if (ts->stream->programs[i]->id == programid) { |
| 316 | 270 | prg = ts->stream->programs[i]; | |
| 317 | 270 | break; | |
| 318 | } | ||
| 319 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
|
270 | if (!prg) |
| 320 | ✗ | return; | |
| 321 | 270 | prg->nb_stream_indexes = 0; | |
| 322 | } | ||
| 323 | |||
| 324 | 492 | static void clear_program(struct Program *p) | |
| 325 | { | ||
| 326 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 492 times.
|
492 | if (!p) |
| 327 | ✗ | return; | |
| 328 | 492 | p->nb_pids = 0; | |
| 329 | 492 | p->nb_streams = 0; | |
| 330 | 492 | p->nb_stream_groups = 0; | |
| 331 | 492 | memset(p->stream_groups, 0, sizeof(p->stream_groups)); | |
| 332 | 492 | p->pmt_found = 0; | |
| 333 | } | ||
| 334 | |||
| 335 | 80 | static void clear_programs(MpegTSContext *ts) | |
| 336 | { | ||
| 337 | 80 | av_freep(&ts->prg); | |
| 338 | 80 | ts->nb_prg = 0; | |
| 339 | 80 | ts->prg_size = 0; | |
| 340 | 80 | } | |
| 341 | |||
| 342 | 333 | static struct Program * add_program(MpegTSContext *ts, unsigned int programid) | |
| 343 | { | ||
| 344 | 333 | struct Program *p = get_program(ts, programid); | |
| 345 | 333 | struct Program *tmp = NULL; | |
| 346 | size_t new_prg_size; | ||
| 347 |
2/2✓ Branch 0 taken 253 times.
✓ Branch 1 taken 80 times.
|
333 | if (p) |
| 348 | 253 | return p; | |
| 349 | |||
| 350 |
1/2✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
|
80 | if (!av_size_mult(ts->nb_prg + 1, sizeof(*ts->prg), &new_prg_size)) |
| 351 | 80 | tmp = av_fast_realloc(ts->prg, &ts->prg_size,new_prg_size); | |
| 352 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
|
80 | if (!tmp) { |
| 353 | ✗ | av_freep(&ts->prg); | |
| 354 | ✗ | ts->nb_prg = 0; | |
| 355 | ✗ | ts->prg_size = 0; | |
| 356 | ✗ | return NULL; | |
| 357 | } | ||
| 358 | 80 | ts->prg = tmp; | |
| 359 | 80 | p = &ts->prg[ts->nb_prg]; | |
| 360 | 80 | p->id = programid; | |
| 361 | 80 | clear_program(p); | |
| 362 | 80 | ts->nb_prg++; | |
| 363 | 80 | return p; | |
| 364 | } | ||
| 365 | |||
| 366 | 1878 | static void add_pid_to_program(struct Program *p, unsigned int pid) | |
| 367 | { | ||
| 368 | int i; | ||
| 369 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1878 times.
|
1878 | if (!p) |
| 370 | ✗ | return; | |
| 371 | |||
| 372 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1878 times.
|
1878 | if (p->nb_pids >= MAX_PIDS_PER_PROGRAM) |
| 373 | ✗ | return; | |
| 374 | |||
| 375 |
2/2✓ Branch 0 taken 2319 times.
✓ Branch 1 taken 1207 times.
|
3526 | for (i = 0; i < p->nb_pids; i++) |
| 376 |
2/2✓ Branch 0 taken 671 times.
✓ Branch 1 taken 1648 times.
|
2319 | if (p->pids[i] == pid) |
| 377 | 671 | return; | |
| 378 | |||
| 379 | 1207 | p->pids[p->nb_pids++] = pid; | |
| 380 | } | ||
| 381 | |||
| 382 | 412 | static void update_av_program_info(AVFormatContext *s, unsigned int programid, | |
| 383 | unsigned int pid, int version) | ||
| 384 | { | ||
| 385 | int i; | ||
| 386 |
1/2✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
|
412 | for (i = 0; i < s->nb_programs; i++) { |
| 387 | 412 | AVProgram *program = s->programs[i]; | |
| 388 |
1/2✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
|
412 | if (program->id == programid) { |
| 389 | 412 | int old_pcr_pid = program->pcr_pid, | |
| 390 | 412 | old_version = program->pmt_version; | |
| 391 | 412 | program->pcr_pid = pid; | |
| 392 | 412 | program->pmt_version = version; | |
| 393 | |||
| 394 |
4/4✓ Branch 0 taken 332 times.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 314 times.
|
412 | if (old_version != -1 && old_version != version) { |
| 395 | 18 | av_log(s, AV_LOG_VERBOSE, | |
| 396 | "detected PMT change (program=%d, version=%d/%d, pcr_pid=0x%x/0x%x)\n", | ||
| 397 | programid, old_version, version, old_pcr_pid, pid); | ||
| 398 | } | ||
| 399 | 412 | break; | |
| 400 | } | ||
| 401 | } | ||
| 402 | 412 | } | |
| 403 | |||
| 404 | /** | ||
| 405 | * @brief discard_pid() decides if the pid is to be discarded according | ||
| 406 | * to caller's programs selection | ||
| 407 | * @param ts : - TS context | ||
| 408 | * @param pid : - pid | ||
| 409 | * @return 1 if the pid is only comprised in programs that have .discard=AVDISCARD_ALL | ||
| 410 | * 0 otherwise | ||
| 411 | */ | ||
| 412 | 43637 | static int discard_pid(MpegTSContext *ts, unsigned int pid) | |
| 413 | { | ||
| 414 | int i, j, k; | ||
| 415 | 43637 | int used = 0, discarded = 0; | |
| 416 | struct Program *p; | ||
| 417 | |||
| 418 |
2/2✓ Branch 0 taken 3768 times.
✓ Branch 1 taken 39869 times.
|
43637 | if (pid == PAT_PID) |
| 419 | 3768 | return 0; | |
| 420 | |||
| 421 | /* If none of the programs have .discard=AVDISCARD_ALL then there's | ||
| 422 | * no way we have to discard this packet */ | ||
| 423 |
2/2✓ Branch 0 taken 39819 times.
✓ Branch 1 taken 39869 times.
|
79688 | for (k = 0; k < ts->stream->nb_programs; k++) |
| 424 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39819 times.
|
39819 | if (ts->stream->programs[k]->discard == AVDISCARD_ALL) |
| 425 | ✗ | break; | |
| 426 |
1/2✓ Branch 0 taken 39869 times.
✗ Branch 1 not taken.
|
39869 | if (k == ts->stream->nb_programs) |
| 427 | 39869 | return 0; | |
| 428 | |||
| 429 | ✗ | for (i = 0; i < ts->nb_prg; i++) { | |
| 430 | ✗ | p = &ts->prg[i]; | |
| 431 | ✗ | for (j = 0; j < p->nb_pids; j++) { | |
| 432 | ✗ | if (p->pids[j] != pid) | |
| 433 | ✗ | continue; | |
| 434 | // is program with id p->id set to be discarded? | ||
| 435 | ✗ | for (k = 0; k < ts->stream->nb_programs; k++) { | |
| 436 | ✗ | if (ts->stream->programs[k]->id == p->id) { | |
| 437 | ✗ | if (ts->stream->programs[k]->discard == AVDISCARD_ALL) | |
| 438 | ✗ | discarded++; | |
| 439 | else | ||
| 440 | ✗ | used++; | |
| 441 | } | ||
| 442 | } | ||
| 443 | } | ||
| 444 | } | ||
| 445 | |||
| 446 | ✗ | return !used && discarded; | |
| 447 | } | ||
| 448 | |||
| 449 | /** | ||
| 450 | * Assemble PES packets out of TS packets, and then call the "section_cb" | ||
| 451 | * function when they are complete. | ||
| 452 | */ | ||
| 453 | 8216 | static void write_section_data(MpegTSContext *ts, MpegTSFilter *tss1, | |
| 454 | const uint8_t *buf, int buf_size, int is_start) | ||
| 455 | { | ||
| 456 | 8216 | MpegTSSectionFilter *tss = &tss1->u.section_filter; | |
| 457 | 8216 | uint8_t *cur_section_buf = NULL; | |
| 458 | int len, offset; | ||
| 459 | |||
| 460 |
2/2✓ Branch 0 taken 8181 times.
✓ Branch 1 taken 35 times.
|
8216 | if (is_start) { |
| 461 | 8181 | memcpy(tss->section_buf, buf, buf_size); | |
| 462 | 8181 | tss->section_index = buf_size; | |
| 463 | 8181 | tss->section_h_size = -1; | |
| 464 | 8181 | tss->end_of_section_reached = 0; | |
| 465 | } else { | ||
| 466 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
|
35 | if (tss->end_of_section_reached) |
| 467 | ✗ | return; | |
| 468 | 35 | len = MAX_SECTION_SIZE - tss->section_index; | |
| 469 |
1/2✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
|
35 | if (buf_size < len) |
| 470 | 35 | len = buf_size; | |
| 471 | 35 | memcpy(tss->section_buf + tss->section_index, buf, len); | |
| 472 | 35 | tss->section_index += len; | |
| 473 | } | ||
| 474 | |||
| 475 | 8216 | offset = 0; | |
| 476 | 8216 | cur_section_buf = tss->section_buf; | |
| 477 |
3/4✓ Branch 0 taken 16397 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8424 times.
✓ Branch 3 taken 7973 times.
|
16397 | while (cur_section_buf - tss->section_buf < MAX_SECTION_SIZE && cur_section_buf[0] != STUFFING_BYTE) { |
| 478 | /* compute section length if possible */ | ||
| 479 |
3/4✓ Branch 0 taken 8424 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8216 times.
✓ Branch 3 taken 208 times.
|
8424 | if (tss->section_h_size == -1 && tss->section_index - offset >= 3) { |
| 480 | 8216 | len = (AV_RB16(cur_section_buf + 1) & 0xfff) + 3; | |
| 481 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8216 times.
|
8216 | if (len > MAX_SECTION_SIZE) |
| 482 | ✗ | return; | |
| 483 | 8216 | tss->section_h_size = len; | |
| 484 | } | ||
| 485 | |||
| 486 |
2/2✓ Branch 0 taken 8216 times.
✓ Branch 1 taken 208 times.
|
8424 | if (tss->section_h_size != -1 && |
| 487 |
2/2✓ Branch 0 taken 8181 times.
✓ Branch 1 taken 35 times.
|
8216 | tss->section_index >= offset + tss->section_h_size) { |
| 488 | 8181 | int crc_valid = 1; | |
| 489 | 8181 | tss->end_of_section_reached = 1; | |
| 490 | |||
| 491 |
1/2✓ Branch 0 taken 8181 times.
✗ Branch 1 not taken.
|
8181 | if (tss->check_crc) { |
| 492 | 8181 | crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, cur_section_buf, tss->section_h_size); | |
| 493 |
1/2✓ Branch 0 taken 8181 times.
✗ Branch 1 not taken.
|
8181 | if (tss->section_h_size >= 4) |
| 494 | 8181 | tss->crc = AV_RB32(cur_section_buf + tss->section_h_size - 4); | |
| 495 | |||
| 496 |
1/2✓ Branch 0 taken 8181 times.
✗ Branch 1 not taken.
|
8181 | if (crc_valid) { |
| 497 | 8181 | ts->crc_validity[ tss1->pid ] = 100; | |
| 498 | ✗ | }else if (ts->crc_validity[ tss1->pid ] > -10) { | |
| 499 | ✗ | ts->crc_validity[ tss1->pid ]--; | |
| 500 | }else | ||
| 501 | ✗ | crc_valid = 2; | |
| 502 | } | ||
| 503 |
1/2✓ Branch 0 taken 8181 times.
✗ Branch 1 not taken.
|
8181 | if (crc_valid) { |
| 504 | 8181 | tss->section_cb(tss1, cur_section_buf, tss->section_h_size); | |
| 505 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8181 times.
|
8181 | if (crc_valid != 1) |
| 506 | ✗ | tss->last_ver = -1; | |
| 507 | } | ||
| 508 | |||
| 509 | 8181 | cur_section_buf += tss->section_h_size; | |
| 510 | 8181 | offset += tss->section_h_size; | |
| 511 | 8181 | tss->section_h_size = -1; | |
| 512 | } else { | ||
| 513 | 243 | tss->section_h_size = -1; | |
| 514 | 243 | tss->end_of_section_reached = 0; | |
| 515 | 243 | break; | |
| 516 | } | ||
| 517 | } | ||
| 518 | } | ||
| 519 | |||
| 520 | 485 | static MpegTSFilter *mpegts_open_filter(MpegTSContext *ts, unsigned int pid, | |
| 521 | enum MpegTSFilterType type) | ||
| 522 | { | ||
| 523 | MpegTSFilter *filter; | ||
| 524 | |||
| 525 | 485 | av_log(ts->stream, AV_LOG_TRACE, "Filter: pid=0x%x type=%d\n", pid, type); | |
| 526 | |||
| 527 |
2/4✓ Branch 0 taken 485 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 485 times.
|
485 | if (pid >= NB_PID_MAX || ts->pids[pid]) |
| 528 | ✗ | return NULL; | |
| 529 | 485 | filter = av_mallocz(sizeof(MpegTSFilter)); | |
| 530 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 485 times.
|
485 | if (!filter) |
| 531 | ✗ | return NULL; | |
| 532 | 485 | ts->pids[pid] = filter; | |
| 533 | |||
| 534 | 485 | filter->type = type; | |
| 535 | 485 | filter->pid = pid; | |
| 536 | 485 | filter->es_id = -1; | |
| 537 | 485 | filter->last_cc = -1; | |
| 538 | 485 | filter->last_pcr= -1; | |
| 539 | |||
| 540 | 485 | return filter; | |
| 541 | } | ||
| 542 | |||
| 543 | 327 | static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, | |
| 544 | unsigned int pid, | ||
| 545 | SectionCallback *section_cb, | ||
| 546 | void *opaque, | ||
| 547 | int check_crc) | ||
| 548 | { | ||
| 549 | MpegTSFilter *filter; | ||
| 550 | MpegTSSectionFilter *sec; | ||
| 551 | 327 | uint8_t *section_buf = av_mallocz(MAX_SECTION_SIZE); | |
| 552 | |||
| 553 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 327 times.
|
327 | if (!section_buf) |
| 554 | ✗ | return NULL; | |
| 555 | |||
| 556 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 327 times.
|
327 | if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_SECTION))) { |
| 557 | ✗ | av_free(section_buf); | |
| 558 | ✗ | return NULL; | |
| 559 | } | ||
| 560 | 327 | sec = &filter->u.section_filter; | |
| 561 | 327 | sec->section_cb = section_cb; | |
| 562 | 327 | sec->opaque = opaque; | |
| 563 | 327 | sec->section_buf = section_buf; | |
| 564 | 327 | sec->check_crc = check_crc; | |
| 565 | 327 | sec->last_ver = -1; | |
| 566 | |||
| 567 | 327 | return filter; | |
| 568 | } | ||
| 569 | |||
| 570 | 158 | static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid, | |
| 571 | PESCallback *pes_cb, | ||
| 572 | void *opaque) | ||
| 573 | { | ||
| 574 | MpegTSFilter *filter; | ||
| 575 | MpegTSPESFilter *pes; | ||
| 576 | |||
| 577 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
|
158 | if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_PES))) |
| 578 | ✗ | return NULL; | |
| 579 | |||
| 580 | 158 | pes = &filter->u.pes_filter; | |
| 581 | 158 | pes->pes_cb = pes_cb; | |
| 582 | 158 | pes->opaque = opaque; | |
| 583 | 158 | return filter; | |
| 584 | } | ||
| 585 | |||
| 586 | ✗ | static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid) | |
| 587 | { | ||
| 588 | ✗ | return mpegts_open_filter(ts, pid, MPEGTS_PCR); | |
| 589 | } | ||
| 590 | |||
| 591 | 485 | static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) | |
| 592 | { | ||
| 593 | int pid; | ||
| 594 | |||
| 595 | 485 | pid = filter->pid; | |
| 596 |
2/2✓ Branch 0 taken 327 times.
✓ Branch 1 taken 158 times.
|
485 | if (filter->type == MPEGTS_SECTION) |
| 597 | 327 | av_freep(&filter->u.section_filter.section_buf); | |
| 598 |
1/2✓ Branch 0 taken 158 times.
✗ Branch 1 not taken.
|
158 | else if (filter->type == MPEGTS_PES) { |
| 599 | 158 | PESContext *pes = filter->u.pes_filter.opaque; | |
| 600 | 158 | av_buffer_unref(&pes->buffer); | |
| 601 | /* referenced private data will be freed later in | ||
| 602 | * avformat_close_input (pes->st->priv_data == pes) */ | ||
| 603 |
5/6✓ Branch 0 taken 140 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 136 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 136 times.
|
158 | if (!pes->st || pes->merged_st || !pes->st->priv_data) { |
| 604 | 22 | av_freep(&filter->u.pes_filter.opaque); | |
| 605 | } | ||
| 606 | } | ||
| 607 | |||
| 608 | 485 | av_free(filter); | |
| 609 | 485 | ts->pids[pid] = NULL; | |
| 610 | 485 | } | |
| 611 | |||
| 612 | 81588 | static int analyze(const uint8_t *buf, int size, int packet_size, | |
| 613 | int probe) | ||
| 614 | { | ||
| 615 | int stat[TS_MAX_PACKET_SIZE]; | ||
| 616 | 81588 | int stat_all = 0; | |
| 617 | int i; | ||
| 618 | 81588 | int best_score = 0; | |
| 619 | |||
| 620 | 81588 | memset(stat, 0, packet_size * sizeof(*stat)); | |
| 621 | |||
| 622 |
2/2✓ Branch 0 taken 1260836769 times.
✓ Branch 1 taken 81588 times.
|
1260918357 | for (i = 0; i < size - 3; i++) { |
| 623 |
2/2✓ Branch 0 taken 2238151 times.
✓ Branch 1 taken 1258598618 times.
|
1260836769 | if (buf[i] == SYNC_BYTE) { |
| 624 | 2238151 | int pid = AV_RB16(buf+1) & 0x1FFF; | |
| 625 | 2238151 | int asc = buf[i + 3] & 0x30; | |
| 626 |
6/6✓ Branch 0 taken 2209945 times.
✓ Branch 1 taken 28206 times.
✓ Branch 2 taken 2208084 times.
✓ Branch 3 taken 1861 times.
✓ Branch 4 taken 1826447 times.
✓ Branch 5 taken 381637 times.
|
2238151 | if (!probe || pid == 0x1FFF || asc) { |
| 627 | 1856514 | int x = i % packet_size; | |
| 628 | 1856514 | stat[x]++; | |
| 629 | 1856514 | stat_all++; | |
| 630 |
2/2✓ Branch 0 taken 137440 times.
✓ Branch 1 taken 1719074 times.
|
1856514 | if (stat[x] > best_score) { |
| 631 | 137440 | best_score = stat[x]; | |
| 632 | } | ||
| 633 | } | ||
| 634 | } | ||
| 635 | } | ||
| 636 | |||
| 637 | 81588 | return best_score - FFMAX(stat_all - 10*best_score, 0)/10; | |
| 638 | } | ||
| 639 | |||
| 640 | /* autodetect fec presence */ | ||
| 641 | 152 | static int get_packet_size(AVFormatContext* s) | |
| 642 | { | ||
| 643 | int score, fec_score, dvhs_score; | ||
| 644 | int margin; | ||
| 645 | int ret; | ||
| 646 | |||
| 647 | /*init buffer to store stream for probing */ | ||
| 648 | 152 | uint8_t buf[PROBE_PACKET_MAX_BUF] = {0}; | |
| 649 | 152 | int buf_size = 0; | |
| 650 | 152 | int max_iterations = 16; | |
| 651 | |||
| 652 |
2/4✓ Branch 0 taken 152 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 152 times.
✗ Branch 3 not taken.
|
152 | while (buf_size < PROBE_PACKET_MAX_BUF && max_iterations--) { |
| 653 | 152 | ret = avio_read_partial(s->pb, buf + buf_size, PROBE_PACKET_MAX_BUF - buf_size); | |
| 654 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 152 times.
|
152 | if (ret < 0) |
| 655 | ✗ | return AVERROR_INVALIDDATA; | |
| 656 | 152 | buf_size += ret; | |
| 657 | |||
| 658 | 152 | score = analyze(buf, buf_size, TS_PACKET_SIZE, 0); | |
| 659 | 152 | dvhs_score = analyze(buf, buf_size, TS_DVHS_PACKET_SIZE, 0); | |
| 660 | 152 | fec_score = analyze(buf, buf_size, TS_FEC_PACKET_SIZE, 0); | |
| 661 | 152 | av_log(s, AV_LOG_TRACE, "Probe: %d, score: %d, dvhs_score: %d, fec_score: %d \n", | |
| 662 | buf_size, score, dvhs_score, fec_score); | ||
| 663 | |||
| 664 | 152 | margin = mid_pred(score, fec_score, dvhs_score); | |
| 665 | |||
| 666 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 143 times.
|
152 | if (buf_size < PROBE_PACKET_MAX_BUF) |
| 667 | 9 | margin += PROBE_PACKET_MARGIN; /*if buffer not filled */ | |
| 668 | |||
| 669 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 10 times.
|
152 | if (score > margin) |
| 670 | 142 | return TS_PACKET_SIZE; | |
| 671 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | else if (dvhs_score > margin) |
| 672 | 10 | return TS_DVHS_PACKET_SIZE; | |
| 673 | ✗ | else if (fec_score > margin) | |
| 674 | ✗ | return TS_FEC_PACKET_SIZE; | |
| 675 | } | ||
| 676 | ✗ | return AVERROR_INVALIDDATA; | |
| 677 | } | ||
| 678 | |||
| 679 | typedef struct SectionHeader { | ||
| 680 | uint8_t tid; | ||
| 681 | uint16_t id; | ||
| 682 | uint8_t version; | ||
| 683 | uint8_t current_next; | ||
| 684 | uint8_t sec_num; | ||
| 685 | uint8_t last_sec_num; | ||
| 686 | } SectionHeader; | ||
| 687 | |||
| 688 | 7283 | static int skip_identical(const SectionHeader *h, MpegTSSectionFilter *tssf) | |
| 689 | { | ||
| 690 |
3/4✓ Branch 0 taken 6322 times.
✓ Branch 1 taken 961 times.
✓ Branch 2 taken 6322 times.
✗ Branch 3 not taken.
|
7283 | if (h->version == tssf->last_ver && tssf->last_crc == tssf->crc) |
| 691 | 6322 | return 1; | |
| 692 | |||
| 693 | 961 | tssf->last_ver = h->version; | |
| 694 | 961 | tssf->last_crc = tssf->crc; | |
| 695 | |||
| 696 | 961 | return 0; | |
| 697 | } | ||
| 698 | |||
| 699 | 40912 | static inline int get8(const uint8_t **pp, const uint8_t *p_end) | |
| 700 | { | ||
| 701 | const uint8_t *p; | ||
| 702 | int c; | ||
| 703 | |||
| 704 | 40912 | p = *pp; | |
| 705 |
2/2✓ Branch 0 taken 2018 times.
✓ Branch 1 taken 38894 times.
|
40912 | if (p >= p_end) |
| 706 | 2018 | return AVERROR_INVALIDDATA; | |
| 707 | 38894 | c = *p++; | |
| 708 | 38894 | *pp = p; | |
| 709 | 38894 | return c; | |
| 710 | } | ||
| 711 | |||
| 712 | 13035 | static inline int get16(const uint8_t **pp, const uint8_t *p_end) | |
| 713 | { | ||
| 714 | const uint8_t *p; | ||
| 715 | int c; | ||
| 716 | |||
| 717 | 13035 | p = *pp; | |
| 718 |
2/2✓ Branch 0 taken 549 times.
✓ Branch 1 taken 12486 times.
|
13035 | if (1 >= p_end - p) |
| 719 | 549 | return AVERROR_INVALIDDATA; | |
| 720 | 12486 | c = AV_RB16(p); | |
| 721 | 12486 | p += 2; | |
| 722 | 12486 | *pp = p; | |
| 723 | 12486 | return c; | |
| 724 | } | ||
| 725 | |||
| 726 | /* read and allocate a DVB string preceded by its length */ | ||
| 727 | 432 | static char *getstr8(const uint8_t **pp, const uint8_t *p_end) | |
| 728 | { | ||
| 729 | int len; | ||
| 730 | const uint8_t *p; | ||
| 731 | char *str; | ||
| 732 | |||
| 733 | 432 | p = *pp; | |
| 734 | 432 | len = get8(&p, p_end); | |
| 735 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
|
432 | if (len < 0) |
| 736 | ✗ | return NULL; | |
| 737 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
|
432 | if (len > p_end - p) |
| 738 | ✗ | return NULL; | |
| 739 | #if CONFIG_ICONV | ||
| 740 |
1/2✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
|
432 | if (len) { |
| 741 | 432 | const char *encodings[] = { | |
| 742 | "ISO6937", "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", | ||
| 743 | "ISO-8859-8", "ISO-8859-9", "ISO-8859-10", "ISO-8859-11", | ||
| 744 | "", "ISO-8859-13", "ISO-8859-14", "ISO-8859-15", "", "", "", "", | ||
| 745 | "", "UCS-2BE", "KSC_5601", "GB2312", "UCS-2BE", "UTF-8", "", "", | ||
| 746 | "", "", "", "", "", "", "", "" | ||
| 747 | }; | ||
| 748 | iconv_t cd; | ||
| 749 | char *in, *out; | ||
| 750 | 432 | size_t inlen = len, outlen = inlen * 6 + 1; | |
| 751 |
2/12✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 432 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
432 | if (len >= 3 && p[0] == 0x10 && !p[1] && p[2] && p[2] <= 0xf && p[2] != 0xc) { |
| 752 | char iso8859[12]; | ||
| 753 | ✗ | snprintf(iso8859, sizeof(iso8859), "ISO-8859-%d", p[2]); | |
| 754 | ✗ | inlen -= 3; | |
| 755 | ✗ | in = (char *)p + 3; | |
| 756 | ✗ | cd = iconv_open("UTF-8", iso8859); | |
| 757 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 424 times.
|
432 | } else if (p[0] < 0x20) { |
| 758 | 8 | inlen -= 1; | |
| 759 | 8 | in = (char *)p + 1; | |
| 760 | 8 | cd = iconv_open("UTF-8", encodings[*p]); | |
| 761 | } else { | ||
| 762 | 424 | in = (char *)p; | |
| 763 | 424 | cd = iconv_open("UTF-8", encodings[0]); | |
| 764 | } | ||
| 765 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
|
432 | if (cd == (iconv_t)-1) |
| 766 | ✗ | goto no_iconv; | |
| 767 | 432 | str = out = av_malloc(outlen); | |
| 768 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
|
432 | if (!str) { |
| 769 | ✗ | iconv_close(cd); | |
| 770 | 432 | return NULL; | |
| 771 | } | ||
| 772 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 432 times.
|
432 | if (iconv(cd, &in, &inlen, &out, &outlen) == -1) { |
| 773 | ✗ | iconv_close(cd); | |
| 774 | ✗ | av_freep(&str); | |
| 775 | ✗ | goto no_iconv; | |
| 776 | } | ||
| 777 | 432 | iconv_close(cd); | |
| 778 | 432 | *out = 0; | |
| 779 | 432 | *pp = p + len; | |
| 780 | 432 | return str; | |
| 781 | } | ||
| 782 | ✗ | no_iconv: | |
| 783 | #endif | ||
| 784 | ✗ | str = av_malloc(len + 1); | |
| 785 | ✗ | if (!str) | |
| 786 | ✗ | return NULL; | |
| 787 | ✗ | memcpy(str, p, len); | |
| 788 | ✗ | str[len] = '\0'; | |
| 789 | ✗ | p += len; | |
| 790 | ✗ | *pp = p; | |
| 791 | ✗ | return str; | |
| 792 | } | ||
| 793 | |||
| 794 | 8179 | static int parse_section_header(SectionHeader *h, | |
| 795 | const uint8_t **pp, const uint8_t *p_end) | ||
| 796 | { | ||
| 797 | int val; | ||
| 798 | |||
| 799 | 8179 | val = get8(pp, p_end); | |
| 800 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8179 times.
|
8179 | if (val < 0) |
| 801 | ✗ | return val; | |
| 802 | 8179 | h->tid = val; | |
| 803 | 8179 | *pp += 2; | |
| 804 | 8179 | val = get16(pp, p_end); | |
| 805 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8179 times.
|
8179 | if (val < 0) |
| 806 | ✗ | return val; | |
| 807 | 8179 | h->id = val; | |
| 808 | 8179 | val = get8(pp, p_end); | |
| 809 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8179 times.
|
8179 | if (val < 0) |
| 810 | ✗ | return val; | |
| 811 | 8179 | h->version = (val >> 1) & 0x1f; | |
| 812 | 8179 | h->current_next = val & 0x01; | |
| 813 | 8179 | val = get8(pp, p_end); | |
| 814 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8179 times.
|
8179 | if (val < 0) |
| 815 | ✗ | return val; | |
| 816 | 8179 | h->sec_num = val; | |
| 817 | 8179 | val = get8(pp, p_end); | |
| 818 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8179 times.
|
8179 | if (val < 0) |
| 819 | ✗ | return val; | |
| 820 | 8179 | h->last_sec_num = val; | |
| 821 | 8179 | return 0; | |
| 822 | } | ||
| 823 | |||
| 824 | typedef struct StreamType { | ||
| 825 | uint32_t stream_type; | ||
| 826 | enum AVMediaType codec_type; | ||
| 827 | enum AVCodecID codec_id; | ||
| 828 | } StreamType; | ||
| 829 | |||
| 830 | static const StreamType ISO_types[] = { | ||
| 831 | { STREAM_TYPE_VIDEO_MPEG1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO }, | ||
| 832 | { STREAM_TYPE_VIDEO_MPEG2, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO }, | ||
| 833 | { STREAM_TYPE_AUDIO_MPEG1, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3 }, | ||
| 834 | { STREAM_TYPE_AUDIO_MPEG2, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3 }, | ||
| 835 | { STREAM_TYPE_AUDIO_AAC, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC }, | ||
| 836 | { STREAM_TYPE_VIDEO_MPEG4, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4 }, | ||
| 837 | /* Makito encoder sets stream type 0x11 for AAC, | ||
| 838 | * so auto-detect LOAS/LATM instead of hardcoding it. */ | ||
| 839 | #if !CONFIG_LOAS_DEMUXER | ||
| 840 | { STREAM_TYPE_AUDIO_AAC_LATM, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC_LATM }, /* LATM syntax */ | ||
| 841 | #endif | ||
| 842 | { STREAM_TYPE_VIDEO_H264, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 }, | ||
| 843 | { STREAM_TYPE_AUDIO_MPEG4, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC }, | ||
| 844 | { STREAM_TYPE_VIDEO_MVC, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 }, | ||
| 845 | { STREAM_TYPE_VIDEO_JPEG2000, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000 }, | ||
| 846 | { STREAM_TYPE_VIDEO_HEVC, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC }, | ||
| 847 | { STREAM_TYPE_VIDEO_JPEGXS, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEGXS }, | ||
| 848 | { STREAM_TYPE_VIDEO_LCEVC, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_LCEVC }, | ||
| 849 | { STREAM_TYPE_VIDEO_VVC, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VVC }, | ||
| 850 | { STREAM_TYPE_VIDEO_CAVS, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS }, | ||
| 851 | { STREAM_TYPE_VIDEO_DIRAC, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, | ||
| 852 | { STREAM_TYPE_VIDEO_AVS2, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_AVS2 }, | ||
| 853 | { STREAM_TYPE_VIDEO_AVS3, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_AVS3 }, | ||
| 854 | { STREAM_TYPE_VIDEO_VC1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 }, | ||
| 855 | { 0 }, | ||
| 856 | }; | ||
| 857 | |||
| 858 | static const StreamType HDMV_types[] = { | ||
| 859 | { STREAM_TYPE_BLURAY_AUDIO_PCM_BLURAY, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_BLURAY }, | ||
| 860 | { STREAM_TYPE_BLURAY_AUDIO_AC3, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, | ||
| 861 | { STREAM_TYPE_BLURAY_AUDIO_DTS, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, | ||
| 862 | { STREAM_TYPE_BLURAY_AUDIO_TRUEHD, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_TRUEHD }, | ||
| 863 | { STREAM_TYPE_BLURAY_AUDIO_EAC3, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, | ||
| 864 | { STREAM_TYPE_BLURAY_AUDIO_DTS_HD, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, | ||
| 865 | { STREAM_TYPE_BLURAY_AUDIO_DTS_HD_MASTER, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, | ||
| 866 | { STREAM_TYPE_BLURAY_AUDIO_EAC3_SECONDARY, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, | ||
| 867 | { STREAM_TYPE_BLURAY_AUDIO_DTS_EXPRESS_SECONDARY, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, | ||
| 868 | { STREAM_TYPE_BLURAY_SUBTITLE_PGS, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_HDMV_PGS_SUBTITLE }, | ||
| 869 | { STREAM_TYPE_BLURAY_SUBTITLE_TEXT, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_HDMV_TEXT_SUBTITLE }, | ||
| 870 | { 0 }, | ||
| 871 | }; | ||
| 872 | |||
| 873 | /* SCTE types */ | ||
| 874 | static const StreamType SCTE_types[] = { | ||
| 875 | { STREAM_TYPE_SCTE_DATA_SCTE_35, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35 }, | ||
| 876 | { 0 }, | ||
| 877 | }; | ||
| 878 | |||
| 879 | /* ATSC ? */ | ||
| 880 | static const StreamType MISC_types[] = { | ||
| 881 | { STREAM_TYPE_ATSC_AUDIO_AC3, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, | ||
| 882 | { STREAM_TYPE_ATSC_AUDIO_EAC3, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, | ||
| 883 | { 0x8a, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, | ||
| 884 | { 0 }, | ||
| 885 | }; | ||
| 886 | |||
| 887 | /* HLS Sample Encryption Types */ | ||
| 888 | static const StreamType HLS_SAMPLE_ENC_types[] = { | ||
| 889 | { STREAM_TYPE_HLS_SE_VIDEO_H264, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264}, | ||
| 890 | { STREAM_TYPE_HLS_SE_AUDIO_AAC, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC }, | ||
| 891 | { STREAM_TYPE_HLS_SE_AUDIO_AC3, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, | ||
| 892 | { STREAM_TYPE_HLS_SE_AUDIO_EAC3, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3}, | ||
| 893 | { 0 }, | ||
| 894 | }; | ||
| 895 | |||
| 896 | static const StreamType REGD_types[] = { | ||
| 897 | { MKTAG('d', 'r', 'a', 'c'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, | ||
| 898 | { MKTAG('A', 'C', '-', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, | ||
| 899 | { MKTAG('A', 'C', '-', '4'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC4 }, | ||
| 900 | { MKTAG('B', 'S', 'S', 'D'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_S302M }, | ||
| 901 | { MKTAG('D', 'T', 'S', '1'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, | ||
| 902 | { MKTAG('D', 'T', 'S', '2'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, | ||
| 903 | { MKTAG('D', 'T', 'S', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, | ||
| 904 | { MKTAG('E', 'A', 'C', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, | ||
| 905 | { MKTAG('H', 'E', 'V', 'C'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC }, | ||
| 906 | { MKTAG('V', 'V', 'C', ' '), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VVC }, | ||
| 907 | { MKTAG('K', 'L', 'V', 'A'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_KLV }, | ||
| 908 | { MKTAG('V', 'A', 'N', 'C'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_2038 }, | ||
| 909 | { MKTAG('I', 'D', '3', ' '), AVMEDIA_TYPE_DATA, AV_CODEC_ID_TIMED_ID3 }, | ||
| 910 | { MKTAG('V', 'C', '-', '1'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 }, | ||
| 911 | { MKTAG('O', 'p', 'u', 's'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_OPUS }, | ||
| 912 | { 0 }, | ||
| 913 | }; | ||
| 914 | |||
| 915 | static const StreamType METADATA_types[] = { | ||
| 916 | { MKTAG('K','L','V','A'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_KLV }, | ||
| 917 | { MKTAG('I','D','3',' '), AVMEDIA_TYPE_DATA, AV_CODEC_ID_TIMED_ID3 }, | ||
| 918 | { 0 }, | ||
| 919 | }; | ||
| 920 | |||
| 921 | /* descriptor present */ | ||
| 922 | static const StreamType DESC_types[] = { | ||
| 923 | { AC3_DESCRIPTOR, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, | ||
| 924 | { ENHANCED_AC3_DESCRIPTOR, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, | ||
| 925 | { DTS_DESCRIPTOR, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, | ||
| 926 | { TELETEXT_DESCRIPTOR, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_TELETEXT }, | ||
| 927 | { SUBTITLING_DESCRIPTOR, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_SUBTITLE }, | ||
| 928 | { 0 }, | ||
| 929 | }; | ||
| 930 | |||
| 931 | 231 | static void mpegts_find_stream_type(AVStream *st, | |
| 932 | uint32_t stream_type, | ||
| 933 | const StreamType *types) | ||
| 934 | { | ||
| 935 | 231 | FFStream *const sti = ffstream(st); | |
| 936 |
2/2✓ Branch 0 taken 1509 times.
✓ Branch 1 taken 80 times.
|
1589 | for (; types->stream_type; types++) |
| 937 |
2/2✓ Branch 0 taken 151 times.
✓ Branch 1 taken 1358 times.
|
1509 | if (stream_type == types->stream_type) { |
| 938 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 137 times.
|
151 | if (st->codecpar->codec_type != types->codec_type || |
| 939 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
|
14 | st->codecpar->codec_id != types->codec_id) { |
| 940 | 150 | st->codecpar->codec_type = types->codec_type; | |
| 941 | 150 | st->codecpar->codec_id = types->codec_id; | |
| 942 | 150 | sti->need_context_update = 1; | |
| 943 | } | ||
| 944 | 151 | sti->request_probe = 0; | |
| 945 | 151 | return; | |
| 946 | } | ||
| 947 | } | ||
| 948 | |||
| 949 | 146 | static int mpegts_set_stream_info(AVStream *st, PESContext *pes, | |
| 950 | uint32_t stream_type, uint32_t prog_reg_desc) | ||
| 951 | { | ||
| 952 | 146 | FFStream *const sti = ffstream(st); | |
| 953 | 146 | int old_codec_type = st->codecpar->codec_type; | |
| 954 | 146 | int old_codec_id = st->codecpar->codec_id; | |
| 955 | 146 | int old_codec_tag = st->codecpar->codec_tag; | |
| 956 | |||
| 957 | 146 | avpriv_set_pts_info(st, 33, 1, 90000); | |
| 958 | 146 | st->priv_data = pes; | |
| 959 | 146 | st->codecpar->codec_type = AVMEDIA_TYPE_DATA; | |
| 960 | 146 | st->codecpar->codec_id = AV_CODEC_ID_NONE; | |
| 961 | 146 | sti->need_parsing = AVSTREAM_PARSE_FULL; | |
| 962 | 146 | pes->st = st; | |
| 963 | 146 | pes->stream_type = stream_type; | |
| 964 | |||
| 965 | 146 | av_log(pes->stream, AV_LOG_DEBUG, | |
| 966 | "stream=%d stream_type=%x pid=%x prog_reg_desc=%.4s\n", | ||
| 967 | st->index, pes->stream_type, pes->pid, (char *)&prog_reg_desc); | ||
| 968 | |||
| 969 | 146 | st->codecpar->codec_tag = pes->stream_type; | |
| 970 | |||
| 971 | 146 | mpegts_find_stream_type(st, pes->stream_type, ISO_types); | |
| 972 |
4/4✓ Branch 0 taken 138 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 135 times.
|
146 | if (pes->stream_type == STREAM_TYPE_AUDIO_MPEG2 || pes->stream_type == STREAM_TYPE_AUDIO_AAC) |
| 973 | 11 | sti->request_probe = 50; | |
| 974 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 135 times.
|
146 | if (pes->stream_type == STREAM_TYPE_PRIVATE_DATA) |
| 975 | 11 | sti->request_probe = AVPROBE_SCORE_STREAM_RETRY; | |
| 976 |
2/2✓ Branch 0 taken 140 times.
✓ Branch 1 taken 6 times.
|
146 | if ((prog_reg_desc == AV_RL32("HDMV") || |
| 977 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
|
140 | prog_reg_desc == AV_RL32("HDPR")) && |
| 978 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | st->codecpar->codec_id == AV_CODEC_ID_NONE) { |
| 979 | 6 | mpegts_find_stream_type(st, pes->stream_type, HDMV_types); | |
| 980 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (pes->stream_type == STREAM_TYPE_BLURAY_AUDIO_TRUEHD) { |
| 981 | // HDMV TrueHD streams also contain an AC3 coded version of the | ||
| 982 | // audio track - add a second stream for this | ||
| 983 | AVStream *sub_st; | ||
| 984 | // priv_data cannot be shared between streams | ||
| 985 | ✗ | PESContext *sub_pes = av_memdup(pes, sizeof(*sub_pes)); | |
| 986 | ✗ | if (!sub_pes) | |
| 987 | ✗ | return AVERROR(ENOMEM); | |
| 988 | |||
| 989 | ✗ | sub_st = avformat_new_stream(pes->stream, NULL); | |
| 990 | ✗ | if (!sub_st) { | |
| 991 | ✗ | av_free(sub_pes); | |
| 992 | ✗ | return AVERROR(ENOMEM); | |
| 993 | } | ||
| 994 | |||
| 995 | ✗ | sub_st->id = pes->pid; | |
| 996 | ✗ | avpriv_set_pts_info(sub_st, 33, 1, 90000); | |
| 997 | ✗ | sub_st->priv_data = sub_pes; | |
| 998 | ✗ | sub_st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; | |
| 999 | ✗ | sub_st->codecpar->codec_id = AV_CODEC_ID_AC3; | |
| 1000 | ✗ | ffstream(sub_st)->need_parsing = AVSTREAM_PARSE_FULL; | |
| 1001 | ✗ | sub_pes->sub_st = pes->sub_st = sub_st; | |
| 1002 | } | ||
| 1003 | } | ||
| 1004 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 110 times.
|
146 | if (st->codecpar->codec_id == AV_CODEC_ID_NONE) |
| 1005 | 36 | mpegts_find_stream_type(st, pes->stream_type, MISC_types); | |
| 1006 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 131 times.
|
146 | if (st->codecpar->codec_id == AV_CODEC_ID_NONE) |
| 1007 | 15 | mpegts_find_stream_type(st, pes->stream_type, HLS_SAMPLE_ENC_types); | |
| 1008 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 131 times.
|
146 | if (st->codecpar->codec_id == AV_CODEC_ID_NONE) { |
| 1009 | 15 | st->codecpar->codec_id = old_codec_id; | |
| 1010 | 15 | st->codecpar->codec_type = old_codec_type; | |
| 1011 | } | ||
| 1012 |
2/2✓ Branch 0 taken 137 times.
✓ Branch 1 taken 9 times.
|
146 | if ((st->codecpar->codec_id == AV_CODEC_ID_NONE || |
| 1013 |
3/4✓ Branch 0 taken 17 times.
✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
|
137 | (sti->request_probe > 0 && sti->request_probe < AVPROBE_SCORE_STREAM_RETRY / 5)) && |
| 1014 |
3/4✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
|
9 | sti->probe_packets > 0 && |
| 1015 | stream_type == STREAM_TYPE_PRIVATE_DATA) { | ||
| 1016 | 5 | st->codecpar->codec_type = AVMEDIA_TYPE_DATA; | |
| 1017 | 5 | st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA; | |
| 1018 | 5 | sti->request_probe = AVPROBE_SCORE_STREAM_RETRY / 5; | |
| 1019 | } | ||
| 1020 | |||
| 1021 | /* queue a context update if properties changed */ | ||
| 1022 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 132 times.
|
146 | if (old_codec_type != st->codecpar->codec_type || |
| 1023 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4 times.
|
14 | old_codec_id != st->codecpar->codec_id || |
| 1024 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | old_codec_tag != st->codecpar->codec_tag) |
| 1025 | 146 | sti->need_context_update = 1; | |
| 1026 | |||
| 1027 | 146 | return 0; | |
| 1028 | } | ||
| 1029 | |||
| 1030 | 65413 | static void reset_pes_packet_state(PESContext *pes) | |
| 1031 | { | ||
| 1032 | 65413 | pes->pts = AV_NOPTS_VALUE; | |
| 1033 | 65413 | pes->dts = AV_NOPTS_VALUE; | |
| 1034 | 65413 | pes->data_index = 0; | |
| 1035 | 65413 | pes->flags = 0; | |
| 1036 | 65413 | av_buffer_unref(&pes->buffer); | |
| 1037 | 65413 | } | |
| 1038 | |||
| 1039 | 12 | static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt) | |
| 1040 | { | ||
| 1041 | 12 | av_packet_unref(pkt); | |
| 1042 | 12 | pkt->data = (uint8_t *)buffer; | |
| 1043 | 12 | pkt->size = len; | |
| 1044 | 12 | } | |
| 1045 | |||
| 1046 | 8 | static int timed_id3_update_metadata(AVStream *s, AVPacket *pkt) | |
| 1047 | { | ||
| 1048 | FFIOContext id3_buf; | ||
| 1049 | 8 | ID3v2ExtraMeta *extra_meta = NULL; | |
| 1050 | 8 | AVDictionary *metadata = NULL; | |
| 1051 | 8 | int ret = 0; | |
| 1052 | |||
| 1053 | 8 | ffio_init_read_context(&id3_buf, pkt->data, pkt->size); | |
| 1054 | 8 | ff_id3v2_read_dict(NULL, &id3_buf.pub, &metadata, ID3v2_DEFAULT_MAGIC, &extra_meta); | |
| 1055 | 8 | ret = ff_id3v2_parse_priv_dict(&metadata, extra_meta); | |
| 1056 | 8 | ff_id3v2_free_extra_meta(&extra_meta); | |
| 1057 | |||
| 1058 |
2/4✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
|
8 | if (ret < 0 || !av_dict_count(metadata)) |
| 1059 | ✗ | goto end; | |
| 1060 | |||
| 1061 | 8 | ret = av_dict_copy(&s->metadata, metadata, 0); | |
| 1062 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (ret == 0) |
| 1063 | 8 | s->event_flags |= AVSTREAM_EVENT_FLAG_METADATA_UPDATED; | |
| 1064 | |||
| 1065 | ✗ | end: | |
| 1066 | 8 | av_dict_free(&metadata); | |
| 1067 | 8 | return ret; | |
| 1068 | } | ||
| 1069 | |||
| 1070 | 34624 | static int new_pes_packet(PESContext *pes, AVPacket *pkt) | |
| 1071 | { | ||
| 1072 | uint8_t *sd; | ||
| 1073 | |||
| 1074 | 34624 | av_packet_unref(pkt); | |
| 1075 | |||
| 1076 | 34624 | pkt->buf = pes->buffer; | |
| 1077 | 34624 | pkt->data = pes->buffer->data; | |
| 1078 | 34624 | pkt->size = pes->data_index; | |
| 1079 | |||
| 1080 |
2/2✓ Branch 0 taken 29849 times.
✓ Branch 1 taken 4775 times.
|
34624 | if (pes->PES_packet_length && |
| 1081 |
2/2✓ Branch 0 taken 93 times.
✓ Branch 1 taken 29756 times.
|
29849 | pes->pes_header_size + pes->data_index != pes->PES_packet_length + |
| 1082 | PES_START_SIZE) { | ||
| 1083 | 93 | av_log(pes->stream, AV_LOG_WARNING, "PES packet size mismatch\n"); | |
| 1084 | 93 | pes->flags |= AV_PKT_FLAG_CORRUPT; | |
| 1085 | } | ||
| 1086 | |||
| 1087 | // JPEG-XS PES payload | ||
| 1088 |
3/4✓ Branch 0 taken 4165 times.
✓ Branch 1 taken 30459 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4165 times.
|
34624 | if (pes->stream_id == 0xbd && pes->stream_type == 0x32 && |
| 1089 | ✗ | pkt->size >= 8 && memcmp(pkt->data + 4, "jxes", 4) == 0) | |
| 1090 | { | ||
| 1091 | ✗ | uint32_t header_size = AV_RB32(pkt->data); | |
| 1092 | ✗ | if (header_size > pkt->size) { | |
| 1093 | ✗ | av_log(pes->stream, AV_LOG_WARNING, | |
| 1094 | "Invalid JPEG-XS header size %"PRIu32" > packet size %d\n", | ||
| 1095 | header_size, pkt->size); | ||
| 1096 | ✗ | pes->flags |= AV_PKT_FLAG_CORRUPT; | |
| 1097 | } else { | ||
| 1098 | ✗ | pkt->data += header_size; | |
| 1099 | ✗ | pkt->size -= header_size; | |
| 1100 | } | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | 34624 | memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); | |
| 1104 | |||
| 1105 | // Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID | ||
| 1106 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 34624 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
34624 | if (pes->sub_st && pes->stream_type == STREAM_TYPE_BLURAY_AUDIO_TRUEHD && pes->extended_stream_id == 0x76) |
| 1107 | ✗ | pkt->stream_index = pes->sub_st->index; | |
| 1108 | else | ||
| 1109 | 34624 | pkt->stream_index = pes->st->index; | |
| 1110 | 34624 | pkt->pts = pes->pts; | |
| 1111 | 34624 | pkt->dts = pes->dts; | |
| 1112 | /* store position of first TS packet of this PES packet */ | ||
| 1113 | 34624 | pkt->pos = pes->ts_packet_pos; | |
| 1114 | 34624 | pkt->flags = pes->flags; | |
| 1115 | |||
| 1116 | 34624 | pes->buffer = NULL; | |
| 1117 | 34624 | reset_pes_packet_state(pes); | |
| 1118 | |||
| 1119 | 34624 | sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1); | |
| 1120 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34624 times.
|
34624 | if (!sd) |
| 1121 | ✗ | return AVERROR(ENOMEM); | |
| 1122 | 34624 | *sd = pes->stream_id; | |
| 1123 | |||
| 1124 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 34616 times.
|
34624 | if (pes->st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) { |
| 1125 | 8 | int ret = timed_id3_update_metadata(pes->st, pkt); | |
| 1126 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (ret < 0) |
| 1127 | ✗ | return ret; | |
| 1128 | } | ||
| 1129 | |||
| 1130 | 34624 | return 0; | |
| 1131 | } | ||
| 1132 | |||
| 1133 | ✗ | static uint64_t get_ts64(GetBitContext *gb, int bits) | |
| 1134 | { | ||
| 1135 | ✗ | if (get_bits_left(gb) < bits) | |
| 1136 | ✗ | return AV_NOPTS_VALUE; | |
| 1137 | ✗ | return get_bits64(gb, bits); | |
| 1138 | } | ||
| 1139 | |||
| 1140 | ✗ | static int read_sl_header(PESContext *pes, SLConfigDescr *sl, | |
| 1141 | const uint8_t *buf, int buf_size) | ||
| 1142 | { | ||
| 1143 | GetBitContext gb; | ||
| 1144 | ✗ | int au_start_flag = 0, au_end_flag = 0, ocr_flag = 0, idle_flag = 0; | |
| 1145 | ✗ | int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0; | |
| 1146 | ✗ | int dts_flag = -1, cts_flag = -1; | |
| 1147 | ✗ | int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE; | |
| 1148 | uint8_t buf_padded[128 + AV_INPUT_BUFFER_PADDING_SIZE]; | ||
| 1149 | ✗ | int buf_padded_size = FFMIN(buf_size, sizeof(buf_padded) - AV_INPUT_BUFFER_PADDING_SIZE); | |
| 1150 | |||
| 1151 | ✗ | memcpy(buf_padded, buf, buf_padded_size); | |
| 1152 | |||
| 1153 | ✗ | init_get_bits(&gb, buf_padded, buf_padded_size * 8); | |
| 1154 | |||
| 1155 | ✗ | if (sl->use_au_start) | |
| 1156 | ✗ | au_start_flag = get_bits1(&gb); | |
| 1157 | ✗ | if (sl->use_au_end) | |
| 1158 | ✗ | au_end_flag = get_bits1(&gb); | |
| 1159 | ✗ | if (!sl->use_au_start && !sl->use_au_end) | |
| 1160 | ✗ | au_start_flag = au_end_flag = 1; | |
| 1161 | ✗ | if (sl->ocr_len > 0) | |
| 1162 | ✗ | ocr_flag = get_bits1(&gb); | |
| 1163 | ✗ | if (sl->use_idle) | |
| 1164 | ✗ | idle_flag = get_bits1(&gb); | |
| 1165 | ✗ | if (sl->use_padding) | |
| 1166 | ✗ | padding_flag = get_bits1(&gb); | |
| 1167 | ✗ | if (padding_flag) | |
| 1168 | ✗ | padding_bits = get_bits(&gb, 3); | |
| 1169 | |||
| 1170 | ✗ | if (!idle_flag && (!padding_flag || padding_bits != 0)) { | |
| 1171 | ✗ | if (sl->packet_seq_num_len) | |
| 1172 | ✗ | skip_bits_long(&gb, sl->packet_seq_num_len); | |
| 1173 | ✗ | if (sl->degr_prior_len) | |
| 1174 | ✗ | if (get_bits1(&gb)) | |
| 1175 | ✗ | skip_bits(&gb, sl->degr_prior_len); | |
| 1176 | ✗ | if (ocr_flag) | |
| 1177 | ✗ | skip_bits_long(&gb, sl->ocr_len); | |
| 1178 | ✗ | if (au_start_flag) { | |
| 1179 | ✗ | if (sl->use_rand_acc_pt) | |
| 1180 | ✗ | get_bits1(&gb); | |
| 1181 | ✗ | if (sl->au_seq_num_len > 0) | |
| 1182 | ✗ | skip_bits_long(&gb, sl->au_seq_num_len); | |
| 1183 | ✗ | if (sl->use_timestamps) { | |
| 1184 | ✗ | dts_flag = get_bits1(&gb); | |
| 1185 | ✗ | cts_flag = get_bits1(&gb); | |
| 1186 | } | ||
| 1187 | } | ||
| 1188 | ✗ | if (sl->inst_bitrate_len) | |
| 1189 | ✗ | inst_bitrate_flag = get_bits1(&gb); | |
| 1190 | ✗ | if (dts_flag == 1) | |
| 1191 | ✗ | dts = get_ts64(&gb, sl->timestamp_len); | |
| 1192 | ✗ | if (cts_flag == 1) | |
| 1193 | ✗ | cts = get_ts64(&gb, sl->timestamp_len); | |
| 1194 | ✗ | if (sl->au_len > 0) | |
| 1195 | ✗ | skip_bits_long(&gb, sl->au_len); | |
| 1196 | ✗ | if (inst_bitrate_flag) | |
| 1197 | ✗ | skip_bits_long(&gb, sl->inst_bitrate_len); | |
| 1198 | } | ||
| 1199 | |||
| 1200 | ✗ | if (dts != AV_NOPTS_VALUE) | |
| 1201 | ✗ | pes->dts = dts; | |
| 1202 | ✗ | if (cts != AV_NOPTS_VALUE) | |
| 1203 | ✗ | pes->pts = cts; | |
| 1204 | |||
| 1205 | ✗ | if (sl->timestamp_len && sl->timestamp_res) | |
| 1206 | ✗ | avpriv_set_pts_info(pes->st, sl->timestamp_len, 1, sl->timestamp_res); | |
| 1207 | |||
| 1208 | ✗ | return (get_bits_count(&gb) + 7) >> 3; | |
| 1209 | } | ||
| 1210 | |||
| 1211 | 34753 | static AVBufferRef *buffer_pool_get(MpegTSContext *ts, int size) | |
| 1212 | { | ||
| 1213 | 34753 | int index = av_log2(size + AV_INPUT_BUFFER_PADDING_SIZE); | |
| 1214 |
2/2✓ Branch 0 taken 187 times.
✓ Branch 1 taken 34566 times.
|
34753 | if (!ts->pools[index]) { |
| 1215 |
2/2✓ Branch 0 taken 147 times.
✓ Branch 1 taken 40 times.
|
187 | int pool_size = FFMIN(ts->max_packet_size + AV_INPUT_BUFFER_PADDING_SIZE, 2 << index); |
| 1216 | 187 | ts->pools[index] = av_buffer_pool_init(pool_size, NULL); | |
| 1217 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 187 times.
|
187 | if (!ts->pools[index]) |
| 1218 | ✗ | return NULL; | |
| 1219 | } | ||
| 1220 | 34753 | return av_buffer_pool_get(ts->pools[index]); | |
| 1221 | } | ||
| 1222 | |||
| 1223 | /* return non zero if a packet could be constructed */ | ||
| 1224 | 434713 | static int mpegts_push_data(MpegTSFilter *filter, | |
| 1225 | const uint8_t *buf, int buf_size, int is_start, | ||
| 1226 | int64_t pos) | ||
| 1227 | { | ||
| 1228 | 434713 | PESContext *pes = filter->u.pes_filter.opaque; | |
| 1229 | 434713 | MpegTSContext *ts = pes->ts; | |
| 1230 | const uint8_t *p; | ||
| 1231 | int ret, len; | ||
| 1232 | |||
| 1233 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 434713 times.
|
434713 | if (!ts->pkt) |
| 1234 | ✗ | return 0; | |
| 1235 | |||
| 1236 |
2/2✓ Branch 0 taken 35443 times.
✓ Branch 1 taken 399270 times.
|
434713 | if (is_start) { |
| 1237 |
3/4✓ Branch 0 taken 4654 times.
✓ Branch 1 taken 30789 times.
✓ Branch 2 taken 4654 times.
✗ Branch 3 not taken.
|
35443 | if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { |
| 1238 | 4654 | ret = new_pes_packet(pes, ts->pkt); | |
| 1239 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4654 times.
|
4654 | if (ret < 0) |
| 1240 | ✗ | return ret; | |
| 1241 | 4654 | ts->stop_parse = 1; | |
| 1242 | } else { | ||
| 1243 | 30789 | reset_pes_packet_state(pes); | |
| 1244 | } | ||
| 1245 | 35443 | pes->state = MPEGTS_HEADER; | |
| 1246 | 35443 | pes->ts_packet_pos = pos; | |
| 1247 | } | ||
| 1248 | 434713 | p = buf; | |
| 1249 |
2/2✓ Branch 0 taken 539660 times.
✓ Branch 1 taken 434713 times.
|
1409086 | while (buf_size > 0) { |
| 1250 |
5/6✓ Branch 0 taken 35443 times.
✓ Branch 1 taken 34753 times.
✓ Branch 2 taken 34753 times.
✓ Branch 3 taken 415592 times.
✓ Branch 4 taken 19119 times.
✗ Branch 5 not taken.
|
539660 | switch (pes->state) { |
| 1251 | 35443 | case MPEGTS_HEADER: | |
| 1252 | 35443 | len = PES_START_SIZE - pes->data_index; | |
| 1253 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 35441 times.
|
35443 | if (len > buf_size) |
| 1254 | 2 | len = buf_size; | |
| 1255 | 35443 | memcpy(pes->header + pes->data_index, p, len); | |
| 1256 | 35443 | pes->data_index += len; | |
| 1257 | 35443 | p += len; | |
| 1258 | 35443 | buf_size -= len; | |
| 1259 |
2/2✓ Branch 0 taken 35441 times.
✓ Branch 1 taken 2 times.
|
35443 | if (pes->data_index == PES_START_SIZE) { |
| 1260 | /* we got all the PES or section header. We can now | ||
| 1261 | * decide */ | ||
| 1262 |
3/4✓ Branch 0 taken 35434 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 35434 times.
|
35441 | if (pes->header[0] == 0x00 && pes->header[1] == 0x00 && |
| 1263 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35434 times.
|
35434 | pes->header[2] == 0x01) { |
| 1264 | /* it must be an MPEG-2 PES stream */ | ||
| 1265 | 35434 | pes->stream_id = pes->header[3]; | |
| 1266 | 35434 | av_log(pes->stream, AV_LOG_TRACE, "pid=%x stream_id=%#x\n", pes->pid, pes->stream_id); | |
| 1267 | |||
| 1268 |
3/4✓ Branch 0 taken 35434 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 681 times.
✓ Branch 3 taken 34753 times.
|
35434 | if ((pes->st && pes->st->discard == AVDISCARD_ALL && |
| 1269 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 681 times.
|
681 | (!pes->sub_st || |
| 1270 | ✗ | pes->sub_st->discard == AVDISCARD_ALL)) || | |
| 1271 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34753 times.
|
34753 | pes->stream_id == STREAM_ID_PADDING_STREAM) |
| 1272 | 681 | goto skip; | |
| 1273 | |||
| 1274 | /* stream not present in PMT */ | ||
| 1275 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34753 times.
|
34753 | if (!pes->st) { |
| 1276 | ✗ | if (ts->skip_changes) | |
| 1277 | ✗ | goto skip; | |
| 1278 | ✗ | if (ts->merge_pmt_versions) | |
| 1279 | ✗ | goto skip; /* wait for PMT to merge new stream */ | |
| 1280 | |||
| 1281 | ✗ | pes->st = avformat_new_stream(ts->stream, NULL); | |
| 1282 | ✗ | if (!pes->st) | |
| 1283 | ✗ | return AVERROR(ENOMEM); | |
| 1284 | ✗ | pes->st->id = pes->pid; | |
| 1285 | ✗ | mpegts_set_stream_info(pes->st, pes, 0, 0); | |
| 1286 | } | ||
| 1287 | |||
| 1288 | 34753 | pes->PES_packet_length = AV_RB16(pes->header + 4); | |
| 1289 | /* NOTE: zero length means the PES size is unbounded */ | ||
| 1290 | |||
| 1291 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | if (pes->stream_id != STREAM_ID_PROGRAM_STREAM_MAP && |
| 1292 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | pes->stream_id != STREAM_ID_PRIVATE_STREAM_2 && |
| 1293 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | pes->stream_id != STREAM_ID_ECM_STREAM && |
| 1294 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | pes->stream_id != STREAM_ID_EMM_STREAM && |
| 1295 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | pes->stream_id != STREAM_ID_PROGRAM_STREAM_DIRECTORY && |
| 1296 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | pes->stream_id != STREAM_ID_DSMCC_STREAM && |
| 1297 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
69506 | pes->stream_id != STREAM_ID_TYPE_E_STREAM) { |
| 1298 | 34753 | FFStream *const pes_sti = ffstream(pes->st); | |
| 1299 | 34753 | pes->state = MPEGTS_PESHEADER; | |
| 1300 |
3/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34751 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
34753 | if (pes->st->codecpar->codec_id == AV_CODEC_ID_NONE && !pes_sti->request_probe) { |
| 1301 | 2 | av_log(pes->stream, AV_LOG_TRACE, | |
| 1302 | "pid=%x stream_type=%x probing\n", | ||
| 1303 | pes->pid, | ||
| 1304 | pes->stream_type); | ||
| 1305 | 2 | pes_sti->request_probe = 1; | |
| 1306 | } | ||
| 1307 | } else { | ||
| 1308 | ✗ | pes->pes_header_size = 6; | |
| 1309 | ✗ | pes->state = MPEGTS_PAYLOAD; | |
| 1310 | ✗ | pes->data_index = 0; | |
| 1311 | } | ||
| 1312 | } else { | ||
| 1313 | /* otherwise, it should be a table */ | ||
| 1314 | /* skip packet */ | ||
| 1315 | 7 | skip: | |
| 1316 | 688 | pes->state = MPEGTS_SKIP; | |
| 1317 | 688 | continue; | |
| 1318 | } | ||
| 1319 | } | ||
| 1320 | 34755 | break; | |
| 1321 | /**********************************************/ | ||
| 1322 | /* PES packing parsing */ | ||
| 1323 | 34753 | case MPEGTS_PESHEADER: | |
| 1324 | 34753 | len = PES_HEADER_SIZE - pes->data_index; | |
| 1325 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34753 times.
|
34753 | if (len < 0) |
| 1326 | ✗ | return AVERROR_INVALIDDATA; | |
| 1327 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34753 times.
|
34753 | if (len > buf_size) |
| 1328 | ✗ | len = buf_size; | |
| 1329 | 34753 | memcpy(pes->header + pes->data_index, p, len); | |
| 1330 | 34753 | pes->data_index += len; | |
| 1331 | 34753 | p += len; | |
| 1332 | 34753 | buf_size -= len; | |
| 1333 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | if (pes->data_index == PES_HEADER_SIZE) { |
| 1334 | 34753 | pes->pes_header_size = pes->header[8] + 9; | |
| 1335 | 34753 | pes->state = MPEGTS_PESHEADER_FILL; | |
| 1336 | } | ||
| 1337 | 34753 | break; | |
| 1338 | 34753 | case MPEGTS_PESHEADER_FILL: | |
| 1339 | 34753 | len = pes->pes_header_size - pes->data_index; | |
| 1340 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34753 times.
|
34753 | if (len < 0) |
| 1341 | ✗ | return AVERROR_INVALIDDATA; | |
| 1342 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34753 times.
|
34753 | if (len > buf_size) |
| 1343 | ✗ | len = buf_size; | |
| 1344 | 34753 | memcpy(pes->header + pes->data_index, p, len); | |
| 1345 | 34753 | pes->data_index += len; | |
| 1346 | 34753 | p += len; | |
| 1347 | 34753 | buf_size -= len; | |
| 1348 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | if (pes->data_index == pes->pes_header_size) { |
| 1349 | const uint8_t *r; | ||
| 1350 | unsigned int flags, pes_ext, skip; | ||
| 1351 | |||
| 1352 | 34753 | flags = pes->header[7]; | |
| 1353 | 34753 | r = pes->header + 9; | |
| 1354 | 34753 | pes->pts = AV_NOPTS_VALUE; | |
| 1355 | 34753 | pes->dts = AV_NOPTS_VALUE; | |
| 1356 |
2/2✓ Branch 0 taken 13119 times.
✓ Branch 1 taken 21634 times.
|
34753 | if ((flags & 0xc0) == 0x80) { |
| 1357 | 13119 | pes->dts = pes->pts = ff_parse_pes_pts(r); | |
| 1358 | 13119 | r += 5; | |
| 1359 |
2/2✓ Branch 0 taken 3131 times.
✓ Branch 1 taken 18503 times.
|
21634 | } else if ((flags & 0xc0) == 0xc0) { |
| 1360 | 3131 | pes->pts = ff_parse_pes_pts(r); | |
| 1361 | 3131 | r += 5; | |
| 1362 | 3131 | pes->dts = ff_parse_pes_pts(r); | |
| 1363 | 3131 | r += 5; | |
| 1364 | } | ||
| 1365 | 34753 | pes->extended_stream_id = -1; | |
| 1366 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34753 times.
|
34753 | if (flags & 0x01) { /* PES extension */ |
| 1367 | ✗ | pes_ext = *r++; | |
| 1368 | /* Skip PES private data, program packet sequence counter and P-STD buffer */ | ||
| 1369 | ✗ | skip = (pes_ext >> 4) & 0xb; | |
| 1370 | ✗ | skip += skip & 0x9; | |
| 1371 | ✗ | r += skip; | |
| 1372 | ✗ | if ((pes_ext & 0x41) == 0x01 && | |
| 1373 | ✗ | (r + 2) <= (pes->header + pes->pes_header_size)) { | |
| 1374 | /* PES extension 2 */ | ||
| 1375 | ✗ | if ((r[0] & 0x7f) > 0 && (r[1] & 0x80) == 0) | |
| 1376 | ✗ | pes->extended_stream_id = r[1]; | |
| 1377 | } | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | /* we got the full header. We parse it and get the payload */ | ||
| 1381 | 34753 | pes->state = MPEGTS_PAYLOAD; | |
| 1382 | 34753 | pes->data_index = 0; | |
| 1383 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 34753 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
34753 | if (pes->stream_type == STREAM_TYPE_ISO_IEC_14496_PES && buf_size > 0) { |
| 1384 | ✗ | int sl_header_bytes = read_sl_header(pes, &pes->sl, p, | |
| 1385 | buf_size); | ||
| 1386 | ✗ | pes->pes_header_size += sl_header_bytes; | |
| 1387 | ✗ | p += sl_header_bytes; | |
| 1388 | ✗ | buf_size -= sl_header_bytes; | |
| 1389 | } | ||
| 1390 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 34745 times.
|
34753 | if (pes->stream_type == STREAM_TYPE_METADATA && |
| 1391 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | pes->stream_id == STREAM_ID_METADATA_STREAM && |
| 1392 | ✗ | pes->st->codecpar->codec_id == AV_CODEC_ID_SMPTE_KLV && | |
| 1393 | buf_size >= 5) { | ||
| 1394 | /* skip metadata access unit header - see MISB ST 1402 */ | ||
| 1395 | ✗ | pes->pes_header_size += 5; | |
| 1396 | ✗ | p += 5; | |
| 1397 | ✗ | buf_size -= 5; | |
| 1398 | } | ||
| 1399 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | if ( pes->ts->fix_teletext_pts |
| 1400 |
1/2✓ Branch 0 taken 34753 times.
✗ Branch 1 not taken.
|
34753 | && ( pes->st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT |
| 1401 |
2/2✓ Branch 0 taken 257 times.
✓ Branch 1 taken 34496 times.
|
34753 | || pes->st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) |
| 1402 | ) { | ||
| 1403 | 257 | AVProgram *p = NULL; | |
| 1404 | 257 | int pcr_found = 0; | |
| 1405 |
2/2✓ Branch 1 taken 257 times.
✓ Branch 2 taken 257 times.
|
514 | while ((p = av_find_program_from_stream(pes->stream, p, pes->st->index))) { |
| 1406 |
2/4✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 257 times.
✗ Branch 3 not taken.
|
257 | if (p->pcr_pid != -1 && p->discard != AVDISCARD_ALL) { |
| 1407 | 257 | MpegTSFilter *f = pes->ts->pids[p->pcr_pid]; | |
| 1408 |
1/2✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
|
257 | if (f) { |
| 1409 | 257 | AVStream *st = NULL; | |
| 1410 |
1/2✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
|
257 | if (f->type == MPEGTS_PES) { |
| 1411 | 257 | PESContext *pcrpes = f->u.pes_filter.opaque; | |
| 1412 |
1/2✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
|
257 | if (pcrpes) |
| 1413 | 257 | st = pcrpes->st; | |
| 1414 | ✗ | } else if (f->type == MPEGTS_PCR) { | |
| 1415 | int i; | ||
| 1416 | ✗ | for (i = 0; i < p->nb_stream_indexes; i++) { | |
| 1417 | ✗ | AVStream *pst = pes->stream->streams[p->stream_index[i]]; | |
| 1418 | ✗ | if (pst->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) | |
| 1419 | ✗ | st = pst; | |
| 1420 | } | ||
| 1421 | } | ||
| 1422 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
257 | if (f->last_pcr != -1 && !f->discard) { |
| 1423 | // teletext packets do not always have correct timestamps, | ||
| 1424 | // the standard says they should be handled after 40.6 ms at most, | ||
| 1425 | // and the pcr error to this packet should be no more than 100 ms. | ||
| 1426 | // TODO: we should interpolate the PCR, not just use the last one | ||
| 1427 | ✗ | int64_t pcr = f->last_pcr / SYSTEM_CLOCK_FREQUENCY_DIVISOR; | |
| 1428 | ✗ | pcr_found = 1; | |
| 1429 | ✗ | if (st) { | |
| 1430 | ✗ | const FFStream *const sti = ffstream(st); | |
| 1431 | ✗ | FFStream *const pes_sti = ffstream(pes->st); | |
| 1432 | |||
| 1433 | ✗ | pes_sti->pts_wrap_reference = sti->pts_wrap_reference; | |
| 1434 | ✗ | pes_sti->pts_wrap_behavior = sti->pts_wrap_behavior; | |
| 1435 | } | ||
| 1436 | ✗ | if (pes->dts == AV_NOPTS_VALUE || pes->dts < pcr) { | |
| 1437 | ✗ | pes->pts = pes->dts = pcr; | |
| 1438 | ✗ | } else if (pes->st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT && | |
| 1439 | ✗ | pes->dts > pcr + 3654 + 9000) { | |
| 1440 | ✗ | pes->pts = pes->dts = pcr + 3654 + 9000; | |
| 1441 | ✗ | } else if (pes->st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE && | |
| 1442 | ✗ | pes->dts > pcr + 10*90000) { //10sec | |
| 1443 | ✗ | pes->pts = pes->dts = pcr + 3654 + 9000; | |
| 1444 | } | ||
| 1445 | ✗ | break; | |
| 1446 | } | ||
| 1447 | } | ||
| 1448 | } | ||
| 1449 | } | ||
| 1450 | |||
| 1451 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
257 | if (pes->st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT && |
| 1452 | !pcr_found) { | ||
| 1453 | ✗ | av_log(pes->stream, AV_LOG_VERBOSE, | |
| 1454 | "Forcing DTS/PTS to be unset for a " | ||
| 1455 | "non-trustworthy PES packet for PID %d as " | ||
| 1456 | "PCR hasn't been received yet.\n", | ||
| 1457 | pes->pid); | ||
| 1458 | ✗ | pes->dts = pes->pts = AV_NOPTS_VALUE; | |
| 1459 | } | ||
| 1460 | } | ||
| 1461 | } | ||
| 1462 | 34753 | break; | |
| 1463 | 415592 | case MPEGTS_PAYLOAD: | |
| 1464 | do { | ||
| 1465 | 415592 | int max_packet_size = ts->max_packet_size; | |
| 1466 |
3/4✓ Branch 0 taken 234677 times.
✓ Branch 1 taken 180915 times.
✓ Branch 2 taken 234677 times.
✗ Branch 3 not taken.
|
415592 | if (pes->PES_packet_length && pes->PES_packet_length + PES_START_SIZE > pes->pes_header_size) { |
| 1467 | 234677 | const int pes_payload_size = pes->PES_packet_length + PES_START_SIZE - pes->pes_header_size; | |
| 1468 | |||
| 1469 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 234677 times.
|
234677 | if (pes_payload_size > ts->max_packet_size) |
| 1470 | ✗ | pes->PES_packet_length = 0; | |
| 1471 | else | ||
| 1472 | 234677 | max_packet_size = pes_payload_size; | |
| 1473 | } | ||
| 1474 | |||
| 1475 |
2/2✓ Branch 0 taken 380839 times.
✓ Branch 1 taken 34753 times.
|
415592 | if (pes->data_index > 0 && |
| 1476 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 380839 times.
|
380839 | pes->data_index + buf_size > max_packet_size) { |
| 1477 | ✗ | ret = new_pes_packet(pes, ts->pkt); | |
| 1478 | ✗ | if (ret < 0) | |
| 1479 | ✗ | return ret; | |
| 1480 | ✗ | pes->PES_packet_length = 0; | |
| 1481 | ✗ | max_packet_size = ts->max_packet_size; | |
| 1482 | ✗ | ts->stop_parse = 1; | |
| 1483 |
3/4✓ Branch 0 taken 34753 times.
✓ Branch 1 taken 380839 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 34753 times.
|
415592 | } else if (pes->data_index == 0 && |
| 1484 | buf_size > max_packet_size) { | ||
| 1485 | // pes packet size is < ts size packet and pes data is padded with STUFFING_BYTE | ||
| 1486 | // not sure if this is legal in ts but see issue #2392 | ||
| 1487 | ✗ | buf_size = max_packet_size; | |
| 1488 | } | ||
| 1489 | |||
| 1490 |
2/2✓ Branch 0 taken 34753 times.
✓ Branch 1 taken 380839 times.
|
415592 | if (!pes->buffer) { |
| 1491 | 34753 | pes->buffer = buffer_pool_get(ts, max_packet_size); | |
| 1492 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34753 times.
|
34753 | if (!pes->buffer) |
| 1493 | ✗ | return AVERROR(ENOMEM); | |
| 1494 | } | ||
| 1495 | |||
| 1496 | 415592 | memcpy(pes->buffer->data + pes->data_index, p, buf_size); | |
| 1497 | 415592 | pes->data_index += buf_size; | |
| 1498 | /* emit complete packets with known packet size | ||
| 1499 | * decreases demuxer delay for infrequent packets like subtitles from | ||
| 1500 | * a couple of seconds to milliseconds for properly muxed files. */ | ||
| 1501 |
4/4✓ Branch 0 taken 410938 times.
✓ Branch 1 taken 4654 times.
✓ Branch 2 taken 234677 times.
✓ Branch 3 taken 176261 times.
|
415592 | if (!ts->stop_parse && pes->PES_packet_length && |
| 1502 |
2/2✓ Branch 0 taken 29756 times.
✓ Branch 1 taken 204921 times.
|
234677 | pes->pes_header_size + pes->data_index == pes->PES_packet_length + PES_START_SIZE) { |
| 1503 | 29756 | ts->stop_parse = 1; | |
| 1504 | 29756 | ret = new_pes_packet(pes, ts->pkt); | |
| 1505 | 29756 | pes->state = MPEGTS_SKIP; | |
| 1506 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 29756 times.
|
29756 | if (ret < 0) |
| 1507 | ✗ | return ret; | |
| 1508 | } | ||
| 1509 | } while (0); | ||
| 1510 | 415592 | buf_size = 0; | |
| 1511 | 415592 | break; | |
| 1512 | 19119 | case MPEGTS_SKIP: | |
| 1513 | 19119 | buf_size = 0; | |
| 1514 | 19119 | break; | |
| 1515 | } | ||
| 1516 | } | ||
| 1517 | |||
| 1518 | 434713 | return 0; | |
| 1519 | } | ||
| 1520 | |||
| 1521 | 158 | static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid) | |
| 1522 | { | ||
| 1523 | MpegTSFilter *tss; | ||
| 1524 | PESContext *pes; | ||
| 1525 | |||
| 1526 | /* if no pid found, then add a pid context */ | ||
| 1527 | 158 | pes = av_mallocz(sizeof(PESContext)); | |
| 1528 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
|
158 | if (!pes) |
| 1529 | ✗ | return 0; | |
| 1530 | 158 | pes->ts = ts; | |
| 1531 | 158 | pes->stream = ts->stream; | |
| 1532 | 158 | pes->pid = pid; | |
| 1533 | 158 | pes->pcr_pid = pcr_pid; | |
| 1534 | 158 | pes->state = MPEGTS_SKIP; | |
| 1535 | 158 | pes->pts = AV_NOPTS_VALUE; | |
| 1536 | 158 | pes->dts = AV_NOPTS_VALUE; | |
| 1537 | 158 | tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes); | |
| 1538 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
|
158 | if (!tss) { |
| 1539 | ✗ | av_free(pes); | |
| 1540 | ✗ | return 0; | |
| 1541 | } | ||
| 1542 | 158 | return pes; | |
| 1543 | } | ||
| 1544 | |||
| 1545 | #define MAX_LEVEL 4 | ||
| 1546 | typedef struct MP4DescrParseContext { | ||
| 1547 | AVFormatContext *s; | ||
| 1548 | FFIOContext pb; | ||
| 1549 | Mp4Descr *descr; | ||
| 1550 | Mp4Descr *active_descr; | ||
| 1551 | int descr_count; | ||
| 1552 | int max_descr_count; | ||
| 1553 | int level; | ||
| 1554 | int predefined_SLConfigDescriptor_seen; | ||
| 1555 | } MP4DescrParseContext; | ||
| 1556 | |||
| 1557 | ✗ | static int init_MP4DescrParseContext(MP4DescrParseContext *d, AVFormatContext *s, | |
| 1558 | const uint8_t *buf, unsigned size, | ||
| 1559 | Mp4Descr *descr, int max_descr_count) | ||
| 1560 | { | ||
| 1561 | ✗ | if (size > (1 << 30)) | |
| 1562 | ✗ | return AVERROR_INVALIDDATA; | |
| 1563 | |||
| 1564 | ✗ | ffio_init_read_context(&d->pb, buf, size); | |
| 1565 | |||
| 1566 | ✗ | d->s = s; | |
| 1567 | ✗ | d->level = 0; | |
| 1568 | ✗ | d->descr_count = 0; | |
| 1569 | ✗ | d->descr = descr; | |
| 1570 | ✗ | d->active_descr = NULL; | |
| 1571 | ✗ | d->max_descr_count = max_descr_count; | |
| 1572 | |||
| 1573 | ✗ | return 0; | |
| 1574 | } | ||
| 1575 | |||
| 1576 | ✗ | static void update_offsets(AVIOContext *pb, int64_t *off, int *len) | |
| 1577 | { | ||
| 1578 | ✗ | int64_t new_off = avio_tell(pb); | |
| 1579 | ✗ | (*len) -= new_off - *off; | |
| 1580 | ✗ | *off = new_off; | |
| 1581 | ✗ | } | |
| 1582 | |||
| 1583 | static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, | ||
| 1584 | int target_tag); | ||
| 1585 | |||
| 1586 | ✗ | static int parse_mp4_descr_arr(MP4DescrParseContext *d, int64_t off, int len) | |
| 1587 | { | ||
| 1588 | ✗ | while (len > 0) { | |
| 1589 | ✗ | int ret = parse_mp4_descr(d, off, len, 0); | |
| 1590 | ✗ | if (ret < 0) | |
| 1591 | ✗ | return ret; | |
| 1592 | ✗ | update_offsets(&d->pb.pub, &off, &len); | |
| 1593 | } | ||
| 1594 | ✗ | return 0; | |
| 1595 | } | ||
| 1596 | |||
| 1597 | ✗ | static int parse_MP4IODescrTag(MP4DescrParseContext *d, int64_t off, int len) | |
| 1598 | { | ||
| 1599 | ✗ | AVIOContext *const pb = &d->pb.pub; | |
| 1600 | ✗ | avio_rb16(pb); // ID | |
| 1601 | ✗ | avio_r8(pb); | |
| 1602 | ✗ | avio_r8(pb); | |
| 1603 | ✗ | avio_r8(pb); | |
| 1604 | ✗ | avio_r8(pb); | |
| 1605 | ✗ | avio_r8(pb); | |
| 1606 | ✗ | update_offsets(pb, &off, &len); | |
| 1607 | ✗ | return parse_mp4_descr_arr(d, off, len); | |
| 1608 | } | ||
| 1609 | |||
| 1610 | ✗ | static int parse_MP4ODescrTag(MP4DescrParseContext *d, int64_t off, int len) | |
| 1611 | { | ||
| 1612 | int id_flags; | ||
| 1613 | ✗ | if (len < 2) | |
| 1614 | ✗ | return 0; | |
| 1615 | ✗ | id_flags = avio_rb16(&d->pb.pub); | |
| 1616 | ✗ | if (!(id_flags & 0x0020)) { // URL_Flag | |
| 1617 | ✗ | update_offsets(&d->pb.pub, &off, &len); | |
| 1618 | ✗ | return parse_mp4_descr_arr(d, off, len); // ES_Descriptor[] | |
| 1619 | } else { | ||
| 1620 | ✗ | return 0; | |
| 1621 | } | ||
| 1622 | } | ||
| 1623 | |||
| 1624 | ✗ | static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len) | |
| 1625 | { | ||
| 1626 | ✗ | AVIOContext *const pb = &d->pb.pub; | |
| 1627 | ✗ | int es_id = 0; | |
| 1628 | ✗ | int ret = 0; | |
| 1629 | |||
| 1630 | ✗ | if (d->descr_count >= d->max_descr_count) | |
| 1631 | ✗ | return AVERROR_INVALIDDATA; | |
| 1632 | ✗ | ff_mp4_parse_es_descr(pb, &es_id); | |
| 1633 | ✗ | d->active_descr = d->descr + (d->descr_count++); | |
| 1634 | |||
| 1635 | ✗ | d->active_descr->es_id = es_id; | |
| 1636 | ✗ | update_offsets(pb, &off, &len); | |
| 1637 | ✗ | if ((ret = parse_mp4_descr(d, off, len, MP4DecConfigDescrTag)) < 0) | |
| 1638 | ✗ | return ret; | |
| 1639 | ✗ | update_offsets(pb, &off, &len); | |
| 1640 | ✗ | if (len > 0) | |
| 1641 | ✗ | ret = parse_mp4_descr(d, off, len, MP4SLDescrTag); | |
| 1642 | ✗ | d->active_descr = NULL; | |
| 1643 | ✗ | return ret; | |
| 1644 | } | ||
| 1645 | |||
| 1646 | ✗ | static int parse_MP4DecConfigDescrTag(MP4DescrParseContext *d, int64_t off, | |
| 1647 | int len) | ||
| 1648 | { | ||
| 1649 | ✗ | Mp4Descr *descr = d->active_descr; | |
| 1650 | ✗ | if (!descr) | |
| 1651 | ✗ | return AVERROR_INVALIDDATA; | |
| 1652 | ✗ | d->active_descr->dec_config_descr = av_malloc(len); | |
| 1653 | ✗ | if (!descr->dec_config_descr) | |
| 1654 | ✗ | return AVERROR(ENOMEM); | |
| 1655 | ✗ | descr->dec_config_descr_len = len; | |
| 1656 | ✗ | avio_read(&d->pb.pub, descr->dec_config_descr, len); | |
| 1657 | ✗ | return 0; | |
| 1658 | } | ||
| 1659 | |||
| 1660 | ✗ | static int parse_MP4SLDescrTag(MP4DescrParseContext *d, int64_t off, int len) | |
| 1661 | { | ||
| 1662 | ✗ | Mp4Descr *descr = d->active_descr; | |
| 1663 | ✗ | AVIOContext *const pb = &d->pb.pub; | |
| 1664 | int predefined; | ||
| 1665 | ✗ | if (!descr) | |
| 1666 | ✗ | return AVERROR_INVALIDDATA; | |
| 1667 | |||
| 1668 | #define R8_CHECK_CLIP_MAX(dst, maxv) do { \ | ||
| 1669 | descr->sl.dst = avio_r8(pb); \ | ||
| 1670 | if (descr->sl.dst > maxv) { \ | ||
| 1671 | descr->sl.dst = maxv; \ | ||
| 1672 | return AVERROR_INVALIDDATA; \ | ||
| 1673 | } \ | ||
| 1674 | } while (0) | ||
| 1675 | |||
| 1676 | ✗ | predefined = avio_r8(pb); | |
| 1677 | ✗ | if (!predefined) { | |
| 1678 | int lengths; | ||
| 1679 | ✗ | int flags = avio_r8(pb); | |
| 1680 | ✗ | descr->sl.use_au_start = !!(flags & 0x80); | |
| 1681 | ✗ | descr->sl.use_au_end = !!(flags & 0x40); | |
| 1682 | ✗ | descr->sl.use_rand_acc_pt = !!(flags & 0x20); | |
| 1683 | ✗ | descr->sl.use_padding = !!(flags & 0x08); | |
| 1684 | ✗ | descr->sl.use_timestamps = !!(flags & 0x04); | |
| 1685 | ✗ | descr->sl.use_idle = !!(flags & 0x02); | |
| 1686 | ✗ | descr->sl.timestamp_res = avio_rb32(pb); | |
| 1687 | ✗ | avio_rb32(pb); | |
| 1688 | ✗ | R8_CHECK_CLIP_MAX(timestamp_len, 63); | |
| 1689 | ✗ | R8_CHECK_CLIP_MAX(ocr_len, 63); | |
| 1690 | ✗ | R8_CHECK_CLIP_MAX(au_len, 31); | |
| 1691 | ✗ | descr->sl.inst_bitrate_len = avio_r8(pb); | |
| 1692 | ✗ | lengths = avio_rb16(pb); | |
| 1693 | ✗ | descr->sl.degr_prior_len = lengths >> 12; | |
| 1694 | ✗ | descr->sl.au_seq_num_len = (lengths >> 7) & 0x1f; | |
| 1695 | ✗ | descr->sl.packet_seq_num_len = (lengths >> 2) & 0x1f; | |
| 1696 | ✗ | } else if (!d->predefined_SLConfigDescriptor_seen){ | |
| 1697 | ✗ | avpriv_report_missing_feature(d->s, "Predefined SLConfigDescriptor"); | |
| 1698 | ✗ | d->predefined_SLConfigDescriptor_seen = 1; | |
| 1699 | } | ||
| 1700 | ✗ | return 0; | |
| 1701 | } | ||
| 1702 | |||
| 1703 | ✗ | static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, | |
| 1704 | int target_tag) | ||
| 1705 | { | ||
| 1706 | int tag; | ||
| 1707 | ✗ | AVIOContext *const pb = &d->pb.pub; | |
| 1708 | ✗ | int len1 = ff_mp4_read_descr(d->s, pb, &tag); | |
| 1709 | ✗ | int ret = 0; | |
| 1710 | |||
| 1711 | ✗ | update_offsets(pb, &off, &len); | |
| 1712 | ✗ | if (len < 0 || len1 > len || len1 <= 0) { | |
| 1713 | ✗ | av_log(d->s, AV_LOG_ERROR, | |
| 1714 | "Tag %x length violation new length %d bytes remaining %d\n", | ||
| 1715 | tag, len1, len); | ||
| 1716 | ✗ | return AVERROR_INVALIDDATA; | |
| 1717 | } | ||
| 1718 | |||
| 1719 | ✗ | if (d->level++ >= MAX_LEVEL) { | |
| 1720 | ✗ | av_log(d->s, AV_LOG_ERROR, "Maximum MP4 descriptor level exceeded\n"); | |
| 1721 | ✗ | ret = AVERROR_INVALIDDATA; | |
| 1722 | ✗ | goto done; | |
| 1723 | } | ||
| 1724 | |||
| 1725 | ✗ | if (target_tag && tag != target_tag) { | |
| 1726 | ✗ | av_log(d->s, AV_LOG_ERROR, "Found tag %x expected %x\n", tag, | |
| 1727 | target_tag); | ||
| 1728 | ✗ | ret = AVERROR_INVALIDDATA; | |
| 1729 | ✗ | goto done; | |
| 1730 | } | ||
| 1731 | |||
| 1732 | ✗ | switch (tag) { | |
| 1733 | ✗ | case MP4IODescrTag: | |
| 1734 | ✗ | ret = parse_MP4IODescrTag(d, off, len1); | |
| 1735 | ✗ | break; | |
| 1736 | ✗ | case MP4ODescrTag: | |
| 1737 | ✗ | ret = parse_MP4ODescrTag(d, off, len1); | |
| 1738 | ✗ | break; | |
| 1739 | ✗ | case MP4ESDescrTag: | |
| 1740 | ✗ | ret = parse_MP4ESDescrTag(d, off, len1); | |
| 1741 | ✗ | break; | |
| 1742 | ✗ | case MP4DecConfigDescrTag: | |
| 1743 | ✗ | ret = parse_MP4DecConfigDescrTag(d, off, len1); | |
| 1744 | ✗ | break; | |
| 1745 | ✗ | case MP4SLDescrTag: | |
| 1746 | ✗ | ret = parse_MP4SLDescrTag(d, off, len1); | |
| 1747 | ✗ | break; | |
| 1748 | } | ||
| 1749 | |||
| 1750 | |||
| 1751 | ✗ | done: | |
| 1752 | ✗ | d->level--; | |
| 1753 | ✗ | avio_seek(pb, off + len1, SEEK_SET); | |
| 1754 | ✗ | return ret; | |
| 1755 | } | ||
| 1756 | |||
| 1757 | ✗ | static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, | |
| 1758 | Mp4Descr *descr, int *descr_count, int max_descr_count) | ||
| 1759 | { | ||
| 1760 | MP4DescrParseContext d; | ||
| 1761 | int ret; | ||
| 1762 | |||
| 1763 | ✗ | d.predefined_SLConfigDescriptor_seen = 0; | |
| 1764 | |||
| 1765 | ✗ | ret = init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count); | |
| 1766 | ✗ | if (ret < 0) | |
| 1767 | ✗ | return ret; | |
| 1768 | |||
| 1769 | ✗ | ret = parse_mp4_descr(&d, avio_tell(&d.pb.pub), size, MP4IODescrTag); | |
| 1770 | |||
| 1771 | ✗ | *descr_count += d.descr_count; | |
| 1772 | ✗ | return ret; | |
| 1773 | } | ||
| 1774 | |||
| 1775 | ✗ | static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size, | |
| 1776 | Mp4Descr *descr, int *descr_count, int max_descr_count) | ||
| 1777 | { | ||
| 1778 | MP4DescrParseContext d; | ||
| 1779 | int ret; | ||
| 1780 | |||
| 1781 | ✗ | ret = init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count); | |
| 1782 | ✗ | if (ret < 0) | |
| 1783 | ✗ | return ret; | |
| 1784 | |||
| 1785 | ✗ | ret = parse_mp4_descr_arr(&d, avio_tell(&d.pb.pub), size); | |
| 1786 | |||
| 1787 | ✗ | *descr_count = d.descr_count; | |
| 1788 | ✗ | return ret; | |
| 1789 | } | ||
| 1790 | |||
| 1791 | ✗ | static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, | |
| 1792 | int section_len) | ||
| 1793 | { | ||
| 1794 | ✗ | MpegTSContext *ts = filter->u.section_filter.opaque; | |
| 1795 | ✗ | MpegTSSectionFilter *tssf = &filter->u.section_filter; | |
| 1796 | SectionHeader h; | ||
| 1797 | const uint8_t *p, *p_end; | ||
| 1798 | ✗ | int mp4_descr_count = 0; | |
| 1799 | ✗ | Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = { { 0 } }; | |
| 1800 | int i, pid; | ||
| 1801 | ✗ | AVFormatContext *s = ts->stream; | |
| 1802 | |||
| 1803 | ✗ | p_end = section + section_len - 4; | |
| 1804 | ✗ | p = section; | |
| 1805 | ✗ | if (parse_section_header(&h, &p, p_end) < 0) | |
| 1806 | ✗ | return; | |
| 1807 | ✗ | if (h.tid != M4OD_TID) | |
| 1808 | ✗ | return; | |
| 1809 | ✗ | if (skip_identical(&h, tssf)) | |
| 1810 | ✗ | return; | |
| 1811 | |||
| 1812 | ✗ | mp4_read_od(s, p, (unsigned) (p_end - p), mp4_descr, &mp4_descr_count, | |
| 1813 | MAX_MP4_DESCR_COUNT); | ||
| 1814 | |||
| 1815 | ✗ | for (pid = 0; pid < NB_PID_MAX; pid++) { | |
| 1816 | ✗ | if (!ts->pids[pid]) | |
| 1817 | ✗ | continue; | |
| 1818 | ✗ | for (i = 0; i < mp4_descr_count; i++) { | |
| 1819 | PESContext *pes; | ||
| 1820 | AVStream *st; | ||
| 1821 | FFStream *sti; | ||
| 1822 | FFIOContext pb; | ||
| 1823 | ✗ | if (ts->pids[pid]->es_id != mp4_descr[i].es_id) | |
| 1824 | ✗ | continue; | |
| 1825 | ✗ | if (ts->pids[pid]->type != MPEGTS_PES) { | |
| 1826 | ✗ | av_log(s, AV_LOG_ERROR, "pid %x is not PES\n", pid); | |
| 1827 | ✗ | continue; | |
| 1828 | } | ||
| 1829 | ✗ | pes = ts->pids[pid]->u.pes_filter.opaque; | |
| 1830 | ✗ | st = pes->st; | |
| 1831 | ✗ | if (!st) | |
| 1832 | ✗ | continue; | |
| 1833 | ✗ | sti = ffstream(st); | |
| 1834 | |||
| 1835 | ✗ | pes->sl = mp4_descr[i].sl; | |
| 1836 | |||
| 1837 | ✗ | ffio_init_read_context(&pb, mp4_descr[i].dec_config_descr, | |
| 1838 | mp4_descr[i].dec_config_descr_len); | ||
| 1839 | ✗ | ff_mp4_read_dec_config_descr(s, st, &pb.pub); | |
| 1840 | ✗ | if (st->codecpar->codec_id == AV_CODEC_ID_AAC && | |
| 1841 | ✗ | st->codecpar->extradata_size > 0) | |
| 1842 | ✗ | sti->need_parsing = 0; | |
| 1843 | ✗ | if (st->codecpar->codec_id == AV_CODEC_ID_H264 && | |
| 1844 | ✗ | st->codecpar->extradata_size > 0) | |
| 1845 | ✗ | sti->need_parsing = 0; | |
| 1846 | |||
| 1847 | ✗ | st->codecpar->codec_type = avcodec_get_type(st->codecpar->codec_id); | |
| 1848 | ✗ | sti->need_context_update = 1; | |
| 1849 | } | ||
| 1850 | } | ||
| 1851 | ✗ | for (i = 0; i < mp4_descr_count; i++) | |
| 1852 | ✗ | av_free(mp4_descr[i].dec_config_descr); | |
| 1853 | } | ||
| 1854 | |||
| 1855 | ✗ | static void scte_data_cb(MpegTSFilter *filter, const uint8_t *section, | |
| 1856 | int section_len) | ||
| 1857 | { | ||
| 1858 | ✗ | AVProgram *prg = NULL; | |
| 1859 | ✗ | MpegTSContext *ts = filter->u.section_filter.opaque; | |
| 1860 | |||
| 1861 | ✗ | int idx = ff_find_stream_index(ts->stream, filter->pid); | |
| 1862 | ✗ | if (idx < 0) | |
| 1863 | ✗ | return; | |
| 1864 | |||
| 1865 | /** | ||
| 1866 | * In case we receive an SCTE-35 packet before mpegts context is fully | ||
| 1867 | * initialized. | ||
| 1868 | */ | ||
| 1869 | ✗ | if (!ts->pkt) | |
| 1870 | ✗ | return; | |
| 1871 | |||
| 1872 | ✗ | new_data_packet(section, section_len, ts->pkt); | |
| 1873 | ✗ | ts->pkt->stream_index = idx; | |
| 1874 | ✗ | prg = av_find_program_from_stream(ts->stream, NULL, idx); | |
| 1875 | ✗ | if (prg && prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { | |
| 1876 | ✗ | MpegTSFilter *f = ts->pids[prg->pcr_pid]; | |
| 1877 | ✗ | if (f && f->last_pcr != -1) | |
| 1878 | ✗ | ts->pkt->pts = ts->pkt->dts = f->last_pcr/SYSTEM_CLOCK_FREQUENCY_DIVISOR; | |
| 1879 | } | ||
| 1880 | ✗ | ts->stop_parse = 1; | |
| 1881 | |||
| 1882 | } | ||
| 1883 | |||
| 1884 | static const uint8_t opus_coupled_stream_cnt[9] = { | ||
| 1885 | 1, 0, 1, 1, 2, 2, 2, 3, 3 | ||
| 1886 | }; | ||
| 1887 | |||
| 1888 | static const uint8_t opus_stream_cnt[9] = { | ||
| 1889 | 1, 1, 1, 2, 2, 3, 4, 4, 5, | ||
| 1890 | }; | ||
| 1891 | |||
| 1892 | static const uint8_t opus_channel_map[8][8] = { | ||
| 1893 | { 0 }, | ||
| 1894 | { 0,1 }, | ||
| 1895 | { 0,2,1 }, | ||
| 1896 | { 0,1,2,3 }, | ||
| 1897 | { 0,4,1,2,3 }, | ||
| 1898 | { 0,4,1,2,3,5 }, | ||
| 1899 | { 0,4,1,2,3,5,6 }, | ||
| 1900 | { 0,6,1,2,3,4,5,7 }, | ||
| 1901 | }; | ||
| 1902 | |||
| 1903 | 90 | static int parse_mpeg2_extension_descriptor(AVFormatContext *fc, AVStream *st, int prg_id, | |
| 1904 | const uint8_t **pp, const uint8_t *desc_end, | ||
| 1905 | MpegTSContext *ts) | ||
| 1906 | { | ||
| 1907 | 90 | int ext_tag = get8(pp, desc_end); | |
| 1908 | |||
| 1909 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 45 times.
✗ Branch 3 not taken.
|
90 | switch (ext_tag) { |
| 1910 | ✗ | case JXS_VIDEO_DESCRIPTOR: /* JPEG-XS video descriptor*/ | |
| 1911 | { | ||
| 1912 | int horizontal_size, vertical_size, schar; | ||
| 1913 | int colour_primaries, transfer_characteristics, matrix_coefficients, video_full_range_flag; | ||
| 1914 | int descriptor_version, interlace_mode, n_fields; | ||
| 1915 | unsigned frat; | ||
| 1916 | |||
| 1917 | ✗ | if (desc_end - *pp < 29) | |
| 1918 | ✗ | return AVERROR_INVALIDDATA; | |
| 1919 | |||
| 1920 | ✗ | descriptor_version = get8(pp, desc_end); | |
| 1921 | ✗ | if (descriptor_version) { | |
| 1922 | ✗ | av_log(fc, AV_LOG_WARNING, "Unsupported JPEG-XS descriptor version (%d != 0)", descriptor_version); | |
| 1923 | ✗ | return AVERROR_INVALIDDATA; | |
| 1924 | } | ||
| 1925 | |||
| 1926 | ✗ | horizontal_size = get16(pp, desc_end); | |
| 1927 | ✗ | vertical_size = get16(pp, desc_end); | |
| 1928 | ✗ | *pp += 4; /* brat */ | |
| 1929 | ✗ | frat = bytestream_get_be32(pp); | |
| 1930 | ✗ | schar = get16(pp, desc_end); | |
| 1931 | ✗ | *pp += 2; /* Ppih */ | |
| 1932 | ✗ | *pp += 2; /* Plev */ | |
| 1933 | ✗ | *pp += 4; /* max_buffer_size */ | |
| 1934 | ✗ | *pp += 1; /* buffer_model_type */ | |
| 1935 | ✗ | colour_primaries = get8(pp, desc_end); | |
| 1936 | ✗ | transfer_characteristics = get8(pp, desc_end); | |
| 1937 | ✗ | matrix_coefficients = get8(pp, desc_end); | |
| 1938 | ✗ | video_full_range_flag = (get8(pp, desc_end) & 0x80) == 0x80 ? 1 : 0; | |
| 1939 | |||
| 1940 | ✗ | interlace_mode = (frat >> 30) & 0x3; | |
| 1941 | ✗ | if (interlace_mode == 3) { | |
| 1942 | ✗ | av_log(fc, AV_LOG_WARNING, "Unknown JPEG XS interlace mode 3"); | |
| 1943 | ✗ | return AVERROR_INVALIDDATA; | |
| 1944 | } | ||
| 1945 | |||
| 1946 | ✗ | st->codecpar->field_order = interlace_mode == 0 ? AV_FIELD_PROGRESSIVE | |
| 1947 | ✗ | : (interlace_mode == 1 ? AV_FIELD_TT : AV_FIELD_BB); | |
| 1948 | ✗ | n_fields = st->codecpar->field_order == AV_FIELD_PROGRESSIVE ? 1 : 2; | |
| 1949 | |||
| 1950 | ✗ | st->codecpar->width = horizontal_size; | |
| 1951 | ✗ | st->codecpar->height = vertical_size * n_fields; | |
| 1952 | |||
| 1953 | ✗ | if (frat != 0) { | |
| 1954 | ✗ | int framerate_num = (frat & 0x0000FFFFU); | |
| 1955 | ✗ | int framerate_den = ((frat >> 24) & 0x0000003FU); | |
| 1956 | |||
| 1957 | ✗ | if (framerate_den == 2) { | |
| 1958 | ✗ | framerate_num *= 1000; | |
| 1959 | ✗ | framerate_den = 1001; | |
| 1960 | ✗ | } else if (framerate_den != 1) { | |
| 1961 | ✗ | av_log(fc, AV_LOG_WARNING, "Unknown JPEG XS framerate denominator code %u", framerate_den); | |
| 1962 | ✗ | return AVERROR_INVALIDDATA; | |
| 1963 | } | ||
| 1964 | |||
| 1965 | ✗ | st->codecpar->framerate.num = framerate_num; | |
| 1966 | ✗ | st->codecpar->framerate.den = framerate_den; | |
| 1967 | } | ||
| 1968 | |||
| 1969 | ✗ | switch (schar & 0xf) { | |
| 1970 | ✗ | case 0: st->codecpar->format = AV_PIX_FMT_YUV422P10LE; break; | |
| 1971 | ✗ | case 1: st->codecpar->format = AV_PIX_FMT_YUV444P10LE; break; | |
| 1972 | ✗ | default: | |
| 1973 | ✗ | av_log(fc, AV_LOG_WARNING, "Unknown JPEG XS sampling format"); | |
| 1974 | ✗ | break; | |
| 1975 | } | ||
| 1976 | |||
| 1977 | ✗ | st->codecpar->color_range = video_full_range_flag ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; | |
| 1978 | ✗ | st->codecpar->color_primaries = colour_primaries; | |
| 1979 | ✗ | st->codecpar->color_trc = transfer_characteristics; | |
| 1980 | ✗ | st->codecpar->color_space = matrix_coefficients; | |
| 1981 | } | ||
| 1982 | ✗ | break; | |
| 1983 | 45 | case LCEVC_VIDEO_DESCRIPTOR: | |
| 1984 | { | ||
| 1985 | 45 | struct Program *p = get_program(ts, prg_id); | |
| 1986 | struct StreamGroup *stg; | ||
| 1987 | 45 | int lcevc_stream_tag = get8(pp, desc_end); | |
| 1988 | int i; | ||
| 1989 | |||
| 1990 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
|
45 | if (!p) |
| 1991 | ✗ | return 0; | |
| 1992 | |||
| 1993 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 21 times.
|
45 | if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) |
| 1994 | 24 | return AVERROR_INVALIDDATA; | |
| 1995 | |||
| 1996 |
1/2✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
|
21 | for (i = 0; i < p->nb_stream_groups; i++) { |
| 1997 | 21 | stg = &p->stream_groups[i]; | |
| 1998 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (stg->type != AV_STREAM_GROUP_PARAMS_LCEVC) |
| 1999 | ✗ | continue; | |
| 2000 |
1/2✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
|
21 | if (stg->id == lcevc_stream_tag) |
| 2001 | 21 | break; | |
| 2002 | } | ||
| 2003 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (i == p->nb_stream_groups) { |
| 2004 | ✗ | if (p->nb_stream_groups == MAX_STREAMS_PER_PROGRAM) | |
| 2005 | ✗ | return AVERROR(EINVAL); | |
| 2006 | ✗ | p->nb_stream_groups++; | |
| 2007 | } | ||
| 2008 | |||
| 2009 | 21 | stg = &p->stream_groups[i]; | |
| 2010 | 21 | stg->id = lcevc_stream_tag; | |
| 2011 | 21 | stg->type = AV_STREAM_GROUP_PARAMS_LCEVC; | |
| 2012 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 21 times.
|
42 | for (i = 0; i < stg->nb_streams; i++) { |
| 2013 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (stg->streams[i]->codecpar->codec_id == AV_CODEC_ID_LCEVC) |
| 2014 | ✗ | break; | |
| 2015 | } | ||
| 2016 |
1/2✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
|
21 | if (i == stg->nb_streams) { |
| 2017 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (stg->nb_streams == MAX_STREAMS_PER_PROGRAM) |
| 2018 | ✗ | return AVERROR(EINVAL); | |
| 2019 | 21 | stg->streams[stg->nb_streams++] = st; | |
| 2020 | } else | ||
| 2021 | ✗ | stg->streams[i] = st; | |
| 2022 | |||
| 2023 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | av_assert0(i < stg->nb_streams); |
| 2024 | } | ||
| 2025 | 21 | break; | |
| 2026 | 45 | case LCEVC_LINKAGE_DESCRIPTOR: | |
| 2027 | { | ||
| 2028 | 45 | struct Program *p = get_program(ts, prg_id); | |
| 2029 | 45 | int num_lcevc_stream_tags = get8(pp, desc_end); | |
| 2030 | |||
| 2031 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
|
45 | if (!p) |
| 2032 | ✗ | return 0; | |
| 2033 | |||
| 2034 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
|
45 | if (st->codecpar->codec_id == AV_CODEC_ID_LCEVC) |
| 2035 | ✗ | return AVERROR_INVALIDDATA; | |
| 2036 | |||
| 2037 |
2/2✓ Branch 0 taken 45 times.
✓ Branch 1 taken 45 times.
|
90 | for (int i = 0; i < num_lcevc_stream_tags; i++) { |
| 2038 | 45 | struct StreamGroup *stg = NULL; | |
| 2039 | 45 | int lcevc_stream_tag = get8(pp, desc_end);; | |
| 2040 | int j; | ||
| 2041 | |||
| 2042 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
|
45 | for (j = 0; j < p->nb_stream_groups; j++) { |
| 2043 | ✗ | stg = &p->stream_groups[j]; | |
| 2044 | ✗ | if (stg->type != AV_STREAM_GROUP_PARAMS_LCEVC) | |
| 2045 | ✗ | continue; | |
| 2046 | ✗ | if (stg->id == lcevc_stream_tag) | |
| 2047 | ✗ | break; | |
| 2048 | } | ||
| 2049 |
1/2✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
|
45 | if (j == p->nb_stream_groups) { |
| 2050 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
|
45 | if (p->nb_stream_groups == MAX_STREAMS_PER_PROGRAM) |
| 2051 | ✗ | return AVERROR(EINVAL); | |
| 2052 | 45 | p->nb_stream_groups++; | |
| 2053 | } | ||
| 2054 | |||
| 2055 | 45 | stg = &p->stream_groups[j]; | |
| 2056 | 45 | stg->id = lcevc_stream_tag; | |
| 2057 | 45 | stg->type = AV_STREAM_GROUP_PARAMS_LCEVC; | |
| 2058 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
|
45 | for (j = 0; j < stg->nb_streams; j++) { |
| 2059 | ✗ | if (stg->streams[j]->index == st->index) | |
| 2060 | ✗ | break; | |
| 2061 | } | ||
| 2062 |
1/2✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
|
45 | if (j == stg->nb_streams) { |
| 2063 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
|
45 | if (stg->nb_streams == MAX_STREAMS_PER_PROGRAM) |
| 2064 | ✗ | return AVERROR(EINVAL); | |
| 2065 | 45 | stg->streams[stg->nb_streams++] = st; | |
| 2066 | } | ||
| 2067 | } | ||
| 2068 | } | ||
| 2069 | 45 | break; | |
| 2070 | ✗ | default: | |
| 2071 | ✗ | break; | |
| 2072 | } | ||
| 2073 | |||
| 2074 | 66 | return 0; | |
| 2075 | } | ||
| 2076 | |||
| 2077 | 1212 | int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, int prg_id, | |
| 2078 | const uint8_t **pp, const uint8_t *desc_list_end, | ||
| 2079 | Mp4Descr *mp4_descr, int mp4_descr_count, int pid, | ||
| 2080 | MpegTSContext *ts) | ||
| 2081 | { | ||
| 2082 | 1212 | FFStream *const sti = ffstream(st); | |
| 2083 | const uint8_t *desc_end; | ||
| 2084 | int desc_len, desc_tag, desc_es_id, ext_desc_tag, channels, channel_config_code; | ||
| 2085 | char language[252]; | ||
| 2086 | int i; | ||
| 2087 | |||
| 2088 | 1212 | desc_tag = get8(pp, desc_list_end); | |
| 2089 |
2/2✓ Branch 0 taken 697 times.
✓ Branch 1 taken 515 times.
|
1212 | if (desc_tag < 0) |
| 2090 | 697 | return AVERROR_INVALIDDATA; | |
| 2091 | 515 | desc_len = get8(pp, desc_list_end); | |
| 2092 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 515 times.
|
515 | if (desc_len < 0) |
| 2093 | ✗ | return AVERROR_INVALIDDATA; | |
| 2094 | 515 | desc_end = *pp + desc_len; | |
| 2095 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 515 times.
|
515 | if (desc_end > desc_list_end) |
| 2096 | ✗ | return AVERROR_INVALIDDATA; | |
| 2097 | |||
| 2098 | 515 | av_log(fc, AV_LOG_TRACE, "tag: 0x%02x len=%d\n", desc_tag, desc_len); | |
| 2099 | |||
| 2100 |
6/6✓ Branch 0 taken 509 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 476 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 23 times.
|
515 | if ((st->codecpar->codec_id == AV_CODEC_ID_NONE || sti->request_probe > 0) && |
| 2101 | stream_type == STREAM_TYPE_PRIVATE_DATA) | ||
| 2102 | 16 | mpegts_find_stream_type(st, desc_tag, DESC_types); | |
| 2103 | |||
| 2104 |
9/15✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 252 times.
✓ Branch 6 taken 53 times.
✓ Branch 7 taken 31 times.
✓ Branch 8 taken 6 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 90 times.
✓ Branch 14 taken 64 times.
|
515 | switch (desc_tag) { |
| 2105 | ✗ | case VIDEO_STREAM_DESCRIPTOR: | |
| 2106 | ✗ | if (get8(pp, desc_end) & 0x1) { | |
| 2107 | ✗ | st->disposition |= AV_DISPOSITION_STILL_IMAGE; | |
| 2108 | } | ||
| 2109 | ✗ | break; | |
| 2110 | ✗ | case SL_DESCRIPTOR: | |
| 2111 | ✗ | desc_es_id = get16(pp, desc_end); | |
| 2112 | ✗ | if (desc_es_id < 0) | |
| 2113 | ✗ | break; | |
| 2114 | ✗ | if (ts && ts->pids[pid]) | |
| 2115 | ✗ | ts->pids[pid]->es_id = desc_es_id; | |
| 2116 | ✗ | for (i = 0; i < mp4_descr_count; i++) | |
| 2117 | ✗ | if (mp4_descr[i].dec_config_descr_len && | |
| 2118 | ✗ | mp4_descr[i].es_id == desc_es_id) { | |
| 2119 | FFIOContext pb; | ||
| 2120 | ✗ | ffio_init_read_context(&pb, mp4_descr[i].dec_config_descr, | |
| 2121 | ✗ | mp4_descr[i].dec_config_descr_len); | |
| 2122 | ✗ | ff_mp4_read_dec_config_descr(fc, st, &pb.pub); | |
| 2123 | ✗ | if (st->codecpar->codec_id == AV_CODEC_ID_AAC && | |
| 2124 | ✗ | st->codecpar->extradata_size > 0) { | |
| 2125 | ✗ | sti->need_parsing = 0; | |
| 2126 | ✗ | sti->need_context_update = 1; | |
| 2127 | } | ||
| 2128 | ✗ | if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4SYSTEMS) | |
| 2129 | ✗ | mpegts_open_section_filter(ts, pid, m4sl_cb, ts, 1); | |
| 2130 | } | ||
| 2131 | ✗ | break; | |
| 2132 | ✗ | case FMC_DESCRIPTOR: | |
| 2133 | ✗ | if (get16(pp, desc_end) < 0) | |
| 2134 | ✗ | break; | |
| 2135 | ✗ | if (mp4_descr_count > 0 && | |
| 2136 | ✗ | (st->codecpar->codec_id == AV_CODEC_ID_AAC_LATM || | |
| 2137 | ✗ | (sti->request_probe == 0 && st->codecpar->codec_id == AV_CODEC_ID_NONE) || | |
| 2138 | ✗ | sti->request_probe > 0) && | |
| 2139 | ✗ | mp4_descr->dec_config_descr_len && mp4_descr->es_id == pid) { | |
| 2140 | FFIOContext pb; | ||
| 2141 | ✗ | ffio_init_read_context(&pb, mp4_descr->dec_config_descr, | |
| 2142 | mp4_descr->dec_config_descr_len); | ||
| 2143 | ✗ | ff_mp4_read_dec_config_descr(fc, st, &pb.pub); | |
| 2144 | ✗ | if (st->codecpar->codec_id == AV_CODEC_ID_AAC && | |
| 2145 | ✗ | st->codecpar->extradata_size > 0) { | |
| 2146 | ✗ | sti->request_probe = sti->need_parsing = 0; | |
| 2147 | ✗ | st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; | |
| 2148 | ✗ | sti->need_context_update = 1; | |
| 2149 | } | ||
| 2150 | } | ||
| 2151 | ✗ | break; | |
| 2152 | ✗ | case TELETEXT_DESCRIPTOR: | |
| 2153 | { | ||
| 2154 | ✗ | uint8_t *extradata = NULL; | |
| 2155 | ✗ | int language_count = desc_len / 5, ret; | |
| 2156 | |||
| 2157 | ✗ | if (desc_len > 0 && desc_len % 5 != 0) | |
| 2158 | ✗ | return AVERROR_INVALIDDATA; | |
| 2159 | |||
| 2160 | ✗ | if (language_count > 0) { | |
| 2161 | /* 4 bytes per language code (3 bytes) with comma or NUL byte should fit language buffer */ | ||
| 2162 | ✗ | av_assert0(language_count <= sizeof(language) / 4); | |
| 2163 | |||
| 2164 | ✗ | if (st->codecpar->extradata == NULL) { | |
| 2165 | ✗ | ret = ff_alloc_extradata(st->codecpar, language_count * 2); | |
| 2166 | ✗ | if (ret < 0) | |
| 2167 | ✗ | return ret; | |
| 2168 | } | ||
| 2169 | |||
| 2170 | ✗ | if (st->codecpar->extradata_size < language_count * 2) | |
| 2171 | ✗ | return AVERROR_INVALIDDATA; | |
| 2172 | |||
| 2173 | ✗ | extradata = st->codecpar->extradata; | |
| 2174 | |||
| 2175 | ✗ | for (i = 0; i < language_count; i++) { | |
| 2176 | ✗ | language[i * 4 + 0] = get8(pp, desc_end); | |
| 2177 | ✗ | language[i * 4 + 1] = get8(pp, desc_end); | |
| 2178 | ✗ | language[i * 4 + 2] = get8(pp, desc_end); | |
| 2179 | ✗ | language[i * 4 + 3] = ','; | |
| 2180 | |||
| 2181 | ✗ | memcpy(extradata, *pp, 2); | |
| 2182 | ✗ | extradata += 2; | |
| 2183 | |||
| 2184 | ✗ | *pp += 2; | |
| 2185 | } | ||
| 2186 | |||
| 2187 | ✗ | language[i * 4 - 1] = 0; | |
| 2188 | ✗ | av_dict_set(&st->metadata, "language", language, 0); | |
| 2189 | ✗ | sti->need_context_update = 1; | |
| 2190 | } | ||
| 2191 | } | ||
| 2192 | ✗ | break; | |
| 2193 | 9 | case SUBTITLING_DESCRIPTOR: | |
| 2194 | { | ||
| 2195 | /* 8 bytes per DVB subtitle substream data: | ||
| 2196 | * ISO_639_language_code (3 bytes), | ||
| 2197 | * subtitling_type (1 byte), | ||
| 2198 | * composition_page_id (2 bytes), | ||
| 2199 | * ancillary_page_id (2 bytes) */ | ||
| 2200 | 9 | int language_count = desc_len / 8, ret; | |
| 2201 | |||
| 2202 |
2/4✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
|
9 | if (desc_len > 0 && desc_len % 8 != 0) |
| 2203 | ✗ | return AVERROR_INVALIDDATA; | |
| 2204 | |||
| 2205 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (language_count > 1) { |
| 2206 | ✗ | avpriv_request_sample(fc, "DVB subtitles with multiple languages"); | |
| 2207 | } | ||
| 2208 | |||
| 2209 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | if (language_count > 0) { |
| 2210 | uint8_t *extradata; | ||
| 2211 | |||
| 2212 | /* 4 bytes per language code (3 bytes) with comma or NUL byte should fit language buffer */ | ||
| 2213 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | av_assert0(language_count <= sizeof(language) / 4); |
| 2214 | |||
| 2215 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6 times.
|
9 | if (st->codecpar->extradata == NULL) { |
| 2216 | 3 | ret = ff_alloc_extradata(st->codecpar, language_count * 5); | |
| 2217 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (ret < 0) |
| 2218 | ✗ | return ret; | |
| 2219 | } | ||
| 2220 | |||
| 2221 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | if (st->codecpar->extradata_size < language_count * 5) |
| 2222 | ✗ | return AVERROR_INVALIDDATA; | |
| 2223 | |||
| 2224 | 9 | extradata = st->codecpar->extradata; | |
| 2225 | |||
| 2226 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
|
18 | for (i = 0; i < language_count; i++) { |
| 2227 | 9 | language[i * 4 + 0] = get8(pp, desc_end); | |
| 2228 | 9 | language[i * 4 + 1] = get8(pp, desc_end); | |
| 2229 | 9 | language[i * 4 + 2] = get8(pp, desc_end); | |
| 2230 | 9 | language[i * 4 + 3] = ','; | |
| 2231 | |||
| 2232 | /* hearing impaired subtitles detection using subtitling_type */ | ||
| 2233 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | switch (*pp[0]) { |
| 2234 | ✗ | case 0x20: /* DVB subtitles (for the hard of hearing) with no monitor aspect ratio criticality */ | |
| 2235 | case 0x21: /* DVB subtitles (for the hard of hearing) for display on 4:3 aspect ratio monitor */ | ||
| 2236 | case 0x22: /* DVB subtitles (for the hard of hearing) for display on 16:9 aspect ratio monitor */ | ||
| 2237 | case 0x23: /* DVB subtitles (for the hard of hearing) for display on 2.21:1 aspect ratio monitor */ | ||
| 2238 | case 0x24: /* DVB subtitles (for the hard of hearing) for display on a high definition monitor */ | ||
| 2239 | case 0x25: /* DVB subtitles (for the hard of hearing) with plano-stereoscopic disparity for display on a high definition monitor */ | ||
| 2240 | ✗ | st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; | |
| 2241 | ✗ | break; | |
| 2242 | } | ||
| 2243 | |||
| 2244 | 9 | extradata[4] = get8(pp, desc_end); /* subtitling_type */ | |
| 2245 | 9 | memcpy(extradata, *pp, 4); /* composition_page_id and ancillary_page_id */ | |
| 2246 | 9 | extradata += 5; | |
| 2247 | |||
| 2248 | 9 | *pp += 4; | |
| 2249 | } | ||
| 2250 | |||
| 2251 | 9 | language[i * 4 - 1] = 0; | |
| 2252 | 9 | av_dict_set(&st->metadata, "language", language, 0); | |
| 2253 | 9 | sti->need_context_update = 1; | |
| 2254 | } | ||
| 2255 | } | ||
| 2256 | 9 | break; | |
| 2257 | 252 | case ISO_639_LANGUAGE_DESCRIPTOR: | |
| 2258 |
2/2✓ Branch 0 taken 246 times.
✓ Branch 1 taken 252 times.
|
498 | for (i = 0; i + 4 <= desc_len; i += 4) { |
| 2259 | 246 | language[i + 0] = get8(pp, desc_end); | |
| 2260 | 246 | language[i + 1] = get8(pp, desc_end); | |
| 2261 | 246 | language[i + 2] = get8(pp, desc_end); | |
| 2262 | 246 | language[i + 3] = ','; | |
| 2263 |
2/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 60 times.
✓ Branch 4 taken 186 times.
|
246 | switch (get8(pp, desc_end)) { |
| 2264 | ✗ | case 0x01: | |
| 2265 | ✗ | st->disposition |= AV_DISPOSITION_CLEAN_EFFECTS; | |
| 2266 | ✗ | break; | |
| 2267 | ✗ | case 0x02: | |
| 2268 | ✗ | st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; | |
| 2269 | ✗ | break; | |
| 2270 | 60 | case 0x03: | |
| 2271 | 60 | st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED; | |
| 2272 | 60 | st->disposition |= AV_DISPOSITION_DESCRIPTIONS; | |
| 2273 | 60 | break; | |
| 2274 | } | ||
| 2275 | } | ||
| 2276 |
4/4✓ Branch 0 taken 246 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 242 times.
✓ Branch 3 taken 4 times.
|
252 | if (i && language[0]) { |
| 2277 | 242 | language[i - 1] = 0; | |
| 2278 | /* don't overwrite language, as it may already have been set by | ||
| 2279 | * another, more specific descriptor (e.g. supplementary audio) */ | ||
| 2280 | 242 | av_dict_set(&st->metadata, "language", language, AV_DICT_DONT_OVERWRITE); | |
| 2281 | } | ||
| 2282 | 252 | break; | |
| 2283 | 53 | case REGISTRATION_DESCRIPTOR: | |
| 2284 | 53 | st->codecpar->codec_tag = bytestream_get_le32(pp); | |
| 2285 | 53 | av_log(fc, AV_LOG_TRACE, "reg_desc=%.4s\n", (char *)&st->codecpar->codec_tag); | |
| 2286 |
3/4✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 50 times.
|
53 | if (st->codecpar->codec_id == AV_CODEC_ID_NONE || sti->request_probe > 0) { |
| 2287 | 3 | mpegts_find_stream_type(st, st->codecpar->codec_tag, REGD_types); | |
| 2288 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | if (st->codecpar->codec_tag == MKTAG('B', 'S', 'S', 'D')) |
| 2289 | 2 | sti->request_probe = 50; | |
| 2290 | } | ||
| 2291 | 53 | break; | |
| 2292 | 31 | case STREAM_IDENTIFIER_DESCRIPTOR: | |
| 2293 | 31 | sti->stream_identifier = 1 + get8(pp, desc_end); | |
| 2294 | 31 | break; | |
| 2295 | 6 | case METADATA_DESCRIPTOR: | |
| 2296 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | if (get16(pp, desc_end) == 0xFFFF) |
| 2297 | 6 | *pp += 4; | |
| 2298 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | if (get8(pp, desc_end) == 0xFF) { |
| 2299 | 6 | st->codecpar->codec_tag = bytestream_get_le32(pp); | |
| 2300 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
|
6 | if (st->codecpar->codec_id == AV_CODEC_ID_NONE) |
| 2301 | 2 | mpegts_find_stream_type(st, st->codecpar->codec_tag, METADATA_types); | |
| 2302 | } | ||
| 2303 | 6 | break; | |
| 2304 | 4 | case DVB_EXTENSION_DESCRIPTOR: /* DVB extension descriptor */ | |
| 2305 | 4 | ext_desc_tag = get8(pp, desc_end); | |
| 2306 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (ext_desc_tag < 0) |
| 2307 | ✗ | return AVERROR_INVALIDDATA; | |
| 2308 |
3/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
4 | if (st->codecpar->codec_id == AV_CODEC_ID_OPUS && |
| 2309 | ext_desc_tag == 0x80) { /* User defined (provisional Opus) */ | ||
| 2310 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (!st->codecpar->extradata) { |
| 2311 | 1 | st->codecpar->extradata = av_mallocz(sizeof(opus_default_extradata) + | |
| 2312 | AV_INPUT_BUFFER_PADDING_SIZE); | ||
| 2313 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!st->codecpar->extradata) |
| 2314 | ✗ | return AVERROR(ENOMEM); | |
| 2315 | |||
| 2316 | 1 | st->codecpar->extradata_size = sizeof(opus_default_extradata); | |
| 2317 | 1 | memcpy(st->codecpar->extradata, opus_default_extradata, sizeof(opus_default_extradata)); | |
| 2318 | |||
| 2319 | 1 | channel_config_code = get8(pp, desc_end); | |
| 2320 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (channel_config_code < 0) |
| 2321 | ✗ | return AVERROR_INVALIDDATA; | |
| 2322 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (channel_config_code <= 0x8) { |
| 2323 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | st->codecpar->extradata[9] = channels = channel_config_code ? channel_config_code : 2; |
| 2324 | 1 | AV_WL32(&st->codecpar->extradata[12], 48000); | |
| 2325 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | st->codecpar->extradata[18] = channel_config_code ? (channels > 2) : /* Dual Mono */ 255; |
| 2326 | 1 | st->codecpar->extradata[19] = opus_stream_cnt[channel_config_code]; | |
| 2327 | 1 | st->codecpar->extradata[20] = opus_coupled_stream_cnt[channel_config_code]; | |
| 2328 | 1 | memcpy(&st->codecpar->extradata[21], opus_channel_map[channels - 1], channels); | |
| 2329 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | st->codecpar->extradata_size = st->codecpar->extradata[18] ? 21 + channels : 19; |
| 2330 | } else { | ||
| 2331 | ✗ | avpriv_request_sample(fc, "Opus in MPEG-TS - channel_config_code > 0x8"); | |
| 2332 | } | ||
| 2333 | 1 | sti->need_parsing = AVSTREAM_PARSE_FULL; | |
| 2334 | 1 | sti->need_context_update = 1; | |
| 2335 | } | ||
| 2336 | 3 | break; | |
| 2337 | } | ||
| 2338 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (ext_desc_tag == SUPPLEMENTARY_AUDIO_DESCRIPTOR) { |
| 2339 | int flags; | ||
| 2340 | |||
| 2341 | ✗ | if (desc_len < 1) | |
| 2342 | ✗ | return AVERROR_INVALIDDATA; | |
| 2343 | ✗ | flags = get8(pp, desc_end); | |
| 2344 | |||
| 2345 | ✗ | if ((flags & 0x80) == 0) /* mix_type */ | |
| 2346 | ✗ | st->disposition |= AV_DISPOSITION_DEPENDENT; | |
| 2347 | |||
| 2348 | ✗ | switch ((flags >> 2) & 0x1F) { /* editorial_classification */ | |
| 2349 | ✗ | case 0x01: | |
| 2350 | ✗ | st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED; | |
| 2351 | ✗ | st->disposition |= AV_DISPOSITION_DESCRIPTIONS; | |
| 2352 | ✗ | break; | |
| 2353 | ✗ | case 0x02: | |
| 2354 | ✗ | st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; | |
| 2355 | ✗ | break; | |
| 2356 | ✗ | case 0x03: | |
| 2357 | ✗ | st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED; | |
| 2358 | ✗ | break; | |
| 2359 | } | ||
| 2360 | |||
| 2361 | ✗ | if (flags & 0x01) { /* language_code_present */ | |
| 2362 | ✗ | if (desc_len < 4) | |
| 2363 | ✗ | return AVERROR_INVALIDDATA; | |
| 2364 | ✗ | language[0] = get8(pp, desc_end); | |
| 2365 | ✗ | language[1] = get8(pp, desc_end); | |
| 2366 | ✗ | language[2] = get8(pp, desc_end); | |
| 2367 | ✗ | language[3] = 0; | |
| 2368 | |||
| 2369 | /* This language always has to override a possible | ||
| 2370 | * ISO 639 language descriptor language */ | ||
| 2371 | ✗ | if (language[0]) | |
| 2372 | ✗ | av_dict_set(&st->metadata, "language", language, 0); | |
| 2373 | } | ||
| 2374 | ✗ | break; | |
| 2375 | } | ||
| 2376 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (ext_desc_tag == AC4_DESCRIPTOR) { |
| 2377 | ✗ | st->codecpar->codec_id = AV_CODEC_ID_AC4; | |
| 2378 | ✗ | st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; | |
| 2379 | } | ||
| 2380 | 1 | break; | |
| 2381 | 6 | case AC3_DESCRIPTOR: | |
| 2382 | case ENHANCED_AC3_DESCRIPTOR: | ||
| 2383 | { | ||
| 2384 | 6 | int component_type_flag = get8(pp, desc_end) & (1 << 7); | |
| 2385 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (component_type_flag) { |
| 2386 | ✗ | int component_type = get8(pp, desc_end); | |
| 2387 | ✗ | int service_type_mask = 0x38; // 0b00111000 | |
| 2388 | ✗ | int service_type = ((component_type & service_type_mask) >> 3); | |
| 2389 | ✗ | if (service_type == 0x02 /* 0b010 */) { | |
| 2390 | ✗ | st->disposition |= AV_DISPOSITION_DESCRIPTIONS; | |
| 2391 | ✗ | av_log(ts ? ts->stream : fc, AV_LOG_DEBUG, "New track disposition for id %u: %u\n", st->id, st->disposition); | |
| 2392 | } | ||
| 2393 | } | ||
| 2394 | } | ||
| 2395 | 6 | break; | |
| 2396 | ✗ | case DATA_COMPONENT_DESCRIPTOR: | |
| 2397 | // STD-B24, fascicle 3, chapter 4 defines private_stream_1 | ||
| 2398 | // for captions | ||
| 2399 | ✗ | if (stream_type == STREAM_TYPE_PRIVATE_DATA) { | |
| 2400 | // This structure is defined in STD-B10, part 1, listing 5.4 and | ||
| 2401 | // part 2, 6.2.20). | ||
| 2402 | // Listing of data_component_ids is in STD-B10, part 2, Annex J. | ||
| 2403 | // Component tag limits are documented in TR-B14, fascicle 2, | ||
| 2404 | // Vol. 3, Section 2, 4.2.8.1 | ||
| 2405 | ✗ | int actual_component_tag = sti->stream_identifier - 1; | |
| 2406 | ✗ | int picked_profile = AV_PROFILE_UNKNOWN; | |
| 2407 | ✗ | int data_component_id = get16(pp, desc_end); | |
| 2408 | ✗ | if (data_component_id < 0) | |
| 2409 | ✗ | return AVERROR_INVALIDDATA; | |
| 2410 | |||
| 2411 | ✗ | switch (data_component_id) { | |
| 2412 | ✗ | case 0x0008: | |
| 2413 | // [0x30..0x37] are component tags utilized for | ||
| 2414 | // non-mobile captioning service ("profile A"). | ||
| 2415 | ✗ | if (actual_component_tag >= 0x30 && | |
| 2416 | actual_component_tag <= 0x37) { | ||
| 2417 | ✗ | picked_profile = AV_PROFILE_ARIB_PROFILE_A; | |
| 2418 | } | ||
| 2419 | ✗ | break; | |
| 2420 | ✗ | case 0x0012: | |
| 2421 | // component tag 0x87 signifies a mobile/partial reception | ||
| 2422 | // (1seg) captioning service ("profile C"). | ||
| 2423 | ✗ | if (actual_component_tag == 0x87) { | |
| 2424 | ✗ | picked_profile = AV_PROFILE_ARIB_PROFILE_C; | |
| 2425 | } | ||
| 2426 | ✗ | break; | |
| 2427 | ✗ | default: | |
| 2428 | ✗ | break; | |
| 2429 | } | ||
| 2430 | |||
| 2431 | ✗ | if (picked_profile == AV_PROFILE_UNKNOWN) | |
| 2432 | ✗ | break; | |
| 2433 | |||
| 2434 | ✗ | st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; | |
| 2435 | ✗ | st->codecpar->codec_id = AV_CODEC_ID_ARIB_CAPTION; | |
| 2436 | ✗ | if (st->codecpar->profile != picked_profile) { | |
| 2437 | ✗ | st->codecpar->profile = picked_profile; | |
| 2438 | ✗ | sti->need_context_update = 1; | |
| 2439 | } | ||
| 2440 | ✗ | sti->request_probe = 0; | |
| 2441 | ✗ | sti->need_parsing = 0; | |
| 2442 | } | ||
| 2443 | ✗ | break; | |
| 2444 | ✗ | case DOVI_VIDEO_STREAM_DESCRIPTOR: | |
| 2445 | { | ||
| 2446 | uint32_t buf; | ||
| 2447 | AVDOVIDecoderConfigurationRecord *dovi; | ||
| 2448 | size_t dovi_size; | ||
| 2449 | ✗ | int dependency_pid = -1; // Unset | |
| 2450 | |||
| 2451 | ✗ | if (desc_end - *pp < 4) // (8 + 8 + 7 + 6 + 1 + 1 + 1) / 8 | |
| 2452 | ✗ | return AVERROR_INVALIDDATA; | |
| 2453 | |||
| 2454 | ✗ | dovi = av_dovi_alloc(&dovi_size); | |
| 2455 | ✗ | if (!dovi) | |
| 2456 | ✗ | return AVERROR(ENOMEM); | |
| 2457 | |||
| 2458 | ✗ | dovi->dv_version_major = get8(pp, desc_end); | |
| 2459 | ✗ | dovi->dv_version_minor = get8(pp, desc_end); | |
| 2460 | ✗ | buf = get16(pp, desc_end); | |
| 2461 | ✗ | dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits | |
| 2462 | ✗ | dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits | |
| 2463 | ✗ | dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit | |
| 2464 | ✗ | dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit | |
| 2465 | ✗ | dovi->bl_present_flag = buf & 0x01; // 1 bit | |
| 2466 | ✗ | if (!dovi->bl_present_flag && desc_end - *pp >= 2) { | |
| 2467 | ✗ | buf = get16(pp, desc_end); | |
| 2468 | ✗ | dependency_pid = buf >> 3; // 13 bits | |
| 2469 | } | ||
| 2470 | ✗ | if (desc_end - *pp >= 1) { // 8 bits | |
| 2471 | ✗ | buf = get8(pp, desc_end); | |
| 2472 | ✗ | dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits | |
| 2473 | ✗ | dovi->dv_md_compression = (buf >> 2) & 0x03; // 2 bits | |
| 2474 | } else { | ||
| 2475 | // 0 stands for None | ||
| 2476 | // Dolby Vision V1.2.93 profiles and levels | ||
| 2477 | ✗ | dovi->dv_bl_signal_compatibility_id = 0; | |
| 2478 | ✗ | dovi->dv_md_compression = AV_DOVI_COMPRESSION_NONE; | |
| 2479 | } | ||
| 2480 | |||
| 2481 | ✗ | if (!av_packet_side_data_add(&st->codecpar->coded_side_data, | |
| 2482 | ✗ | &st->codecpar->nb_coded_side_data, | |
| 2483 | AV_PKT_DATA_DOVI_CONF, | ||
| 2484 | (uint8_t *)dovi, dovi_size, 0)) { | ||
| 2485 | ✗ | av_free(dovi); | |
| 2486 | ✗ | return AVERROR(ENOMEM); | |
| 2487 | } | ||
| 2488 | |||
| 2489 | ✗ | av_log(fc, AV_LOG_TRACE, "DOVI, version: %d.%d, profile: %d, level: %d, " | |
| 2490 | "rpu flag: %d, el flag: %d, bl flag: %d, dependency_pid: %d, " | ||
| 2491 | "compatibility id: %d, compression: %d\n", | ||
| 2492 | ✗ | dovi->dv_version_major, dovi->dv_version_minor, | |
| 2493 | ✗ | dovi->dv_profile, dovi->dv_level, | |
| 2494 | ✗ | dovi->rpu_present_flag, | |
| 2495 | ✗ | dovi->el_present_flag, | |
| 2496 | ✗ | dovi->bl_present_flag, | |
| 2497 | dependency_pid, | ||
| 2498 | ✗ | dovi->dv_bl_signal_compatibility_id, | |
| 2499 | ✗ | dovi->dv_md_compression); | |
| 2500 | |||
| 2501 | /* A Profile 7 dual-track EL stream points at its base layer via | ||
| 2502 | * the descriptor's dependency_pid. Record a pending group entry, | ||
| 2503 | * it will be resolved once all streams are available. */ | ||
| 2504 | ✗ | if (dovi->dv_profile == 7 && dovi->el_present_flag && | |
| 2505 | ✗ | !dovi->bl_present_flag && dependency_pid >= 0) { | |
| 2506 | ✗ | struct Program *p = get_program(ts, prg_id); | |
| 2507 | struct StreamGroup *stg; | ||
| 2508 | int gi; | ||
| 2509 | |||
| 2510 | ✗ | if (!p) | |
| 2511 | ✗ | break; | |
| 2512 | |||
| 2513 | ✗ | for (gi = 0; gi < p->nb_stream_groups; gi++) { | |
| 2514 | ✗ | stg = &p->stream_groups[gi]; | |
| 2515 | ✗ | if (stg->type == AV_STREAM_GROUP_PARAMS_DOLBY_VISION && | |
| 2516 | ✗ | stg->nb_streams && stg->streams[0] == st) | |
| 2517 | ✗ | break; | |
| 2518 | } | ||
| 2519 | ✗ | if (gi == p->nb_stream_groups) { | |
| 2520 | ✗ | if (p->nb_stream_groups == MAX_STREAMS_PER_PROGRAM) | |
| 2521 | ✗ | return AVERROR(EINVAL); | |
| 2522 | ✗ | p->nb_stream_groups++; | |
| 2523 | ✗ | stg = &p->stream_groups[gi]; | |
| 2524 | ✗ | stg->type = AV_STREAM_GROUP_PARAMS_DOLBY_VISION; | |
| 2525 | ✗ | stg->id = st->id; | |
| 2526 | ✗ | stg->streams[stg->nb_streams++] = st; | |
| 2527 | } | ||
| 2528 | ✗ | stg->dep_pid = dependency_pid; | |
| 2529 | } | ||
| 2530 | } | ||
| 2531 | ✗ | break; | |
| 2532 | 90 | case EXTENSION_DESCRIPTOR: /* descriptor extension */ | |
| 2533 | { | ||
| 2534 | 90 | int ret = parse_mpeg2_extension_descriptor(fc, st, prg_id, pp, desc_end, ts); | |
| 2535 | |||
| 2536 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 66 times.
|
90 | if (ret < 0) |
| 2537 | 24 | return ret; | |
| 2538 | } | ||
| 2539 | 66 | break; | |
| 2540 | 64 | default: | |
| 2541 | 64 | break; | |
| 2542 | } | ||
| 2543 | 491 | *pp = desc_end; | |
| 2544 | 491 | return 0; | |
| 2545 | } | ||
| 2546 | |||
| 2547 | 12 | static AVStream *find_matching_stream(MpegTSContext *ts, int pid, unsigned int programid, | |
| 2548 | int stream_identifier, int pmt_stream_idx, struct Program *p) | ||
| 2549 | { | ||
| 2550 | 12 | AVFormatContext *s = ts->stream; | |
| 2551 | 12 | AVStream *found = NULL; | |
| 2552 | |||
| 2553 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (stream_identifier) { /* match based on "stream identifier descriptor" if present */ |
| 2554 | ✗ | for (int i = 0; i < p->nb_streams; i++) { | |
| 2555 | ✗ | if (p->streams[i].stream_identifier == stream_identifier) | |
| 2556 | ✗ | if (!found || pmt_stream_idx == i) /* fallback to idx based guess if multiple streams have the same identifier */ | |
| 2557 | ✗ | found = s->streams[p->streams[i].idx]; | |
| 2558 | } | ||
| 2559 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 5 times.
|
12 | } else if (pmt_stream_idx < p->nb_streams) { /* match based on position within the PMT */ |
| 2560 | 7 | found = s->streams[p->streams[pmt_stream_idx].idx]; | |
| 2561 | } | ||
| 2562 | |||
| 2563 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 5 times.
|
12 | if (found) { |
| 2564 | 7 | av_log(ts->stream, AV_LOG_VERBOSE, | |
| 2565 | "reusing existing %s stream %d (pid=0x%x) for new pid=0x%x\n", | ||
| 2566 | 7 | av_get_media_type_string(found->codecpar->codec_type), | |
| 2567 | found->index, found->id, pid); | ||
| 2568 | } | ||
| 2569 | |||
| 2570 | 12 | return found; | |
| 2571 | } | ||
| 2572 | |||
| 2573 | 721 | static int parse_stream_identifier_desc(const uint8_t *p, const uint8_t *p_end) | |
| 2574 | { | ||
| 2575 | 721 | const uint8_t **pp = &p; | |
| 2576 | const uint8_t *desc_list_end; | ||
| 2577 | const uint8_t *desc_end; | ||
| 2578 | int desc_list_len; | ||
| 2579 | int desc_len, desc_tag; | ||
| 2580 | |||
| 2581 | 721 | desc_list_len = get16(pp, p_end); | |
| 2582 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 721 times.
|
721 | if (desc_list_len < 0) |
| 2583 | ✗ | return -1; | |
| 2584 | 721 | desc_list_len &= 0xfff; | |
| 2585 | 721 | desc_list_end = p + desc_list_len; | |
| 2586 |
1/2✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
|
721 | if (desc_list_end > p_end) |
| 2587 | ✗ | return -1; | |
| 2588 | |||
| 2589 | while (1) { | ||
| 2590 | 1196 | desc_tag = get8(pp, desc_list_end); | |
| 2591 |
2/2✓ Branch 0 taken 693 times.
✓ Branch 1 taken 503 times.
|
1196 | if (desc_tag < 0) |
| 2592 | 693 | return -1; | |
| 2593 | 503 | desc_len = get8(pp, desc_list_end); | |
| 2594 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 503 times.
|
503 | if (desc_len < 0) |
| 2595 | ✗ | return -1; | |
| 2596 | 503 | desc_end = *pp + desc_len; | |
| 2597 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 503 times.
|
503 | if (desc_end > desc_list_end) |
| 2598 | ✗ | return -1; | |
| 2599 | |||
| 2600 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 475 times.
|
503 | if (desc_tag == STREAM_IDENTIFIER_DESCRIPTOR) { |
| 2601 | 28 | return get8(pp, desc_end); | |
| 2602 | } | ||
| 2603 | 475 | *pp = desc_end; | |
| 2604 | } | ||
| 2605 | |||
| 2606 | return -1; | ||
| 2607 | } | ||
| 2608 | |||
| 2609 | 170 | static int is_pes_stream(int stream_type, uint32_t prog_reg_desc) | |
| 2610 | { | ||
| 2611 |
2/3✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 140 times.
|
170 | switch (stream_type) { |
| 2612 | ✗ | case STREAM_TYPE_PRIVATE_SECTION: | |
| 2613 | case STREAM_TYPE_ISO_IEC_14496_SECTION: | ||
| 2614 | ✗ | return 0; | |
| 2615 | 30 | case STREAM_TYPE_SCTE_DATA_SCTE_35: | |
| 2616 | /* This User Private stream_type value is used by multiple organizations | ||
| 2617 | for different things. ANSI/SCTE 35 splice_info_section() is a | ||
| 2618 | private_section() not a PES_packet(). */ | ||
| 2619 | 30 | return !(prog_reg_desc == AV_RL32("CUEI")); | |
| 2620 | 140 | default: | |
| 2621 | 140 | return 1; | |
| 2622 | } | ||
| 2623 | } | ||
| 2624 | |||
| 2625 | /* UHD Blu-ray titles don't follow the Dolby Vision MPEG-TS spec [1] when | ||
| 2626 | * signaling a dual-PID Profile 7 stream. The enhancement-layer PID lacks the | ||
| 2627 | * DOVI_video_stream_descriptor, is advertised with stream_type 0x24 (HEVC) | ||
| 2628 | * instead of the spec-mandated 0x06, and uses the HDMV registration descriptor | ||
| 2629 | * instead of "DOVI". EL always has M2TS_VIDEO_EL_PID (0x1015) PID. | ||
| 2630 | * [1] <https://professionalsupport.dolby.com/s/article/How-to-signal-Dolby-Vision-in-MPEG-2-TS> | ||
| 2631 | */ | ||
| 2632 | 412 | static void detect_bdmv_dovi_group(MpegTSContext *ts, struct Program *prg, | |
| 2633 | uint32_t prog_reg_desc) | ||
| 2634 | { | ||
| 2635 | 412 | AVStream *bl_st = NULL, *el_st = NULL; | |
| 2636 | struct StreamGroup *grp; | ||
| 2637 | |||
| 2638 |
2/2✓ Branch 0 taken 388 times.
✓ Branch 1 taken 24 times.
|
412 | if (prog_reg_desc != AV_RL32("HDMV")) |
| 2639 | 388 | return; | |
| 2640 | |||
| 2641 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | if (prg->nb_stream_groups >= MAX_STREAMS_PER_PROGRAM) |
| 2642 | ✗ | return; | |
| 2643 | |||
| 2644 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | for (int i = 0; i < prg->nb_stream_groups; i++) { |
| 2645 | ✗ | if (prg->stream_groups[i].type == AV_STREAM_GROUP_PARAMS_DOLBY_VISION) | |
| 2646 | ✗ | return; | |
| 2647 | } | ||
| 2648 | |||
| 2649 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
|
48 | for (int j = 0; j < prg->nb_streams; j++) { |
| 2650 | 24 | int idx = prg->streams[j].idx; | |
| 2651 | AVStream *st; | ||
| 2652 |
2/4✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
|
24 | if (idx < 0 || idx >= ts->stream->nb_streams) |
| 2653 | ✗ | continue; | |
| 2654 | 24 | st = ts->stream->streams[idx]; | |
| 2655 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
24 | if (st->codecpar->codec_id != AV_CODEC_ID_HEVC) |
| 2656 | 24 | continue; | |
| 2657 | ✗ | if (st->id == M2TS_VIDEO_PID) | |
| 2658 | ✗ | bl_st = st; | |
| 2659 | ✗ | else if (st->id == M2TS_VIDEO_EL_PID) | |
| 2660 | ✗ | el_st = st; | |
| 2661 | } | ||
| 2662 | |||
| 2663 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
24 | if (!bl_st || !el_st) |
| 2664 | 24 | return; | |
| 2665 | |||
| 2666 | ✗ | grp = &prg->stream_groups[prg->nb_stream_groups++]; | |
| 2667 | ✗ | grp->type = AV_STREAM_GROUP_PARAMS_DOLBY_VISION; | |
| 2668 | ✗ | grp->id = el_st->id; | |
| 2669 | ✗ | grp->streams[0] = bl_st; | |
| 2670 | ✗ | grp->streams[1] = el_st; | |
| 2671 | ✗ | grp->nb_streams = 2; | |
| 2672 | } | ||
| 2673 | |||
| 2674 | 412 | static void create_stream_groups(MpegTSContext *ts, struct Program *prg) | |
| 2675 | { | ||
| 2676 |
2/2✓ Branch 0 taken 45 times.
✓ Branch 1 taken 412 times.
|
457 | for (int i = 0; i < prg->nb_stream_groups; i++) { |
| 2677 | 45 | struct StreamGroup *grp = &prg->stream_groups[i]; | |
| 2678 | AVStreamGroup *stg; | ||
| 2679 | int j; | ||
| 2680 | |||
| 2681 | /* The DOVI descriptor on a Profile 7 EL points at its base layer | ||
| 2682 | * via dependency_pid. Resolve the BL now that all streams of the | ||
| 2683 | * program have been added. */ | ||
| 2684 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
45 | if (grp->type == AV_STREAM_GROUP_PARAMS_DOLBY_VISION && grp->nb_streams == 1) { |
| 2685 | ✗ | for (j = 0; j < prg->nb_streams; j++) { | |
| 2686 | ✗ | int idx = prg->streams[j].idx; | |
| 2687 | AVStream *cand; | ||
| 2688 | ✗ | if (idx < 0 || idx >= ts->stream->nb_streams) | |
| 2689 | ✗ | continue; | |
| 2690 | ✗ | cand = ts->stream->streams[idx]; | |
| 2691 | ✗ | if (cand == grp->streams[0] || cand->id != grp->dep_pid) | |
| 2692 | ✗ | continue; | |
| 2693 | ✗ | grp->streams[1] = grp->streams[0]; | |
| 2694 | ✗ | grp->streams[0] = cand; | |
| 2695 | ✗ | grp->nb_streams = 2; | |
| 2696 | ✗ | break; | |
| 2697 | } | ||
| 2698 | } | ||
| 2699 | |||
| 2700 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 21 times.
|
45 | if (grp->nb_streams < 2) |
| 2701 | 24 | continue; | |
| 2702 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 6 times.
|
21 | for (j = 0; j < ts->stream->nb_stream_groups; j++) { |
| 2703 | 15 | stg = ts->stream->stream_groups[j]; | |
| 2704 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | if (stg->id == grp->id) |
| 2705 | 15 | break; | |
| 2706 | } | ||
| 2707 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15 times.
|
21 | if (j == ts->stream->nb_stream_groups) |
| 2708 | 6 | stg = avformat_stream_group_create(ts->stream, grp->type, NULL); | |
| 2709 | else | ||
| 2710 | 15 | continue; | |
| 2711 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (!stg) |
| 2712 | ✗ | continue; | |
| 2713 | 6 | stg->id = grp->id; | |
| 2714 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
|
18 | for (int j = 0; j < grp->nb_streams; j++) { |
| 2715 | 12 | int ret = avformat_stream_group_add_stream(stg, grp->streams[j]); | |
| 2716 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (ret < 0) { |
| 2717 | ✗ | ff_remove_stream_group(ts->stream, stg); | |
| 2718 | ✗ | continue; | |
| 2719 | } | ||
| 2720 |
1/3✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
12 | switch (grp->type) { |
| 2721 | 12 | case AV_STREAM_GROUP_PARAMS_LCEVC: | |
| 2722 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
|
12 | if (grp->streams[j]->codecpar->codec_id == AV_CODEC_ID_LCEVC) |
| 2723 | 6 | stg->params.layered_video->el_index = stg->nb_streams - 1; | |
| 2724 | 12 | break; | |
| 2725 | ✗ | case AV_STREAM_GROUP_PARAMS_DOLBY_VISION: | |
| 2726 | ✗ | if (j == 0) { | |
| 2727 | ✗ | stg->params.layered_video->width = grp->streams[j]->codecpar->width; | |
| 2728 | ✗ | stg->params.layered_video->height = grp->streams[j]->codecpar->height; | |
| 2729 | } | ||
| 2730 | ✗ | if (j == grp->nb_streams - 1) | |
| 2731 | ✗ | stg->params.layered_video->el_index = stg->nb_streams - 1; | |
| 2732 | ✗ | break; | |
| 2733 | ✗ | default: | |
| 2734 | ✗ | av_unreachable("Invalid group type!"); | |
| 2735 | } | ||
| 2736 | } | ||
| 2737 | } | ||
| 2738 | 412 | } | |
| 2739 | |||
| 2740 | 3741 | static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) | |
| 2741 | { | ||
| 2742 | 3741 | MpegTSContext *ts = filter->u.section_filter.opaque; | |
| 2743 | 3741 | MpegTSSectionFilter *tssf = &filter->u.section_filter; | |
| 2744 | struct Program old_program; | ||
| 2745 | 3741 | SectionHeader h1, *h = &h1; | |
| 2746 | PESContext *pes; | ||
| 2747 | AVStream *st; | ||
| 2748 | const uint8_t *p, *p_end, *desc_list_end; | ||
| 2749 | int program_info_length, pcr_pid, pid, stream_type; | ||
| 2750 | int desc_list_len; | ||
| 2751 | 3741 | uint32_t prog_reg_desc = 0; /* registration descriptor */ | |
| 2752 | 3741 | int stream_identifier = -1; | |
| 2753 | struct Program *prg; | ||
| 2754 | |||
| 2755 | 3741 | int mp4_descr_count = 0; | |
| 2756 | 3741 | Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = { { 0 } }; | |
| 2757 | int i; | ||
| 2758 | |||
| 2759 | 3741 | av_log(ts->stream, AV_LOG_TRACE, "PMT: len %i\n", section_len); | |
| 2760 | hex_dump_debug(ts->stream, section, section_len); | ||
| 2761 | |||
| 2762 | 3741 | p_end = section + section_len - 4; | |
| 2763 | 3741 | p = section; | |
| 2764 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3741 times.
|
3741 | if (parse_section_header(h, &p, p_end) < 0) |
| 2765 | 3329 | return; | |
| 2766 |
2/2✓ Branch 0 taken 75 times.
✓ Branch 1 taken 3666 times.
|
3741 | if (h->tid != PMT_TID) |
| 2767 | 75 | return; | |
| 2768 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3666 times.
|
3666 | if (!h->current_next) |
| 2769 | ✗ | return; | |
| 2770 |
2/2✓ Branch 1 taken 3254 times.
✓ Branch 2 taken 412 times.
|
3666 | if (skip_identical(h, tssf)) |
| 2771 | 3254 | return; | |
| 2772 | |||
| 2773 | 412 | av_log(ts->stream, AV_LOG_TRACE, "sid=0x%x sec_num=%d/%d version=%d tid=%d\n", | |
| 2774 | 412 | h->id, h->sec_num, h->last_sec_num, h->version, h->tid); | |
| 2775 | |||
| 2776 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 412 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
412 | if (!ts->scan_all_pmts && ts->skip_changes) |
| 2777 | ✗ | return; | |
| 2778 | |||
| 2779 | 412 | prg = get_program(ts, h->id); | |
| 2780 |
1/2✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
|
412 | if (prg) |
| 2781 | 412 | old_program = *prg; | |
| 2782 | else | ||
| 2783 | ✗ | clear_program(&old_program); | |
| 2784 | |||
| 2785 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 412 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
412 | if (ts->skip_unknown_pmt && !prg) |
| 2786 | ✗ | return; | |
| 2787 |
3/6✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 412 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 412 times.
|
412 | if (prg && prg->nb_pids && prg->pids[0] != ts->current_pid) |
| 2788 | ✗ | return; | |
| 2789 |
2/2✓ Branch 0 taken 270 times.
✓ Branch 1 taken 142 times.
|
412 | if (!ts->skip_clear) |
| 2790 | 270 | clear_avprogram(ts, h->id); | |
| 2791 | 412 | clear_program(prg); | |
| 2792 | 412 | add_pid_to_program(prg, ts->current_pid); | |
| 2793 | |||
| 2794 | 412 | pcr_pid = get16(&p, p_end); | |
| 2795 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 412 times.
|
412 | if (pcr_pid < 0) |
| 2796 | ✗ | return; | |
| 2797 | 412 | pcr_pid &= 0x1fff; | |
| 2798 | 412 | add_pid_to_program(prg, pcr_pid); | |
| 2799 | 412 | update_av_program_info(ts->stream, h->id, pcr_pid, h->version); | |
| 2800 | |||
| 2801 | 412 | av_log(ts->stream, AV_LOG_TRACE, "pcr_pid=0x%x\n", pcr_pid); | |
| 2802 | |||
| 2803 | 412 | program_info_length = get16(&p, p_end); | |
| 2804 | |||
| 2805 |
2/4✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 412 times.
|
412 | if (program_info_length < 0 || (program_info_length & 0xFFF) > p_end - p) |
| 2806 | ✗ | return; | |
| 2807 | 412 | program_info_length &= 0xfff; | |
| 2808 |
2/2✓ Branch 0 taken 294 times.
✓ Branch 1 taken 412 times.
|
706 | while (program_info_length >= 2) { |
| 2809 | uint8_t tag, len; | ||
| 2810 | 294 | tag = get8(&p, p_end); | |
| 2811 | 294 | len = get8(&p, p_end); | |
| 2812 | |||
| 2813 | 294 | av_log(ts->stream, AV_LOG_TRACE, "program tag: 0x%02x len=%d\n", tag, len); | |
| 2814 | |||
| 2815 | 294 | program_info_length -= 2; | |
| 2816 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 294 times.
|
294 | if (len > program_info_length) |
| 2817 | // something else is broken, exit the program_descriptors_loop | ||
| 2818 | ✗ | break; | |
| 2819 | 294 | program_info_length -= len; | |
| 2820 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 294 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
294 | if (tag == IOD_DESCRIPTOR && len >= 2) { |
| 2821 | ✗ | get8(&p, p_end); // scope | |
| 2822 | ✗ | get8(&p, p_end); // label | |
| 2823 | ✗ | len -= 2; | |
| 2824 | ✗ | mp4_read_iods(ts->stream, p, len, mp4_descr + mp4_descr_count, | |
| 2825 | &mp4_descr_count, MAX_MP4_DESCR_COUNT - mp4_descr_count); | ||
| 2826 |
3/4✓ Branch 0 taken 144 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
|
294 | } else if (tag == REGISTRATION_DESCRIPTOR && len >= 4) { |
| 2827 | 144 | prog_reg_desc = bytestream_get_le32(&p); | |
| 2828 | 144 | len -= 4; | |
| 2829 | } | ||
| 2830 | 294 | p += len; | |
| 2831 | } | ||
| 2832 | 412 | p += program_info_length; | |
| 2833 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 412 times.
|
412 | if (p >= p_end) |
| 2834 | ✗ | goto out; | |
| 2835 | |||
| 2836 | // stop parsing after pmt, we found header | ||
| 2837 |
2/2✓ Branch 0 taken 80 times.
✓ Branch 1 taken 332 times.
|
412 | if (!ts->pkt) |
| 2838 | 80 | ts->stop_parse = 2; | |
| 2839 | |||
| 2840 |
1/2✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
|
412 | if (prg) |
| 2841 | 412 | prg->pmt_found = 1; | |
| 2842 | |||
| 2843 |
1/2✓ Branch 0 taken 1133 times.
✗ Branch 1 not taken.
|
1133 | for (i = 0; i < MAX_STREAMS_PER_PROGRAM; i++) { |
| 2844 | 1133 | st = 0; | |
| 2845 | 1133 | pes = NULL; | |
| 2846 | 1133 | stream_type = get8(&p, p_end); | |
| 2847 |
2/2✓ Branch 0 taken 412 times.
✓ Branch 1 taken 721 times.
|
1133 | if (stream_type < 0) |
| 2848 | 412 | break; | |
| 2849 | 721 | pid = get16(&p, p_end); | |
| 2850 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 721 times.
|
721 | if (pid < 0) |
| 2851 | ✗ | goto out; | |
| 2852 | 721 | pid &= 0x1fff; | |
| 2853 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 721 times.
|
721 | if (pid == ts->current_pid) |
| 2854 | ✗ | goto out; | |
| 2855 | |||
| 2856 | 721 | stream_identifier = parse_stream_identifier_desc(p, p_end) + 1; | |
| 2857 | |||
| 2858 | /* now create stream */ | ||
| 2859 |
4/4✓ Branch 0 taken 571 times.
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 551 times.
✓ Branch 3 taken 20 times.
|
721 | if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) { |
| 2860 | 551 | pes = ts->pids[pid]->u.pes_filter.opaque; | |
| 2861 |
3/4✓ Branch 0 taken 16 times.
✓ Branch 1 taken 535 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
551 | if (ts->merge_pmt_versions && !pes->st) { |
| 2862 | ✗ | st = find_matching_stream(ts, pid, h->id, stream_identifier, i, &old_program); | |
| 2863 | ✗ | if (st) { | |
| 2864 | ✗ | pes->st = st; | |
| 2865 | ✗ | pes->stream_type = stream_type; | |
| 2866 | ✗ | pes->merged_st = 1; | |
| 2867 | } | ||
| 2868 | } | ||
| 2869 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 551 times.
|
551 | if (!pes->st) { |
| 2870 | ✗ | pes->st = avformat_new_stream(pes->stream, NULL); | |
| 2871 | ✗ | if (!pes->st) | |
| 2872 | ✗ | goto out; | |
| 2873 | ✗ | pes->st->id = pes->pid; | |
| 2874 | } | ||
| 2875 | 551 | st = pes->st; | |
| 2876 |
2/2✓ Branch 1 taken 140 times.
✓ Branch 2 taken 30 times.
|
170 | } else if (is_pes_stream(stream_type, prog_reg_desc)) { |
| 2877 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
|
140 | if (ts->pids[pid]) |
| 2878 | ✗ | mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably | |
| 2879 | 140 | pes = add_pes_stream(ts, pid, pcr_pid); | |
| 2880 |
4/6✓ Branch 0 taken 8 times.
✓ Branch 1 taken 132 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
140 | if (ts->merge_pmt_versions && pes && !pes->st) { |
| 2881 | 8 | st = find_matching_stream(ts, pid, h->id, stream_identifier, i, &old_program); | |
| 2882 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | if (st) { |
| 2883 | 4 | pes->st = st; | |
| 2884 | 4 | pes->stream_type = stream_type; | |
| 2885 | 4 | pes->merged_st = 1; | |
| 2886 | } | ||
| 2887 | } | ||
| 2888 |
3/4✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 136 times.
✓ Branch 3 taken 4 times.
|
140 | if (pes && !pes->st) { |
| 2889 | 136 | st = avformat_new_stream(pes->stream, NULL); | |
| 2890 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 136 times.
|
136 | if (!st) |
| 2891 | ✗ | goto out; | |
| 2892 | 136 | st->id = pes->pid; | |
| 2893 | } | ||
| 2894 | } else { | ||
| 2895 | 30 | int idx = ff_find_stream_index(ts->stream, pid); | |
| 2896 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
|
30 | if (idx >= 0) { |
| 2897 | 20 | st = ts->stream->streams[idx]; | |
| 2898 | } | ||
| 2899 |
4/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
|
30 | if (ts->merge_pmt_versions && !st) { |
| 2900 | 4 | st = find_matching_stream(ts, pid, h->id, stream_identifier, i, &old_program); | |
| 2901 | } | ||
| 2902 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 23 times.
|
30 | if (!st) { |
| 2903 | 7 | st = avformat_new_stream(ts->stream, NULL); | |
| 2904 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (!st) |
| 2905 | ✗ | goto out; | |
| 2906 | 7 | st->id = pid; | |
| 2907 | 7 | st->codecpar->codec_type = AVMEDIA_TYPE_DATA; | |
| 2908 |
2/4✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
7 | if (stream_type == STREAM_TYPE_SCTE_DATA_SCTE_35 && prog_reg_desc == AV_RL32("CUEI")) { |
| 2909 | 7 | mpegts_find_stream_type(st, stream_type, SCTE_types); | |
| 2910 | 7 | mpegts_open_section_filter(ts, pid, scte_data_cb, ts, 1); | |
| 2911 | } | ||
| 2912 | } | ||
| 2913 | } | ||
| 2914 | |||
| 2915 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 721 times.
|
721 | if (!st) |
| 2916 | ✗ | goto out; | |
| 2917 | |||
| 2918 |
4/4✓ Branch 0 taken 691 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 146 times.
✓ Branch 3 taken 545 times.
|
721 | if (pes && pes->stream_type != stream_type) |
| 2919 | 146 | mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc); | |
| 2920 | |||
| 2921 | 721 | add_pid_to_program(prg, pid); | |
| 2922 |
1/2✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
|
721 | if (prg) { |
| 2923 | 721 | prg->streams[i].idx = st->index; | |
| 2924 | 721 | prg->streams[i].stream_identifier = stream_identifier; | |
| 2925 | 721 | prg->nb_streams++; | |
| 2926 | } | ||
| 2927 | |||
| 2928 | 721 | av_program_add_stream_index(ts->stream, h->id, st->index); | |
| 2929 | |||
| 2930 | 721 | desc_list_len = get16(&p, p_end); | |
| 2931 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 721 times.
|
721 | if (desc_list_len < 0) |
| 2932 | ✗ | goto out; | |
| 2933 | 721 | desc_list_len &= 0xfff; | |
| 2934 | 721 | desc_list_end = p + desc_list_len; | |
| 2935 |
1/2✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
|
721 | if (desc_list_end > p_end) |
| 2936 | ✗ | goto out; | |
| 2937 | for (;;) { | ||
| 2938 |
2/2✓ Branch 1 taken 721 times.
✓ Branch 2 taken 487 times.
|
1208 | if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, h->id, &p, |
| 2939 | desc_list_end, mp4_descr, | ||
| 2940 | mp4_descr_count, pid, ts) < 0) | ||
| 2941 | 721 | break; | |
| 2942 | |||
| 2943 |
2/6✓ Branch 0 taken 487 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 487 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
487 | if (pes && prog_reg_desc == AV_RL32("HDMV") && |
| 2944 | ✗ | stream_type == STREAM_TYPE_BLURAY_AUDIO_TRUEHD && pes->sub_st) { | |
| 2945 | ✗ | av_program_add_stream_index(ts->stream, h->id, | |
| 2946 | ✗ | pes->sub_st->index); | |
| 2947 | ✗ | pes->sub_st->codecpar->codec_tag = st->codecpar->codec_tag; | |
| 2948 | } | ||
| 2949 | } | ||
| 2950 | 721 | p = desc_list_end; | |
| 2951 | } | ||
| 2952 | |||
| 2953 |
1/2✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
|
412 | if (!ts->pids[pcr_pid]) |
| 2954 | ✗ | mpegts_open_pcr_filter(ts, pcr_pid); | |
| 2955 | |||
| 2956 | 412 | out: | |
| 2957 |
1/2✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
|
412 | if (prg) { |
| 2958 | 412 | detect_bdmv_dovi_group(ts, prg, prog_reg_desc); | |
| 2959 | 412 | create_stream_groups(ts, prg); | |
| 2960 | } | ||
| 2961 | |||
| 2962 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 412 times.
|
412 | for (i = 0; i < mp4_descr_count; i++) |
| 2963 | ✗ | av_free(mp4_descr[i].dec_config_descr); | |
| 2964 | } | ||
| 2965 | |||
| 2966 | 3768 | static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) | |
| 2967 | { | ||
| 2968 | 3768 | MpegTSContext *ts = filter->u.section_filter.opaque; | |
| 2969 | 3768 | MpegTSSectionFilter *tssf = &filter->u.section_filter; | |
| 2970 | 3768 | SectionHeader h1, *h = &h1; | |
| 2971 | const uint8_t *p, *p_end; | ||
| 2972 | int sid, pmt_pid; | ||
| 2973 | 3768 | int nb_prg = 0; | |
| 2974 | AVProgram *program; | ||
| 2975 | |||
| 2976 | 3768 | av_log(ts->stream, AV_LOG_TRACE, "PAT:\n"); | |
| 2977 | hex_dump_debug(ts->stream, section, section_len); | ||
| 2978 | |||
| 2979 | 3768 | p_end = section + section_len - 4; | |
| 2980 | 3768 | p = section; | |
| 2981 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3768 times.
|
3768 | if (parse_section_header(h, &p, p_end) < 0) |
| 2982 | 3435 | return; | |
| 2983 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3768 times.
|
3768 | if (h->tid != PAT_TID) |
| 2984 | ✗ | return; | |
| 2985 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3768 times.
|
3768 | if (!h->current_next) |
| 2986 | ✗ | return; | |
| 2987 |
2/2✓ Branch 0 taken 717 times.
✓ Branch 1 taken 3051 times.
|
3768 | if (ts->skip_changes) |
| 2988 | 717 | return; | |
| 2989 | |||
| 2990 |
2/2✓ Branch 1 taken 2718 times.
✓ Branch 2 taken 333 times.
|
3051 | if (skip_identical(h, tssf)) |
| 2991 | 2718 | return; | |
| 2992 | 333 | ts->id = h->id; | |
| 2993 | |||
| 2994 | for (;;) { | ||
| 2995 | 666 | sid = get16(&p, p_end); | |
| 2996 |
2/2✓ Branch 0 taken 333 times.
✓ Branch 1 taken 333 times.
|
666 | if (sid < 0) |
| 2997 | 333 | break; | |
| 2998 | 333 | pmt_pid = get16(&p, p_end); | |
| 2999 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 333 times.
|
333 | if (pmt_pid < 0) |
| 3000 | ✗ | break; | |
| 3001 | 333 | pmt_pid &= 0x1fff; | |
| 3002 | |||
| 3003 |
2/4✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 333 times.
|
333 | if (pmt_pid <= 0x000F || pmt_pid == 0x1FFF) { |
| 3004 | ✗ | av_log(ts->stream, AV_LOG_WARNING, | |
| 3005 | "Ignoring invalid PAT entry: sid=0x%x pid=0x%x\n", sid, pmt_pid); | ||
| 3006 | ✗ | continue; | |
| 3007 | } | ||
| 3008 | |||
| 3009 | 333 | av_log(ts->stream, AV_LOG_TRACE, "sid=0x%x pid=0x%x\n", sid, pmt_pid); | |
| 3010 | |||
| 3011 |
1/2✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
|
333 | if (sid == 0x0000) { |
| 3012 | /* NIT info */ | ||
| 3013 | } else { | ||
| 3014 | 333 | MpegTSFilter *fil = ts->pids[pmt_pid]; | |
| 3015 | struct Program *prg; | ||
| 3016 | 333 | program = av_new_program(ts->stream, sid); | |
| 3017 |
1/2✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
|
333 | if (program) { |
| 3018 | 333 | program->program_num = sid; | |
| 3019 | 333 | program->pmt_pid = pmt_pid; | |
| 3020 | } | ||
| 3021 |
2/2✓ Branch 0 taken 253 times.
✓ Branch 1 taken 80 times.
|
333 | if (fil) |
| 3022 |
1/2✓ Branch 0 taken 253 times.
✗ Branch 1 not taken.
|
253 | if ( fil->type != MPEGTS_SECTION |
| 3023 |
1/2✓ Branch 0 taken 253 times.
✗ Branch 1 not taken.
|
253 | || fil->pid != pmt_pid |
| 3024 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 253 times.
|
253 | || fil->u.section_filter.section_cb != pmt_cb) |
| 3025 | ✗ | mpegts_close_filter(ts, ts->pids[pmt_pid]); | |
| 3026 | |||
| 3027 |
2/2✓ Branch 0 taken 80 times.
✓ Branch 1 taken 253 times.
|
333 | if (!ts->pids[pmt_pid]) |
| 3028 | 80 | mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1); | |
| 3029 | 333 | prg = add_program(ts, sid); | |
| 3030 |
1/2✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
|
333 | if (prg) { |
| 3031 | 333 | unsigned prg_idx = prg - ts->prg; | |
| 3032 |
3/4✓ Branch 0 taken 253 times.
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 253 times.
|
333 | if (prg->nb_pids && prg->pids[0] != pmt_pid) |
| 3033 | ✗ | clear_program(prg); | |
| 3034 | 333 | add_pid_to_program(prg, pmt_pid); | |
| 3035 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 333 times.
|
333 | if (prg_idx > nb_prg) |
| 3036 | ✗ | FFSWAP(struct Program, ts->prg[nb_prg], ts->prg[prg_idx]); | |
| 3037 |
1/2✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
|
333 | if (prg_idx >= nb_prg) |
| 3038 | 333 | nb_prg++; | |
| 3039 | } else | ||
| 3040 | ✗ | nb_prg = 0; | |
| 3041 | } | ||
| 3042 | } | ||
| 3043 | 333 | ts->nb_prg = nb_prg; | |
| 3044 | |||
| 3045 |
1/2✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
|
333 | if (sid < 0) { |
| 3046 | int i,j; | ||
| 3047 |
2/2✓ Branch 0 taken 333 times.
✓ Branch 1 taken 333 times.
|
666 | for (j=0; j<ts->stream->nb_programs; j++) { |
| 3048 |
1/2✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
|
333 | for (i = 0; i < ts->nb_prg; i++) |
| 3049 |
1/2✓ Branch 0 taken 333 times.
✗ Branch 1 not taken.
|
333 | if (ts->prg[i].id == ts->stream->programs[j]->id) |
| 3050 | 333 | break; | |
| 3051 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 333 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
333 | if (i==ts->nb_prg && !ts->skip_clear) |
| 3052 | ✗ | clear_avprogram(ts, ts->stream->programs[j]->id); | |
| 3053 | } | ||
| 3054 | } | ||
| 3055 | } | ||
| 3056 | |||
| 3057 | 14 | static void eit_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) | |
| 3058 | { | ||
| 3059 | 14 | MpegTSContext *ts = filter->u.section_filter.opaque; | |
| 3060 | const uint8_t *p, *p_end; | ||
| 3061 | 14 | SectionHeader h1, *h = &h1; | |
| 3062 | |||
| 3063 | /* | ||
| 3064 | * Sometimes we receive EPG packets but SDT table do not have | ||
| 3065 | * eit_pres_following or eit_sched turned on, so we open EPG | ||
| 3066 | * stream directly here. | ||
| 3067 | */ | ||
| 3068 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
|
14 | if (!ts->epg_stream) { |
| 3069 | 3 | ts->epg_stream = avformat_new_stream(ts->stream, NULL); | |
| 3070 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (!ts->epg_stream) |
| 3071 | 2 | return; | |
| 3072 | 3 | ts->epg_stream->id = EIT_PID; | |
| 3073 | 3 | ts->epg_stream->codecpar->codec_type = AVMEDIA_TYPE_DATA; | |
| 3074 | 3 | ts->epg_stream->codecpar->codec_id = AV_CODEC_ID_EPG; | |
| 3075 | } | ||
| 3076 | |||
| 3077 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | if (ts->epg_stream->discard == AVDISCARD_ALL) |
| 3078 | 2 | return; | |
| 3079 | |||
| 3080 | 12 | p_end = section + section_len - 4; | |
| 3081 | 12 | p = section; | |
| 3082 | |||
| 3083 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
|
12 | if (parse_section_header(h, &p, p_end) < 0) |
| 3084 | ✗ | return; | |
| 3085 |
2/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
|
12 | if (h->tid < EIT_TID || h->tid > OEITS_END_TID) |
| 3086 | ✗ | return; | |
| 3087 | |||
| 3088 | 12 | av_log(ts->stream, AV_LOG_TRACE, "EIT: tid received = %.02x\n", h->tid); | |
| 3089 | |||
| 3090 | /** | ||
| 3091 | * Service_id 0xFFFF is reserved, it indicates that the current EIT table | ||
| 3092 | * is scrambled. | ||
| 3093 | */ | ||
| 3094 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (h->id == 0xFFFF) { |
| 3095 | ✗ | av_log(ts->stream, AV_LOG_TRACE, "Scrambled EIT table received.\n"); | |
| 3096 | ✗ | return; | |
| 3097 | } | ||
| 3098 | |||
| 3099 | /** | ||
| 3100 | * In case we receive an EPG packet before mpegts context is fully | ||
| 3101 | * initialized. | ||
| 3102 | */ | ||
| 3103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (!ts->pkt) |
| 3104 | ✗ | return; | |
| 3105 | |||
| 3106 | 12 | new_data_packet(section, section_len, ts->pkt); | |
| 3107 | 12 | ts->pkt->stream_index = ts->epg_stream->index; | |
| 3108 | 12 | ts->stop_parse = 1; | |
| 3109 | } | ||
| 3110 | |||
| 3111 | 658 | static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) | |
| 3112 | { | ||
| 3113 | 658 | MpegTSContext *ts = filter->u.section_filter.opaque; | |
| 3114 | 658 | MpegTSSectionFilter *tssf = &filter->u.section_filter; | |
| 3115 | 658 | SectionHeader h1, *h = &h1; | |
| 3116 | const uint8_t *p, *p_end, *desc_list_end, *desc_end; | ||
| 3117 | int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type; | ||
| 3118 | char *name, *provider_name; | ||
| 3119 | |||
| 3120 | 658 | av_log(ts->stream, AV_LOG_TRACE, "SDT:\n"); | |
| 3121 | hex_dump_debug(ts->stream, section, section_len); | ||
| 3122 | |||
| 3123 | 658 | p_end = section + section_len - 4; | |
| 3124 | 658 | p = section; | |
| 3125 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 658 times.
|
658 | if (parse_section_header(h, &p, p_end) < 0) |
| 3126 | 442 | return; | |
| 3127 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 658 times.
|
658 | if (h->tid != SDT_TID) |
| 3128 | ✗ | return; | |
| 3129 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 658 times.
|
658 | if (!h->current_next) |
| 3130 | ✗ | return; | |
| 3131 |
2/2✓ Branch 0 taken 92 times.
✓ Branch 1 taken 566 times.
|
658 | if (ts->skip_changes) |
| 3132 | 92 | return; | |
| 3133 |
2/2✓ Branch 1 taken 350 times.
✓ Branch 2 taken 216 times.
|
566 | if (skip_identical(h, tssf)) |
| 3134 | 350 | return; | |
| 3135 | |||
| 3136 | 216 | onid = get16(&p, p_end); | |
| 3137 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
|
216 | if (onid < 0) |
| 3138 | ✗ | return; | |
| 3139 | 216 | val = get8(&p, p_end); | |
| 3140 |
1/2✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
|
216 | if (val < 0) |
| 3141 | ✗ | return; | |
| 3142 | for (;;) { | ||
| 3143 | 432 | sid = get16(&p, p_end); | |
| 3144 |
2/2✓ Branch 0 taken 216 times.
✓ Branch 1 taken 216 times.
|
432 | if (sid < 0) |
| 3145 | 216 | break; | |
| 3146 | 216 | val = get8(&p, p_end); | |
| 3147 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
|
216 | if (val < 0) |
| 3148 | ✗ | break; | |
| 3149 | 216 | desc_list_len = get16(&p, p_end); | |
| 3150 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
|
216 | if (desc_list_len < 0) |
| 3151 | ✗ | break; | |
| 3152 | 216 | desc_list_len &= 0xfff; | |
| 3153 | 216 | desc_list_end = p + desc_list_len; | |
| 3154 |
1/2✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
|
216 | if (desc_list_end > p_end) |
| 3155 | ✗ | break; | |
| 3156 | for (;;) { | ||
| 3157 | 432 | desc_tag = get8(&p, desc_list_end); | |
| 3158 |
2/2✓ Branch 0 taken 216 times.
✓ Branch 1 taken 216 times.
|
432 | if (desc_tag < 0) |
| 3159 | 216 | break; | |
| 3160 | 216 | desc_len = get8(&p, desc_list_end); | |
| 3161 | 216 | desc_end = p + desc_len; | |
| 3162 |
2/4✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
|
216 | if (desc_len < 0 || desc_end > desc_list_end) |
| 3163 | break; | ||
| 3164 | |||
| 3165 | 216 | av_log(ts->stream, AV_LOG_TRACE, "tag: 0x%02x len=%d\n", | |
| 3166 | desc_tag, desc_len); | ||
| 3167 | |||
| 3168 |
1/2✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
|
216 | switch (desc_tag) { |
| 3169 | 216 | case SERVICE_DESCRIPTOR: | |
| 3170 | 216 | service_type = get8(&p, desc_end); | |
| 3171 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
|
216 | if (service_type < 0) |
| 3172 | ✗ | break; | |
| 3173 | 216 | provider_name = getstr8(&p, desc_end); | |
| 3174 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
|
216 | if (!provider_name) |
| 3175 | ✗ | break; | |
| 3176 | 216 | name = getstr8(&p, desc_end); | |
| 3177 |
1/2✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
|
216 | if (name) { |
| 3178 | 216 | AVProgram *program = av_new_program(ts->stream, sid); | |
| 3179 |
1/2✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
|
216 | if (program) { |
| 3180 | 216 | av_dict_set(&program->metadata, "service_name", name, 0); | |
| 3181 | 216 | av_dict_set(&program->metadata, "service_provider", | |
| 3182 | provider_name, 0); | ||
| 3183 | } | ||
| 3184 | } | ||
| 3185 | 216 | av_free(name); | |
| 3186 | 216 | av_free(provider_name); | |
| 3187 | 216 | break; | |
| 3188 | ✗ | default: | |
| 3189 | ✗ | break; | |
| 3190 | } | ||
| 3191 | 216 | p = desc_end; | |
| 3192 | } | ||
| 3193 | 216 | p = desc_list_end; | |
| 3194 | } | ||
| 3195 | } | ||
| 3196 | |||
| 3197 | static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, | ||
| 3198 | const uint8_t *packet); | ||
| 3199 | |||
| 3200 | /* handle one TS packet */ | ||
| 3201 | 461706 | static int handle_packet(MpegTSContext *ts, const uint8_t *packet, int64_t pos) | |
| 3202 | { | ||
| 3203 | MpegTSFilter *tss; | ||
| 3204 | int len, pid, cc, expected_cc, cc_ok, afc, is_start, is_discontinuity, | ||
| 3205 | has_adaptation, has_payload; | ||
| 3206 | const uint8_t *p, *p_end; | ||
| 3207 | |||
| 3208 | 461706 | pid = AV_RB16(packet + 1) & 0x1fff; | |
| 3209 | 461706 | is_start = packet[1] & 0x40; | |
| 3210 | 461706 | tss = ts->pids[pid]; | |
| 3211 |
6/6✓ Branch 0 taken 453383 times.
✓ Branch 1 taken 8323 times.
✓ Branch 2 taken 7754 times.
✓ Branch 3 taken 445629 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 7736 times.
|
461706 | if (ts->auto_guess && !tss && is_start) { |
| 3212 | 18 | add_pes_stream(ts, pid, -1); | |
| 3213 | 18 | tss = ts->pids[pid]; | |
| 3214 | } | ||
| 3215 |
2/2✓ Branch 0 taken 15845 times.
✓ Branch 1 taken 445861 times.
|
461706 | if (!tss) |
| 3216 | 15845 | return 0; | |
| 3217 |
2/2✓ Branch 0 taken 43637 times.
✓ Branch 1 taken 402224 times.
|
445861 | if (is_start) |
| 3218 | 43637 | tss->discard = discard_pid(ts, pid); | |
| 3219 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 445861 times.
|
445861 | if (tss->discard) |
| 3220 | ✗ | return 0; | |
| 3221 | 445861 | ts->current_pid = pid; | |
| 3222 | |||
| 3223 | 445861 | afc = (packet[3] >> 4) & 3; | |
| 3224 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 445861 times.
|
445861 | if (afc == 0) /* reserved value */ |
| 3225 | ✗ | return 0; | |
| 3226 | 445861 | has_adaptation = afc & 2; | |
| 3227 | 445861 | has_payload = afc & 1; | |
| 3228 | 515500 | is_discontinuity = has_adaptation && | |
| 3229 |
4/4✓ Branch 0 taken 69639 times.
✓ Branch 1 taken 376222 times.
✓ Branch 2 taken 69596 times.
✓ Branch 3 taken 43 times.
|
515457 | packet[4] != 0 && /* with length > 0 */ |
| 3230 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 69596 times.
|
69596 | (packet[5] & 0x80); /* and discontinuity indicated */ |
| 3231 | |||
| 3232 | /* continuity check (currently not used) */ | ||
| 3233 | 445861 | cc = (packet[3] & 0xf); | |
| 3234 |
2/2✓ Branch 0 taken 442942 times.
✓ Branch 1 taken 2919 times.
|
445861 | expected_cc = has_payload ? (tss->last_cc + 1) & 0x0f : tss->last_cc; |
| 3235 |
1/2✓ Branch 0 taken 445861 times.
✗ Branch 1 not taken.
|
445861 | cc_ok = pid == NULL_PID || |
| 3236 | 445861 | is_discontinuity || | |
| 3237 |
5/6✓ Branch 0 taken 445861 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 444167 times.
✓ Branch 3 taken 1694 times.
✓ Branch 4 taken 443515 times.
✓ Branch 5 taken 652 times.
|
891722 | tss->last_cc < 0 || |
| 3238 | expected_cc == cc; | ||
| 3239 | |||
| 3240 | 445861 | tss->last_cc = cc; | |
| 3241 |
2/2✓ Branch 0 taken 652 times.
✓ Branch 1 taken 445209 times.
|
445861 | if (!cc_ok) { |
| 3242 | 652 | av_log(ts->stream, AV_LOG_DEBUG, | |
| 3243 | "Continuity check failed for pid %d expected %d got %d\n", | ||
| 3244 | pid, expected_cc, cc); | ||
| 3245 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 645 times.
|
652 | if (tss->type == MPEGTS_PES) { |
| 3246 | 7 | PESContext *pc = tss->u.pes_filter.opaque; | |
| 3247 | 7 | pc->flags |= AV_PKT_FLAG_CORRUPT; | |
| 3248 | } | ||
| 3249 | } | ||
| 3250 | |||
| 3251 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 445848 times.
|
445861 | if (packet[1] & 0x80) { |
| 3252 | 13 | av_log(ts->stream, AV_LOG_DEBUG, "Packet had TEI flag set; marking as corrupt\n"); | |
| 3253 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | if (tss->type == MPEGTS_PES) { |
| 3254 | 13 | PESContext *pc = tss->u.pes_filter.opaque; | |
| 3255 | 13 | pc->flags |= AV_PKT_FLAG_CORRUPT; | |
| 3256 | } | ||
| 3257 | } | ||
| 3258 | |||
| 3259 | 445861 | p = packet + 4; | |
| 3260 |
2/2✓ Branch 0 taken 69639 times.
✓ Branch 1 taken 376222 times.
|
445861 | if (has_adaptation) { |
| 3261 | int64_t pcr_h; | ||
| 3262 | int pcr_l; | ||
| 3263 |
2/2✓ Branch 1 taken 32091 times.
✓ Branch 2 taken 37548 times.
|
69639 | if (parse_pcr(&pcr_h, &pcr_l, packet) == 0) |
| 3264 | 32091 | tss->last_pcr = pcr_h * SYSTEM_CLOCK_FREQUENCY_DIVISOR + pcr_l; | |
| 3265 | /* skip adaptation field */ | ||
| 3266 | 69639 | p += p[0] + 1; | |
| 3267 | } | ||
| 3268 | /* if past the end of packet, ignore */ | ||
| 3269 | 445861 | p_end = packet + TS_PACKET_SIZE; | |
| 3270 |
3/4✓ Branch 0 taken 442929 times.
✓ Branch 1 taken 2932 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 442929 times.
|
445861 | if (p >= p_end || !has_payload) |
| 3271 | 2932 | return 0; | |
| 3272 | |||
| 3273 |
1/2✓ Branch 0 taken 442929 times.
✗ Branch 1 not taken.
|
442929 | if (pos >= 0) { |
| 3274 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 442929 times.
|
442929 | av_assert0(pos >= TS_PACKET_SIZE); |
| 3275 | 442929 | ts->pos47_full = pos - TS_PACKET_SIZE; | |
| 3276 | } | ||
| 3277 | |||
| 3278 |
2/2✓ Branch 0 taken 8216 times.
✓ Branch 1 taken 434713 times.
|
442929 | if (tss->type == MPEGTS_SECTION) { |
| 3279 |
2/2✓ Branch 0 taken 8181 times.
✓ Branch 1 taken 35 times.
|
8216 | if (is_start) { |
| 3280 | /* pointer field present */ | ||
| 3281 | 8181 | len = *p++; | |
| 3282 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8181 times.
|
8181 | if (len > p_end - p) |
| 3283 | ✗ | return 0; | |
| 3284 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 8181 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
8181 | if (len && cc_ok) { |
| 3285 | /* write remaining section bytes */ | ||
| 3286 | ✗ | write_section_data(ts, tss, | |
| 3287 | p, len, 0); | ||
| 3288 | /* check whether filter has been closed */ | ||
| 3289 | ✗ | if (!ts->pids[pid]) | |
| 3290 | ✗ | return 0; | |
| 3291 | } | ||
| 3292 | 8181 | p += len; | |
| 3293 |
1/2✓ Branch 0 taken 8181 times.
✗ Branch 1 not taken.
|
8181 | if (p < p_end) { |
| 3294 | 8181 | write_section_data(ts, tss, | |
| 3295 | 8181 | p, p_end - p, 1); | |
| 3296 | } | ||
| 3297 | } else { | ||
| 3298 |
1/2✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
|
35 | if (cc_ok) { |
| 3299 | 35 | write_section_data(ts, tss, | |
| 3300 | 35 | p, p_end - p, 0); | |
| 3301 | } | ||
| 3302 | } | ||
| 3303 | |||
| 3304 | // stop find_stream_info from waiting for more streams | ||
| 3305 | // when all programs have received a PMT | ||
| 3306 |
4/4✓ Branch 0 taken 5446 times.
✓ Branch 1 taken 2770 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 5424 times.
|
8216 | if (ts->stream->ctx_flags & AVFMTCTX_NOHEADER && ts->scan_all_pmts <= 0) { |
| 3307 | int i; | ||
| 3308 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 22 times.
|
44 | for (i = 0; i < ts->nb_prg; i++) { |
| 3309 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
|
22 | if (!ts->prg[i].pmt_found) |
| 3310 | ✗ | break; | |
| 3311 | } | ||
| 3312 |
2/4✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
|
22 | if (i == ts->nb_prg && ts->nb_prg > 0) { |
| 3313 | 22 | av_log(ts->stream, AV_LOG_DEBUG, "All programs have pmt, headers found\n"); | |
| 3314 | 22 | ts->stream->ctx_flags &= ~AVFMTCTX_NOHEADER; | |
| 3315 | } | ||
| 3316 | } | ||
| 3317 | |||
| 3318 | } else { | ||
| 3319 | int ret; | ||
| 3320 | // Note: The position here points actually behind the current packet. | ||
| 3321 |
1/2✓ Branch 0 taken 434713 times.
✗ Branch 1 not taken.
|
434713 | if (tss->type == MPEGTS_PES) { |
| 3322 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 434713 times.
|
434713 | if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, |
| 3323 | 434713 | pos - ts->raw_packet_size)) < 0) | |
| 3324 | ✗ | return ret; | |
| 3325 | } | ||
| 3326 | } | ||
| 3327 | |||
| 3328 | 442929 | return 0; | |
| 3329 | } | ||
| 3330 | |||
| 3331 | 72 | static int mpegts_resync(AVFormatContext *s, int seekback, const uint8_t *current_packet) | |
| 3332 | { | ||
| 3333 | 72 | MpegTSContext *ts = s->priv_data; | |
| 3334 | 72 | AVIOContext *pb = s->pb; | |
| 3335 | int c, i; | ||
| 3336 | 72 | uint64_t pos = avio_tell(pb); | |
| 3337 | 72 | int64_t back = FFMIN(seekback, pos); | |
| 3338 | |||
| 3339 | //Special case for files like 01c56b0dc1.ts | ||
| 3340 |
3/6✓ Branch 0 taken 6 times.
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
72 | if (current_packet[0] == 0x80 && current_packet[12] == SYNC_BYTE && pos >= TS_PACKET_SIZE) { |
| 3341 | ✗ | avio_seek(pb, 12 - TS_PACKET_SIZE, SEEK_CUR); | |
| 3342 | ✗ | return 0; | |
| 3343 | } | ||
| 3344 | |||
| 3345 | 72 | avio_seek(pb, -back, SEEK_CUR); | |
| 3346 | |||
| 3347 |
1/2✓ Branch 0 taken 4796 times.
✗ Branch 1 not taken.
|
4796 | for (i = 0; i < ts->resync_size; i++) { |
| 3348 | 4796 | c = avio_r8(pb); | |
| 3349 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4796 times.
|
4796 | if (avio_feof(pb)) |
| 3350 | ✗ | return AVERROR_EOF; | |
| 3351 |
2/2✓ Branch 0 taken 72 times.
✓ Branch 1 taken 4724 times.
|
4796 | if (c == SYNC_BYTE) { |
| 3352 | int new_packet_size, ret; | ||
| 3353 | 72 | avio_seek(pb, -1, SEEK_CUR); | |
| 3354 | 72 | pos = avio_tell(pb); | |
| 3355 | 72 | ret = ffio_ensure_seekback(pb, PROBE_PACKET_MAX_BUF); | |
| 3356 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
|
72 | if (ret < 0) |
| 3357 | ✗ | return ret; | |
| 3358 | 72 | new_packet_size = get_packet_size(s); | |
| 3359 |
2/4✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
|
72 | if (new_packet_size > 0 && new_packet_size != ts->raw_packet_size) { |
| 3360 | ✗ | av_log(ts->stream, AV_LOG_WARNING, "changing packet size to %d\n", new_packet_size); | |
| 3361 | ✗ | ts->raw_packet_size = new_packet_size; | |
| 3362 | } | ||
| 3363 | 72 | avio_seek(pb, pos, SEEK_SET); | |
| 3364 | 72 | return 0; | |
| 3365 | } | ||
| 3366 | } | ||
| 3367 | ✗ | av_log(s, AV_LOG_ERROR, | |
| 3368 | "max resync size reached, could not find sync byte\n"); | ||
| 3369 | /* no sync found */ | ||
| 3370 | ✗ | return AVERROR_INVALIDDATA; | |
| 3371 | } | ||
| 3372 | |||
| 3373 | /* return AVERROR_something if error or EOF. Return 0 if OK. */ | ||
| 3374 | 462208 | static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size, | |
| 3375 | const uint8_t **data) | ||
| 3376 | { | ||
| 3377 | 462208 | AVIOContext *pb = s->pb; | |
| 3378 | int len; | ||
| 3379 | |||
| 3380 | // 192 bytes source packet that start with a 4 bytes TP_extra_header | ||
| 3381 | // followed by 188 bytes of TS packet. The sync byte is at offset 4, so skip | ||
| 3382 | // the first 4 bytes otherwise we'll end up syncing to the wrong packet. | ||
| 3383 |
2/2✓ Branch 0 taken 27772 times.
✓ Branch 1 taken 434436 times.
|
462208 | if (raw_packet_size == TS_DVHS_PACKET_SIZE) |
| 3384 | 27772 | avio_skip(pb, 4); | |
| 3385 | |||
| 3386 | for (;;) { | ||
| 3387 | 462280 | len = ffio_read_indirect(pb, buf, TS_PACKET_SIZE, data); | |
| 3388 |
2/2✓ Branch 0 taken 502 times.
✓ Branch 1 taken 461778 times.
|
462280 | if (len != TS_PACKET_SIZE) |
| 3389 |
2/2✓ Branch 0 taken 444 times.
✓ Branch 1 taken 58 times.
|
502 | return len < 0 ? len : AVERROR_EOF; |
| 3390 | /* check packet sync byte */ | ||
| 3391 |
2/2✓ Branch 0 taken 72 times.
✓ Branch 1 taken 461706 times.
|
461778 | if ((*data)[0] != SYNC_BYTE) { |
| 3392 | /* find a new packet start */ | ||
| 3393 | |||
| 3394 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
|
72 | if (mpegts_resync(s, raw_packet_size, *data) < 0) |
| 3395 | ✗ | return AVERROR(EAGAIN); | |
| 3396 | else | ||
| 3397 | 72 | continue; | |
| 3398 | } else { | ||
| 3399 | 461706 | break; | |
| 3400 | } | ||
| 3401 | } | ||
| 3402 | 461706 | return 0; | |
| 3403 | } | ||
| 3404 | |||
| 3405 | 461706 | static void finished_reading_packet(AVFormatContext *s, int raw_packet_size) | |
| 3406 | { | ||
| 3407 | 461706 | AVIOContext *pb = s->pb; | |
| 3408 | int skip; | ||
| 3409 |
2/2✓ Branch 0 taken 27754 times.
✓ Branch 1 taken 433952 times.
|
461706 | if (raw_packet_size == TS_DVHS_PACKET_SIZE) |
| 3410 | 27754 | skip = raw_packet_size - TS_DVHS_PACKET_SIZE; | |
| 3411 | else | ||
| 3412 | 433952 | skip = raw_packet_size - TS_PACKET_SIZE; | |
| 3413 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 461706 times.
|
461706 | if (skip > 0) |
| 3414 | ✗ | avio_skip(pb, skip); | |
| 3415 | 461706 | } | |
| 3416 | |||
| 3417 | 35004 | static int handle_packets(MpegTSContext *ts, int64_t nb_packets) | |
| 3418 | { | ||
| 3419 | 35004 | AVFormatContext *s = ts->stream; | |
| 3420 | uint8_t packet[TS_PACKET_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; | ||
| 3421 | const uint8_t *data; | ||
| 3422 | int64_t packet_num; | ||
| 3423 | 35004 | int ret = 0; | |
| 3424 | |||
| 3425 |
2/2✓ Branch 1 taken 376 times.
✓ Branch 2 taken 34628 times.
|
35004 | if (avio_tell(s->pb) != ts->last_pos) { |
| 3426 | int i; | ||
| 3427 | 376 | av_log(ts->stream, AV_LOG_TRACE, "Skipping after seek\n"); | |
| 3428 | /* seek detected, flush pes buffer */ | ||
| 3429 |
2/2✓ Branch 0 taken 3080192 times.
✓ Branch 1 taken 376 times.
|
3080568 | for (i = 0; i < NB_PID_MAX; i++) { |
| 3430 |
2/2✓ Branch 0 taken 2219 times.
✓ Branch 1 taken 3077973 times.
|
3080192 | if (ts->pids[i]) { |
| 3431 |
2/2✓ Branch 0 taken 691 times.
✓ Branch 1 taken 1528 times.
|
2219 | if (ts->pids[i]->type == MPEGTS_PES) { |
| 3432 | 691 | PESContext *pes = ts->pids[i]->u.pes_filter.opaque; | |
| 3433 | 691 | av_buffer_unref(&pes->buffer); | |
| 3434 | 691 | pes->data_index = 0; | |
| 3435 | 691 | pes->state = MPEGTS_SKIP; /* skip until pes header */ | |
| 3436 |
1/2✓ Branch 0 taken 1528 times.
✗ Branch 1 not taken.
|
1528 | } else if (ts->pids[i]->type == MPEGTS_SECTION) { |
| 3437 | 1528 | ts->pids[i]->u.section_filter.last_ver = -1; | |
| 3438 | } | ||
| 3439 | 2219 | ts->pids[i]->last_cc = -1; | |
| 3440 | 2219 | ts->pids[i]->last_pcr = -1; | |
| 3441 | } | ||
| 3442 | } | ||
| 3443 | } | ||
| 3444 | |||
| 3445 | 35004 | ts->stop_parse = 0; | |
| 3446 | 35004 | packet_num = 0; | |
| 3447 | 35004 | memset(packet + TS_PACKET_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE); | |
| 3448 | for (;;) { | ||
| 3449 | 496710 | packet_num++; | |
| 3450 |
3/4✓ Branch 0 taken 8403 times.
✓ Branch 1 taken 488307 times.
✓ Branch 2 taken 8403 times.
✗ Branch 3 not taken.
|
496710 | if (nb_packets != 0 && packet_num >= nb_packets || |
| 3451 |
2/2✓ Branch 0 taken 80 times.
✓ Branch 1 taken 496630 times.
|
496710 | ts->stop_parse > 1) { |
| 3452 | 80 | ret = AVERROR(EAGAIN); | |
| 3453 | 80 | break; | |
| 3454 | } | ||
| 3455 |
2/2✓ Branch 0 taken 34422 times.
✓ Branch 1 taken 462208 times.
|
496630 | if (ts->stop_parse > 0) |
| 3456 | 34422 | break; | |
| 3457 | |||
| 3458 | 462208 | ret = read_packet(s, packet, ts->raw_packet_size, &data); | |
| 3459 |
2/2✓ Branch 0 taken 502 times.
✓ Branch 1 taken 461706 times.
|
462208 | if (ret != 0) |
| 3460 | 502 | break; | |
| 3461 | 461706 | ret = handle_packet(ts, data, avio_tell(s->pb)); | |
| 3462 | 461706 | finished_reading_packet(s, ts->raw_packet_size); | |
| 3463 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 461706 times.
|
461706 | if (ret != 0) |
| 3464 | ✗ | break; | |
| 3465 | } | ||
| 3466 | 35004 | ts->last_pos = avio_tell(s->pb); | |
| 3467 | 35004 | return ret; | |
| 3468 | } | ||
| 3469 | |||
| 3470 | 7800 | static int mpegts_probe(const AVProbeData *p) | |
| 3471 | { | ||
| 3472 | 7800 | const int size = p->buf_size; | |
| 3473 | 7800 | int maxscore = 0; | |
| 3474 | 7800 | int sumscore = 0; | |
| 3475 | int i; | ||
| 3476 | 7800 | int check_count = size / TS_FEC_PACKET_SIZE; | |
| 3477 | #define CHECK_COUNT 10 | ||
| 3478 | #define CHECK_BLOCK 100 | ||
| 3479 | |||
| 3480 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 7783 times.
|
7800 | if (!check_count) |
| 3481 | 17 | return 0; | |
| 3482 | |||
| 3483 |
2/2✓ Branch 0 taken 27044 times.
✓ Branch 1 taken 7783 times.
|
34827 | for (i = 0; i<check_count; i+=CHECK_BLOCK) { |
| 3484 | 27044 | int left = FFMIN(check_count - i, CHECK_BLOCK); | |
| 3485 | 27044 | int score = analyze(p->buf + TS_PACKET_SIZE *i, TS_PACKET_SIZE *left, TS_PACKET_SIZE , 1); | |
| 3486 | 27044 | int dvhs_score = analyze(p->buf + TS_DVHS_PACKET_SIZE*i, TS_DVHS_PACKET_SIZE*left, TS_DVHS_PACKET_SIZE, 1); | |
| 3487 | 27044 | int fec_score = analyze(p->buf + TS_FEC_PACKET_SIZE *i, TS_FEC_PACKET_SIZE *left, TS_FEC_PACKET_SIZE , 1); | |
| 3488 | 27044 | score = FFMAX3(score, dvhs_score, fec_score); | |
| 3489 | 27044 | sumscore += score; | |
| 3490 | 27044 | maxscore = FFMAX(maxscore, score); | |
| 3491 | } | ||
| 3492 | |||
| 3493 | 7783 | sumscore = sumscore * CHECK_COUNT / check_count; | |
| 3494 | 7783 | maxscore = maxscore * CHECK_COUNT / CHECK_BLOCK; | |
| 3495 | |||
| 3496 | ff_dlog(0, "TS score: %d %d\n", sumscore, maxscore); | ||
| 3497 | |||
| 3498 |
3/4✓ Branch 0 taken 3495 times.
✓ Branch 1 taken 4288 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3495 times.
|
7783 | if (check_count > CHECK_COUNT && sumscore > 6) { |
| 3499 | ✗ | return AVPROBE_SCORE_MAX + sumscore - CHECK_COUNT; | |
| 3500 |
4/4✓ Branch 0 taken 7372 times.
✓ Branch 1 taken 411 times.
✓ Branch 2 taken 64 times.
✓ Branch 3 taken 7308 times.
|
7783 | } else if (check_count >= CHECK_COUNT && sumscore >= CHECK_COUNT) { |
| 3501 | 64 | return AVPROBE_SCORE_MAX + sumscore - CHECK_COUNT; | |
| 3502 |
4/4✓ Branch 0 taken 7308 times.
✓ Branch 1 taken 411 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 7306 times.
|
7719 | } else if (check_count >= CHECK_COUNT && sumscore > 6) { |
| 3503 | 2 | return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT; | |
| 3504 |
3/4✓ Branch 0 taken 7306 times.
✓ Branch 1 taken 411 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7306 times.
|
7717 | } else if (check_count >= CHECK_COUNT && maxscore > 6) { |
| 3505 | ✗ | return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT; | |
| 3506 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 7709 times.
|
7717 | } else if (sumscore > 6) { |
| 3507 | 8 | return 2; | |
| 3508 | } else { | ||
| 3509 | 7709 | return 0; | |
| 3510 | } | ||
| 3511 | } | ||
| 3512 | |||
| 3513 | /* return the 90kHz PCR and the extension for the 27MHz PCR. return | ||
| 3514 | * (-1) if not available */ | ||
| 3515 | 69639 | static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, const uint8_t *packet) | |
| 3516 | { | ||
| 3517 | int afc, len, flags; | ||
| 3518 | const uint8_t *p; | ||
| 3519 | unsigned int v; | ||
| 3520 | |||
| 3521 | 69639 | afc = (packet[3] >> 4) & 3; | |
| 3522 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 69639 times.
|
69639 | if (afc <= 1) |
| 3523 | ✗ | return AVERROR_INVALIDDATA; | |
| 3524 | 69639 | p = packet + 4; | |
| 3525 | 69639 | len = p[0]; | |
| 3526 | 69639 | p++; | |
| 3527 |
2/2✓ Branch 0 taken 43 times.
✓ Branch 1 taken 69596 times.
|
69639 | if (len == 0) |
| 3528 | 43 | return AVERROR_INVALIDDATA; | |
| 3529 | 69596 | flags = *p++; | |
| 3530 | 69596 | len--; | |
| 3531 |
2/2✓ Branch 0 taken 37505 times.
✓ Branch 1 taken 32091 times.
|
69596 | if (!(flags & 0x10)) |
| 3532 | 37505 | return AVERROR_INVALIDDATA; | |
| 3533 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32091 times.
|
32091 | if (len < 6) |
| 3534 | ✗ | return AVERROR_INVALIDDATA; | |
| 3535 | 32091 | v = AV_RB32(p); | |
| 3536 | 32091 | *ppcr_high = ((int64_t) v << 1) | (p[4] >> 7); | |
| 3537 | 32091 | *ppcr_low = ((p[4] & 1) << 8) | p[5]; | |
| 3538 | 32091 | return 0; | |
| 3539 | } | ||
| 3540 | |||
| 3541 | 160 | static void seek_back(AVFormatContext *s, AVIOContext *pb, int64_t pos) { | |
| 3542 | |||
| 3543 | /* NOTE: We attempt to seek on non-seekable files as well, as the | ||
| 3544 | * probe buffer usually is big enough. Only warn if the seek failed | ||
| 3545 | * on files where the seek should work. */ | ||
| 3546 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 160 times.
|
160 | if (avio_seek(pb, pos, SEEK_SET) < 0) |
| 3547 | ✗ | av_log(s, (pb->seekable & AVIO_SEEKABLE_NORMAL) ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n"); | |
| 3548 | 160 | } | |
| 3549 | |||
| 3550 | 80 | static int mpegts_read_header(AVFormatContext *s) | |
| 3551 | { | ||
| 3552 | 80 | MpegTSContext *ts = s->priv_data; | |
| 3553 | 80 | AVIOContext *pb = s->pb; | |
| 3554 | 80 | int64_t pos, probesize = s->probesize; | |
| 3555 | 80 | int64_t seekback = FFMAX(s->probesize, (int64_t)ts->resync_size + PROBE_PACKET_MAX_BUF); | |
| 3556 | |||
| 3557 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
|
80 | if (ffio_ensure_seekback(pb, seekback) < 0) |
| 3558 | ✗ | av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n"); | |
| 3559 | |||
| 3560 | 80 | pos = avio_tell(pb); | |
| 3561 | 80 | ts->raw_packet_size = get_packet_size(s); | |
| 3562 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
|
80 | if (ts->raw_packet_size <= 0) { |
| 3563 | ✗ | av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n"); | |
| 3564 | ✗ | ts->raw_packet_size = TS_PACKET_SIZE; | |
| 3565 | } | ||
| 3566 | 80 | ts->stream = s; | |
| 3567 | 80 | ts->auto_guess = 0; | |
| 3568 | |||
| 3569 |
1/2✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
|
80 | if (s->iformat == &ff_mpegts_demuxer.p) { |
| 3570 | /* normal demux */ | ||
| 3571 | |||
| 3572 | /* first do a scan to get all the services */ | ||
| 3573 | 80 | seek_back(s, pb, pos); | |
| 3574 | |||
| 3575 | 80 | mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); | |
| 3576 | 80 | mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1); | |
| 3577 | 80 | mpegts_open_section_filter(ts, EIT_PID, eit_cb, ts, 1); | |
| 3578 | |||
| 3579 | 80 | handle_packets(ts, probesize / ts->raw_packet_size); | |
| 3580 | /* if could not find service, enable auto_guess */ | ||
| 3581 | |||
| 3582 | 80 | ts->auto_guess = 1; | |
| 3583 | |||
| 3584 | 80 | av_log(ts->stream, AV_LOG_TRACE, "tuning done\n"); | |
| 3585 | |||
| 3586 | 80 | s->ctx_flags |= AVFMTCTX_NOHEADER; | |
| 3587 | } else { | ||
| 3588 | AVStream *st; | ||
| 3589 | int pcr_pid, pid, nb_packets, nb_pcrs, ret, pcr_l; | ||
| 3590 | int64_t pcrs[2], pcr_h; | ||
| 3591 | uint8_t packet[TS_PACKET_SIZE]; | ||
| 3592 | const uint8_t *data; | ||
| 3593 | |||
| 3594 | /* only read packets */ | ||
| 3595 | |||
| 3596 | ✗ | st = avformat_new_stream(s, NULL); | |
| 3597 | ✗ | if (!st) | |
| 3598 | ✗ | return AVERROR(ENOMEM); | |
| 3599 | ✗ | avpriv_set_pts_info(st, 60, 1, 27000000); | |
| 3600 | ✗ | st->codecpar->codec_type = AVMEDIA_TYPE_DATA; | |
| 3601 | ✗ | st->codecpar->codec_id = AV_CODEC_ID_MPEG2TS; | |
| 3602 | |||
| 3603 | /* we iterate until we find two PCRs to estimate the bitrate */ | ||
| 3604 | ✗ | pcr_pid = -1; | |
| 3605 | ✗ | nb_pcrs = 0; | |
| 3606 | ✗ | nb_packets = 0; | |
| 3607 | for (;;) { | ||
| 3608 | ✗ | ret = read_packet(s, packet, ts->raw_packet_size, &data); | |
| 3609 | ✗ | if (ret < 0) | |
| 3610 | ✗ | return ret; | |
| 3611 | ✗ | pid = AV_RB16(data + 1) & 0x1fff; | |
| 3612 | ✗ | if ((pcr_pid == -1 || pcr_pid == pid) && | |
| 3613 | ✗ | parse_pcr(&pcr_h, &pcr_l, data) == 0) { | |
| 3614 | ✗ | finished_reading_packet(s, ts->raw_packet_size); | |
| 3615 | ✗ | pcr_pid = pid; | |
| 3616 | ✗ | pcrs[nb_pcrs] = pcr_h * SYSTEM_CLOCK_FREQUENCY_DIVISOR + pcr_l; | |
| 3617 | ✗ | nb_pcrs++; | |
| 3618 | ✗ | if (nb_pcrs >= 2) { | |
| 3619 | ✗ | if (pcrs[1] - pcrs[0] > 0) { | |
| 3620 | /* the difference needs to be positive to make sense for bitrate computation */ | ||
| 3621 | ✗ | break; | |
| 3622 | } else { | ||
| 3623 | ✗ | av_log(ts->stream, AV_LOG_WARNING, "invalid pcr pair %"PRId64" >= %"PRId64"\n", pcrs[0], pcrs[1]); | |
| 3624 | ✗ | pcrs[0] = pcrs[1]; | |
| 3625 | ✗ | nb_pcrs--; | |
| 3626 | } | ||
| 3627 | } | ||
| 3628 | } else { | ||
| 3629 | ✗ | finished_reading_packet(s, ts->raw_packet_size); | |
| 3630 | } | ||
| 3631 | ✗ | nb_packets++; | |
| 3632 | } | ||
| 3633 | |||
| 3634 | /* NOTE1: the bitrate is computed without the FEC */ | ||
| 3635 | /* NOTE2: it is only the bitrate of the start of the stream */ | ||
| 3636 | ✗ | ts->pcr_incr = pcrs[1] - pcrs[0]; | |
| 3637 | ✗ | ts->cur_pcr = pcrs[0] - ts->pcr_incr * (nb_packets - 1); | |
| 3638 | ✗ | s->bit_rate = TS_PACKET_SIZE * 8 * 27000000LL / ts->pcr_incr; | |
| 3639 | ✗ | st->codecpar->bit_rate = s->bit_rate; | |
| 3640 | ✗ | st->start_time = ts->cur_pcr; | |
| 3641 | ✗ | av_log(ts->stream, AV_LOG_TRACE, "start=%0.3f pcr=%0.3f incr=%"PRId64"\n", | |
| 3642 | ✗ | st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr); | |
| 3643 | } | ||
| 3644 | |||
| 3645 | 80 | seek_back(s, pb, pos); | |
| 3646 | 80 | return 0; | |
| 3647 | } | ||
| 3648 | |||
| 3649 | #define MAX_PACKET_READAHEAD ((128 * 1024) / 188) | ||
| 3650 | |||
| 3651 | ✗ | static int mpegts_raw_read_packet(AVFormatContext *s, AVPacket *pkt) | |
| 3652 | { | ||
| 3653 | ✗ | MpegTSContext *ts = s->priv_data; | |
| 3654 | int ret, i; | ||
| 3655 | int64_t pcr_h, next_pcr_h, pos; | ||
| 3656 | int pcr_l, next_pcr_l; | ||
| 3657 | uint8_t pcr_buf[12]; | ||
| 3658 | const uint8_t *data; | ||
| 3659 | |||
| 3660 | ✗ | if ((ret = av_new_packet(pkt, TS_PACKET_SIZE)) < 0) | |
| 3661 | ✗ | return ret; | |
| 3662 | ✗ | ret = read_packet(s, pkt->data, ts->raw_packet_size, &data); | |
| 3663 | ✗ | pkt->pos = avio_tell(s->pb); | |
| 3664 | ✗ | if (ret < 0) { | |
| 3665 | ✗ | return ret; | |
| 3666 | } | ||
| 3667 | ✗ | if (data != pkt->data) | |
| 3668 | ✗ | memcpy(pkt->data, data, TS_PACKET_SIZE); | |
| 3669 | ✗ | finished_reading_packet(s, ts->raw_packet_size); | |
| 3670 | ✗ | if (ts->mpeg2ts_compute_pcr) { | |
| 3671 | /* compute exact PCR for each packet */ | ||
| 3672 | ✗ | if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) { | |
| 3673 | /* we read the next PCR (XXX: optimize it by using a bigger buffer */ | ||
| 3674 | ✗ | pos = avio_tell(s->pb); | |
| 3675 | ✗ | for (i = 0; i < MAX_PACKET_READAHEAD; i++) { | |
| 3676 | ✗ | avio_seek(s->pb, pos + i * ts->raw_packet_size, SEEK_SET); | |
| 3677 | ✗ | avio_read(s->pb, pcr_buf, 12); | |
| 3678 | ✗ | if (parse_pcr(&next_pcr_h, &next_pcr_l, pcr_buf) == 0) { | |
| 3679 | /* XXX: not precise enough */ | ||
| 3680 | ✗ | ts->pcr_incr = | |
| 3681 | ✗ | ((next_pcr_h - pcr_h) * SYSTEM_CLOCK_FREQUENCY_DIVISOR + (next_pcr_l - pcr_l)) / | |
| 3682 | ✗ | (i + 1); | |
| 3683 | ✗ | break; | |
| 3684 | } | ||
| 3685 | } | ||
| 3686 | ✗ | avio_seek(s->pb, pos, SEEK_SET); | |
| 3687 | /* no next PCR found: we use previous increment */ | ||
| 3688 | ✗ | ts->cur_pcr = pcr_h * SYSTEM_CLOCK_FREQUENCY_DIVISOR + pcr_l; | |
| 3689 | } | ||
| 3690 | ✗ | pkt->pts = ts->cur_pcr; | |
| 3691 | ✗ | pkt->duration = ts->pcr_incr; | |
| 3692 | ✗ | ts->cur_pcr += ts->pcr_incr; | |
| 3693 | } | ||
| 3694 | ✗ | pkt->stream_index = 0; | |
| 3695 | ✗ | return 0; | |
| 3696 | } | ||
| 3697 | |||
| 3698 | 34924 | static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt) | |
| 3699 | { | ||
| 3700 | 34924 | MpegTSContext *ts = s->priv_data; | |
| 3701 | int ret, i; | ||
| 3702 | |||
| 3703 | 34924 | pkt->size = -1; | |
| 3704 | 34924 | ts->pkt = pkt; | |
| 3705 | 34924 | ret = handle_packets(ts, 0); | |
| 3706 |
2/2✓ Branch 0 taken 502 times.
✓ Branch 1 taken 34422 times.
|
34924 | if (ret < 0) { |
| 3707 | 502 | av_packet_unref(ts->pkt); | |
| 3708 | /* flush pes data left */ | ||
| 3709 |
2/2✓ Branch 0 taken 2878533 times.
✓ Branch 1 taken 288 times.
|
2878821 | for (i = 0; i < NB_PID_MAX; i++) |
| 3710 |
4/4✓ Branch 0 taken 2983 times.
✓ Branch 1 taken 2875550 times.
✓ Branch 2 taken 1029 times.
✓ Branch 3 taken 1954 times.
|
2878533 | if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) { |
| 3711 | 1029 | PESContext *pes = ts->pids[i]->u.pes_filter.opaque; | |
| 3712 |
3/4✓ Branch 0 taken 214 times.
✓ Branch 1 taken 815 times.
✓ Branch 2 taken 214 times.
✗ Branch 3 not taken.
|
1029 | if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { |
| 3713 | 214 | ret = new_pes_packet(pes, pkt); | |
| 3714 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 214 times.
|
214 | if (ret < 0) |
| 3715 | ✗ | return ret; | |
| 3716 | 214 | pes->state = MPEGTS_SKIP; | |
| 3717 | 214 | ret = 0; | |
| 3718 | 214 | break; | |
| 3719 | } | ||
| 3720 | } | ||
| 3721 | } | ||
| 3722 | |||
| 3723 |
3/4✓ Branch 0 taken 34636 times.
✓ Branch 1 taken 288 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 34636 times.
|
34924 | if (!ret && pkt->size < 0) |
| 3724 | ✗ | ret = AVERROR_INVALIDDATA; | |
| 3725 | 34924 | return ret; | |
| 3726 | } | ||
| 3727 | |||
| 3728 | 80 | static void mpegts_free(MpegTSContext *ts) | |
| 3729 | { | ||
| 3730 | int i; | ||
| 3731 | |||
| 3732 | 80 | clear_programs(ts); | |
| 3733 | |||
| 3734 |
2/2✓ Branch 0 taken 2560 times.
✓ Branch 1 taken 80 times.
|
2640 | for (i = 0; i < FF_ARRAY_ELEMS(ts->pools); i++) |
| 3735 | 2560 | av_buffer_pool_uninit(&ts->pools[i]); | |
| 3736 | |||
| 3737 |
2/2✓ Branch 0 taken 655360 times.
✓ Branch 1 taken 80 times.
|
655440 | for (i = 0; i < NB_PID_MAX; i++) |
| 3738 |
2/2✓ Branch 0 taken 485 times.
✓ Branch 1 taken 654875 times.
|
655360 | if (ts->pids[i]) |
| 3739 | 485 | mpegts_close_filter(ts, ts->pids[i]); | |
| 3740 | 80 | } | |
| 3741 | |||
| 3742 | 80 | static int mpegts_read_close(AVFormatContext *s) | |
| 3743 | { | ||
| 3744 | 80 | MpegTSContext *ts = s->priv_data; | |
| 3745 | 80 | mpegts_free(ts); | |
| 3746 | 80 | return 0; | |
| 3747 | } | ||
| 3748 | |||
| 3749 | ✗ | av_unused static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, | |
| 3750 | int64_t *ppos, int64_t pos_limit) | ||
| 3751 | { | ||
| 3752 | ✗ | MpegTSContext *ts = s->priv_data; | |
| 3753 | int64_t pos, timestamp; | ||
| 3754 | uint8_t buf[TS_PACKET_SIZE]; | ||
| 3755 | ✗ | int pcr_l, pcr_pid = | |
| 3756 | ✗ | ((PESContext *)s->streams[stream_index]->priv_data)->pcr_pid; | |
| 3757 | ✗ | int pos47 = ts->pos47_full % ts->raw_packet_size; | |
| 3758 | ✗ | pos = | |
| 3759 | ✗ | ((*ppos + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * | |
| 3760 | ✗ | ts->raw_packet_size + pos47; | |
| 3761 | ✗ | while(pos < pos_limit) { | |
| 3762 | ✗ | if (avio_seek(s->pb, pos, SEEK_SET) < 0) | |
| 3763 | ✗ | return AV_NOPTS_VALUE; | |
| 3764 | ✗ | if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) | |
| 3765 | ✗ | return AV_NOPTS_VALUE; | |
| 3766 | ✗ | if (buf[0] != SYNC_BYTE) { | |
| 3767 | ✗ | if (mpegts_resync(s, TS_PACKET_SIZE, buf) < 0) | |
| 3768 | ✗ | return AV_NOPTS_VALUE; | |
| 3769 | ✗ | pos = avio_tell(s->pb); | |
| 3770 | ✗ | continue; | |
| 3771 | } | ||
| 3772 | ✗ | if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) && | |
| 3773 | ✗ | parse_pcr(×tamp, &pcr_l, buf) == 0) { | |
| 3774 | ✗ | *ppos = pos; | |
| 3775 | ✗ | return timestamp; | |
| 3776 | } | ||
| 3777 | ✗ | pos += ts->raw_packet_size; | |
| 3778 | } | ||
| 3779 | |||
| 3780 | ✗ | return AV_NOPTS_VALUE; | |
| 3781 | } | ||
| 3782 | |||
| 3783 | 90 | static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index, | |
| 3784 | int64_t *ppos, int64_t pos_limit) | ||
| 3785 | { | ||
| 3786 | 90 | MpegTSContext *ts = s->priv_data; | |
| 3787 | AVPacket *pkt; | ||
| 3788 | int64_t pos; | ||
| 3789 | 90 | int pos47 = ts->pos47_full % ts->raw_packet_size; | |
| 3790 | 90 | pos = ((*ppos + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * ts->raw_packet_size + pos47; | |
| 3791 | 90 | ff_read_frame_flush(s); | |
| 3792 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
|
90 | if (avio_seek(s->pb, pos, SEEK_SET) < 0) |
| 3793 | ✗ | return AV_NOPTS_VALUE; | |
| 3794 | 90 | pkt = av_packet_alloc(); | |
| 3795 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
|
90 | if (!pkt) |
| 3796 | ✗ | return AV_NOPTS_VALUE; | |
| 3797 |
2/2✓ Branch 0 taken 484 times.
✓ Branch 1 taken 12 times.
|
496 | while(pos < pos_limit) { |
| 3798 | 484 | int ret = av_read_frame(s, pkt); | |
| 3799 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 466 times.
|
484 | if (ret < 0) { |
| 3800 | 18 | av_packet_free(&pkt); | |
| 3801 | 18 | return AV_NOPTS_VALUE; | |
| 3802 | } | ||
| 3803 |
3/4✓ Branch 0 taken 466 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 163 times.
✓ Branch 3 taken 303 times.
|
466 | if (pkt->dts != AV_NOPTS_VALUE && pkt->pos >= 0) { |
| 3804 | 163 | ff_reduce_index(s, pkt->stream_index); | |
| 3805 | 163 | av_add_index_entry(s->streams[pkt->stream_index], pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); | |
| 3806 |
3/4✓ Branch 0 taken 60 times.
✓ Branch 1 taken 103 times.
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
|
163 | if (pkt->stream_index == stream_index && pkt->pos >= *ppos) { |
| 3807 | 60 | int64_t dts = pkt->dts; | |
| 3808 | 60 | *ppos = pkt->pos; | |
| 3809 | 60 | av_packet_free(&pkt); | |
| 3810 | 60 | return dts; | |
| 3811 | } | ||
| 3812 | } | ||
| 3813 | 406 | pos = pkt->pos; | |
| 3814 | 406 | av_packet_unref(pkt); | |
| 3815 | } | ||
| 3816 | |||
| 3817 | 12 | av_packet_free(&pkt); | |
| 3818 | 12 | return AV_NOPTS_VALUE; | |
| 3819 | } | ||
| 3820 | |||
| 3821 | /**************************************************************/ | ||
| 3822 | /* parsing functions - called from other demuxers such as RTP */ | ||
| 3823 | |||
| 3824 | ✗ | MpegTSContext *avpriv_mpegts_parse_open(AVFormatContext *s) | |
| 3825 | { | ||
| 3826 | MpegTSContext *ts; | ||
| 3827 | |||
| 3828 | ✗ | ts = av_mallocz(sizeof(MpegTSContext)); | |
| 3829 | ✗ | if (!ts) | |
| 3830 | ✗ | return NULL; | |
| 3831 | /* no stream case, currently used by RTP */ | ||
| 3832 | ✗ | ts->raw_packet_size = TS_PACKET_SIZE; | |
| 3833 | ✗ | ts->max_packet_size = 2048000; | |
| 3834 | ✗ | ts->stream = s; | |
| 3835 | ✗ | ts->auto_guess = 1; | |
| 3836 | |||
| 3837 | ✗ | mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); | |
| 3838 | ✗ | mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1); | |
| 3839 | ✗ | mpegts_open_section_filter(ts, EIT_PID, eit_cb, ts, 1); | |
| 3840 | |||
| 3841 | ✗ | return ts; | |
| 3842 | } | ||
| 3843 | |||
| 3844 | /* return the consumed length if a packet was output, or -1 if no | ||
| 3845 | * packet is output */ | ||
| 3846 | ✗ | int avpriv_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, | |
| 3847 | const uint8_t *buf, int len) | ||
| 3848 | { | ||
| 3849 | int len1; | ||
| 3850 | |||
| 3851 | ✗ | len1 = len; | |
| 3852 | ✗ | ts->pkt = pkt; | |
| 3853 | for (;;) { | ||
| 3854 | ✗ | ts->stop_parse = 0; | |
| 3855 | ✗ | if (len < TS_PACKET_SIZE) | |
| 3856 | ✗ | return AVERROR_INVALIDDATA; | |
| 3857 | ✗ | if (buf[0] != SYNC_BYTE) { | |
| 3858 | ✗ | buf++; | |
| 3859 | ✗ | len--; | |
| 3860 | } else { | ||
| 3861 | ✗ | handle_packet(ts, buf, len1 - len + TS_PACKET_SIZE); | |
| 3862 | ✗ | buf += TS_PACKET_SIZE; | |
| 3863 | ✗ | len -= TS_PACKET_SIZE; | |
| 3864 | ✗ | if (ts->stop_parse == 1) | |
| 3865 | ✗ | break; | |
| 3866 | } | ||
| 3867 | } | ||
| 3868 | ✗ | return len1 - len; | |
| 3869 | } | ||
| 3870 | |||
| 3871 | ✗ | void avpriv_mpegts_parse_close(MpegTSContext *ts) | |
| 3872 | { | ||
| 3873 | ✗ | mpegts_free(ts); | |
| 3874 | ✗ | av_free(ts); | |
| 3875 | ✗ | } | |
| 3876 | |||
| 3877 | const FFInputFormat ff_mpegts_demuxer = { | ||
| 3878 | .p.name = "mpegts", | ||
| 3879 | .p.long_name = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"), | ||
| 3880 | .p.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, | ||
| 3881 | .p.priv_class = &mpegts_class, | ||
| 3882 | .priv_data_size = sizeof(MpegTSContext), | ||
| 3883 | .read_probe = mpegts_probe, | ||
| 3884 | .read_header = mpegts_read_header, | ||
| 3885 | .read_packet = mpegts_read_packet, | ||
| 3886 | .read_close = mpegts_read_close, | ||
| 3887 | .read_timestamp = mpegts_get_dts, | ||
| 3888 | .flags_internal = FF_INFMT_FLAG_PREFER_CODEC_FRAMERATE, | ||
| 3889 | }; | ||
| 3890 | |||
| 3891 | const FFInputFormat ff_mpegtsraw_demuxer = { | ||
| 3892 | .p.name = "mpegtsraw", | ||
| 3893 | .p.long_name = NULL_IF_CONFIG_SMALL("raw MPEG-TS (MPEG-2 Transport Stream)"), | ||
| 3894 | .p.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, | ||
| 3895 | .p.priv_class = &mpegtsraw_class, | ||
| 3896 | .priv_data_size = sizeof(MpegTSContext), | ||
| 3897 | .read_header = mpegts_read_header, | ||
| 3898 | .read_packet = mpegts_raw_read_packet, | ||
| 3899 | .read_close = mpegts_read_close, | ||
| 3900 | .read_timestamp = mpegts_get_dts, | ||
| 3901 | .flags_internal = FF_INFMT_FLAG_PREFER_CODEC_FRAMERATE, | ||
| 3902 | }; | ||
| 3903 |