mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-11-26 20:50:34 +00:00
av3a格式封装和解封装
Signed-off-by: liushuai <cqliushuai@outlook.com>
This commit is contained in:
parent
740f635c30
commit
ac883016d9
1
BUILD.gn
1
BUILD.gn
@ -1118,6 +1118,7 @@ ohos_source_set("ffmpeg_dynamic") {
|
|||||||
# "//third_party/ffmpeg/libavformat/au.c",
|
# "//third_party/ffmpeg/libavformat/au.c",
|
||||||
"//third_party/ffmpeg/libavformat/av1.c",
|
"//third_party/ffmpeg/libavformat/av1.c",
|
||||||
"//third_party/ffmpeg/libavformat/avc.c",
|
"//third_party/ffmpeg/libavformat/avc.c",
|
||||||
|
"//third_party/ffmpeg/libavformat/av3adec.c",
|
||||||
|
|
||||||
# "//third_party/ffmpeg/libavformat/avidec.c",
|
# "//third_party/ffmpeg/libavformat/avidec.c",
|
||||||
"//third_party/ffmpeg/libavformat/avio.c",
|
"//third_party/ffmpeg/libavformat/avio.c",
|
||||||
|
@ -1563,6 +1563,7 @@
|
|||||||
#define CONFIG_AST_DEMUXER 1
|
#define CONFIG_AST_DEMUXER 1
|
||||||
#define CONFIG_AU_DEMUXER 1
|
#define CONFIG_AU_DEMUXER 1
|
||||||
#define CONFIG_AV1_DEMUXER 1
|
#define CONFIG_AV1_DEMUXER 1
|
||||||
|
#define CONFIG_AV3A_DEMUXER 1
|
||||||
#define CONFIG_AVI_DEMUXER 1
|
#define CONFIG_AVI_DEMUXER 1
|
||||||
#define CONFIG_AVISYNTH_DEMUXER 0
|
#define CONFIG_AVISYNTH_DEMUXER 0
|
||||||
#define CONFIG_AVR_DEMUXER 1
|
#define CONFIG_AVR_DEMUXER 1
|
||||||
@ -1887,6 +1888,7 @@
|
|||||||
#define CONFIG_AST_MUXER 1
|
#define CONFIG_AST_MUXER 1
|
||||||
#define CONFIG_ASF_STREAM_MUXER 1
|
#define CONFIG_ASF_STREAM_MUXER 1
|
||||||
#define CONFIG_AU_MUXER 1
|
#define CONFIG_AU_MUXER 1
|
||||||
|
#define CONFIG_AV3A_MUXER 1
|
||||||
#define CONFIG_AVI_MUXER 1
|
#define CONFIG_AVI_MUXER 1
|
||||||
#define CONFIG_AVIF_MUXER 1
|
#define CONFIG_AVIF_MUXER 1
|
||||||
#define CONFIG_AVM2_MUXER 1
|
#define CONFIG_AVM2_MUXER 1
|
||||||
|
270
libavcodec/av3a.h
Normal file
270
libavcodec/av3a.h
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* AV3A Format Common Header
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AVCODEC_AV3A_H
|
||||||
|
#define AVCODEC_AV3A_H
|
||||||
|
|
||||||
|
#include "libavutil/samplefmt.h"
|
||||||
|
|
||||||
|
/* AATF header */
|
||||||
|
#define AV3A_MAX_NBYTES_HEADER 9
|
||||||
|
#define AV3A_AUDIO_SYNC_WORD 0xFFF
|
||||||
|
#define AV3A_AUDIO_FRAME_SIZE 1024
|
||||||
|
#define AV3A_CHANNEL_LAYOUT_SIZE 15
|
||||||
|
#define AV3A_SIZE_BITRATE_TABLE 16
|
||||||
|
#define AV3A_SIZE_FS_TABLE 9
|
||||||
|
#define AV3A_SIZE_RESOLUTION_TABLE 3
|
||||||
|
|
||||||
|
/* Channel Layout */
|
||||||
|
#define AV3A_CH_LAYOUT_MONO (AV_CH_LAYOUT_MONO)
|
||||||
|
#define AV3A_CH_LAYOUT_STEREO (AV_CH_LAYOUT_STEREO)
|
||||||
|
#define AV3A_CH_LAYOUT_4POINT0 (AV3A_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER)
|
||||||
|
#define AV3A_CH_LAYOUT_5POINT1 (AV_CH_LAYOUT_5POINT1)
|
||||||
|
#define AV3A_CH_LAYOUT_7POINT1 (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)
|
||||||
|
#define AV3A_CH_LAYOUT_5POINT1POINT2 (AV_CH_LAYOUT_5POINT1|AV_CH_TOP_SIDE_LEFT|AV_CH_TOP_SIDE_RIGHT)
|
||||||
|
#define AV3A_CH_LAYOUT_7POINT1POINT2 (AV3A_CH_LAYOUT_7POINT1|AV_CH_TOP_SIDE_LEFT|AV_CH_TOP_SIDE_RIGHT)
|
||||||
|
#define AV3A_CH_LAYOUT_5POINT1POINT4 (AV_CH_LAYOUT_5POINT1|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT)
|
||||||
|
#define AV3A_CH_LAYOUT_7POINT1POINT4 (AV3A_CH_LAYOUT_7POINT1|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT)
|
||||||
|
#define AV3A_CH_AUDIO_OBJECT (AV_CHAN_UNKNOWN)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CHANNEL_CONFIG_MONO = 0, /* Mono = 0 */
|
||||||
|
CHANNEL_CONFIG_STEREO = 1, /* Stereo = 1 */
|
||||||
|
CHANNEL_CONFIG_MC_5_1 = 2, /* 5.1 = 2 */
|
||||||
|
CHANNEL_CONFIG_MC_7_1 = 3, /* 7.1 = 3 */
|
||||||
|
CHANNEL_CONFIG_MC_10_2 = 4, /* 10.2 = 4 */
|
||||||
|
CHANNEL_CONFIG_MC_22_2 = 5, /* 22.2 = 5 */
|
||||||
|
CHANNEL_CONFIG_MC_4_0 = 6, /* 4.0 = 6 */
|
||||||
|
CHANNEL_CONFIG_MC_5_1_2 = 7, /* 5.1.2 = 7 */
|
||||||
|
CHANNEL_CONFIG_MC_5_1_4 = 8, /* 5.1.4 = 8 */
|
||||||
|
CHANNEL_CONFIG_MC_7_1_2 = 9, /* 7.1.2 = 9 */
|
||||||
|
CHANNEL_CONFIG_MC_7_1_4 = 10, /* 7.1.4 = 10 */
|
||||||
|
CHANNEL_CONFIG_HOA_ORDER1 = 11, /* FOA = 11 */
|
||||||
|
CHANNEL_CONFIG_HOA_ORDER2 = 12, /* HOA2 = 12 */
|
||||||
|
CHANNEL_CONFIG_HOA_ORDER3 = 13, /* HOA3 = 13 */
|
||||||
|
CHANNEL_CONFIG_UNKNOWN = 14 /* UNKNOWN = 14 */
|
||||||
|
} AV3AChannelConfig;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int16_t sync_word; /* sync word */
|
||||||
|
int16_t audio_codec_id; /* audio codec id */
|
||||||
|
int16_t anc_data; /* anc data */
|
||||||
|
int16_t nn_type; /* neural network type */
|
||||||
|
int16_t coding_profile; /* coding profile */
|
||||||
|
int16_t sampling_frequency_index; /* samping rate index */
|
||||||
|
int16_t channel_number_index; /* channel number index */
|
||||||
|
int16_t bitrate_index; /* bitrate index */
|
||||||
|
int16_t soundBedType; /* soundbed type */
|
||||||
|
int16_t object_channel_number; /* object channel number */
|
||||||
|
int16_t bitrate_index_per_channel; /* bitrate per object */
|
||||||
|
int16_t order; /* ambisonics order */
|
||||||
|
int16_t resolution_index; /* resolution index */
|
||||||
|
|
||||||
|
int32_t sampling_rate; /* sampling rate */
|
||||||
|
int64_t total_bitrate; /* total bitrate */
|
||||||
|
int16_t sample_format ; /* sample format */
|
||||||
|
int16_t resolution; /* resolution */
|
||||||
|
int16_t content_type; /* internal content type */
|
||||||
|
int16_t nb_channels; /* number of channels (channel configuration) */
|
||||||
|
int16_t nb_objects; /* number of objects (object_channel_number + 1) */
|
||||||
|
int16_t total_channels; /* total channels */
|
||||||
|
int16_t hoa_order; /* ambisonics order (order + 1) */
|
||||||
|
int32_t ch_layout_mask; /* channel layout mask */
|
||||||
|
} AATFHeaderInfo;
|
||||||
|
|
||||||
|
// bitrate table for mono
|
||||||
|
static const int64_t ff_av3a_mono_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
16000, 32000, 44000, 56000, 64000, 72000, 80000, 96000, 128000, 144000,
|
||||||
|
164000, 192000, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
// bitrate table for stereo
|
||||||
|
static const int64_t ff_av3a_stereo_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
24000, 32000, 48000, 64000, 80000, 96000, 128000, 144000, 192000, 256000,
|
||||||
|
320000, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
// bitrate table for MC 5.1
|
||||||
|
static const int64_t ff_av3a_mc5p1_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
192000, 256000, 320000, 384000, 448000, 512000, 640000, 720000, 144000, 96000,
|
||||||
|
128000, 160000, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
// bitrate table for MC 7.1
|
||||||
|
static const int64_t ff_av3a_mc7p1_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
192000, 480000, 256000, 384000, 576000, 640000, 128000, 160000, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
// bitrate table for MC 4.0
|
||||||
|
static const int64_t ff_av3a_mc4p0_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
48000, 96000, 128000, 192000, 256000, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
// bitrate table for MC 5.1.2
|
||||||
|
static const int64_t ff_av3a_mc5p1p2_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
152000, 320000, 480000, 576000, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
// bitrate table for MC 5.1.4
|
||||||
|
static const int64_t ff_av3a_mc5p1p4_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
176000, 384000, 576000, 704000, 256000, 448000, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
// bitrate table for MC 7.1.2
|
||||||
|
static const int64_t ff_av3a_mc7p1p2_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
216000, 480000, 576000, 384000, 768000, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
// bitrate table for MC 7.1.4
|
||||||
|
static const int64_t ff_av3a_mc7p1p4_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
240000, 608000, 384000, 512000, 832000, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
static const int64_t ff_av3a_foa_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
48000, 96000, 128000, 192000, 256000, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
static const int64_t ff_av3a_hoa2_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
192000, 256000, 320000, 384000, 480000, 512000, 640000, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
// bitrate table for HOA order 3
|
||||||
|
static const int64_t ff_av3a_hoa3_bitrate_table[AV3A_SIZE_BITRATE_TABLE] = {
|
||||||
|
256000, 320000, 384000, 512000, 640000, 896000, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
static const int32_t ff_av3a_sampling_rate_table[AV3A_SIZE_FS_TABLE] = {
|
||||||
|
192000, 96000, 48000, 44100, 32000, 24000, 22050, 16000, 8000
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int16_t resolution;
|
||||||
|
enum AVSampleFormat sample_format;
|
||||||
|
} Av3aSampleFormatMap;
|
||||||
|
|
||||||
|
static const Av3aSampleFormatMap ff_av3a_sample_format_map_table[AV3A_SIZE_RESOLUTION_TABLE] = {
|
||||||
|
{8, AV_SAMPLE_FMT_U8 }, /* 0: 8 bits */
|
||||||
|
{16, AV_SAMPLE_FMT_S16}, /* 1: 16 bits */
|
||||||
|
{24, AV_SAMPLE_FMT_S32}, /* 2: 24 bits */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
AV3AChannelConfig channel_number_index;
|
||||||
|
int16_t channels;
|
||||||
|
const enum AVChannel* channel_layout;
|
||||||
|
uint64_t mask;
|
||||||
|
} Av3aChannelConfigMap;
|
||||||
|
|
||||||
|
static const enum AVChannel ff_av3a_default_channel_layout_mono[1] ={
|
||||||
|
AV_CHAN_FRONT_CENTER
|
||||||
|
};
|
||||||
|
|
||||||
|
static const enum AVChannel ff_av3a_default_channel_layout_stereo[2] ={
|
||||||
|
AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
static const enum AVChannel ff_av3a_channel_layout_mc_4_0[4] ={
|
||||||
|
AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT,
|
||||||
|
AV_CHAN_FRONT_CENTER, AV_CHAN_BACK_CENTER
|
||||||
|
};
|
||||||
|
|
||||||
|
static const enum AVChannel ff_av3a_default_channel_layout_mc_5_1[6] ={
|
||||||
|
AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, AV_CHAN_FRONT_CENTER,
|
||||||
|
AV_CHAN_LOW_FREQUENCY,
|
||||||
|
AV_CHAN_SIDE_LEFT, AV_CHAN_SIDE_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
static const enum AVChannel ff_av3a_default_channel_layout_mc_5_1_2[8] ={
|
||||||
|
AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, AV_CHAN_FRONT_CENTER,
|
||||||
|
AV_CHAN_LOW_FREQUENCY,
|
||||||
|
AV_CHAN_SIDE_LEFT, AV_CHAN_SIDE_RIGHT,
|
||||||
|
AV_CHAN_TOP_SIDE_LEFT, AV_CHAN_TOP_SIDE_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
static const enum AVChannel ff_av3a_default_channel_layout_mc_7_1[8] ={
|
||||||
|
AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, AV_CHAN_FRONT_CENTER,
|
||||||
|
AV_CHAN_LOW_FREQUENCY,
|
||||||
|
AV_CHAN_SIDE_LEFT, AV_CHAN_SIDE_RIGHT,
|
||||||
|
AV_CHAN_BACK_LEFT, AV_CHAN_BACK_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
static const enum AVChannel ff_av3a_default_channel_layout_mc_5_1_4[10] ={
|
||||||
|
AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, AV_CHAN_FRONT_CENTER,
|
||||||
|
AV_CHAN_LOW_FREQUENCY,
|
||||||
|
AV_CHAN_SIDE_LEFT, AV_CHAN_SIDE_RIGHT,
|
||||||
|
AV_CHAN_TOP_FRONT_LEFT, AV_CHAN_TOP_FRONT_RIGHT,
|
||||||
|
AV_CHAN_TOP_BACK_LEFT, AV_CHAN_TOP_BACK_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
static const enum AVChannel ff_av3a_default_channel_layout_mc_7_1_2[10] ={
|
||||||
|
AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, AV_CHAN_FRONT_CENTER,
|
||||||
|
AV_CHAN_LOW_FREQUENCY,
|
||||||
|
AV_CHAN_SIDE_LEFT, AV_CHAN_SIDE_RIGHT,
|
||||||
|
AV_CHAN_BACK_LEFT, AV_CHAN_BACK_RIGHT,
|
||||||
|
AV_CHAN_TOP_SIDE_LEFT, AV_CHAN_TOP_SIDE_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
static const enum AVChannel ff_av3a_default_channel_layout_mc_7_1_4[12] ={
|
||||||
|
AV_CHAN_FRONT_LEFT, AV_CHAN_FRONT_RIGHT, AV_CHAN_FRONT_CENTER,
|
||||||
|
AV_CHAN_LOW_FREQUENCY,
|
||||||
|
AV_CHAN_SIDE_LEFT, AV_CHAN_SIDE_RIGHT,
|
||||||
|
AV_CHAN_BACK_LEFT, AV_CHAN_BACK_RIGHT,
|
||||||
|
AV_CHAN_TOP_FRONT_LEFT, AV_CHAN_TOP_FRONT_RIGHT,
|
||||||
|
AV_CHAN_TOP_BACK_LEFT, AV_CHAN_TOP_BACK_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Av3aChannelConfigMap ff_av3a_channels_map_table[AV3A_CHANNEL_LAYOUT_SIZE] = {
|
||||||
|
{ CHANNEL_CONFIG_MONO, 1, ff_av3a_default_channel_layout_mono , AV3A_CH_LAYOUT_MONO, },
|
||||||
|
{ CHANNEL_CONFIG_STEREO, 2, ff_av3a_default_channel_layout_stereo, AV3A_CH_LAYOUT_STEREO },
|
||||||
|
{ CHANNEL_CONFIG_MC_5_1, 6, ff_av3a_default_channel_layout_mc_5_1, AV3A_CH_LAYOUT_5POINT1 },
|
||||||
|
{ CHANNEL_CONFIG_MC_7_1, 8, ff_av3a_default_channel_layout_mc_7_1, AV3A_CH_LAYOUT_7POINT1 },
|
||||||
|
{ CHANNEL_CONFIG_MC_10_2, 12, NULL, 0L }, /* reserved */
|
||||||
|
{ CHANNEL_CONFIG_MC_22_2, 24, NULL, 0L }, /* reserved */
|
||||||
|
{ CHANNEL_CONFIG_MC_4_0, 4, ff_av3a_channel_layout_mc_4_0, AV3A_CH_LAYOUT_4POINT0 },
|
||||||
|
{ CHANNEL_CONFIG_MC_5_1_2, 8, ff_av3a_default_channel_layout_mc_5_1_2, AV3A_CH_LAYOUT_5POINT1POINT2 },
|
||||||
|
{ CHANNEL_CONFIG_MC_5_1_4, 10, ff_av3a_default_channel_layout_mc_5_1_4, AV3A_CH_LAYOUT_5POINT1POINT4 },
|
||||||
|
{ CHANNEL_CONFIG_MC_7_1_2, 10, ff_av3a_default_channel_layout_mc_7_1_2, AV3A_CH_LAYOUT_7POINT1POINT2 },
|
||||||
|
{ CHANNEL_CONFIG_MC_7_1_4, 12, ff_av3a_default_channel_layout_mc_7_1_4, AV3A_CH_LAYOUT_7POINT1POINT4 },
|
||||||
|
{ CHANNEL_CONFIG_HOA_ORDER1, 4, NULL, 0L },
|
||||||
|
{ CHANNEL_CONFIG_HOA_ORDER2, 9, NULL, 0L },
|
||||||
|
{ CHANNEL_CONFIG_HOA_ORDER3, 16, NULL, 0L },
|
||||||
|
{ CHANNEL_CONFIG_UNKNOWN, 0, NULL, 0L },
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
AV3AChannelConfig channel_number_index;
|
||||||
|
const int64_t *bitrate_table;
|
||||||
|
} Av3aBitrateMap;
|
||||||
|
|
||||||
|
static const Av3aBitrateMap ff_av3a_bitrate_map_table[15] = {
|
||||||
|
{CHANNEL_CONFIG_MONO, ff_av3a_mono_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_STEREO, ff_av3a_stereo_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_MC_5_1, ff_av3a_mc5p1_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_MC_7_1, ff_av3a_mc7p1_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_MC_10_2, NULL }, /* reserved */
|
||||||
|
{CHANNEL_CONFIG_MC_22_2, NULL }, /* reserved */
|
||||||
|
{CHANNEL_CONFIG_MC_4_0, ff_av3a_mc4p0_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_MC_5_1_2, ff_av3a_mc5p1p2_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_MC_5_1_4, ff_av3a_mc5p1p4_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_MC_7_1_2, ff_av3a_mc7p1p2_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_MC_7_1_4, ff_av3a_mc7p1p4_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_HOA_ORDER1, ff_av3a_foa_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_HOA_ORDER2, ff_av3a_hoa2_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_HOA_ORDER3, ff_av3a_hoa3_bitrate_table },
|
||||||
|
{CHANNEL_CONFIG_UNKNOWN, NULL },
|
||||||
|
};
|
||||||
|
#endif /* AVCODEC_AV3A_H */
|
@ -1,7 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* av3a parser
|
* AV3A Format Parser
|
||||||
*
|
|
||||||
* Copyright (c) 2018 James Almer <jamrial@gmail.com>
|
|
||||||
*
|
*
|
||||||
* This file is part of FFmpeg.
|
* This file is part of FFmpeg.
|
||||||
*
|
*
|
||||||
@ -27,478 +25,195 @@
|
|||||||
#include "libavutil/intreadwrite.h"
|
#include "libavutil/intreadwrite.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "get_bits.h"
|
#include "get_bits.h"
|
||||||
|
#include "av3a.h"
|
||||||
|
|
||||||
/* AVS3 header */
|
typedef struct{
|
||||||
#define AVS3_AUDIO_HEADER_SIZE 7
|
int16_t audio_codec_id;
|
||||||
#define AVS3_SYNC_WORD_SIZE 2
|
int16_t nn_type;
|
||||||
#define MAX_NBYTES_FRAME_HEADER 9
|
int16_t frame_size;
|
||||||
#define AVS3_AUDIO_SYNC_WORD 0xFFF
|
int16_t resolution;
|
||||||
|
|
||||||
#define AVS3_AUDIO_FRAME_SIZE 1024
|
|
||||||
#define AVS3_SIZE_BITRATE_TABLE 16
|
|
||||||
#define AVS3_SIZE_FS_TABLE 9
|
|
||||||
|
|
||||||
/* AVS3 Audio Format */
|
|
||||||
#define AVS3_MONO_FORMAT 0
|
|
||||||
#define AVS3_STEREO_FORMAT 1
|
|
||||||
#define AVS3_MC_FORMAT 2
|
|
||||||
#define AVS3_HOA_FORMAT 3
|
|
||||||
#define AVS3_MIX_FORMAT 4
|
|
||||||
|
|
||||||
#define AVS3_SIZE_MC_CONFIG_TABLE 10
|
|
||||||
|
|
||||||
#define AVS3P3_CH_LAYOUT_5POINT1 (AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)
|
|
||||||
|
|
||||||
typedef struct AVS3AudioParseContext {
|
|
||||||
int32_t frame_size;
|
|
||||||
int32_t bitdepth;
|
|
||||||
int32_t sample_rate;
|
int32_t sample_rate;
|
||||||
uint64_t bit_rate;
|
int64_t bit_rate;
|
||||||
uint16_t channels;
|
|
||||||
uint64_t channel_layout;
|
|
||||||
} AVS3AParseContext;
|
|
||||||
|
|
||||||
// AVS3P3 header information
|
int16_t content_type;
|
||||||
typedef struct {
|
int16_t channel_number_index;
|
||||||
// header info
|
int16_t nb_channels;
|
||||||
uint8_t codec_id;
|
int16_t nb_objects;
|
||||||
uint8_t sampling_rate_index;
|
int16_t total_channels;
|
||||||
int32_t sampling_rate;
|
} AV3AParseContext;
|
||||||
|
|
||||||
uint16_t bitdepth;
|
|
||||||
uint16_t channels;
|
|
||||||
uint16_t objects;
|
|
||||||
uint16_t hoa_order;
|
|
||||||
uint64_t channel_layout;
|
|
||||||
int64_t total_bitrate;
|
|
||||||
|
|
||||||
// configuration
|
static int ff_read_av3a_header_parse(GetBitContext *gb, AATFHeaderInfo* hdf)
|
||||||
uint8_t content_type;
|
{
|
||||||
uint16_t channel_num_index;
|
int64_t soundbed_bitrate, object_bitrate;
|
||||||
uint16_t total_channels;
|
|
||||||
uint8_t resolution;
|
|
||||||
uint8_t nn_type;
|
|
||||||
uint8_t resolution_index;
|
|
||||||
} AVS3AHeaderInfo;
|
|
||||||
|
|
||||||
typedef enum {
|
hdf->nb_channels = 0;
|
||||||
CHANNEL_CONFIG_MONO = 0,
|
hdf->nb_objects = 0;
|
||||||
CHANNEL_CONFIG_STEREO = 1,
|
|
||||||
CHANNEL_CONFIG_MC_5_1,
|
|
||||||
CHANNEL_CONFIG_MC_7_1,
|
|
||||||
CHANNEL_CONFIG_MC_10_2,
|
|
||||||
CHANNEL_CONFIG_MC_22_2,
|
|
||||||
CHANNEL_CONFIG_MC_4_0,
|
|
||||||
CHANNEL_CONFIG_MC_5_1_2,
|
|
||||||
CHANNEL_CONFIG_MC_5_1_4,
|
|
||||||
CHANNEL_CONFIG_MC_7_1_2,
|
|
||||||
CHANNEL_CONFIG_MC_7_1_4,
|
|
||||||
CHANNEL_CONFIG_HOA_ORDER1,
|
|
||||||
CHANNEL_CONFIG_HOA_ORDER2,
|
|
||||||
CHANNEL_CONFIG_HOA_ORDER3,
|
|
||||||
CHANNEL_CONFIG_UNKNOWN
|
|
||||||
} AVS3AChannelConfig;
|
|
||||||
|
|
||||||
/* Codec bitrate config struct */
|
hdf->sync_word = get_bits(gb, 12);
|
||||||
typedef struct CodecBitrateConfigStructure {
|
if (hdf->sync_word != AV3A_AUDIO_SYNC_WORD) {
|
||||||
AVS3AChannelConfig channelNumConfig;
|
|
||||||
const int64_t *bitrateTable;
|
|
||||||
} CodecBitrateConfig;
|
|
||||||
|
|
||||||
typedef struct McChannelConfigStructure {
|
|
||||||
const char mcCmdString[10];
|
|
||||||
AVS3AChannelConfig channelNumConfig;
|
|
||||||
const int16_t numChannels;
|
|
||||||
} McChanelConfig;
|
|
||||||
|
|
||||||
static const McChanelConfig mcChannelConfigTable[AVS3_SIZE_MC_CONFIG_TABLE] = {
|
|
||||||
{"STEREO", CHANNEL_CONFIG_STEREO, 2},
|
|
||||||
{"MC_5_1_0", CHANNEL_CONFIG_MC_5_1, 6},
|
|
||||||
{"MC_7_1_0", CHANNEL_CONFIG_MC_7_1, 8},
|
|
||||||
{"MC_10_2", CHANNEL_CONFIG_MC_10_2, 12},
|
|
||||||
{"MC_22_2", CHANNEL_CONFIG_MC_22_2, 24},
|
|
||||||
{"MC_4_0", CHANNEL_CONFIG_MC_4_0, 4},
|
|
||||||
{"MC_5_1_2", CHANNEL_CONFIG_MC_5_1_2, 8},
|
|
||||||
{"MC_5_1_4", CHANNEL_CONFIG_MC_5_1_4, 10},
|
|
||||||
{"MC_7_1_2", CHANNEL_CONFIG_MC_7_1_2, 10},
|
|
||||||
{"MC_7_1_4", CHANNEL_CONFIG_MC_7_1_4, 12}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int32_t avs3_samplingrate_table[AVS3_SIZE_FS_TABLE] = {
|
|
||||||
192000, 96000, 48000, 44100, 32000, 24000, 22050, 16000, 8000
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for mono
|
|
||||||
static const int64_t bitrateTableMono[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
16000, 32000, 44000, 56000, 64000, 72000, 80000, 96000, 128000, 144000, 164000, 192000, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for stereo
|
|
||||||
static const int64_t bitrateTableStereo[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
24000, 32000, 48000, 64000, 80000, 96000, 128000, 144000, 192000, 256000, 320000, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for MC 5.1
|
|
||||||
static const int64_t bitrateTableMC5P1[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
192000, 256000, 320000, 384000, 448000, 512000, 640000, 720000, 144000, 96000, 128000, 160000, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for MC 7.1
|
|
||||||
static const int64_t bitrateTableMC7P1[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
192000, 480000, 256000, 384000, 576000, 640000, 128000, 160000, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for MC 4.0
|
|
||||||
static const int64_t bitrateTableMC4P0[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
48000, 96000, 128000, 192000, 256000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for MC 5.1.2
|
|
||||||
static const int64_t bitrateTableMC5P1P2[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
152000, 320000, 480000, 576000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for MC 5.1.4
|
|
||||||
static const int64_t bitrateTableMC5P1P4[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
176000, 384000, 576000, 704000, 256000, 448000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for MC 7.1.2
|
|
||||||
static const int64_t bitrateTableMC7P1P2[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
216000, 480000, 576000, 384000, 768000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for MC 7.1.4
|
|
||||||
static const int64_t bitrateTableMC7P1P4[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
240000, 608000, 384000, 512000, 832000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int64_t bitrateTableFoa[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
48000, 96000, 128000, 192000, 256000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int64_t bitrateTableHoa2[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
192000, 256000, 320000, 384000, 480000, 512000, 640000, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// bitrate table for HOA order 3
|
|
||||||
static const int64_t bitrateTableHoa3[AVS3_SIZE_BITRATE_TABLE] = {
|
|
||||||
256000, 320000, 384000, 512000, 640000, 896000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// Codec channel number & bitrate config table
|
|
||||||
// format: {channelConfigIdx, numChannels, bitrateTable}
|
|
||||||
static const CodecBitrateConfig codecBitrateConfigTable[CHANNEL_CONFIG_UNKNOWN] = {
|
|
||||||
{CHANNEL_CONFIG_MONO, bitrateTableMono},
|
|
||||||
{CHANNEL_CONFIG_STEREO, bitrateTableStereo},
|
|
||||||
{CHANNEL_CONFIG_MC_5_1, bitrateTableMC5P1},
|
|
||||||
{CHANNEL_CONFIG_MC_7_1, bitrateTableMC7P1},
|
|
||||||
{CHANNEL_CONFIG_MC_10_2, NULL},
|
|
||||||
{CHANNEL_CONFIG_MC_22_2, NULL},
|
|
||||||
{CHANNEL_CONFIG_MC_4_0, bitrateTableMC4P0},
|
|
||||||
{CHANNEL_CONFIG_MC_5_1_2, bitrateTableMC5P1P2},
|
|
||||||
{CHANNEL_CONFIG_MC_5_1_4, bitrateTableMC5P1P4},
|
|
||||||
{CHANNEL_CONFIG_MC_7_1_2, bitrateTableMC7P1P2},
|
|
||||||
{CHANNEL_CONFIG_MC_7_1_4, bitrateTableMC7P1P4},
|
|
||||||
{CHANNEL_CONFIG_HOA_ORDER1, bitrateTableFoa},
|
|
||||||
{CHANNEL_CONFIG_HOA_ORDER2, bitrateTableHoa2},
|
|
||||||
{CHANNEL_CONFIG_HOA_ORDER3, bitrateTableHoa3}
|
|
||||||
};
|
|
||||||
|
|
||||||
static int read_av3a_frame_header(AVS3AHeaderInfo *hdf, const uint8_t *buf, const int32_t byte_size)
|
|
||||||
{
|
|
||||||
GetBitContext gb;
|
|
||||||
AVS3AChannelConfig channel_config = CHANNEL_CONFIG_UNKNOWN;
|
|
||||||
|
|
||||||
uint8_t content_type = 0;
|
|
||||||
uint8_t hoa_order = 0;
|
|
||||||
uint8_t bitdepth = 0;
|
|
||||||
uint8_t resolution = 0;
|
|
||||||
|
|
||||||
int16_t channels = 0;
|
|
||||||
int16_t objects = 0;
|
|
||||||
uint64_t channel_layout = 0;
|
|
||||||
|
|
||||||
int64_t bitrate_per_obj = 0;
|
|
||||||
int64_t bitrate_bed_mc = 0;
|
|
||||||
int64_t total_bitrate = 0;
|
|
||||||
|
|
||||||
uint8_t num_chan_index = 0;
|
|
||||||
uint8_t obj_brt_idx = 0;
|
|
||||||
uint8_t bed_brt_idx = 0;
|
|
||||||
uint8_t brt_idx = 0;
|
|
||||||
|
|
||||||
// Read max header length into bs buffer
|
|
||||||
init_get_bits8(&gb, buf, MAX_NBYTES_FRAME_HEADER);
|
|
||||||
|
|
||||||
// 12 bits for frame sync word
|
|
||||||
if (get_bits(&gb, 12) != AVS3_AUDIO_SYNC_WORD) {
|
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4 bits for codec id
|
hdf->audio_codec_id = get_bits(gb, 4);
|
||||||
uint8_t codec_id = get_bits(&gb, 4);
|
if (hdf->audio_codec_id != 2) {
|
||||||
if (codec_id != 2) {
|
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 bits for anc data
|
hdf->anc_data = get_bits(gb, 1);
|
||||||
if (get_bits(&gb, 1) != 0) {
|
if (hdf->anc_data != 0) {
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3 bits nn type
|
hdf->nn_type = get_bits(gb, 3);
|
||||||
uint8_t nn_type = get_bits(&gb, 3);
|
hdf->coding_profile = get_bits(gb, 3);
|
||||||
|
|
||||||
// 3 bits for coding profile
|
hdf->sampling_frequency_index = get_bits(gb, 4);
|
||||||
uint8_t coding_profile = get_bits(&gb, 3);
|
if (hdf->sampling_frequency_index >= AV3A_SIZE_FS_TABLE) {
|
||||||
|
|
||||||
// 4 bits for sampling index
|
|
||||||
uint8_t samping_rate_index = get_bits(&gb, 4);
|
|
||||||
if (samping_rate_index >= AVS3_SIZE_FS_TABLE) {
|
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
hdf->sampling_rate = ff_av3a_sampling_rate_table[hdf->sampling_frequency_index];
|
||||||
|
|
||||||
// skip 8 bits for CRC first part
|
skip_bits(gb, 8);
|
||||||
skip_bits(&gb, 8);
|
|
||||||
|
|
||||||
if (coding_profile == 0) {
|
if (hdf->coding_profile == 0) {
|
||||||
content_type = 0;
|
hdf->content_type = 0; /* channel-based */
|
||||||
|
hdf->channel_number_index = get_bits(gb, 7);
|
||||||
// 7 bits for mono/stereo/MC
|
if ((hdf->channel_number_index >= CHANNEL_CONFIG_UNKNOWN) ||
|
||||||
num_chan_index = get_bits(&gb, 7);
|
(hdf->channel_number_index == CHANNEL_CONFIG_MC_10_2) ||
|
||||||
if (num_chan_index >= CHANNEL_CONFIG_UNKNOWN) {
|
(hdf->channel_number_index == CHANNEL_CONFIG_MC_22_2)) {
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
hdf->nb_channels = ff_av3a_channels_map_table[hdf->channel_number_index].channels;
|
||||||
|
} else if (hdf->coding_profile == 1) {
|
||||||
|
hdf->soundBedType = get_bits(gb, 2);
|
||||||
|
if (hdf->soundBedType == 0) {
|
||||||
|
hdf->content_type = 1; /* objects-based */
|
||||||
|
hdf->object_channel_number = get_bits(gb, 7);
|
||||||
|
hdf->nb_objects = hdf->object_channel_number + 1;
|
||||||
|
|
||||||
channel_config = (AVS3AChannelConfig)num_chan_index;
|
hdf->bitrate_index_per_channel = get_bits(gb, 4);
|
||||||
switch (channel_config) {
|
if (hdf->bitrate_index_per_channel < 0 ) {
|
||||||
case CHANNEL_CONFIG_MONO:
|
return AVERROR_INVALIDDATA;
|
||||||
channels = 1;
|
}
|
||||||
channel_layout = AV_CH_LAYOUT_MONO;
|
object_bitrate = ff_av3a_bitrate_map_table[CHANNEL_CONFIG_MONO].bitrate_table[hdf->bitrate_index_per_channel];
|
||||||
break;
|
hdf->total_bitrate = object_bitrate * hdf->nb_objects;
|
||||||
case CHANNEL_CONFIG_STEREO:
|
} else if (hdf->soundBedType == 1) {
|
||||||
channels = 2;
|
hdf->content_type = 2; /* channel-based + objects */
|
||||||
channel_layout = AV_CH_LAYOUT_STEREO;
|
hdf->channel_number_index = get_bits(gb, 7);
|
||||||
break;
|
if ((hdf->channel_number_index >= CHANNEL_CONFIG_UNKNOWN) ||
|
||||||
case CHANNEL_CONFIG_MC_4_0:
|
(hdf->channel_number_index == CHANNEL_CONFIG_MC_10_2) ||
|
||||||
channels = 4;
|
(hdf->channel_number_index == CHANNEL_CONFIG_MC_22_2)) {
|
||||||
break;
|
|
||||||
case CHANNEL_CONFIG_MC_5_1:
|
|
||||||
channels = 6;
|
|
||||||
channel_layout = AVS3P3_CH_LAYOUT_5POINT1;
|
|
||||||
break;
|
|
||||||
case CHANNEL_CONFIG_MC_7_1:
|
|
||||||
channels = 8;
|
|
||||||
channel_layout = AV_CH_LAYOUT_7POINT1;
|
|
||||||
break;
|
|
||||||
case CHANNEL_CONFIG_MC_5_1_2:
|
|
||||||
channels = 8;
|
|
||||||
break;
|
|
||||||
case CHANNEL_CONFIG_MC_5_1_4:
|
|
||||||
channels = 10;
|
|
||||||
break;
|
|
||||||
case CHANNEL_CONFIG_MC_7_1_2:
|
|
||||||
channels = 10;
|
|
||||||
break;
|
|
||||||
case CHANNEL_CONFIG_MC_7_1_4:
|
|
||||||
channels = 12;
|
|
||||||
break;
|
|
||||||
case CHANNEL_CONFIG_MC_22_2:
|
|
||||||
channels = 24;
|
|
||||||
channel_layout = AV_CH_LAYOUT_22POINT2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (coding_profile == 1) {
|
|
||||||
// sound bed type, 2bits
|
|
||||||
uint8_t soundBedType = get_bits(&gb, 2);
|
|
||||||
|
|
||||||
if (soundBedType == 0) {
|
|
||||||
content_type = 1;
|
|
||||||
|
|
||||||
// for only objects
|
|
||||||
// object number, 7 bits
|
|
||||||
objects = get_bits(&gb, 7);
|
|
||||||
objects += 1;
|
|
||||||
|
|
||||||
// bitrate index for each obj, 4 bits
|
|
||||||
obj_brt_idx = get_bits(&gb, 4);
|
|
||||||
|
|
||||||
total_bitrate = codecBitrateConfigTable[CHANNEL_CONFIG_MONO].bitrateTable[obj_brt_idx] * objects;
|
|
||||||
} else if (soundBedType == 1) {
|
|
||||||
content_type = 2;
|
|
||||||
|
|
||||||
// for MC + objs
|
|
||||||
// channel number index, 7 bits
|
|
||||||
num_chan_index = get_bits(&gb, 7);
|
|
||||||
if (num_chan_index >= CHANNEL_CONFIG_UNKNOWN) {
|
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bitrate index for sound bed, 4 bits
|
hdf->bitrate_index = get_bits(gb, 4);
|
||||||
bed_brt_idx = get_bits(&gb, 4);
|
if (hdf->bitrate_index < 0 ) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
// object number, 7 bits
|
|
||||||
objects = get_bits(&gb, 7);
|
|
||||||
objects += 1;
|
|
||||||
|
|
||||||
// bitrate index for each obj, 4 bits
|
|
||||||
obj_brt_idx = get_bits(&gb, 4);
|
|
||||||
|
|
||||||
// channelNumIdx for sound bed
|
|
||||||
channel_config = (AVS3AChannelConfig)num_chan_index;
|
|
||||||
|
|
||||||
// sound bed bitrate
|
|
||||||
bitrate_bed_mc = codecBitrateConfigTable[channel_config].bitrateTable[bed_brt_idx];
|
|
||||||
|
|
||||||
// numChannels for sound bed
|
|
||||||
for (int16_t i = 0; i < AVS3_SIZE_MC_CONFIG_TABLE; i++) {
|
|
||||||
if (channel_config == mcChannelConfigTable[i].channelNumConfig) {
|
|
||||||
channels = mcChannelConfigTable[i].numChannels;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
hdf->nb_channels = ff_av3a_channels_map_table[hdf->channel_number_index].channels;
|
||||||
|
soundbed_bitrate = ff_av3a_bitrate_map_table[hdf->channel_number_index].bitrate_table[hdf->bitrate_index];
|
||||||
|
|
||||||
// bitrate per obj
|
hdf->object_channel_number = get_bits(gb, 7);
|
||||||
bitrate_per_obj = codecBitrateConfigTable[CHANNEL_CONFIG_MONO].bitrateTable[obj_brt_idx];
|
hdf->bitrate_index_per_channel = get_bits(gb, 4);
|
||||||
|
if (hdf->bitrate_index_per_channel < 0 ) {
|
||||||
// add num chans and num objs to get total chans
|
return AVERROR_INVALIDDATA;
|
||||||
/* channels += objects; */
|
}
|
||||||
|
hdf->nb_objects = hdf->object_channel_number + 1;
|
||||||
total_bitrate = bitrate_bed_mc + bitrate_per_obj * objects;
|
object_bitrate = ff_av3a_bitrate_map_table[CHANNEL_CONFIG_MONO].bitrate_table[hdf->bitrate_index_per_channel];
|
||||||
}
|
hdf->total_bitrate = soundbed_bitrate + (object_bitrate * hdf->nb_objects);
|
||||||
} else if (coding_profile == 2) {
|
} else {
|
||||||
content_type = 3;
|
|
||||||
|
|
||||||
// 4 bits for HOA order
|
|
||||||
hoa_order = get_bits(&gb, 4);
|
|
||||||
hoa_order += 1;
|
|
||||||
|
|
||||||
switch (hoa_order) {
|
|
||||||
case 1:
|
|
||||||
channels = 4;
|
|
||||||
channel_config = CHANNEL_CONFIG_HOA_ORDER1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
channels = 9;
|
|
||||||
channel_config = CHANNEL_CONFIG_HOA_ORDER2;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
channels = 16;
|
|
||||||
channel_config = CHANNEL_CONFIG_HOA_ORDER3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2 bits for bit depth
|
|
||||||
uint8_t resolution_index = get_bits(&gb, 2);
|
|
||||||
switch (resolution_index) {
|
|
||||||
case 0:
|
|
||||||
bitdepth = AV_SAMPLE_FMT_U8;
|
|
||||||
resolution = 8;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
bitdepth = AV_SAMPLE_FMT_S16;
|
|
||||||
resolution = 16;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
resolution = 24;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
} else if (hdf->coding_profile == 2) {
|
||||||
|
hdf->content_type = 3; /* ambisonics */
|
||||||
|
hdf->order = get_bits(gb, 4);
|
||||||
|
hdf->hoa_order += 1;
|
||||||
|
|
||||||
if (coding_profile != 1) {
|
if (hdf->hoa_order == 1) {
|
||||||
// 4 bits for bitrate index
|
hdf->channel_number_index = CHANNEL_CONFIG_HOA_ORDER1;
|
||||||
brt_idx = get_bits(&gb, 4);
|
} else if (hdf->hoa_order == 2) {
|
||||||
total_bitrate = codecBitrateConfigTable[channel_config].bitrateTable[brt_idx];
|
hdf->channel_number_index = CHANNEL_CONFIG_HOA_ORDER2;
|
||||||
}
|
} else if (hdf->hoa_order == 3) {
|
||||||
|
hdf->channel_number_index = CHANNEL_CONFIG_HOA_ORDER3;
|
||||||
// 8 bits for CRC second part
|
} else {
|
||||||
skip_bits(&gb, 8);
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
/* AVS3P6 M6954-v3 */
|
hdf->nb_channels = (hdf->hoa_order + 1) * (hdf->hoa_order + 1);
|
||||||
hdf->codec_id = codec_id;
|
|
||||||
hdf->sampling_rate_index = samping_rate_index;
|
|
||||||
hdf->sampling_rate = avs3_samplingrate_table[samping_rate_index];
|
|
||||||
hdf->bitdepth = bitdepth;
|
|
||||||
|
|
||||||
hdf->nn_type = nn_type;
|
|
||||||
hdf->content_type = content_type;
|
|
||||||
|
|
||||||
if (hdf->content_type == 0) {
|
|
||||||
hdf->channel_num_index = num_chan_index;
|
|
||||||
hdf->channels = channels;
|
|
||||||
hdf->objects = 0;
|
|
||||||
hdf->total_channels = channels;
|
|
||||||
hdf->channel_layout = channel_layout;
|
|
||||||
} else if (hdf->content_type == 1) {
|
|
||||||
hdf->objects = objects;
|
|
||||||
hdf->channels = 0;
|
|
||||||
hdf->total_channels = objects;
|
|
||||||
} else if (hdf->content_type == 2) {
|
|
||||||
hdf->channel_num_index = num_chan_index;
|
|
||||||
hdf->channels = channels;
|
|
||||||
hdf->objects = objects;
|
|
||||||
hdf->total_channels = channels + objects;
|
|
||||||
hdf->channel_layout = channel_layout;
|
|
||||||
} else if (hdf->content_type == 3) {
|
|
||||||
hdf->hoa_order = hoa_order;
|
|
||||||
hdf->channels = channels;
|
|
||||||
hdf->total_channels = channels;
|
|
||||||
} else {
|
} else {
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdf->total_bitrate = total_bitrate;
|
hdf->total_channels = hdf->nb_channels + hdf->nb_objects;
|
||||||
hdf->resolution = resolution;
|
|
||||||
hdf->resolution_index = resolution_index;
|
hdf->resolution_index = get_bits(gb, 2);
|
||||||
|
if(hdf->resolution_index >= AV3A_SIZE_RESOLUTION_TABLE) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
hdf->resolution = ff_av3a_sample_format_map_table[hdf->resolution_index].resolution;
|
||||||
|
hdf->sample_format = ff_av3a_sample_format_map_table[hdf->resolution_index].sample_format;
|
||||||
|
|
||||||
|
if (hdf->coding_profile != 1) {
|
||||||
|
hdf->bitrate_index = get_bits(gb, 4);
|
||||||
|
if (hdf->bitrate_index < 0) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
hdf->total_bitrate = ff_av3a_bitrate_map_table[hdf->channel_number_index].bitrate_table[hdf->bitrate_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_bits(gb, 8);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t raw_av3a_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf,
|
static int raw_av3a_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf,
|
||||||
int32_t *poutbuf_size, const uint8_t *buf, int32_t buf_size)
|
int32_t *poutbuf_size, const uint8_t *buf, int32_t buf_size)
|
||||||
{
|
{
|
||||||
uint8_t header[MAX_NBYTES_FRAME_HEADER];
|
int ret = 0;
|
||||||
AVS3AHeaderInfo hdf;
|
uint8_t header[AV3A_MAX_NBYTES_HEADER];
|
||||||
hdf.channel_layout = 0;
|
AATFHeaderInfo hdf;
|
||||||
|
GetBitContext gb;
|
||||||
|
AV3AParseContext *s1 = s->priv_data;
|
||||||
|
|
||||||
if (buf_size < MAX_NBYTES_FRAME_HEADER) {
|
if (buf_size < AV3A_MAX_NBYTES_HEADER) {
|
||||||
return buf_size;
|
return buf_size;
|
||||||
}
|
}
|
||||||
|
memcpy(header, buf, AV3A_MAX_NBYTES_HEADER);
|
||||||
|
|
||||||
memcpy(header, buf, MAX_NBYTES_FRAME_HEADER);
|
init_get_bits8(&gb, buf, AV3A_MAX_NBYTES_HEADER);
|
||||||
|
if ((ret = ff_read_av3a_header_parse(&gb, &hdf)) != 0) {
|
||||||
// read frame header
|
|
||||||
int32_t ret = read_av3a_frame_header(&hdf, header, MAX_NBYTES_FRAME_HEADER);
|
|
||||||
if (ret != 0) {
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx->sample_rate = hdf.sampling_rate;
|
s1->audio_codec_id = hdf.audio_codec_id;
|
||||||
avctx->bit_rate = hdf.total_bitrate;
|
s1->nn_type = hdf.nn_type;
|
||||||
avctx->channels = hdf.total_channels;
|
s1->frame_size = AV3A_AUDIO_FRAME_SIZE;
|
||||||
avctx->channel_layout = hdf.channel_layout;
|
s1->resolution = hdf.resolution;
|
||||||
avctx->frame_size = AVS3_AUDIO_FRAME_SIZE;
|
s1->sample_rate = hdf.sampling_rate;
|
||||||
s->format = hdf.bitdepth;
|
s1->bit_rate = hdf.total_bitrate;
|
||||||
|
s1->content_type = hdf.content_type;
|
||||||
|
s1->nb_channels = hdf.nb_channels;
|
||||||
|
s1->nb_objects = hdf.nb_objects;
|
||||||
|
s1->total_channels = hdf.total_channels;
|
||||||
|
s1->channel_number_index = hdf.channel_number_index;
|
||||||
|
|
||||||
|
avctx->codec_id = AV_CODEC_ID_AVS3DA;
|
||||||
|
avctx->frame_size = AV3A_AUDIO_FRAME_SIZE;
|
||||||
|
avctx->bits_per_raw_sample = hdf.resolution;
|
||||||
|
avctx->sample_rate = hdf.sampling_rate;
|
||||||
|
avctx->bit_rate = hdf.total_bitrate;
|
||||||
|
|
||||||
|
avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
|
||||||
|
avctx->ch_layout.nb_channels = hdf.total_channels;
|
||||||
|
|
||||||
/* return the full packet */
|
|
||||||
*poutbuf = buf;
|
*poutbuf = buf;
|
||||||
*poutbuf_size = buf_size;
|
*poutbuf_size = buf_size;
|
||||||
|
|
||||||
return buf_size;
|
return buf_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_AV3A_PARSER
|
|
||||||
const AVCodecParser ff_av3a_parser = {
|
const AVCodecParser ff_av3a_parser = {
|
||||||
.codec_ids = { AV_CODEC_ID_AVS3DA },
|
.codec_ids = { AV_CODEC_ID_AVS3DA },
|
||||||
.priv_data_size = sizeof(AVS3AParseContext),
|
.priv_data_size = sizeof(AV3AParseContext),
|
||||||
.parser_parse = raw_av3a_parse,
|
.parser_parse = raw_av3a_parse,
|
||||||
};
|
};
|
||||||
#endif
|
|
@ -3242,8 +3242,8 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
|||||||
{
|
{
|
||||||
.id = AV_CODEC_ID_AVS3DA,
|
.id = AV_CODEC_ID_AVS3DA,
|
||||||
.type = AVMEDIA_TYPE_AUDIO,
|
.type = AVMEDIA_TYPE_AUDIO,
|
||||||
.name = "avs_3da",
|
.name = "av3a",
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("AVS3 Audio"),
|
.long_name = NULL_IF_CONFIG_SMALL("Audio Vivid"),
|
||||||
.props = AV_CODEC_PROP_LOSSY,
|
.props = AV_CODEC_PROP_LOSSY,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -647,7 +647,7 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba,
|
|||||||
case AV_CODEC_ID_MP2:
|
case AV_CODEC_ID_MP2:
|
||||||
case AV_CODEC_ID_MUSEPACK7: return 1152;
|
case AV_CODEC_ID_MUSEPACK7: return 1152;
|
||||||
case AV_CODEC_ID_AC3: return 1536;
|
case AV_CODEC_ID_AC3: return 1536;
|
||||||
case AV_CODEC_ID_AVS3DA: return 1024; // avs3p3/audio vivid fixed frame size
|
case AV_CODEC_ID_AVS3DA: return 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sr > 0) {
|
if (sr > 0) {
|
||||||
|
@ -131,6 +131,8 @@ OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o
|
|||||||
OBJS-$(CONFIG_AVI_MUXER) += avienc.o mpegtsenc.o avlanguage.o rawutils.o
|
OBJS-$(CONFIG_AVI_MUXER) += avienc.o mpegtsenc.o avlanguage.o rawutils.o
|
||||||
OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o swf.o
|
OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o swf.o
|
||||||
OBJS-$(CONFIG_AVR_DEMUXER) += avr.o pcm.o
|
OBJS-$(CONFIG_AVR_DEMUXER) += avr.o pcm.o
|
||||||
|
OBJS-$(CONFIG_AV3A_MUXER) += rawenc.o
|
||||||
|
OBJS-$(CONFIG_AV3A_DEMUXER) += av3adec.o
|
||||||
OBJS-$(CONFIG_AVS_DEMUXER) += avs.o voc_packet.o voc.o
|
OBJS-$(CONFIG_AVS_DEMUXER) += avs.o voc_packet.o voc.o
|
||||||
OBJS-$(CONFIG_AVS2_DEMUXER) += avs2dec.o rawdec.o
|
OBJS-$(CONFIG_AVS2_DEMUXER) += avs2dec.o rawdec.o
|
||||||
OBJS-$(CONFIG_AVS2_MUXER) += rawenc.o
|
OBJS-$(CONFIG_AVS2_MUXER) += rawenc.o
|
||||||
|
@ -79,6 +79,8 @@ extern const AVOutputFormat ff_asf_stream_muxer;
|
|||||||
extern const AVInputFormat ff_au_demuxer;
|
extern const AVInputFormat ff_au_demuxer;
|
||||||
extern const AVOutputFormat ff_au_muxer;
|
extern const AVOutputFormat ff_au_muxer;
|
||||||
extern const AVInputFormat ff_av1_demuxer;
|
extern const AVInputFormat ff_av1_demuxer;
|
||||||
|
extern const AVOutputFormat ff_av3a_muxer;
|
||||||
|
extern const AVInputFormat ff_av3a_demuxer;
|
||||||
extern const AVInputFormat ff_avi_demuxer;
|
extern const AVInputFormat ff_avi_demuxer;
|
||||||
extern const AVOutputFormat ff_avi_muxer;
|
extern const AVOutputFormat ff_avi_muxer;
|
||||||
extern const AVOutputFormat ff_avif_muxer;
|
extern const AVOutputFormat ff_avif_muxer;
|
||||||
|
418
libavformat/av3adec.c
Normal file
418
libavformat/av3adec.c
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
/*
|
||||||
|
* Audio Vivid Demuxer
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#include "avformat.h"
|
||||||
|
#include "avio_internal.h"
|
||||||
|
#include "internal.h"
|
||||||
|
#include "rawdec.h"
|
||||||
|
#include "libavutil/opt.h"
|
||||||
|
#include "libavutil/avassert.h"
|
||||||
|
#include "libavutil/intreadwrite.h"
|
||||||
|
#include "libavutil/channel_layout.h"
|
||||||
|
#include "libavcodec/get_bits.h"
|
||||||
|
#include "libavcodec/av3a.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t audio_codec_id;
|
||||||
|
uint8_t sampling_frequency_index;
|
||||||
|
uint8_t nn_type;
|
||||||
|
uint8_t content_type;
|
||||||
|
uint8_t channel_number_index;
|
||||||
|
uint8_t number_objects;
|
||||||
|
uint8_t hoa_order;
|
||||||
|
uint8_t resolution_index;
|
||||||
|
uint16_t total_bitrate_kbps;
|
||||||
|
} Av3aFormatContext;
|
||||||
|
|
||||||
|
static int av3a_read_aatf_frame_header(AATFHeaderInfo *hdf, const uint8_t *buf)
|
||||||
|
{
|
||||||
|
int16_t sync_word;
|
||||||
|
GetBitContext gb;
|
||||||
|
|
||||||
|
hdf->nb_channels = 0;
|
||||||
|
hdf->nb_objects = 0;
|
||||||
|
|
||||||
|
init_get_bits8(&gb, buf, AV3A_MAX_NBYTES_HEADER);
|
||||||
|
|
||||||
|
sync_word = get_bits(&gb, 12);
|
||||||
|
if (sync_word != AV3A_AUDIO_SYNC_WORD) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* codec id */
|
||||||
|
hdf->audio_codec_id = get_bits(&gb, 4);
|
||||||
|
if (hdf->audio_codec_id != 2) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* anc data */
|
||||||
|
hdf->anc_data = get_bits(&gb, 1);
|
||||||
|
if (hdf->audio_codec_id == 2 && hdf->anc_data) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdf->nn_type = get_bits(&gb, 3);
|
||||||
|
if (hdf->audio_codec_id == 2 && (hdf->nn_type != 0 && hdf->nn_type != 1)) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdf->coding_profile = get_bits(&gb, 3);
|
||||||
|
|
||||||
|
/* sampling rate */
|
||||||
|
hdf->sampling_frequency_index = get_bits(&gb, 4);
|
||||||
|
if (hdf->sampling_frequency_index >= AV3A_SIZE_FS_TABLE) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
hdf->sampling_rate = ff_av3a_sampling_rate_table[hdf->sampling_frequency_index];
|
||||||
|
|
||||||
|
skip_bits(&gb, 8);
|
||||||
|
|
||||||
|
if (hdf->coding_profile == 0) {
|
||||||
|
hdf->content_type = 0;
|
||||||
|
hdf->channel_number_index = get_bits(&gb, 7);
|
||||||
|
if ((hdf->channel_number_index >= CHANNEL_CONFIG_UNKNOWN) ||
|
||||||
|
(hdf->channel_number_index == CHANNEL_CONFIG_MC_10_2) ||
|
||||||
|
(hdf->channel_number_index == CHANNEL_CONFIG_MC_22_2)) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
hdf->nb_channels = ff_av3a_channels_map_table[hdf->channel_number_index].channels;
|
||||||
|
} else if (hdf->coding_profile == 1) {
|
||||||
|
hdf->soundBedType = get_bits(&gb, 2);
|
||||||
|
if (hdf->soundBedType == 0) {
|
||||||
|
hdf->content_type = 1;
|
||||||
|
hdf->object_channel_number = get_bits(&gb, 7);
|
||||||
|
hdf->bitrate_index_per_channel = get_bits(&gb, 4);
|
||||||
|
if (hdf->bitrate_index_per_channel < 0){
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
hdf->nb_objects = hdf->object_channel_number + 1;
|
||||||
|
hdf->total_bitrate = ff_av3a_bitrate_map_table[CHANNEL_CONFIG_MONO].bitrate_table[hdf->bitrate_index_per_channel] * hdf->nb_objects;
|
||||||
|
} else if (hdf->soundBedType == 1) {
|
||||||
|
hdf->content_type = 2;
|
||||||
|
hdf->channel_number_index = get_bits(&gb, 7);
|
||||||
|
if ((hdf->channel_number_index >= CHANNEL_CONFIG_UNKNOWN) ||
|
||||||
|
(hdf->channel_number_index == CHANNEL_CONFIG_MC_10_2) ||
|
||||||
|
(hdf->channel_number_index == CHANNEL_CONFIG_MC_22_2)) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
hdf->nb_channels = ff_av3a_channels_map_table[hdf->channel_number_index].channels;
|
||||||
|
hdf->bitrate_index = get_bits(&gb, 4);
|
||||||
|
if (hdf->bitrate_index < 0) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdf->object_channel_number = get_bits(&gb, 7);
|
||||||
|
hdf->nb_objects = hdf->object_channel_number + 1;
|
||||||
|
hdf->bitrate_index_per_channel = get_bits(&gb, 4);
|
||||||
|
if (hdf->bitrate_index_per_channel < 0) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdf->total_bitrate = ff_av3a_bitrate_map_table[hdf->channel_number_index].bitrate_table[hdf->bitrate_index] +
|
||||||
|
ff_av3a_bitrate_map_table[CHANNEL_CONFIG_MONO].bitrate_table[hdf->bitrate_index_per_channel] * hdf->nb_objects;
|
||||||
|
} else {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
} else if (hdf->coding_profile == 2) {
|
||||||
|
/* FOA/HOA */
|
||||||
|
hdf->content_type = 3;
|
||||||
|
hdf->order = get_bits(&gb, 4);
|
||||||
|
hdf->hoa_order = hdf->order + 1;
|
||||||
|
hdf->nb_channels = (hdf->hoa_order + 1) * (hdf->hoa_order + 1);
|
||||||
|
|
||||||
|
if (hdf->hoa_order == 1) {
|
||||||
|
hdf->channel_number_index = CHANNEL_CONFIG_HOA_ORDER1;
|
||||||
|
} else if (hdf->hoa_order == 2) {
|
||||||
|
hdf->channel_number_index = CHANNEL_CONFIG_HOA_ORDER2;
|
||||||
|
} else if (hdf->hoa_order == 3) {
|
||||||
|
hdf->channel_number_index = CHANNEL_CONFIG_HOA_ORDER3;
|
||||||
|
} else {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdf->total_channels = hdf->nb_channels + hdf->nb_objects;
|
||||||
|
|
||||||
|
hdf->resolution_index = get_bits(&gb, 2);
|
||||||
|
if(hdf->resolution_index >= AV3A_SIZE_RESOLUTION_TABLE) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdf->resolution = ff_av3a_sample_format_map_table[hdf->resolution_index].resolution;
|
||||||
|
hdf->sample_format = ff_av3a_sample_format_map_table[hdf->resolution_index].sample_format;
|
||||||
|
|
||||||
|
if (hdf->coding_profile != 1) {
|
||||||
|
hdf->bitrate_index = get_bits(&gb, 4);
|
||||||
|
if (hdf->bitrate_index < 0){
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
hdf->total_bitrate = ff_av3a_bitrate_map_table[hdf->channel_number_index].bitrate_table[hdf->bitrate_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_bits(&gb, 8);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int av3a_get_packet_size(AVFormatContext *s)
|
||||||
|
{
|
||||||
|
int read_bytes = 0;
|
||||||
|
uint16_t sync_word = 0;
|
||||||
|
uint8_t header[AV3A_MAX_NBYTES_HEADER];
|
||||||
|
GetBitContext gb;
|
||||||
|
int32_t sampling_rate;
|
||||||
|
int16_t coding_profile, sampling_frequency_index, bitrate_index, channel_number_index, object_bitrate_index;
|
||||||
|
int16_t objects, hoa_order;
|
||||||
|
int64_t total_bitrate;
|
||||||
|
int32_t payload_bytes;
|
||||||
|
int32_t payloud_bits;
|
||||||
|
|
||||||
|
payload_bytes = 0;
|
||||||
|
payloud_bits = 0;
|
||||||
|
|
||||||
|
read_bytes = avio_read(s->pb, header, AV3A_MAX_NBYTES_HEADER);
|
||||||
|
if (read_bytes != AV3A_MAX_NBYTES_HEADER)
|
||||||
|
return (read_bytes < 0) ? read_bytes : AVERROR_EOF;
|
||||||
|
|
||||||
|
init_get_bits8(&gb, header, AV3A_MAX_NBYTES_HEADER);
|
||||||
|
|
||||||
|
sync_word = get_bits(&gb, 12);
|
||||||
|
if (sync_word != AV3A_AUDIO_SYNC_WORD) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_bits(&gb, 8);
|
||||||
|
|
||||||
|
coding_profile = get_bits(&gb, 3);
|
||||||
|
sampling_frequency_index = get_bits(&gb, 4);
|
||||||
|
if (sampling_frequency_index >= AV3A_SIZE_FS_TABLE) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
sampling_rate = ff_av3a_sampling_rate_table[sampling_frequency_index];
|
||||||
|
|
||||||
|
skip_bits(&gb, 8);
|
||||||
|
|
||||||
|
if (coding_profile == 0) {
|
||||||
|
channel_number_index = get_bits(&gb, 7);
|
||||||
|
if ((channel_number_index >= CHANNEL_CONFIG_UNKNOWN) ||
|
||||||
|
(channel_number_index == CHANNEL_CONFIG_MC_10_2) ||
|
||||||
|
(channel_number_index == CHANNEL_CONFIG_MC_22_2)) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
} else if (coding_profile == 1) {
|
||||||
|
int64_t bitrate_index_per_channel, soundbed_bitrate;
|
||||||
|
int16_t soundbed_type = get_bits(&gb, 2);
|
||||||
|
if (soundbed_type == 0) {
|
||||||
|
objects = get_bits(&gb, 7);
|
||||||
|
objects += 1;
|
||||||
|
object_bitrate_index = get_bits(&gb, 4);
|
||||||
|
if (object_bitrate_index < 0) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
total_bitrate = ff_av3a_mono_bitrate_table[object_bitrate_index] * objects;
|
||||||
|
} else if (soundbed_type == 1) {
|
||||||
|
channel_number_index = get_bits(&gb, 7);
|
||||||
|
if ((channel_number_index >= CHANNEL_CONFIG_UNKNOWN) ||
|
||||||
|
(channel_number_index == CHANNEL_CONFIG_MC_10_2) ||
|
||||||
|
(channel_number_index == CHANNEL_CONFIG_MC_22_2)) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
bitrate_index = get_bits(&gb, 4);
|
||||||
|
objects = get_bits(&gb, 7);
|
||||||
|
objects += 1;
|
||||||
|
object_bitrate_index = get_bits(&gb, 4);
|
||||||
|
if (bitrate_index < 0 || object_bitrate_index < 0){
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
soundbed_bitrate = ff_av3a_bitrate_map_table[channel_number_index].bitrate_table[bitrate_index];
|
||||||
|
bitrate_index_per_channel = ff_av3a_bitrate_map_table[CHANNEL_CONFIG_MONO].bitrate_table[object_bitrate_index];
|
||||||
|
total_bitrate = soundbed_bitrate + (bitrate_index_per_channel * objects);
|
||||||
|
} else {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
} else if (coding_profile == 2) {
|
||||||
|
hoa_order = get_bits(&gb, 4);
|
||||||
|
hoa_order += 1;
|
||||||
|
if(hoa_order == 1) {
|
||||||
|
channel_number_index = CHANNEL_CONFIG_HOA_ORDER1;
|
||||||
|
} else if(hoa_order == 2) {
|
||||||
|
channel_number_index = CHANNEL_CONFIG_HOA_ORDER2;
|
||||||
|
} else if(hoa_order == 3) {
|
||||||
|
channel_number_index = CHANNEL_CONFIG_HOA_ORDER3;
|
||||||
|
} else {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_bits(&gb, 2);
|
||||||
|
if (coding_profile != 1) {
|
||||||
|
bitrate_index = get_bits(&gb, 4);
|
||||||
|
if (bitrate_index < 0) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
total_bitrate = ff_av3a_bitrate_map_table[channel_number_index].bitrate_table[bitrate_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_bits(&gb, 8);
|
||||||
|
|
||||||
|
if (sampling_rate == 44100) {
|
||||||
|
payloud_bits = (int)floor(((float) (total_bitrate) / sampling_rate) * AV3A_AUDIO_FRAME_SIZE);
|
||||||
|
payload_bytes = (int)ceil((float)payloud_bits / 8);
|
||||||
|
} else {
|
||||||
|
payload_bytes = (int)ceil((((float) (total_bitrate) / sampling_rate) * AV3A_AUDIO_FRAME_SIZE) / 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
avio_seek(s->pb, -read_bytes, SEEK_CUR);
|
||||||
|
|
||||||
|
return payload_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int av3a_probe(const AVProbeData *p)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t frame_sync_word;
|
||||||
|
uint16_t lval = ((uint16_t)(p->buf[0]));
|
||||||
|
uint16_t rval = ((uint16_t)(p->buf[1]));
|
||||||
|
frame_sync_word = ((lval << 8) | rval) >> 4;
|
||||||
|
|
||||||
|
if (frame_sync_word == AV3A_AUDIO_SYNC_WORD && av_match_ext(p->filename, "av3a")) {
|
||||||
|
return AVPROBE_SCORE_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int av3a_read_header(AVFormatContext *s)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
uint8_t header[AV3A_MAX_NBYTES_HEADER];
|
||||||
|
AVIOContext *pb = s->pb;
|
||||||
|
AVStream *stream = NULL;
|
||||||
|
Av3aFormatContext av3afmtctx;
|
||||||
|
AATFHeaderInfo hdf;
|
||||||
|
|
||||||
|
if (!(stream = avformat_new_stream(s, NULL))) {
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->start_time = 0;
|
||||||
|
ffstream(stream)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
|
||||||
|
stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||||
|
stream->codecpar->codec_id = s->iformat->raw_codec_id;
|
||||||
|
stream->codecpar->codec_tag = MKTAG('a', 'v', '3', 'a');
|
||||||
|
|
||||||
|
if ((ret = avio_read(pb, header, AV3A_MAX_NBYTES_HEADER)) != AV3A_MAX_NBYTES_HEADER) {
|
||||||
|
return (ret < 0) ? ret : AVERROR_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = av3a_read_aatf_frame_header(&hdf, header);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stream parameters */
|
||||||
|
stream->codecpar->format = hdf.sample_format;
|
||||||
|
stream->codecpar->bits_per_raw_sample = hdf.resolution;
|
||||||
|
stream->codecpar->bit_rate = hdf.total_bitrate;
|
||||||
|
stream->codecpar->sample_rate = (int) (hdf.sampling_rate);
|
||||||
|
stream->codecpar->frame_size = AV3A_AUDIO_FRAME_SIZE;
|
||||||
|
stream->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
|
||||||
|
stream->codecpar->ch_layout.nb_channels = hdf.total_channels;
|
||||||
|
|
||||||
|
/* extradata */
|
||||||
|
av3afmtctx.audio_codec_id = hdf.audio_codec_id;
|
||||||
|
av3afmtctx.sampling_frequency_index = hdf.sampling_frequency_index;
|
||||||
|
av3afmtctx.nn_type = hdf.nn_type;
|
||||||
|
av3afmtctx.content_type = hdf.content_type;
|
||||||
|
av3afmtctx.channel_number_index = hdf.channel_number_index;
|
||||||
|
av3afmtctx.number_objects = hdf.nb_objects;
|
||||||
|
av3afmtctx.hoa_order = hdf.hoa_order;
|
||||||
|
av3afmtctx.resolution_index = hdf.resolution_index;
|
||||||
|
av3afmtctx.total_bitrate_kbps = (int) (hdf.total_bitrate / 1000);
|
||||||
|
|
||||||
|
if((ret = ff_alloc_extradata(stream->codecpar, sizeof(Av3aFormatContext))) < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
memcpy(stream->codecpar->extradata, &av3afmtctx, sizeof(Av3aFormatContext));
|
||||||
|
|
||||||
|
avio_seek(s->pb, -AV3A_MAX_NBYTES_HEADER, SEEK_CUR);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int av3a_read_packet(AVFormatContext *s, AVPacket *pkt) {
|
||||||
|
|
||||||
|
int64_t pos;
|
||||||
|
int packet_size = 0;
|
||||||
|
int read_bytes = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!s->streams[0]->codecpar) {
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avio_feof(s->pb)) {
|
||||||
|
return AVERROR_EOF;
|
||||||
|
}
|
||||||
|
pos = avio_tell(s->pb);
|
||||||
|
|
||||||
|
if (!(packet_size = av3a_get_packet_size(s))) {
|
||||||
|
return AVERROR_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet_size < 0) {
|
||||||
|
return packet_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = av_new_packet(pkt, packet_size);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_log(s, AV_LOG_ERROR, "Failed to allocate packet of size %d\n", packet_size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkt->stream_index = 0;
|
||||||
|
pkt->pos = pos;
|
||||||
|
pkt->duration = s->streams[0]->codecpar->frame_size;
|
||||||
|
|
||||||
|
read_bytes = avio_read(s->pb, pkt->data, packet_size);
|
||||||
|
if (read_bytes != packet_size) {
|
||||||
|
return (read_bytes < 0) ? read_bytes : AVERROR_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AVInputFormat ff_av3a_demuxer = {
|
||||||
|
.name = "av3a",
|
||||||
|
.long_name = NULL_IF_CONFIG_SMALL("Audio Vivid"),
|
||||||
|
.raw_codec_id = AV_CODEC_ID_AVS3DA,
|
||||||
|
.priv_data_size = sizeof(FFRawDemuxerContext),
|
||||||
|
.read_probe = av3a_probe,
|
||||||
|
.read_header = av3a_read_header,
|
||||||
|
.read_packet = av3a_read_packet,
|
||||||
|
.flags = AVFMT_GENERIC_INDEX,
|
||||||
|
.extensions = "av3a",
|
||||||
|
.mime_type = "audio/av3a",
|
||||||
|
};
|
@ -339,7 +339,7 @@ const AVCodecTag ff_codec_movaudio_tags[] = {
|
|||||||
{ AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') }, /* mp4ra.org */
|
{ AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') }, /* mp4ra.org */
|
||||||
{ AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') }, /* mp4ra.org */
|
{ AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') }, /* mp4ra.org */
|
||||||
{ AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') }, /* MPEG-H 3D Audio bitstream */
|
{ AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') }, /* MPEG-H 3D Audio bitstream */
|
||||||
{ AV_CODEC_ID_AVS3DA, MKTAG('a', 'v', '3', 'a') }, /* AVS3 Audio */
|
{ AV_CODEC_ID_AVS3DA, MKTAG('a', 'v', '3', 'a') },
|
||||||
{ AV_CODEC_ID_NONE, 0 },
|
{ AV_CODEC_ID_NONE, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
#include "id3v1.h"
|
#include "id3v1.h"
|
||||||
#include "mov_chan.h"
|
#include "mov_chan.h"
|
||||||
#include "replaygain.h"
|
#include "replaygain.h"
|
||||||
|
#include "libavcodec/av3a.h"
|
||||||
|
|
||||||
#if CONFIG_ZLIB
|
#if CONFIG_ZLIB
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
@ -7922,6 +7923,123 @@ static int mov_read_gnre(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int mov_read_dca3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int i = 0;
|
||||||
|
AVStream *st = NULL;
|
||||||
|
GetBitContext gb;
|
||||||
|
uint8_t buffer[7];
|
||||||
|
uint8_t audio_codec_id, sampling_frequency_index;
|
||||||
|
uint8_t nn_type, content_type, channel_number_index, number_objects;
|
||||||
|
uint8_t hoa_order, resolution_index, reserved;
|
||||||
|
int32_t bitrate_kbps;
|
||||||
|
int16_t nb_channels, nb_objects;
|
||||||
|
|
||||||
|
nb_channels = 0;
|
||||||
|
nb_objects = 0;
|
||||||
|
|
||||||
|
if (atom.size < 5) {
|
||||||
|
av_log(c->fc, AV_LOG_INFO, "Invalid dca3 box size %ld\n", atom.size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_get_bits8(&gb, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
if (c->fc->nb_streams < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
st = c->fc->streams[c->fc->nb_streams - 1];
|
||||||
|
|
||||||
|
ret = avio_read(pb, buffer, sizeof(buffer));
|
||||||
|
if (ret < 0){
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_codec_id = get_bits(&gb, 4);
|
||||||
|
if (audio_codec_id != 2) {
|
||||||
|
av_log(c->fc, AV_LOG_INFO, "Invalid dca3 box size %ld\n", atom.size);
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->codecpar->frame_size = AV3A_AUDIO_FRAME_SIZE;
|
||||||
|
sampling_frequency_index = get_bits(&gb, 4);
|
||||||
|
if (sampling_frequency_index >= AV3A_SIZE_FS_TABLE) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
st->codecpar->sample_rate = ff_av3a_sampling_rate_table[sampling_frequency_index];
|
||||||
|
|
||||||
|
nn_type = get_bits(&gb, 3);
|
||||||
|
reserved = get_bits(&gb, 1);
|
||||||
|
content_type = get_bits(&gb, 4);
|
||||||
|
|
||||||
|
if (content_type == 0) {
|
||||||
|
channel_number_index = get_bits(&gb, 7);
|
||||||
|
reserved = get_bits(&gb, 1);
|
||||||
|
if (channel_number_index >= CHANNEL_CONFIG_UNKNOWN) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
nb_channels = ff_av3a_channels_map_table[channel_number_index].channels;
|
||||||
|
} else if (content_type == 1) {
|
||||||
|
number_objects = get_bits(&gb, 7);
|
||||||
|
reserved = get_bits(&gb, 1);
|
||||||
|
nb_objects = number_objects;
|
||||||
|
} else if (content_type == 2) {
|
||||||
|
channel_number_index = get_bits(&gb, 7);
|
||||||
|
reserved = get_bits(&gb, 1);
|
||||||
|
number_objects = get_bits(&gb, 7);
|
||||||
|
reserved = get_bits(&gb, 1);
|
||||||
|
|
||||||
|
if (channel_number_index >= CHANNEL_CONFIG_UNKNOWN) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
nb_channels = ff_av3a_channels_map_table[channel_number_index].channels;
|
||||||
|
nb_objects = number_objects;
|
||||||
|
} else if (content_type == 3) {
|
||||||
|
hoa_order = get_bits(&gb , 4);
|
||||||
|
if (hoa_order > 3) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
nb_channels = (hoa_order + 1) * (hoa_order + 1);
|
||||||
|
} else {
|
||||||
|
av_log(c->fc, AV_LOG_INFO, "Invalid content_type value %ld\n", content_type);
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitrate_kbps = get_bits(&gb, 16);
|
||||||
|
st->codecpar->bit_rate = bitrate_kbps * 1000;
|
||||||
|
|
||||||
|
resolution_index = get_bits(&gb, 2);
|
||||||
|
if (resolution_index >= AV3A_SIZE_RESOLUTION_TABLE) {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
st->codecpar->format = ff_av3a_sample_format_map_table[resolution_index].sample_format;
|
||||||
|
st->codecpar->bits_per_raw_sample = ff_av3a_sample_format_map_table[resolution_index].resolution;
|
||||||
|
|
||||||
|
av_channel_layout_uninit(&st->codecpar->channel_layout);
|
||||||
|
if (content_type != 3) {
|
||||||
|
st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_CUSTOM;
|
||||||
|
st->codecpar->ch_layout.nb_channels = (nb_channels + nb_objects);
|
||||||
|
st->codecpar->ch_layout.u.map = av_calloc(st->codecpar->ch_layout.nb_channels,
|
||||||
|
sizeof(*st->codecpar->ch_layout.u.map));
|
||||||
|
|
||||||
|
if (content_type != 1) {
|
||||||
|
for(i = 0; i < nb_channels; i ++) {
|
||||||
|
st->codecpar->ch_layout.u.map[i].id = ff_av3a_channels_map_table[channel_number_index].channel_layout[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = nb_channels; i < st->codecpar->ch_layout.nb_channels; i++) {
|
||||||
|
st->codecpar->ch_layout.u.map[i].id = AV3A_CH_AUDIO_OBJECT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_AMBISONIC;
|
||||||
|
st->codecpar->ch_layout.nb_channels = nb_channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const MOVParseTableEntry mov_default_parse_table[] = {
|
static const MOVParseTableEntry mov_default_parse_table[] = {
|
||||||
{ MKTAG('A','C','L','R'), mov_read_aclr },
|
{ MKTAG('A','C','L','R'), mov_read_aclr },
|
||||||
{ MKTAG('A','P','R','G'), mov_read_avid },
|
{ MKTAG('A','P','R','G'), mov_read_avid },
|
||||||
@ -8037,6 +8155,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
|
|||||||
#ifdef OHOS_TIMED_META_TRACK
|
#ifdef OHOS_TIMED_META_TRACK
|
||||||
{ MKTAG('c','d','s','c'), mov_read_cdsc },
|
{ MKTAG('c','d','s','c'), mov_read_cdsc },
|
||||||
#endif
|
#endif
|
||||||
|
{ MKTAG('d','c','a','3'), mov_read_dca3 },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -899,6 +899,78 @@ static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
|
|||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mov_write_dca3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
|
||||||
|
{
|
||||||
|
int64_t pos = avio_tell(pb);
|
||||||
|
uint8_t buffer[7];
|
||||||
|
PutBitContext pb_dca3;
|
||||||
|
int16_t audio_codec_id, sampling_frequency_index, nn_type, content_type;
|
||||||
|
int16_t channel_number_index, number_objects, hoa_order, resolution_index;
|
||||||
|
int32_t bitrate_kbps;
|
||||||
|
|
||||||
|
if (track->par->extradata_size < 10) {
|
||||||
|
av_log(s, AV_LOG_WARNING, "Can not write dca3 box\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
avio_wb32(pb, 0); /* Size */
|
||||||
|
ffio_wfourcc(pb, "dca3"); /* Type */
|
||||||
|
|
||||||
|
init_put_bits(&pb_dca3, buffer, 7);
|
||||||
|
|
||||||
|
audio_codec_id = AV_RB8(track->par->extradata + 0);
|
||||||
|
sampling_frequency_index = AV_RB8(track->par->extradata + 1);
|
||||||
|
nn_type = AV_RB8(track->par->extradata + 2);
|
||||||
|
content_type = AV_RB8(track->par->extradata + 3);
|
||||||
|
channel_number_index = AV_RB8(track->par->extradata + 4);
|
||||||
|
number_objects = AV_RB8(track->par->extradata + 5);
|
||||||
|
hoa_order = AV_RB8(track->par->extradata + 6);
|
||||||
|
resolution_index = AV_RB8(track->par->extradata + 7);
|
||||||
|
bitrate_kbps = AV_RB16(track->par->extradata + 8);
|
||||||
|
|
||||||
|
if (audio_codec_id != 2) {
|
||||||
|
av_log(s, AV_LOG_ERROR, "Not support audio codec id %d\n", audio_codec_id);
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
put_bits(&pb_dca3, 4, audio_codec_id);
|
||||||
|
put_bits(&pb_dca3, 4, sampling_frequency_index);
|
||||||
|
|
||||||
|
put_bits(&pb_dca3, 3, nn_type);
|
||||||
|
put_bits(&pb_dca3, 1, 0); /* reserved */
|
||||||
|
put_bits(&pb_dca3, 4, content_type);
|
||||||
|
|
||||||
|
if (content_type == 0) {
|
||||||
|
put_bits(&pb_dca3, 7, channel_number_index);
|
||||||
|
put_bits(&pb_dca3, 1, 0); /* reserved */
|
||||||
|
} else if (content_type == 1){
|
||||||
|
put_bits(&pb_dca3, 7, number_objects);
|
||||||
|
put_bits(&pb_dca3, 1, 0); /* reserved */
|
||||||
|
} else if (content_type == 2){
|
||||||
|
put_bits(&pb_dca3, 7, channel_number_index);
|
||||||
|
put_bits(&pb_dca3, 1, 0); /* reserved */
|
||||||
|
put_bits(&pb_dca3, 7, number_objects);
|
||||||
|
put_bits(&pb_dca3, 1, 0); /* reserved */
|
||||||
|
} else if (content_type == 3) {
|
||||||
|
put_bits(&pb_dca3, 4, hoa_order);
|
||||||
|
} else {
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
put_bits(&pb_dca3, 16, bitrate_kbps);
|
||||||
|
put_bits(&pb_dca3, 2, resolution_index);
|
||||||
|
|
||||||
|
if (content_type == 3) {
|
||||||
|
put_bits(&pb_dca3, 2, 0); /* reserved */
|
||||||
|
} else {
|
||||||
|
put_bits(&pb_dca3, 6, 0); /* reserved */
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_put_bits(&pb_dca3);
|
||||||
|
avio_write(pb, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
return update_size(pb, pos);
|
||||||
|
}
|
||||||
|
|
||||||
static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
|
static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
|
||||||
{
|
{
|
||||||
uint32_t layout_tag, bitmap, *channel_desc;
|
uint32_t layout_tag, bitmap, *channel_desc;
|
||||||
@ -1258,7 +1330,8 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
|
|||||||
} else { /* reserved for mp4/3gp */
|
} else { /* reserved for mp4/3gp */
|
||||||
if (track->par->codec_id == AV_CODEC_ID_FLAC ||
|
if (track->par->codec_id == AV_CODEC_ID_FLAC ||
|
||||||
track->par->codec_id == AV_CODEC_ID_ALAC ||
|
track->par->codec_id == AV_CODEC_ID_ALAC ||
|
||||||
track->par->codec_id == AV_CODEC_ID_OPUS) {
|
track->par->codec_id == AV_CODEC_ID_OPUS ||
|
||||||
|
track->par->codec_id == AV_CODEC_ID_AVS3DA) {
|
||||||
avio_wb16(pb, track->par->ch_layout.nb_channels);
|
avio_wb16(pb, track->par->ch_layout.nb_channels);
|
||||||
} else {
|
} else {
|
||||||
avio_wb16(pb, 2);
|
avio_wb16(pb, 2);
|
||||||
@ -1326,6 +1399,8 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
|
|||||||
ret = mov_write_dops_tag(s, pb, track);
|
ret = mov_write_dops_tag(s, pb, track);
|
||||||
else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
|
else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
|
||||||
ret = mov_write_dmlp_tag(s, pb, track);
|
ret = mov_write_dmlp_tag(s, pb, track);
|
||||||
|
else if (track->par->codec_id == AV_CODEC_ID_AVS3DA)
|
||||||
|
ret = mov_write_dca3_tag(s, pb, track);
|
||||||
else if (track->vos_len > 0)
|
else if (track->vos_len > 0)
|
||||||
ret = mov_write_glbl_tag(pb, track);
|
ret = mov_write_glbl_tag(pb, track);
|
||||||
|
|
||||||
@ -8277,6 +8352,7 @@ static const AVCodecTag codec_mp4_tags[] = {
|
|||||||
#ifdef OHOS_TIMED_META_TRACK
|
#ifdef OHOS_TIMED_META_TRACK
|
||||||
{ AV_CODEC_ID_FFMETADATA, MKTAG('c', 'd', 's', 'c') },
|
{ AV_CODEC_ID_FFMETADATA, MKTAG('c', 'd', 's', 'c') },
|
||||||
#endif
|
#endif
|
||||||
|
{ AV_CODEC_ID_AVS3DA, MKTAG('a', 'v', '3', 'a') },
|
||||||
{ AV_CODEC_ID_NONE, 0 },
|
{ AV_CODEC_ID_NONE, 0 },
|
||||||
};
|
};
|
||||||
#if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
|
#if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
|
||||||
|
@ -1408,7 +1408,7 @@ static const StreamType ISO_types[] = {
|
|||||||
{ 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC },
|
{ 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC },
|
||||||
{ 0xd2, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_AVS2 },
|
{ 0xd2, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_AVS2 },
|
||||||
{ 0xd4, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_AVS3 },
|
{ 0xd4, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_AVS3 },
|
||||||
{ 0xd5, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AVS3DA }, /* avs3 audio */
|
{ 0xd5, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AVS3DA },
|
||||||
{ 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 },
|
{ 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 },
|
||||||
{ 0 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
@ -1463,7 +1463,6 @@ static const StreamType REGD_types[] = {
|
|||||||
{ MKTAG('I', 'D', '3', ' '), AVMEDIA_TYPE_DATA, AV_CODEC_ID_TIMED_ID3 },
|
{ MKTAG('I', 'D', '3', ' '), AVMEDIA_TYPE_DATA, AV_CODEC_ID_TIMED_ID3 },
|
||||||
{ MKTAG('V', 'C', '-', '1'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 },
|
{ MKTAG('V', 'C', '-', '1'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 },
|
||||||
{ MKTAG('O', 'p', 'u', 's'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_OPUS },
|
{ MKTAG('O', 'p', 'u', 's'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_OPUS },
|
||||||
{ MKTAG('a', 'v', '3', 'a'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AVS3DA}, /* AVS3 Audio descriptor Tag */
|
|
||||||
{ 0 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,6 +133,7 @@
|
|||||||
#define STREAM_TYPE_VIDEO_AVS3 0xd4
|
#define STREAM_TYPE_VIDEO_AVS3 0xd4
|
||||||
#define STREAM_TYPE_VIDEO_VC1 0xea
|
#define STREAM_TYPE_VIDEO_VC1 0xea
|
||||||
#define STREAM_TYPE_VIDEO_DIRAC 0xd1
|
#define STREAM_TYPE_VIDEO_DIRAC 0xd1
|
||||||
|
#define STREAM_TYPE_AUDIO_AV3A 0xd5
|
||||||
|
|
||||||
#define STREAM_TYPE_AUDIO_AC3 0x81
|
#define STREAM_TYPE_AUDIO_AC3 0x81
|
||||||
#define STREAM_TYPE_AUDIO_DTS 0x82
|
#define STREAM_TYPE_AUDIO_DTS 0x82
|
||||||
|
@ -433,6 +433,9 @@ static int get_dvb_stream_type(AVFormatContext *s, AVStream *st)
|
|||||||
stream_type = STREAM_TYPE_PRIVATE_DATA;
|
stream_type = STREAM_TYPE_PRIVATE_DATA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case AV_CODEC_ID_AVS3DA:
|
||||||
|
stream_type = STREAM_TYPE_AUDIO_AV3A;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
av_log_once(s, AV_LOG_WARNING, AV_LOG_DEBUG, &ts_st->data_st_warning,
|
av_log_once(s, AV_LOG_WARNING, AV_LOG_DEBUG, &ts_st->data_st_warning,
|
||||||
"Stream %d, codec %s, is muxed as a private data stream "
|
"Stream %d, codec %s, is muxed as a private data stream "
|
||||||
@ -441,6 +444,7 @@ static int get_dvb_stream_type(AVFormatContext *s, AVStream *st)
|
|||||||
stream_type = STREAM_TYPE_PRIVATE_DATA;
|
stream_type = STREAM_TYPE_PRIVATE_DATA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return stream_type;
|
return stream_type;
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,20 @@ const AVOutputFormat ff_aptx_hd_muxer = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_AV3A_MUXER
|
||||||
|
const AVOutputFormat ff_av3a_muxer = {
|
||||||
|
.name = "av3a",
|
||||||
|
.long_name = NULL_IF_CONFIG_SMALL("Audio Vivid"),
|
||||||
|
.mime_type = "audio/av3a",
|
||||||
|
.extensions = "av3a",
|
||||||
|
.audio_codec = AV_CODEC_ID_AVS3DA,
|
||||||
|
.video_codec = AV_CODEC_ID_NONE,
|
||||||
|
.init = force_one_stream,
|
||||||
|
.write_packet = ff_raw_write_packet,
|
||||||
|
.flags = AVFMT_NOTIMESTAMPS,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_AVS2_MUXER
|
#if CONFIG_AVS2_MUXER
|
||||||
const AVOutputFormat ff_avs2_muxer = {
|
const AVOutputFormat ff_avs2_muxer = {
|
||||||
.name = "avs2",
|
.name = "avs2",
|
||||||
|
@ -50,8 +50,8 @@ FF_CONFIG_OPTIONS="
|
|||||||
--disable-bzlib
|
--disable-bzlib
|
||||||
--disable-lzma
|
--disable-lzma
|
||||||
--disable-vulkan
|
--disable-vulkan
|
||||||
--enable-demuxer=mp3,aac,ape,flac,ogg,wav,mov,mpegts,amr,amrnb,amrwb,matroska,flv,mpegps,asf,asf_o,srt,h264,webvtt
|
--enable-demuxer=mp3,aac,ape,flac,ogg,wav,mov,mpegts,amr,amrnb,amrwb,matroska,flv,mpegps,asf,asf_o,srt,h264,webvtt,av3a
|
||||||
--enable-muxer=mp4,h264,ipod,amr,mpegts,mp3,wav,flac
|
--enable-muxer=mp4,h264,ipod,amr,mpegts,mp3,wav,flac,av3a
|
||||||
--enable-parser=h263,h264,mpeg4video,vp8,vp9,mpegvideo
|
--enable-parser=h263,h264,mpeg4video,vp8,vp9,mpegvideo
|
||||||
--enable-parser=mpegaudio,aac,aac_latm,av3a,amr,opus
|
--enable-parser=mpegaudio,aac,aac_latm,av3a,amr,opus
|
||||||
--enable-decoder=h263,h264,mpeg2video,mpeg4,vp8,vp9
|
--enable-decoder=h263,h264,mpeg2video,mpeg4,vp8,vp9
|
||||||
@ -144,8 +144,8 @@ FF_CONFIG_OPTIONS="
|
|||||||
--disable-sdl2
|
--disable-sdl2
|
||||||
--disable-bzlib
|
--disable-bzlib
|
||||||
--disable-lzma
|
--disable-lzma
|
||||||
--enable-demuxer=mp3,aac,ape,flac,ogg,wav,mov,mpegts,amr,amrnb,amrwb,matroska,flv,mpegps,asf,asf_o,srt,h264,webvtt
|
--enable-demuxer=mp3,aac,ape,flac,ogg,wav,mov,mpegts,amr,amrnb,amrwb,matroska,flv,mpegps,asf,asf_o,srt,h264,webvtt,av3a
|
||||||
--enable-muxer=mp4,h264,ipod,amr,mpegts,mp3,wav,flac
|
--enable-muxer=mp4,h264,ipod,amr,mpegts,mp3,wav,flac,av3a
|
||||||
--enable-parser=h263,h264,mpeg4video,vp8,vp9,mpegvideo
|
--enable-parser=h263,h264,mpeg4video,vp8,vp9,mpegvideo
|
||||||
--enable-parser=mpegaudio,aac,aac_latm,av3a,amr,opus
|
--enable-parser=mpegaudio,aac,aac_latm,av3a,amr,opus
|
||||||
--enable-decoder=h263,h264,mpeg2video,mpeg4,vp8,vp9
|
--enable-decoder=h263,h264,mpeg2video,mpeg4,vp8,vp9
|
||||||
|
Loading…
Reference in New Issue
Block a user