[FFmpeg-devel] [PATCH v5 1/2 ] avformat/mpegts: opus muxing for mapping family 255
pkv.stream
pkv.stream at gmail.com
Mon Oct 30 00:11:39 EET 2017
Le 29/10/2017 à 4:44 PM, Michael Niedermayer a écrit :
> On Sat, Oct 28, 2017 at 03:49:13AM +0200, pkv.stream wrote:
>>
>> mpegtsenc.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>> 1 file changed, 60 insertions(+), 7 deletions(-)
>> 1423a193788547952e3c4cdcb424b4724b0f1157 0001-libavf-mpegts-opus-muxing-for-mapping-family-255.patch
>> From 105f20b8af8ce5376165ca30a81276dae2e61e40 Mon Sep 17 00:00:00 2001
>> From: pkviet <pkv.stream at 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.stream at 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));
Hello Michael
thanks again for your reviews.
>> + if (!buf) {
>> + av_freep(buf);
> that looks wrong
>
right; fixed.
>> + 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;
> this duplicates previious expressions
> also it can probably be simplified with put_bits_count()
>
thanks alot for pointing to put_bits_count. followed your suggestion.
>> + for (i = 0; i < buf_size; i++) {
>> + memcpy(q++, buf+i, 1);
> memcpy isnt needed for seting one char
fixed;
I moved also the buffer size calculation earlier where it was first
required in the (draft) spec and factorized where i could.
Passes fate + patcheck.
Thanks very much for your patience. Much appreciated.
-------------- next part --------------
From 72ffc2f5e57f6f730dc255aaff4a0ce8b64143de Mon Sep 17 00:00:00 2001
From: pkviet <pkv.stream at 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.stream at gmail.com>
---
libavformat/mpegtsenc.c | 58 +++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 51 insertions(+), 7 deletions(-)
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index fdfa544..1de520d 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,29 @@ 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 && st->codecpar->channels > 2) {
+ /* channel_config_code 0x81 */
+ channel_count = st->codecpar->channels;
+ stream_count = st->codecpar->extradata[19];
+ coupled_stream_count = st->codecpar->extradata[20];
+ buf = av_mallocz_array(channel_count + 6, sizeof(uint8_t));
+ if (!buf) {
+ return AVERROR(ENOMEM);
+ }
+ init_put_bits(&pbc, buf, (channel_count + 6));
+ 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 = put_bits_count(&pbc) / 8;
+ *q++ = buf_size + 4;
+ } 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 +508,28 @@ 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 0x81 */
+ *q++ = 0x81;
+ *q++ = st->codecpar->channels;
+ *q++ = st->codecpar->extradata[18];
+ for (i = 0; i < buf_size; i++) {
+ *q++ = *(buf + i);
+ }
+ 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
More information about the ffmpeg-devel
mailing list