#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
+#include "libavcodec/ac3_parser_internal.h"
#include "libavcodec/internal.h"
#include "avformat.h"
/* For Opus */
int opus_queued_samples;
int opus_pending_trim_start;
+
+ DVBAC3Descriptor *dvb_ac3_desc;
} MpegTSWriteStream;
static void mpegts_write_pat(AVFormatContext *s)
AVStream *st = s->streams[i];
MpegTSWriteStream *ts_st = st->priv_data;
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
+ enum AVCodecID codec_id = st->codecpar->codec_id;
if (s->nb_programs) {
int k, found = 0;
switch (st->codecpar->codec_type) {
case AVMEDIA_TYPE_AUDIO:
if (ts->flags & MPEGTS_FLAG_SYSTEM_B) {
- if (st->codecpar->codec_id==AV_CODEC_ID_AC3) {
- *q++=0x6a; // AC3 descriptor see A038 DVB SI
- *q++=1; // 1 byte, all flags sets to 0
- *q++=0; // omit all fields...
- }
- else if (st->codecpar->codec_id==AV_CODEC_ID_EAC3) {
- *q++=0x7a; // EAC3 descriptor see A038 DVB SI
- *q++=1; // 1 byte, all flags sets to 0
- *q++=0; // omit all fields...
- }
+ if (codec_id == AV_CODEC_ID_AC3) {
+ DVBAC3Descriptor *dvb_ac3_desc = ts_st->dvb_ac3_desc;
+
+ *q++=0x6a; // AC3 descriptor see A038 DVB SI
+ if (dvb_ac3_desc) {
+ int len = 1 +
+ !!(dvb_ac3_desc->component_type_flag) +
+ !!(dvb_ac3_desc->bsid_flag) +
+ !!(dvb_ac3_desc->mainid_flag) +
+ !!(dvb_ac3_desc->asvc_flag);
+
+ *q++ = len;
+ *q++ = dvb_ac3_desc->component_type_flag << 7 | dvb_ac3_desc->bsid_flag << 6 |
+ dvb_ac3_desc->mainid_flag << 5 | dvb_ac3_desc->asvc_flag << 4;
+
+ if (dvb_ac3_desc->component_type_flag) *q++ = dvb_ac3_desc->component_type;
+ if (dvb_ac3_desc->bsid_flag) *q++ = dvb_ac3_desc->bsid;
+ if (dvb_ac3_desc->mainid_flag) *q++ = dvb_ac3_desc->mainid;
+ if (dvb_ac3_desc->asvc_flag) *q++ = dvb_ac3_desc->asvc;
+ } else {
+ *q++=1; // 1 byte, all flags sets to 0
+ *q++=0; // omit all fields...
+ }
+ } else if (codec_id == AV_CODEC_ID_EAC3) {
+ *q++=0x7a; // EAC3 descriptor see A038 DVB SI
+ *q++=1; // 1 byte, all flags sets to 0
+ *q++=0; // omit all fields...
+ }
}
- if (st->codecpar->codec_id==AV_CODEC_ID_S302M)
+ if (codec_id == AV_CODEC_ID_S302M)
put_registration_descriptor(&q, MKTAG('B', 'S', 'S', 'D'));
- if (st->codecpar->codec_id==AV_CODEC_ID_OPUS) {
+ if (codec_id == AV_CODEC_ID_OPUS) {
/* 6 bytes registration descriptor, 4 bytes Opus audio descriptor */
if (q - data > SECTION_LENGTH - 6 - 4) {
err = 1;
const char default_language[] = "und";
const char *language = lang && strlen(lang->value) >= 3 ? lang->value : default_language;
- if (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
+ if (codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
uint8_t *len_ptr;
int extradata_copied = 0;
}
*len_ptr = q - len_ptr - 1;
- } else if (st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+ } else if (codec_id == AV_CODEC_ID_DVB_TELETEXT) {
uint8_t *len_ptr = NULL;
int extradata_copied = 0;
}
break;
case AVMEDIA_TYPE_DATA:
- if (st->codecpar->codec_id == AV_CODEC_ID_SMPTE_KLV) {
+ if (codec_id == AV_CODEC_ID_SMPTE_KLV) {
put_registration_descriptor(&q, MKTAG('K', 'L', 'V', 'A'));
- } else if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
+ } else if (codec_id == AV_CODEC_ID_TIMED_ID3) {
const char *tag = "ID3 ";
*q++ = 0x26; /* metadata descriptor */
*q++ = 13;
* need to count the samples of that too! */
av_log(s, AV_LOG_WARNING, "Got MPEG-TS formatted Opus data, unhandled");
}
+ } else if (st->codecpar->codec_id == AV_CODEC_ID_AC3 && !ts_st->dvb_ac3_desc) {
+ AC3HeaderInfo *hdr = NULL;
+
+ if (avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size) >= 0) {
+ uint8_t number_of_channels_flag;
+ uint8_t service_type_flag;
+ uint8_t full_service_flag = 1;
+ DVBAC3Descriptor *dvb_ac3_desc;
+
+ dvb_ac3_desc = av_mallocz(sizeof(*dvb_ac3_desc));
+ if (!dvb_ac3_desc) {
+ av_free(hdr);
+ return AVERROR(ENOMEM);
+ }
+
+ service_type_flag = hdr->bitstream_mode;
+ switch (hdr->channel_mode) {
+ case AC3_CHMODE_DUALMONO:
+ number_of_channels_flag = 1;
+ break;
+ case AC3_CHMODE_MONO:
+ number_of_channels_flag = 0;
+ break;
+ case AC3_CHMODE_STEREO:
+ if (hdr->dolby_surround_mode == AC3_DSURMOD_ON)
+ number_of_channels_flag = 3;
+ else
+ number_of_channels_flag = 2;
+ break;
+ case AC3_CHMODE_3F:
+ case AC3_CHMODE_2F1R:
+ case AC3_CHMODE_3F1R:
+ case AC3_CHMODE_2F2R:
+ case AC3_CHMODE_3F2R:
+ number_of_channels_flag = 4;
+ break;
+ default: /* reserved */
+ number_of_channels_flag = 7;
+ break;
+ }
+
+ if (service_type_flag == 1 || service_type_flag == 4 ||
+ (service_type_flag == 7 && !number_of_channels_flag))
+ full_service_flag = 0;
+
+ dvb_ac3_desc->component_type_flag = 1;
+ dvb_ac3_desc->component_type = (full_service_flag << 6) |
+ ((service_type_flag & 0x7) << 3) |
+ (number_of_channels_flag & 0x7);
+ dvb_ac3_desc->bsid_flag = 1;
+ dvb_ac3_desc->bsid = hdr->bitstream_id;
+ dvb_ac3_desc->mainid_flag = 0;
+ dvb_ac3_desc->asvc_flag = 0;
+
+ ts_st->dvb_ac3_desc = dvb_ac3_desc;
+ }
+ av_free(hdr);
}
if (ts_st->payload_size && (ts_st->payload_size + size > ts->pes_payload_size ||
AVStream *st = s->streams[i];
MpegTSWriteStream *ts_st = st->priv_data;
if (ts_st) {
+ av_freep(&ts_st->dvb_ac3_desc);
av_freep(&ts_st->payload);
if (ts_st->amux) {
avformat_free_context(ts_st->amux);