#include "libavutil/crc.h"
#include "libavcodec/mpegvideo.h"
#include "avformat.h"
+#include "internal.h"
#include "mpegts.h"
+#include "adts.h"
/* write DVB SI sections */
int64_t payload_pts;
int64_t payload_dts;
uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE];
+ ADTSContext *adts;
} MpegTSWriteStream;
static void mpegts_write_pat(AVFormatContext *s)
/* 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;
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;
}
+ if (st->codec->codec_id == CODEC_ID_AAC &&
+ st->codec->extradata_size > 0) {
+ ts_st->adts = av_mallocz(sizeof(*ts_st->adts));
+ if (!ts_st->adts)
+ return AVERROR(ENOMEM);
+ if (ff_adts_decode_extradata(s, ts_st->adts, st->codec->extradata,
+ st->codec->extradata_size) < 0)
+ return -1;
+ }
}
/* if no video stream, use the first stream as PCR */
ts->mux_rate = s->mux_rate ? s->mux_rate : 1;
if (ts->mux_rate > 1) {
- service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) /
- (TS_PACKET_SIZE * 8 * 1000);
- ts->sdt_packet_period = (ts->mux_rate * SDT_RETRANS_TIME) /
- (TS_PACKET_SIZE * 8 * 1000);
- ts->pat_packet_period = (ts->mux_rate * PAT_RETRANS_TIME) /
- (TS_PACKET_SIZE * 8 * 1000);
-
- ts->cur_pcr = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
+ service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) /
+ (TS_PACKET_SIZE * 8 * 1000);
+ ts->sdt_packet_period = (ts->mux_rate * SDT_RETRANS_TIME) /
+ (TS_PACKET_SIZE * 8 * 1000);
+ ts->pat_packet_period = (ts->mux_rate * PAT_RETRANS_TIME) /
+ (TS_PACKET_SIZE * 8 * 1000);
+
+ ts->cur_pcr = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
} else {
/* 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 =
*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;
buf = data;
size = pkt->size+6;
}
+ } else if (st->codec->codec_id == CODEC_ID_AAC) {
+ if (pkt->size < 2)
+ return -1;
+ if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) {
+ ADTSContext *adts = ts_st->adts;
+ int new_size;
+ if (!adts) {
+ av_log(s, AV_LOG_ERROR, "aac bitstream not in adts format "
+ "and extradata missing\n");
+ return -1;
+ }
+ new_size = ADTS_HEADER_SIZE+adts->pce_size+pkt->size;
+ if ((unsigned)new_size >= INT_MAX)
+ return -1;
+ data = av_malloc(new_size);
+ if (!data)
+ 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);
+ adts->pce_size = 0;
+ }
+ memcpy(data+ADTS_HEADER_SIZE+adts->pce_size, pkt->data, pkt->size);
+ buf = data;
+ size = new_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);