Unified · Split
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #include "libavutil/avstring.h" |
| 28 | 28 | #include "libavutil/channel_layout.h" |
| 29 | +#include "libavutil/downmix_info.h" | |
| 29 | 30 | #include "libavutil/opt.h" |
| 30 | 31 | #include "libavutil/samplefmt.h" |
| 31 | 32 | #include "libavutil/avassert.h" |
| @@ -123,6 +124,7 @@ static int query_formats(const AVFilterContext *ctx, · 91 unmodified lines | ||
| 123 | 124 | return ff_channel_layouts_ref(out_layouts, &cfg_out[0]->channel_layouts); |
| 124 | 125 | } |
| 125 | 126 | |
| 127 | +#define SWR_CH_MAX 64 | |
| 126 | 128 | |
| 127 | 129 | static int config_output(AVFilterLink *outlink) |
| 128 | 130 | { |
| @@ -132,6 +134,7 @@ static int config_output(AVFilterLink *outlink) · 3 unmodified lines | ||
| 132 | 134 | AResampleContext *aresample = ctx->priv; |
| 133 | 135 | AVChannelLayout out_layout = { 0 }; |
| 134 | 136 | int64_t out_rate; |
| 137 | + const AVFrameSideData *sd; | |
| 135 | 138 | enum AVSampleFormat out_format; |
| 136 | 139 | char inchl_buf[128], outchl_buf[128]; |
| 137 | 140 | |
| @@ -142,6 +145,44 @@ static int config_output(AVFilterLink *outlink) · 4 unmodified lines | ||
| 142 | 145 | if (ret < 0) |
| 143 | 146 | return ret; |
| 144 | 147 | |
| 148 | + sd = av_frame_side_data_get(inlink->side_data, inlink->nb_side_data, | |
| 149 | + AV_FRAME_DATA_DOWNMIX_INFO); | |
| 150 | + if (sd) { | |
| 151 | + const AVDownmixInfo *di = (AVDownmixInfo *)sd->data; | |
| 152 | + enum AVMatrixEncoding matrix_encoding = AV_MATRIX_ENCODING_NONE; | |
| 153 | + double center_mix_level, surround_mix_level; | |
| 154 | + | |
| 155 | + switch (di->preferred_downmix_type) { | |
| 156 | + case AV_DOWNMIX_TYPE_LTRT: | |
| 157 | + matrix_encoding = AV_MATRIX_ENCODING_DOLBY; | |
| 158 | + center_mix_level = di->center_mix_level_ltrt; | |
| 159 | + surround_mix_level = di->surround_mix_level_ltrt; | |
| 160 | + break; | |
| 161 | + case AV_DOWNMIX_TYPE_DPLII: | |
| 162 | + matrix_encoding = AV_MATRIX_ENCODING_DPLII; | |
| 163 | + center_mix_level = di->center_mix_level_ltrt; | |
| 164 | + surround_mix_level = di->surround_mix_level_ltrt; | |
| 165 | + break; | |
| 166 | + default: | |
| 167 | + center_mix_level = di->center_mix_level; | |
| 168 | + surround_mix_level = di->surround_mix_level; | |
| 169 | + break; | |
| 170 | + } | |
| 171 | + | |
| 172 | + av_log(ctx, AV_LOG_VERBOSE, "Mix levels: center %f - " | |
| 173 | + "surround %f - lfe %f.\n", | |
| 174 | + center_mix_level, surround_mix_level, di->lfe_mix_level); | |
| 175 | + | |
| 176 | + av_opt_set_double(aresample->swr, "clev", center_mix_level, 0); | |
| 177 | + av_opt_set_double(aresample->swr, "slev", surround_mix_level, 0); | |
| 178 | + av_opt_set_double(aresample->swr, "lfe_mix_level", di->lfe_mix_level, 0); | |
| 179 | + av_opt_set_int(aresample->swr, "matrix_encoding", matrix_encoding, 0); | |
| 180 | + | |
| 181 | + if (av_channel_layout_compare(&outlink->ch_layout, &out_layout)) | |
| 182 | + av_frame_side_data_remove(&outlink->side_data, &outlink->nb_side_data, | |
| 183 | + AV_FRAME_DATA_DOWNMIX_INFO); | |
| 184 | + } | |
| 185 | + | |
| 145 | 186 | ret = swr_init(aresample->swr); |
| 146 | 187 | if (ret < 0) |
| 147 | 188 | return ret; |
| @@ -200,6 +241,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) · 52 unmodified lines | ||
| 200 | 241 | } |
| 201 | 242 | outsamplesref->sample_rate = outlink->sample_rate; |
| 202 | 243 | |
| 244 | + if (av_channel_layout_compare(&outsamplesref->ch_layout, &insamplesref->ch_layout)) | |
| 245 | + av_frame_side_data_remove_by_props(&outsamplesref->side_data, &outsamplesref->nb_side_data, | |
| 246 | + AV_SIDE_DATA_PROP_CHANNEL_DEPENDENT); | |
| 247 | + | |
| 203 | 248 | if(insamplesref->pts != AV_NOPTS_VALUE) { |
| 204 | 249 | int64_t inpts = av_rescale(insamplesref->pts, inlink->time_base.num * (int64_t)outlink->sample_rate * inlink->sample_rate, inlink->time_base.den); |
| 205 | 250 | int64_t outpts= swr_next_pts(aresample->swr, inpts); |