#include "avconv.h"
#include "libavfilter/avfilter.h"
-#include "libavfilter/avfiltergraph.h"
#include "libavresample/avresample.h"
/* Define a function for building a string containing a list of
* allowed formats. */
-#define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name, separator)\
+#define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name) \
static char *choose_ ## var ## s(OutputStream *ost) \
{ \
if (ost->st->codec->var != none) { \
get_name(ost->st->codec->var); \
return av_strdup(name); \
- } else if (ost->enc->supported_list) { \
+ } else if (ost->enc && ost->enc->supported_list) { \
const type *p; \
AVIOContext *s = NULL; \
uint8_t *ret; \
\
for (p = ost->enc->supported_list; *p != none; p++) { \
get_name(*p); \
- avio_printf(s, "%s" separator, name); \
+ avio_printf(s, "%s|", name); \
} \
len = avio_close_dyn_buf(s, &ret); \
ret[len - 1] = 0; \
}
DEF_CHOOSE_FORMAT(enum AVPixelFormat, pix_fmt, pix_fmts, AV_PIX_FMT_NONE,
- GET_PIX_FMT_NAME, ":")
+ GET_PIX_FMT_NAME)
DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts,
- AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME, ",")
+ AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME)
DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0,
- GET_SAMPLE_RATE_NAME, ",")
+ GET_SAMPLE_RATE_NAME)
DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0,
- GET_CH_LAYOUT_NAME, ",")
+ GET_CH_LAYOUT_NAME)
FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost)
{
ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
}
+static int insert_trim(OutputStream *ost, AVFilterContext **last_filter, int *pad_idx)
+{
+ OutputFile *of = output_files[ost->file_index];
+ AVFilterGraph *graph = (*last_filter)->graph;
+ AVFilterContext *ctx;
+ const AVFilter *trim;
+ const char *name = ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO ? "trim" : "atrim";
+ char filter_name[128];
+ int ret = 0;
+
+ if (of->recording_time == INT64_MAX && !of->start_time)
+ return 0;
+
+ trim = avfilter_get_by_name(name);
+ if (!trim) {
+ av_log(NULL, AV_LOG_ERROR, "%s filter not present, cannot limit "
+ "recording time.\n", name);
+ return AVERROR_FILTER_NOT_FOUND;
+ }
+
+ snprintf(filter_name, sizeof(filter_name), "%s for output stream %d:%d",
+ name, ost->file_index, ost->index);
+ ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
+ if (!ctx)
+ return AVERROR(ENOMEM);
+
+ if (of->recording_time != INT64_MAX) {
+ ret = av_opt_set_double(ctx, "duration", (double)of->recording_time / 1e6,
+ AV_OPT_SEARCH_CHILDREN);
+ }
+ if (ret >= 0 && of->start_time) {
+ ret = av_opt_set_double(ctx, "start", (double)of->start_time / 1e6,
+ AV_OPT_SEARCH_CHILDREN);
+ }
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);
+ return ret;
+ }
+
+ ret = avfilter_init_str(ctx, NULL);
+ if (ret < 0)
+ return ret;
+
+ ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
+ if (ret < 0)
+ return ret;
+
+ *last_filter = ctx;
+ *pad_idx = 0;
+ return 0;
+}
+
static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
{
char *pix_fmts;
pad_idx = 0;
}
+ ret = insert_trim(ost, &last_filter, &pad_idx);
+ if (ret < 0)
+ return ret;
+
+
if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
return ret;
pad_idx = 0;
}
+ ret = insert_trim(ost, &last_filter, &pad_idx);
+ if (ret < 0)
+ return ret;
+
if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
return ret;
OutputStream *ost = fg->outputs[0]->ost;
char args[512];
AVDictionaryEntry *e = NULL;
- const AVClass *rc = avresample_get_class();
snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
fg->graph->scale_sws_opts = av_strdup(args);