Unified · Split
| @@ -26,6 +26,7 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | #include "libavutil/avstring.h" | 27 | #include "libavutil/avstring.h" |
| 28 | #include "libavutil/channel_layout.h" | 28 | #include "libavutil/channel_layout.h" |
| 29 | #include "libavutil/downmix_info.h" | ||
| 29 | #include "libavutil/opt.h" | 30 | #include "libavutil/opt.h" |
| 30 | #include "libavutil/samplefmt.h" | 31 | #include "libavutil/samplefmt.h" |
| 31 | #include "libavutil/avassert.h" | 32 | #include "libavutil/avassert.h" |
| @@ -123,6 +124,7 @@ static int query_formats(const AVFilterContext *ctx, · 91 unmodified lines | |||
| 123 | return ff_channel_layouts_ref(out_layouts, &cfg_out[0]->channel_layouts); | 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 | static int config_output(AVFilterLink *outlink) | 129 | static int config_output(AVFilterLink *outlink) |
| 128 | { | 130 | { |
| @@ -132,6 +134,7 @@ static int config_output(AVFilterLink *outlink) · 3 unmodified lines | |||
| 132 | AResampleContext *aresample = ctx->priv; | 134 | AResampleContext *aresample = ctx->priv; |
| 133 | AVChannelLayout out_layout = { 0 }; | 135 | AVChannelLayout out_layout = { 0 }; |
| 134 | int64_t out_rate; | 136 | int64_t out_rate; |
| 137 | const AVFrameSideData *sd; | ||
| 135 | enum AVSampleFormat out_format; | 138 | enum AVSampleFormat out_format; |
| 136 | char inchl_buf[128], outchl_buf[128]; | 139 | char inchl_buf[128], outchl_buf[128]; |
| 137 | 140 | ||
| @@ -142,6 +145,44 @@ static int config_output(AVFilterLink *outlink) · 4 unmodified lines | |||
| 142 | if (ret < 0) | 145 | if (ret < 0) |
| 143 | return ret; | 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 | ret = swr_init(aresample->swr); | 186 | ret = swr_init(aresample->swr); |
| 146 | if (ret < 0) | 187 | if (ret < 0) |
| 147 | return ret; | 188 | return ret; |
| @@ -200,6 +241,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) · 52 unmodified lines | |||
| 200 | } | 241 | } |
| 201 | outsamplesref->sample_rate = outlink->sample_rate; | 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 | if(insamplesref->pts != AV_NOPTS_VALUE) { | 248 | if(insamplesref->pts != AV_NOPTS_VALUE) { |
| 204 | int64_t inpts = av_rescale(insamplesref->pts, inlink->time_base.num * (int64_t)outlink->sample_rate * inlink->sample_rate, inlink->time_base.den); | 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 | int64_t outpts= swr_next_pts(aresample->swr, inpts); | 250 | int64_t outpts= swr_next_pts(aresample->swr, inpts); |