AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a, AVFilterFormats *b) { AVFilterFormats *ret = NULL; if (a == b) return a; if (a->nb_formats && b->nb_formats) { MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail); } else if (a->nb_formats) { MERGE_REF(a, b, formats, AVFilterFormats, fail); ret = a; } else { MERGE_REF(b, a, formats, AVFilterFormats, fail); ret = b; } return ret; fail: if (ret) { av_freep(&ret->refs); av_freep(&ret->formats); } av_freep(&ret); return NULL; }
AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, AVFilterChannelLayouts *b) { AVFilterChannelLayouts *ret = NULL; if (a == b) return a; if (a->nb_channel_layouts && b->nb_channel_layouts) { MERGE_FORMATS(ret, a, b, channel_layouts, nb_channel_layouts, AVFilterChannelLayouts, fail); } else if (a->nb_channel_layouts) { MERGE_REF(a, b, channel_layouts, AVFilterChannelLayouts, fail); ret = a; } else { MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail); ret = b; } return ret; fail: if (ret) { av_freep(&ret->refs); av_freep(&ret->channel_layouts); } av_freep(&ret); return NULL; }
AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, enum AVMediaType type) { AVFilterFormats *ret = NULL; int i, j; int alpha1=0, alpha2=0; int chroma1=0, chroma2=0; if (a == b) return a; /* Do not lose chroma or alpha in merging. It happens if both lists have formats with chroma (resp. alpha), but the only formats in common do not have it (e.g. YUV+gray vs. RGB+gray): in that case, the merging would select the gray format, possibly causing a lossy conversion elsewhere in the graph. To avoid that, pretend that there are no common formats to force the insertion of a conversion filter. */ if (type == AVMEDIA_TYPE_VIDEO) for (i = 0; i < a->nb_formats; i++) for (j = 0; j < b->nb_formats; j++) { const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]); const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]); alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA; chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1; if (a->formats[i] == b->formats[j]) { alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA; chroma1|= adesc->nb_components > 1; } } // If chroma or alpha can be lost through merging then do not merge if (alpha2 > alpha1 || chroma2 > chroma1) return NULL; MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail); return ret; fail: if (ret) { av_freep(&ret->refs); av_freep(&ret->formats); } av_freep(&ret); return NULL; }
AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b) { AVFilterFormats *ret = NULL; if (a == b) return a; MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail); return ret; fail: if (ret) { av_freep(&ret->refs); av_freep(&ret->formats); } av_freep(&ret); return NULL; }