* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/common.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
#include "internal.h"
MERGE_REF(ret, b, fmts, type, fail); \
} while (0)
-AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
+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);
+ MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
return ret;
fail:
if (a == b) return a;
- if (a->format_count && b->format_count) {
- MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
- } else if (a->format_count) {
+ 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 {
{
const int *p;
- for (p = fmts; *p != PIX_FMT_NONE; p++) {
+ for (p = fmts; *p != AV_PIX_FMT_NONE; p++) {
if (fmt == *p)
return 1;
}
return 0;
}
-AVFilterFormats *avfilter_make_format_list(const int *fmts)
+AVFilterFormats *ff_make_format_list(const int *fmts)
{
AVFilterFormats *formats;
int count;
;
formats = av_mallocz(sizeof(*formats));
- if (count)
+ if (!formats)
+ return NULL;
+ if (count) {
formats->formats = av_malloc(sizeof(*formats->formats) * count);
- formats->format_count = count;
+ if (!formats->formats) {
+ av_freep(&formats);
+ return NULL;
+ }
+ }
+ formats->nb_formats = count;
memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
return formats;
\
fmts = av_realloc((*f)->list, \
sizeof(*(*f)->list) * ((*f)->nb + 1));\
- if (!fmts) \
+ if (!fmts) { \
+ av_freep(&f); \
return AVERROR(ENOMEM); \
+ } \
\
(*f)->list = fmts; \
(*f)->list[(*f)->nb++] = fmt; \
return 0; \
} while (0)
-int avfilter_add_format(AVFilterFormats **avff, int fmt)
+int ff_add_format(AVFilterFormats **avff, int fmt)
{
- ADD_FORMAT(avff, fmt, int, formats, format_count);
+ ADD_FORMAT(avff, fmt, int, formats, nb_formats);
}
int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
}
-AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
+AVFilterFormats *ff_all_formats(enum AVMediaType type)
+{
+ AVFilterFormats *ret = NULL;
+
+ if (type == AVMEDIA_TYPE_VIDEO) {
+ const AVPixFmtDescriptor *desc = NULL;
+ while ((desc = av_pix_fmt_desc_next(desc))) {
+ ff_add_format(&ret, av_pix_fmt_desc_get_id(desc));
+ }
+ } else if (type == AVMEDIA_TYPE_AUDIO) {
+ enum AVSampleFormat fmt = 0;
+ while (av_get_sample_fmt_name(fmt)) {
+ ff_add_format(&ret, fmt);
+ fmt++;
+ }
+ }
+
+ return ret;
+}
+
+AVFilterFormats *ff_planar_sample_fmts(void)
{
AVFilterFormats *ret = NULL;
int fmt;
- int num_formats = type == AVMEDIA_TYPE_VIDEO ? PIX_FMT_NB :
- type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
- for (fmt = 0; fmt < num_formats; fmt++)
- if ((type != AVMEDIA_TYPE_VIDEO) ||
- (type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL)))
- avfilter_add_format(&ret, fmt);
+ for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++)
+ if (av_sample_fmt_is_planar(fmt))
+ ff_add_format(&ret, fmt);
return ret;
}
do { \
*ref = f; \
f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
+ if (!f->refs) \
+ return; \
f->refs[f->refcount-1] = ref; \
} while (0)
FORMATS_REF(f, ref);
}
-void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
+void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
{
FORMATS_REF(f, ref);
}
*ref = NULL; \
} while (0)
-void avfilter_formats_unref(AVFilterFormats **ref)
+void ff_formats_unref(AVFilterFormats **ref)
{
FORMATS_UNREF(ref, formats);
}
FORMATS_CHANGEREF(oldref, newref);
}
-void avfilter_formats_changeref(AVFilterFormats **oldref,
- AVFilterFormats **newref)
+void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
{
FORMATS_CHANGEREF(oldref, newref);
}
+
+#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
+{ \
+ int count = 0, i; \
+ \
+ for (i = 0; i < ctx->nb_inputs; i++) { \
+ if (ctx->inputs[i]) { \
+ ref(fmts, &ctx->inputs[i]->out_fmts); \
+ count++; \
+ } \
+ } \
+ for (i = 0; i < ctx->nb_outputs; i++) { \
+ if (ctx->outputs[i]) { \
+ ref(fmts, &ctx->outputs[i]->in_fmts); \
+ count++; \
+ } \
+ } \
+ \
+ if (!count) { \
+ av_freep(&fmts->list); \
+ av_freep(&fmts->refs); \
+ av_freep(&fmts); \
+ } \
+}
+
+void ff_set_common_channel_layouts(AVFilterContext *ctx,
+ AVFilterChannelLayouts *layouts)
+{
+ SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
+ ff_channel_layouts_ref, channel_layouts);
+}
+
+void ff_set_common_samplerates(AVFilterContext *ctx,
+ AVFilterFormats *samplerates)
+{
+ SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
+ ff_formats_ref, formats);
+}
+
+/**
+ * A helper for query_formats() which sets all links to the same list of
+ * formats. If there are no links hooked to this filter, the list of formats is
+ * freed.
+ */
+void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
+{
+ SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
+ ff_formats_ref, formats);
+}
+
+int ff_default_query_formats(AVFilterContext *ctx)
+{
+ enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
+ ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
+ AVMEDIA_TYPE_VIDEO;
+
+ ff_set_common_formats(ctx, ff_all_formats(type));
+ if (type == AVMEDIA_TYPE_AUDIO) {
+ ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
+ ff_set_common_samplerates(ctx, ff_all_samplerates());
+ }
+
+ return 0;
+}