Unified · Split
| @@ -44,7 +44,7 @@ AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms, · 43 unmodified lines | |||
| 44 | AVFilterBufferRef *samplesref = NULL; | 44 | AVFilterBufferRef *samplesref = NULL; |
| 45 | uint8_t **data; | 45 | uint8_t **data; |
| 46 | int planar = av_sample_fmt_is_planar(link->format); | 46 | int planar = av_sample_fmt_is_planar(link->format); |
| 47 | int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout); | 47 | int nb_channels = link->channels; |
| 48 | int planes = planar ? nb_channels : 1; | 48 | int planes = planar ? nb_channels : 1; |
| 49 | int linesize; | 49 | int linesize; |
| 50 | int full_perms = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE | | 50 | int full_perms = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE | |
| @@ -96,9 +96,6 @@ AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame · 95 unmodified lines | |||
| 96 | int channels = av_frame_get_channels(frame); | 96 | int channels = av_frame_get_channels(frame); |
| 97 | int64_t layout = av_frame_get_channel_layout(frame); | 97 | int64_t layout = av_frame_get_channel_layout(frame); |
| 98 | 98 | ||
| 99 | if(av_frame_get_channels(frame) > 8) // libavfilter does not suport more than 8 channels FIXME, remove once libavfilter is fixed | ||
| 100 | return NULL; | ||
| 101 | |||
| 102 | if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) { | 99 | if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) { |
| 103 | av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); | 100 | av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); |
| 104 | return NULL; | 101 | return NULL; |
| @@ -185,9 +185,24 @@ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name) · 184 unmodified lines | |||
| 185 | return NULL; | 185 | return NULL; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l) | ||
| 189 | { | ||
| 190 | if (!l) | ||
| 191 | return; | ||
| 192 | if (l->nb_channel_layouts) { | ||
| 193 | if (l->all_layouts || l->all_counts) | ||
| 194 | av_log(log, AV_LOG_WARNING, "All layouts set on non-empty list\n"); | ||
| 195 | l->all_layouts = l->all_counts = 0; | ||
| 196 | } else { | ||
| 197 | if (l->all_counts && !l->all_layouts) | ||
| 198 | av_log(log, AV_LOG_WARNING, "All counts without all layouts\n"); | ||
| 199 | l->all_layouts = 1; | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 188 | static int filter_query_formats(AVFilterContext *ctx) | 203 | static int filter_query_formats(AVFilterContext *ctx) |
| 189 | { | 204 | { |
| 190 | int ret; | 205 | int ret, i; |
| 191 | AVFilterFormats *formats; | 206 | AVFilterFormats *formats; |
| 192 | AVFilterChannelLayouts *chlayouts; | 207 | AVFilterChannelLayouts *chlayouts; |
| 193 | AVFilterFormats *samplerates; | 208 | AVFilterFormats *samplerates; |
| @@ -201,6 +216,11 @@ static int filter_query_formats(AVFilterContext *ctx) · 7 unmodified lines | |||
| 201 | return ret; | 216 | return ret; |
| 202 | } | 217 | } |
| 203 | 218 | ||
| 219 | for (i = 0; i < ctx->nb_inputs; i++) | ||
| 220 | sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts); | ||
| 221 | for (i = 0; i < ctx->nb_outputs; i++) | ||
| 222 | sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts); | ||
| 223 | |||
| 204 | formats = ff_all_formats(type); | 224 | formats = ff_all_formats(type); |
| 205 | if (!formats) | 225 | if (!formats) |
| 206 | return AVERROR(ENOMEM); | 226 | return AVERROR(ENOMEM); |
| @@ -470,7 +490,7 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 263 unmodified lines | |||
| 470 | link->in_samplerates->format_count = 1; | 490 | link->in_samplerates->format_count = 1; |
| 471 | link->sample_rate = link->in_samplerates->formats[0]; | 491 | link->sample_rate = link->in_samplerates->formats[0]; |
| 472 | 492 | ||
| 473 | if (!link->in_channel_layouts->nb_channel_layouts) { | 493 | if (link->in_channel_layouts->all_layouts) { |
| 474 | av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for" | 494 | av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for" |
| 475 | "the link between filters %s and %s.\n", link->src->name, | 495 | "the link between filters %s and %s.\n", link->src->name, |
| 476 | link->dst->name); | 496 | link->dst->name); |
| @@ -478,7 +498,10 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 1 unmodified line | |||
| 478 | } | 498 | } |
| 479 | link->in_channel_layouts->nb_channel_layouts = 1; | 499 | link->in_channel_layouts->nb_channel_layouts = 1; |
| 480 | link->channel_layout = link->in_channel_layouts->channel_layouts[0]; | 500 | link->channel_layout = link->in_channel_layouts->channel_layouts[0]; |
| 481 | link->channels = av_get_channel_layout_nb_channels(link->channel_layout); | 501 | if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout))) |
| 502 | link->channel_layout = 0; | ||
| 503 | else | ||
| 504 | link->channels = av_get_channel_layout_nb_channels(link->channel_layout); | ||
| 482 | } | 505 | } |
| 483 | 506 | ||
| 484 | ff_formats_unref(&link->in_formats); | 507 | ff_formats_unref(&link->in_formats); |
| @@ -534,8 +557,42 @@ static int reduce_formats_on_filter(AVFilterContext *filter) · 49 unmodified lines | |||
| 534 | format_count, ff_add_format); | 557 | format_count, ff_add_format); |
| 535 | REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, | 558 | REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, |
| 536 | format_count, ff_add_format); | 559 | format_count, ff_add_format); |
| 537 | REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts, | 560 | |
| 538 | channel_layouts, nb_channel_layouts, ff_add_channel_layout); | 561 | /* reduce channel layouts */ |
| 562 | for (i = 0; i < filter->nb_inputs; i++) { | ||
| 563 | AVFilterLink *inlink = filter->inputs[i]; | ||
| 564 | uint64_t fmt; | ||
| 565 | |||
| 566 | if (!inlink->out_channel_layouts || | ||
| 567 | inlink->out_channel_layouts->nb_channel_layouts != 1) | ||
| 568 | continue; | ||
| 569 | fmt = inlink->out_channel_layouts->channel_layouts[0]; | ||
| 570 | |||
| 571 | for (j = 0; j < filter->nb_outputs; j++) { | ||
| 572 | AVFilterLink *outlink = filter->outputs[j]; | ||
| 573 | AVFilterChannelLayouts *fmts; | ||
| 574 | |||
| 575 | fmts = outlink->in_channel_layouts; | ||
| 576 | if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1) | ||
| 577 | continue; | ||
| 578 | |||
| 579 | if (fmts->all_layouts) { | ||
| 580 | /* Turn the infinite list into a singleton */ | ||
| 581 | fmts->all_layouts = fmts->all_counts = 0; | ||
| 582 | ff_add_channel_layout(&outlink->in_channel_layouts, fmt); | ||
| 583 | break; | ||
| 584 | } | ||
| 585 | |||
| 586 | for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) { | ||
| 587 | if (fmts->channel_layouts[k] == fmt) { | ||
| 588 | fmts->channel_layouts[0] = fmt; | ||
| 589 | fmts->nb_channel_layouts = 1; | ||
| 590 | ret = 1; | ||
| 591 | break; | ||
| 592 | } | ||
| 593 | } | ||
| 594 | } | ||
| 595 | } | ||
| 539 | 596 | ||
| 540 | return ret; | 597 | return ret; |
| 541 | } | 598 | } |
| @@ -663,7 +720,23 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) · 121 unmodified lines | |||
| 663 | int out_channels = av_get_channel_layout_nb_channels(out_chlayout); | 720 | int out_channels = av_get_channel_layout_nb_channels(out_chlayout); |
| 664 | int count_diff = out_channels - in_channels; | 721 | int count_diff = out_channels - in_channels; |
| 665 | int matched_channels, extra_channels; | 722 | int matched_channels, extra_channels; |
| 666 | int score = 0; | 723 | int score = 100000; |
| 724 | |||
| 725 | if (FF_LAYOUT2COUNT(in_chlayout) || FF_LAYOUT2COUNT(out_chlayout)) { | ||
| 726 | /* Compute score in case the input or output layout encodes | ||
| 727 | a channel count; in this case the score is not altered by | ||
| 728 | the computation afterwards, as in_chlayout and | ||
| 729 | out_chlayout have both been set to 0 */ | ||
| 730 | if (FF_LAYOUT2COUNT(in_chlayout)) | ||
| 731 | in_channels = FF_LAYOUT2COUNT(in_chlayout); | ||
| 732 | if (FF_LAYOUT2COUNT(out_chlayout)) | ||
| 733 | out_channels = FF_LAYOUT2COUNT(out_chlayout); | ||
| 734 | score -= 10000 + FFABS(out_channels - in_channels) + | ||
| 735 | (in_channels > out_channels ? 10000 : 0); | ||
| 736 | in_chlayout = out_chlayout = 0; | ||
| 737 | /* Let the remaining computation run, even if the score | ||
| 738 | value is not altered */ | ||
| 739 | } | ||
| 667 | 740 | ||
| 668 | /* channel substitution */ | 741 | /* channel substitution */ |
| 669 | for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) { | 742 | for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) { |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "libavutil/avassert.h" | ||
| 22 | #include "libavutil/channel_layout.h" | 23 | #include "libavutil/channel_layout.h" |
| 23 | #include "libavutil/common.h" | 24 | #include "libavutil/common.h" |
| 24 | #include "libavutil/eval.h" | 25 | #include "libavutil/eval.h" |
| @@ -28,6 +29,8 @@ · 3 unmodified lines | |||
| 28 | #include "internal.h" | 29 | #include "internal.h" |
| 29 | #include "formats.h" | 30 | #include "formats.h" |
| 30 | 31 | ||
| 32 | #define KNOWN(l) (!FF_LAYOUT2COUNT(l)) /* for readability */ | ||
| 33 | |||
| 31 | /** | 34 | /** |
| 32 | * Add all refs from a to ret and destroy a. | 35 | * Add all refs from a to ret and destroy a. |
| 33 | */ | 36 | */ |
| @@ -136,21 +139,77 @@ AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, · 102 unmodified lines | |||
| 136 | AVFilterChannelLayouts *b) | 139 | AVFilterChannelLayouts *b) |
| 137 | { | 140 | { |
| 138 | AVFilterChannelLayouts *ret = NULL; | 141 | AVFilterChannelLayouts *ret = NULL; |
| 142 | unsigned a_all = a->all_layouts + a->all_counts; | ||
| 143 | unsigned b_all = b->all_layouts + b->all_counts; | ||
| 144 | int ret_max, ret_nb = 0, i, j, round; | ||
| 139 | 145 | ||
| 140 | if (a == b) return a; | 146 | if (a == b) return a; |
| 141 | 147 | ||
| 142 | if (a->nb_channel_layouts && b->nb_channel_layouts) { | 148 | /* Put the most generic set in a, to avoid doing everything twice */ |
| 143 | MERGE_FORMATS(ret, a, b, channel_layouts, nb_channel_layouts, | 149 | if (a_all < b_all) { |
| 144 | AVFilterChannelLayouts, fail); | 150 | FFSWAP(AVFilterChannelLayouts *, a, b); |
| 145 | } else if (a->nb_channel_layouts) { | 151 | FFSWAP(unsigned, a_all, b_all); |
| 146 | MERGE_REF(a, b, channel_layouts, AVFilterChannelLayouts, fail); | 152 | } |
| 147 | ret = a; | 153 | if (a_all) { |
| 148 | } else { | 154 | if (a_all == 1 && !b_all) { |
| 155 | /* keep only known layouts in b; works also for b_all = 1 */ | ||
| 156 | for (i = j = 0; i < b->nb_channel_layouts; i++) | ||
| 157 | if (KNOWN(b->channel_layouts[i])) | ||
| 158 | b->channel_layouts[j++] = b->channel_layouts[i]; | ||
| 159 | b->nb_channel_layouts = j; | ||
| 160 | } | ||
| 149 | MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail); | 161 | MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail); |
| 150 | ret = b; | 162 | return b; |
| 151 | } | 163 | } |
| 152 | 164 | ||
| 165 | ret_max = a->nb_channel_layouts + b->nb_channel_layouts; | ||
| 166 | if (!(ret = av_mallocz(sizeof(*ret))) || | ||
| 167 | !(ret->channel_layouts = av_malloc(sizeof(*ret->channel_layouts) * | ||
| 168 | ret_max))) | ||
| 169 | goto fail; | ||
| 170 | |||
| 171 | /* a[known] intersect b[known] */ | ||
| 172 | for (i = 0; i < a->nb_channel_layouts; i++) { | ||
| 173 | if (!KNOWN(a->channel_layouts[i])) | ||
| 174 | continue; | ||
| 175 | for (j = 0; j < b->nb_channel_layouts; j++) { | ||
| 176 | if (a->channel_layouts[i] == b->channel_layouts[j]) { | ||
| 177 | ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; | ||
| 178 | a->channel_layouts[i] = b->channel_layouts[j] = 0; | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | ||
| 182 | /* 1st round: a[known] intersect b[generic] | ||
| 183 | 2nd round: a[generic] intersect b[known] */ | ||
| 184 | for (round = 0; round < 2; round++) { | ||
| 185 | for (i = 0; i < a->nb_channel_layouts; i++) { | ||
| 186 | uint64_t fmt = a->channel_layouts[i], bfmt; | ||
| 187 | if (!fmt || !KNOWN(fmt)) | ||
| 188 | continue; | ||
| 189 | bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt)); | ||
| 190 | for (j = 0; j < b->nb_channel_layouts; j++) | ||
| 191 | if (b->channel_layouts[j] == bfmt) | ||
| 192 | ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; | ||
| 193 | } | ||
| 194 | /* 1st round: swap to prepare 2nd round; 2nd round: put it back */ | ||
| 195 | FFSWAP(AVFilterChannelLayouts *, a, b); | ||
| 196 | } | ||
| 197 | /* a[generic] intersect b[generic] */ | ||
| 198 | for (i = 0; i < a->nb_channel_layouts; i++) { | ||
| 199 | if (KNOWN(a->channel_layouts[i])) | ||
| 200 | continue; | ||
| 201 | for (j = 0; j < b->nb_channel_layouts; j++) | ||
| 202 | if (a->channel_layouts[i] == b->channel_layouts[j]) | ||
| 203 | ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; | ||
| 204 | } | ||
| 205 | |||
| 206 | ret->nb_channel_layouts = ret_nb; | ||
| 207 | if (!ret->nb_channel_layouts) | ||
| 208 | goto fail; | ||
| 209 | MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail); | ||
| 210 | MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail); | ||
| 153 | return ret; | 211 | return ret; |
| 212 | |||
| 154 | fail: | 213 | fail: |
| 155 | if (ret) { | 214 | if (ret) { |
| 156 | av_freep(&ret->refs); | 215 | av_freep(&ret->refs); |
| @@ -248,17 +307,19 @@ do { \ · 91 unmodified lines | |||
| 248 | \ | 307 | \ |
| 249 | (*f)->list = fmts; \ | 308 | (*f)->list = fmts; \ |
| 250 | (*f)->list[(*f)->nb++] = fmt; \ | 309 | (*f)->list[(*f)->nb++] = fmt; \ |
| 251 | return 0; \ | ||
| 252 | } while (0) | 310 | } while (0) |
| 253 | 311 | ||
| 254 | int ff_add_format(AVFilterFormats **avff, int64_t fmt) | 312 | int ff_add_format(AVFilterFormats **avff, int64_t fmt) |
| 255 | { | 313 | { |
| 256 | ADD_FORMAT(avff, fmt, int, formats, format_count); | 314 | ADD_FORMAT(avff, fmt, int, formats, format_count); |
| 315 | return 0; | ||
| 257 | } | 316 | } |
| 258 | 317 | ||
| 259 | int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout) | 318 | int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout) |
| 260 | { | 319 | { |
| 320 | av_assert1(!(*l && (*l)->all_layouts)); | ||
| 261 | ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts); | 321 | ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts); |
| 322 | return 0; | ||
| 262 | } | 323 | } |
| 263 | 324 | ||
| 264 | AVFilterFormats *ff_all_formats(enum AVMediaType type) | 325 | AVFilterFormats *ff_all_formats(enum AVMediaType type) |
| @@ -309,6 +370,9 @@ AVFilterFormats *ff_all_samplerates(void) · 44 unmodified lines | |||
| 309 | AVFilterChannelLayouts *ff_all_channel_layouts(void) | 370 | AVFilterChannelLayouts *ff_all_channel_layouts(void) |
| 310 | { | 371 | { |
| 311 | AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret)); | 372 | AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret)); |
| 373 | if (!ret) | ||
| 374 | return NULL; | ||
| 375 | ret->all_layouts = 1; | ||
| 312 | return ret; | 376 | return ret; |
| 313 | } | 377 | } |
| 314 | 378 | ||
| @@ -69,14 +69,45 @@ struct AVFilterFormats { · 68 unmodified lines | |||
| 69 | struct AVFilterFormats ***refs; ///< references to this list | 69 | struct AVFilterFormats ***refs; ///< references to this list |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | /** | ||
| 73 | * A list of supported channel layouts. | ||
| 74 | * | ||
| 75 | * The list works the same as AVFilterFormats, except for the following | ||
| 76 | * differences: | ||
| 77 | * - A list with all_layouts = 1 means all channel layouts with a known | ||
| 78 | * disposition; nb_channel_layouts must then be 0. | ||
| 79 | * - A list with all_counts = 1 means all channel counts, with a known or | ||
| 80 | * unknown disposition; nb_channel_layouts must then be 0 and all_layouts 1. | ||
| 81 | * - The list must not contain a layout with a known disposition and a | ||
| 82 | * channel count with unknown disposition with the same number of channels | ||
| 83 | * (e.g. AV_CH_LAYOUT_STEREO and FF_COUNT2LAYOUT(2). | ||
| 84 | */ | ||
| 72 | typedef struct AVFilterChannelLayouts { | 85 | typedef struct AVFilterChannelLayouts { |
| 73 | uint64_t *channel_layouts; ///< list of channel layouts | 86 | uint64_t *channel_layouts; ///< list of channel layouts |
| 74 | int nb_channel_layouts; ///< number of channel layouts | 87 | int nb_channel_layouts; ///< number of channel layouts |
| 88 | char all_layouts; ///< accept any known channel layout | ||
| 89 | char all_counts; ///< accept any channel layout or count | ||
| 75 | 90 | ||
| 76 | unsigned refcount; ///< number of references to this list | 91 | unsigned refcount; ///< number of references to this list |
| 77 | struct AVFilterChannelLayouts ***refs; ///< references to this list | 92 | struct AVFilterChannelLayouts ***refs; ///< references to this list |
| 78 | } AVFilterChannelLayouts; | 93 | } AVFilterChannelLayouts; |
| 79 | 94 | ||
| 95 | /** | ||
| 96 | * Encode a channel count as a channel layout. | ||
| 97 | * FF_COUNT2LAYOUT(c) means any channel layout with c channels, with a known | ||
| 98 | * or unknown disposition. | ||
| 99 | * The result is only valid inside AVFilterChannelLayouts and immediately | ||
| 100 | * related functions. | ||
| 101 | */ | ||
| 102 | #define FF_COUNT2LAYOUT(c) (0x8000000000000000ULL | (c)) | ||
| 103 | |||
| 104 | /** | ||
| 105 | * Decode a channel count encoded as a channel layout. | ||
| 106 | * Return 0 if the channel layout was a real one. | ||
| 107 | */ | ||
| 108 | #define FF_LAYOUT2COUNT(l) (((l) & 0x8000000000000000ULL) ? \ | ||
| 109 | (int)((l) & 0x7FFFFFFF) : 0) | ||
| 110 | |||
| 80 | /** | 111 | /** |
| 81 | * Return a channel layouts/samplerates list which contains the intersection of | 112 | * Return a channel layouts/samplerates list which contains the intersection of |
| 82 | * the layouts/samplerates of a and b. Also, all the references of a, all the | 113 | * the layouts/samplerates of a and b. Also, all the references of a, all the |