#include "libavutil/crc.h"
#include "libavcodec/mpegvideo.h"
#include "avformat.h"
+#include "internal.h"
#include "mpegts.h"
#include "adts.h"
MpegTSService *service;
AVStream *st, *pcr_st = NULL;
AVMetadataTag *title;
- int i;
+ int i, j;
const char *service_name;
+ int *pids;
ts->tsid = DEFAULT_TSID;
ts->onid = DEFAULT_ONID;
ts->sdt.write_packet = section_write_packet;
ts->sdt.opaque = s;
+ pids = av_malloc(s->nb_streams);
+ if (!pids)
+ return AVERROR(ENOMEM);
+
/* assign pids to each stream */
for(i = 0;i < s->nb_streams; i++) {
st = s->streams[i];
goto fail;
st->priv_data = ts_st;
ts_st->service = service;
- ts_st->pid = DEFAULT_START_PID + i;
+ /* MPEG pid values < 16 are reserved. Applications which set st->id in
+ * this range are assigned a calculated pid. */
+ if (st->id < 16) {
+ ts_st->pid = DEFAULT_START_PID + i;
+ } else if (st->id < 0x1FFF) {
+ ts_st->pid = st->id;
+ } else {
+ av_log(s, AV_LOG_ERROR, "Invalid stream id %d, must be less than 8191\n", st->id);
+ goto fail;
+ }
+ if (ts_st->pid == service->pmt.pid) {
+ av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
+ goto fail;
+ }
+ for (j = 0; j < i; j++)
+ if (pids[j] == ts_st->pid) {
+ av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
+ goto fail;
+ }
+ pids[i] = ts_st->pid;
ts_st->payload_pts = AV_NOPTS_VALUE;
ts_st->payload_dts = AV_NOPTS_VALUE;
ts_st->first_pts_check = 1;
st->codec->extradata_size > 0) {
ts_st->adts = av_mallocz(sizeof(*ts_st->adts));
if (!ts_st->adts)
- return AVERROR_NOMEM;
+ return AVERROR(ENOMEM);
if (ff_adts_decode_extradata(s, ts_st->adts, st->codec->extradata,
st->codec->extradata_size) < 0)
return -1;
}
}
+ av_free(pids);
+
/* if no video stream, use the first stream as PCR */
if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {
pcr_st = s->streams[0];
return 0;
fail:
+ av_free(pids);
for(i = 0;i < s->nb_streams; i++) {
st = s->streams[i];
av_free(st->priv_data);
return -1;
data = av_malloc(new_size);
if (!data)
- return AVERROR_NOMEM;
+ return AVERROR(ENOMEM);
ff_adts_write_frame_header(adts, data, pkt->size, adts->pce_size);
if (adts->pce_size) {
memcpy(data+ADTS_HEADER_SIZE, adts->pce_data, adts->pce_size);