#include "libavutil/crc.h"
#include "libavcodec/mpegvideo.h"
#include "avformat.h"
+#include "internal.h"
#include "mpegts.h"
#include "adts.h"
/* write optional descriptors here */
switch(st->codec->codec_type) {
- case CODEC_TYPE_AUDIO:
+ case AVMEDIA_TYPE_AUDIO:
if (lang && strlen(lang->value) == 3) {
*q++ = 0x0a; /* ISO 639 language descriptor */
*q++ = 4;
*q++ = 0; /* undefined type */
}
break;
- case CODEC_TYPE_SUBTITLE:
+ case AVMEDIA_TYPE_SUBTITLE:
{
const char *language;
language = lang && strlen(lang->value)==3 ? lang->value : "eng";
put16(&q, 1); /* ancillary page id */
}
break;
- case CODEC_TYPE_VIDEO:
+ case AVMEDIA_TYPE_VIDEO:
if (stream_type == STREAM_TYPE_VIDEO_DIRAC) {
*q++ = 0x05; /*MPEG-2 registration descriptor*/
*q++ = 4;
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;
ts_st->cc = 15;
/* update PCR pid by using the first video stream */
- if (st->codec->codec_type == CODEC_TYPE_VIDEO &&
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
service->pcr_pid == 0x1fff) {
service->pcr_pid = ts_st->pid;
pcr_st = st;
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];
/* Arbitrary values, PAT/PMT could be written on key frames */
ts->sdt_packet_period = 200;
ts->pat_packet_period = 40;
- if (pcr_st->codec->codec_type == CODEC_TYPE_AUDIO) {
+ if (pcr_st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
if (!pcr_st->codec->frame_size) {
av_log(s, AV_LOG_WARNING, "frame size not set\n");
service->pcr_packet_period =
return 0;
fail:
+ av_free(pids);
for(i = 0;i < s->nb_streams; i++) {
st = s->streams[i];
av_free(st->priv_data);
*q++ = 0x00;
*q++ = 0x01;
private_code = 0;
- if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
if (st->codec->codec_id == CODEC_ID_DIRAC) {
*q++ = 0xfd;
} else
*q++ = 0xe0;
- } else if (st->codec->codec_type == CODEC_TYPE_AUDIO &&
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
(st->codec->codec_id == CODEC_ID_MP2 ||
st->codec->codec_id == CODEC_ID_MP3)) {
*q++ = 0xc0;
} else {
*q++ = 0xbd;
- if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) {
+ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
private_code = 0x20;
}
}
header_len += 5;
flags |= 0x40;
}
- if (st->codec->codec_type == CODEC_TYPE_VIDEO &&
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
st->codec->codec_id == CODEC_ID_DIRAC) {
/* set PES_extension_flag */
pes_extension = 1;
*q++ = len;
val = 0x80;
/* data alignment indicator is required for subtitle data */
- if (st->codec->codec_type == CODEC_TYPE_SUBTITLE)
+ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
val |= 0x04;
*q++ = val;
*q++ = flags;
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);
}
}
- if (st->codec->codec_type != CODEC_TYPE_AUDIO) {
+ if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
// for video and subtitle, write a single pes packet
mpegts_write_pes(s, st, buf, size, pts, dts);
av_free(data);
memcpy(ts_st->payload + ts_st->payload_index, buf, size);
ts_st->payload_index += size;
+ av_free(data);
+
return 0;
}
mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
ts_st->payload_pts, ts_st->payload_dts);
}
+ av_freep(&ts_st->adts);
}
put_flush_packet(s->pb);