From 105f20b8af8ce5376165ca30a81276dae2e61e40 Mon Sep 17 00:00:00 2001 From: pkviet <pkv.str...@gmail.com> Date: Sat, 28 Oct 2017 02:48:08 +0200 Subject: [PATCH 1/2] libavf/mpegts: opus muxing for mapping family 255 Adds to mpegts muxer the capability to mux libopus with mapping family 255, following the provisional spec for opus in mepg-ts (https://people.xiph.org/~tterribe/opus/ETSI_TS_opus-v0.1.3-draft.doc). Signed-off-by: pkviet <pkv.str...@gmail.com> --- libavformat/mpegtsenc.c | 67 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index fdfa544..a31663c 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -28,6 +28,7 @@ #include "libavutil/opt.h" #include "libavcodec/internal.h" +#include "libavcodec/put_bits.h" #include "avformat.h" #include "avio_internal.h" @@ -291,6 +292,9 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) MpegTSWrite *ts = s->priv_data; uint8_t data[SECTION_LENGTH], *q, *desc_length_ptr, *program_info_length_ptr; int val, stream_type, i, err = 0; + uint8_t channel_count, stream_count, coupled_stream_count, *buf; + PutBitContext pbc; + size_t buf_size; q = data; put16(&q, 0xe000 | service->pcr_pid); @@ -421,8 +425,8 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) *q++ = 'D'; } if (st->codecpar->codec_id==AV_CODEC_ID_OPUS) { - /* 6 bytes registration descriptor, 4 bytes Opus audio descriptor */ - if (q - data > SECTION_LENGTH - 6 - 4) { + /* 6 bytes registration descriptor, 6 bytes Opus audio descriptor */ + if (q - data > SECTION_LENGTH - 6 - 6) { err = 1; break; } @@ -435,8 +439,19 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) *q++ = 's'; *q++ = 0x7f; /* DVB extension descriptor */ - *q++ = 2; - *q++ = 0x80; + /* descriptor_length */ + if (st->codecpar->extradata[18] == 255) { + /* dual mono */ + if (st->codecpar->channels == 2) { + *q++ = 2; + } else { + /* channel_config_code 0x81 */ + *q++ = st->codecpar->channels + 6; + } + } else { + *q++ = 2; + } + *q++ = 0x80; /* descriptor_tag_extension */ if (st->codecpar->extradata && st->codecpar->extradata_size >= 19) { if (st->codecpar->extradata[18] == 0 && st->codecpar->channels <= 2) { @@ -483,9 +498,47 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) *q++ = 0xff; } } else { - /* Unsupported */ - av_log(s, AV_LOG_ERROR, "Unsupported Opus channel mapping for family %d", st->codecpar->extradata[18]); - *q++ = 0xff; + /* mapping family 255 , set channel_config_code to 0x81 except for dual-mono */ + if (st->codecpar->extradata[18] == 255) { + /* dual mono */ + if (st->codecpar->channels == 2 && st->codecpar->extradata[19] == 1) { + *q++ = 0x00; + } else if (st->codecpar->channels == 2 && st->codecpar->extradata[19] == 2) { + *q++ = 0x80; + } else { + /* application defined channel configuration */ + *q++ = 0x81; + *q++ = st->codecpar->channels; + *q++ = st->codecpar->extradata[18]; + channel_count = st->codecpar->channels; + stream_count = st->codecpar->extradata[19]; + coupled_stream_count = st->codecpar->extradata[20]; + buf = av_mallocz_array( st->codecpar->channels + 2 , sizeof(uint8_t)); + if (!buf) { + av_freep(buf); + return AVERROR(ENOMEM); + } + init_put_bits(&pbc, buf, (st->codecpar->channels + 2)); + put_bits(&pbc, av_ceil_log2_c(channel_count), st->codecpar->extradata[19] - 1); + put_bits(&pbc, av_ceil_log2_c(stream_count + 1), st->codecpar->extradata[20]); + for (i = 0; i < channel_count; i++) { + put_bits(&pbc, av_ceil_log2_c(stream_count + coupled_stream_count + 1), st->codecpar->extradata[21 + i]); + } + flush_put_bits(&pbc); + buf_size = av_ceil_log2_c(channel_count) + av_ceil_log2_c(stream_count + 1) + + channel_count * (av_ceil_log2_c(stream_count + coupled_stream_count + 1)) + + (8 * (2 + channel_count) - av_ceil_log2_c(channel_count) - av_ceil_log2_c(stream_count + 1) + - channel_count * (av_ceil_log2_c(stream_count + coupled_stream_count + 1))) % 8; + for (i = 0; i < buf_size; i++) { + memcpy(q++, buf+i, 1); + } + av_freep(&buf); + } + } else { + /* Unsupported */ + av_log(s, AV_LOG_ERROR, "Unsupported Opus channel mapping for family %d", st->codecpar->extradata[18]); + *q++ = 0xff; + } } } else if (st->codecpar->channels <= 2) { /* Assume RTP mapping family */ -- 2.10.1.windows.1
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel