void Utility::FilterApplier::initFilters() {
	int ret=0;

	filterGraph_=avfilter_graph_alloc();
	if(!filterGraph_) {
		throw std::runtime_error("Could not create filtergraph");
	}

	AVFilter *buffersrc  = avfilter_get_by_name("buffer");
	AVFilter *buffersink = avfilter_get_by_name("buffersink");

	std::string args="video_size="+std::to_string(width_)+"x"+std::to_string(
	                     height_)+":pix_fmt="+std::to_string(pixelFormat_)+":time_base=1/1";
	ret=avfilter_graph_create_filter(&buffersourceContext_, buffersrc, "in",args.c_str(), NULL,
	                                 filterGraph_);
	if(ret<0) {
		throw std::runtime_error("Could not create the buffersource for the filtergraph.");
	}

	ret = avfilter_graph_create_filter(&buffersinkContext_, buffersink, "out",NULL, NULL, filterGraph_);
	if(ret<0) {
		throw std::runtime_error("Could not create the buffersink for the filtergraph.");
	}

	enum AVPixelFormat pixelFormats[]= {AV_PIX_FMT_RGB24,AV_PIX_FMT_NONE};
	ret = av_opt_set_int_list(buffersinkContext_, "pix_fmts", pixelFormats,AV_PIX_FMT_NONE,
	                          AV_OPT_SEARCH_CHILDREN);
	if (ret < 0) {
		throw std::runtime_error("Could net set output pixelformat for the graph");
	}

	AVFilterInOut *outputs = avfilter_inout_alloc();
	AVFilterInOut *inputs  = avfilter_inout_alloc();

	outputs->name       = av_strdup("in");
	outputs->filter_ctx = buffersourceContext_;
	outputs->pad_idx    = 0;
	outputs->next       = NULL;

	inputs->name       = av_strdup("out");
	inputs->filter_ctx = buffersinkContext_;
	inputs->pad_idx    = 0;
	inputs->next       = NULL;

	ret = avfilter_graph_parse_ptr(filterGraph_, filterDescription_.c_str(), &inputs, &outputs, NULL);
	if(ret<0) {
		avfilter_inout_free(&inputs);
		avfilter_inout_free(&outputs);
		throw std::runtime_error("Could not parse the filter descritopns.");
	}

	ret = avfilter_graph_config(filterGraph_, NULL);
	if(ret<0) {
		avfilter_inout_free(&inputs);
		avfilter_inout_free(&outputs);
		throw std::runtime_error("Could not configure filtergraph.");
	}

}
Пример #2
0
int CDVDVideoCodecFFmpeg::FilterOpen(const std::string& filters, bool scale)
{
  int result;

  if (m_pFilterGraph)
    FilterClose();

  if (filters.empty() && !scale)
    return 0;

  if (m_pHardware)
  {
    CLog::Log(LOGWARNING, "CDVDVideoCodecFFmpeg::FilterOpen - skipped opening filters on hardware decode");
    return 0;
  }

  if (!(m_pFilterGraph = avfilter_graph_alloc()))
  {
    CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - unable to alloc filter graph");
    return -1;
  }

  AVFilter* srcFilter = avfilter_get_by_name("buffer");
  AVFilter* outFilter = avfilter_get_by_name("buffersink"); // should be last filter in the graph for now

  std::string args = StringUtils::Format("%d:%d:%d:%d:%d:%d:%d",
                                        m_pCodecContext->width,
                                        m_pCodecContext->height,
                                        m_pCodecContext->pix_fmt,
                                        m_pCodecContext->time_base.num ? m_pCodecContext->time_base.num : 1,
                                        m_pCodecContext->time_base.num ? m_pCodecContext->time_base.den : 1,
                                        m_pCodecContext->sample_aspect_ratio.num != 0 ? m_pCodecContext->sample_aspect_ratio.num : 1,
                                        m_pCodecContext->sample_aspect_ratio.num != 0 ? m_pCodecContext->sample_aspect_ratio.den : 1);

  if ((result = avfilter_graph_create_filter(&m_pFilterIn, srcFilter, "src", args.c_str(), NULL, m_pFilterGraph)) < 0)
  {
    CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: src");
    return result;
  }

  if ((result = avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, NULL, m_pFilterGraph)) < 0)
  {
    CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: out");
    return result;
  }
  if ((result = av_opt_set_int_list(m_pFilterOut, "pix_fmts", &m_formats[0],  AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
  {
    CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - failed settings pix formats");
    return result;
  }

  if (!filters.empty())
  {
    AVFilterInOut* outputs = avfilter_inout_alloc();
    AVFilterInOut* inputs  = avfilter_inout_alloc();

    outputs->name = av_strdup("in");
    outputs->filter_ctx = m_pFilterIn;
    outputs->pad_idx = 0;
    outputs->next = nullptr;

    inputs->name = av_strdup("out");
    inputs->filter_ctx = m_pFilterOut;
    inputs->pad_idx = 0;
    inputs->next = nullptr;

    if ((result = avfilter_graph_parse_ptr(m_pFilterGraph, (const char*)m_filters.c_str(), &inputs, &outputs, NULL)) < 0)
    {
      CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_parse");
      return result;
    }

    avfilter_inout_free(&outputs);
    avfilter_inout_free(&inputs);
  }
  else
  {
    if ((result = avfilter_link(m_pFilterIn, 0, m_pFilterOut, 0)) < 0)
    {
      CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_link");
      return result;
    }
  }

  if ((result = avfilter_graph_config(m_pFilterGraph,  nullptr)) < 0)
  {
    CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_config");
    return result;
  }

  m_filterEof = false;
  return result;
}
Пример #3
0
static int init_filters(const char *filters_descr)
{
    char args[512];
    int ret = 0;
    AVFilter *buffersrc  = avfilter_get_by_name("buffer");
    AVFilter *buffersink = avfilter_get_by_name("buffersink");
    AVFilterInOut *outputs = avfilter_inout_alloc();
    AVFilterInOut *inputs  = avfilter_inout_alloc();
    AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;
    enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };

    filter_graph = avfilter_graph_alloc();
    if (!outputs || !inputs || !filter_graph) {
        ret = AVERROR(ENOMEM);
        goto end;
    }

    /* buffer video source: the decoded frames from the decoder will be inserted here. */
    snprintf(args, sizeof(args),
            "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
            dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
            time_base.num, time_base.den,
            dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);

    ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
                                       args, NULL, filter_graph);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
        goto end;
    }

    /* buffer video sink: to terminate the filter chain. */
    ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
                                       NULL, NULL, filter_graph);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
        goto end;
    }

    ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
                              AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
        goto end;
    }

    /*
     * Set the endpoints for the filter graph. The filter_graph will
     * be linked to the graph described by filters_descr.
     */

    /*
     * The buffer source output must be connected to the input pad of
     * the first filter described by filters_descr; since the first
     * filter input label is not specified, it is set to "in" by
     * default.
     */
    outputs->name       = av_strdup("in");
    outputs->filter_ctx = buffersrc_ctx;
    outputs->pad_idx    = 0;
    outputs->next       = NULL;

    /*
     * The buffer sink input must be connected to the output pad of
     * the last filter described by filters_descr; since the last
     * filter output label is not specified, it is set to "out" by
     * default.
     */
    inputs->name       = av_strdup("out");
    inputs->filter_ctx = buffersink_ctx;
    inputs->pad_idx    = 0;
    inputs->next       = NULL;

    if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
                                    &inputs, &outputs, NULL)) < 0)
        goto end;

    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
        goto end;

end:
    avfilter_inout_free(&inputs);
    avfilter_inout_free(&outputs);

    return ret;
}
Пример #4
0
	void configure_filtergraph()
	{
		if (filtergraph_.empty())
		{
			video_graph_.reset();
			return;
		}

		video_graph_.reset(
			avfilter_graph_alloc(), 
			[](AVFilterGraph* p)
			{
				avfilter_graph_free(&p);
			});
				
		const auto vsrc_options = (boost::format("video_size=%1%x%2%:pix_fmt=%3%:time_base=%4%/%5%:pixel_aspect=%6%/%7%")
			% in_width_ % in_height_
			% in_pix_format_
			% in_time_base_.num % in_time_base_.den
			% in_sample_aspect_ratio_.num % in_sample_aspect_ratio_.den).str();

		AVFilterContext* filt_vsrc = nullptr;			
		FF(avfilter_graph_create_filter(
			&filt_vsrc,
			avfilter_get_by_name("buffer"), 
			"filter_buffer",
			vsrc_options.c_str(), 
			nullptr, 
			video_graph_.get()));
				
		AVFilterContext* filt_vsink = nullptr;
		FF(avfilter_graph_create_filter(
			&filt_vsink,
			avfilter_get_by_name("buffersink"), 
			"filter_buffersink",
			nullptr, 
			nullptr, 
			video_graph_.get()));
		
#pragma warning (push)
#pragma warning (disable : 4245)

		FF(av_opt_set_int_list(
			filt_vsink, 
			"pix_fmts", 
			out_pix_fmts_.data(), 
			-1,
			AV_OPT_SEARCH_CHILDREN));

#pragma warning (pop)
		try
		{
			configure_filtergraph(
				*video_graph_,
				filtergraph_,
				*filt_vsrc,
				*filt_vsink);
			video_graph_in_ = filt_vsrc;
			video_graph_out_ = filt_vsink;

			CASPAR_LOG(trace) << L"Filter configured:\n" << avfilter_graph_dump(video_graph_.get(), nullptr);
		}
		catch (...)
		{
			CASPAR_LOG(error) << L"Cannot configure filtergraph: " << filtergraph_.c_str();
			filtergraph_.clear(); // disable filtering on configure_filtergraph  failure
		}
	}
Пример #5
0
static int init_filters(const char *filters_descr)
{
    char args[512];
    int ret = 0;
    AVFilter *abuffersrc  = avfilter_get_by_name("abuffer");
    AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
    AVFilterInOut *outputs = avfilter_inout_alloc();
    AVFilterInOut *inputs  = avfilter_inout_alloc();
    static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
    static const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_MONO, -1 };
    static const int out_sample_rates[] = { 8000, -1 };
    const AVFilterLink *outlink;
    AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;

    filter_graph = avfilter_graph_alloc();
    if (!outputs || !inputs || !filter_graph) {
        ret = AVERROR(ENOMEM);
        goto end;
    }

    /* buffer audio source: the decoded frames from the decoder will be inserted here. */
    if (!dec_ctx->channel_layout)
        dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels);
    snprintf(args, sizeof(args),
            "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
             time_base.num, time_base.den, dec_ctx->sample_rate,
             av_get_sample_fmt_name(dec_ctx->sample_fmt), dec_ctx->channel_layout);
    ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in",
                                       args, NULL, filter_graph);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
        goto end;
    }

    /* buffer audio sink: to terminate the filter chain. */
    ret = avfilter_graph_create_filter(&buffersink_ctx, abuffersink, "out",
                                       NULL, NULL, filter_graph);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
        goto end;
    }

    ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1,
                              AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
        goto end;
    }

    ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
                              AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
        goto end;
    }

    ret = av_opt_set_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1,
                              AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
        goto end;
    }

    /* Endpoints for the filter graph. */
    outputs->name       = av_strdup("in");
    outputs->filter_ctx = buffersrc_ctx;
    outputs->pad_idx    = 0;
    outputs->next       = NULL;

    inputs->name       = av_strdup("out");
    inputs->filter_ctx = buffersink_ctx;
    inputs->pad_idx    = 0;
    inputs->next       = NULL;

    if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
                                        &inputs, &outputs, NULL)) < 0)
        goto end;

    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
        goto end;

    /* Print summary of the sink buffer
     * Note: args buffer is reused to store channel layout string */
    outlink = buffersink_ctx->inputs[0];
    av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout);
    av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n",
           (int)outlink->sample_rate,
           (char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
           args);

end:
    avfilter_inout_free(&inputs);
    avfilter_inout_free(&outputs);

    return ret;
}
Пример #6
0
static bool recreate_graph(struct af_instance *af, struct mp_audio *config)
{
    void *tmp = talloc_new(NULL);
    struct priv *p = af->priv;
    AVFilterContext *in = NULL, *out = NULL;
    int r;

    if (bstr0(p->cfg_graph).len == 0) {
        mp_msg(MSGT_AFILTER, MSGL_FATAL, "lavfi: no filter graph set\n");
        return false;
    }

    destroy_graph(af);
    mp_msg(MSGT_AFILTER, MSGL_V, "lavfi: create graph: '%s'\n", p->cfg_graph);

    AVFilterGraph *graph = avfilter_graph_alloc();
    if (!graph)
        goto error;

    if (parse_avopts(graph, p->cfg_avopts) < 0) {
        mp_msg(MSGT_VFILTER, MSGL_FATAL, "lavfi: could not set opts: '%s'\n",
               p->cfg_avopts);
        goto error;
    }

    AVFilterInOut *outputs = avfilter_inout_alloc();
    AVFilterInOut *inputs  = avfilter_inout_alloc();
    if (!outputs || !inputs)
        goto error;

    char *src_args = talloc_asprintf(tmp,
        "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d:"
        "channel_layout=0x%"PRIx64,  config->rate,
        av_get_sample_fmt_name(af_to_avformat(config->format)),
        config->channels.num, 1, config->rate,
        mp_chmap_to_lavc(&config->channels));

    if (avfilter_graph_create_filter(&in, avfilter_get_by_name("abuffer"),
                                     "src", src_args, NULL, graph) < 0)
        goto error;

    if (avfilter_graph_create_filter(&out, avfilter_get_by_name("abuffersink"),
                                     "out", NULL, NULL, graph) < 0)
        goto error;

    static const enum AVSampleFormat sample_fmts[] = {
        AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
        AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL,
        AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P,
        AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP,
        AV_SAMPLE_FMT_NONE
    };
    r = av_opt_set_int_list(out, "sample_fmts", sample_fmts,
                            AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
    if (r < 0)
        goto error;

    r = av_opt_set_int(out, "all_channel_counts", 1, AV_OPT_SEARCH_CHILDREN);
    if (r < 0)
        goto error;

    outputs->name = av_strdup("in");
    outputs->filter_ctx = in;

    inputs->name = av_strdup("out");
    inputs->filter_ctx = out;

    if (graph_parse(graph, p->cfg_graph, inputs, outputs, NULL) < 0)
        goto error;

    if (avfilter_graph_config(graph, NULL) < 0)
        goto error;

    p->in = in;
    p->out = out;
    p->graph = graph;

    assert(out->nb_inputs == 1);
    assert(in->nb_outputs == 1);

    talloc_free(tmp);
    return true;

error:
    mp_msg(MSGT_AFILTER, MSGL_FATAL, "Can't configure libavfilter graph.\n");
    avfilter_graph_free(&graph);
    talloc_free(tmp);
    return false;
}
Пример #7
0
HRESULT CLAVVideo::Filter(LAVFrame *pFrame)
{
  int ret = 0;
  BOOL bFlush = pFrame->flags & LAV_FRAME_FLAG_FLUSH;
  if (m_Decoder.IsInterlaced(FALSE) && m_settings.DeintMode != DeintMode_Disable
    && (m_settings.SWDeintMode == SWDeintMode_YADIF || m_settings.SWDeintMode == SWDeintMode_W3FDIF_Simple || m_settings.SWDeintMode == SWDeintMode_W3FDIF_Complex)
    && ((bFlush && m_pFilterGraph) || pFrame->format == LAVPixFmt_YUV420 || pFrame->format == LAVPixFmt_YUV422 || pFrame->format == LAVPixFmt_NV12)) {
    AVPixelFormat ff_pixfmt = (pFrame->format == LAVPixFmt_YUV420) ? AV_PIX_FMT_YUV420P : (pFrame->format == LAVPixFmt_YUV422) ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_NV12;

    if (!bFlush && (!m_pFilterGraph || pFrame->format != m_filterPixFmt || pFrame->width != m_filterWidth || pFrame->height != m_filterHeight)) {
      DbgLog((LOG_TRACE, 10, L":Filter()(init) Initializing YADIF deinterlacing filter..."));
      if (m_pFilterGraph) {
        avfilter_graph_free(&m_pFilterGraph);
        m_pFilterBufferSrc = nullptr;
        m_pFilterBufferSink = nullptr;
      }

      m_filterPixFmt = pFrame->format;
      m_filterWidth  = pFrame->width;
      m_filterHeight = pFrame->height;

      char args[512];
      enum AVPixelFormat pix_fmts[3];

      if (ff_pixfmt == AV_PIX_FMT_NV12) {
        pix_fmts[0] = AV_PIX_FMT_NV12;
        pix_fmts[1] = AV_PIX_FMT_YUV420P;
      } else {
        pix_fmts[0] = ff_pixfmt;
        pix_fmts[1] = AV_PIX_FMT_NONE;
      }
      pix_fmts[2] = AV_PIX_FMT_NONE;

      AVFilter *buffersrc  = avfilter_get_by_name("buffer");
      AVFilter *buffersink = avfilter_get_by_name("buffersink");
      AVFilterInOut *outputs = avfilter_inout_alloc();
      AVFilterInOut *inputs  = avfilter_inout_alloc();

      m_pFilterGraph = avfilter_graph_alloc();

      av_opt_set(m_pFilterGraph, "thread_type", "slice", AV_OPT_SEARCH_CHILDREN);
      av_opt_set_int(m_pFilterGraph, "threads", FFMAX(1, av_cpu_count() / 2), AV_OPT_SEARCH_CHILDREN);

      // 0/0 is not a valid value for avfilter, make sure it doesn't happen
      AVRational aspect_ratio = pFrame->aspect_ratio;
      if (aspect_ratio.num == 0 || aspect_ratio.den == 0)
        aspect_ratio = { 0, 1 };

      _snprintf_s(args, sizeof(args), "video_size=%dx%d:pix_fmt=%s:time_base=1/10000000:pixel_aspect=%d/%d", pFrame->width, pFrame->height, av_get_pix_fmt_name(ff_pixfmt), pFrame->aspect_ratio.num, pFrame->aspect_ratio.den);
      ret = avfilter_graph_create_filter(&m_pFilterBufferSrc, buffersrc, "in", args, nullptr, m_pFilterGraph);
      if (ret < 0) {
        DbgLog((LOG_TRACE, 10, L"::Filter()(init) Creating the input buffer filter failed with code %d", ret));
        avfilter_graph_free(&m_pFilterGraph);
        goto deliver;
      }

      ret = avfilter_graph_create_filter(&m_pFilterBufferSink, buffersink, "out", nullptr, nullptr, m_pFilterGraph);
      if (ret < 0) {
        DbgLog((LOG_TRACE, 10, L"::Filter()(init) Creating the buffer sink filter failed with code %d", ret));
        avfilter_free(m_pFilterBufferSrc);
        m_pFilterBufferSrc = nullptr;
        avfilter_graph_free(&m_pFilterGraph);
        goto deliver;
      }

      /* set allowed pixfmts on the output */
      av_opt_set_int_list(m_pFilterBufferSink->priv, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, 0);

      /* Endpoints for the filter graph. */
      outputs->name       = av_strdup("in");
      outputs->filter_ctx = m_pFilterBufferSrc;
      outputs->pad_idx    = 0;
      outputs->next       = nullptr;

      inputs->name       = av_strdup("out");
      inputs->filter_ctx = m_pFilterBufferSink;
      inputs->pad_idx    = 0;
      inputs->next       = nullptr;

      if (m_settings.SWDeintMode == SWDeintMode_YADIF)
        _snprintf_s(args, sizeof(args), "yadif=mode=%s:parity=auto:deint=interlaced", (m_settings.SWDeintOutput == DeintOutput_FramePerField) ? "send_field" : "send_frame");
      else if (m_settings.SWDeintMode == SWDeintMode_W3FDIF_Simple)
        _snprintf_s(args, sizeof(args), "w3fdif=filter=simple:deint=interlaced");
      else if (m_settings.SWDeintMode == SWDeintMode_W3FDIF_Complex)
        _snprintf_s(args, sizeof(args), "w3fdif=filter=complex:deint=interlaced");
      else
        ASSERT(0);

      if ((ret = avfilter_graph_parse_ptr(m_pFilterGraph, args, &inputs, &outputs, nullptr)) < 0) {
        DbgLog((LOG_TRACE, 10, L"::Filter()(init) Parsing the graph failed with code %d", ret));
        avfilter_graph_free(&m_pFilterGraph);
        goto deliver;
      }

      if ((ret = avfilter_graph_config(m_pFilterGraph, nullptr)) < 0) {
        DbgLog((LOG_TRACE, 10, L"::Filter()(init) Configuring the graph failed with code %d", ret));
        avfilter_graph_free(&m_pFilterGraph);
        goto deliver;
      }

      DbgLog((LOG_TRACE, 10, L":Filter()(init) avfilter Initialization complete"));
    }

    if (!m_pFilterGraph)
      goto deliver;

    if (pFrame->direct) {
      HRESULT hr = DeDirectFrame(pFrame, true);
      if (FAILED(hr)) {
        ReleaseFrame(&pFrame);
        return hr;
      }
    }

    AVFrame *in_frame = nullptr;
    BOOL refcountedFrame = (m_Decoder.HasThreadSafeBuffers() == S_OK);
    // When flushing, we feed a NULL frame
    if (!bFlush) {
      in_frame = av_frame_alloc();

      for (int i = 0; i < 4; i++) {
        in_frame->data[i] = pFrame->data[i];
        in_frame->linesize[i] = (int)pFrame->stride[i];
      }

      in_frame->width               = pFrame->width;
      in_frame->height              = pFrame->height;
      in_frame->format              = ff_pixfmt;
      in_frame->pts                 = pFrame->rtStart;
      in_frame->interlaced_frame    = pFrame->interlaced;
      in_frame->top_field_first     = pFrame->tff;
      in_frame->sample_aspect_ratio = pFrame->aspect_ratio;

      if (refcountedFrame) {
        AVBufferRef *pFrameBuf = av_buffer_create(nullptr, 0, lav_free_lavframe, pFrame, 0);
        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get((AVPixelFormat)in_frame->format);
        int planes = (in_frame->format == AV_PIX_FMT_NV12) ? 2 : desc->nb_components;

        for (int i = 0; i < planes; i++) {
          int h_shift    = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
          int plane_size = (in_frame->height >> h_shift) * in_frame->linesize[i];

          AVBufferRef *planeRef = av_buffer_ref(pFrameBuf);
          in_frame->buf[i] = av_buffer_create(in_frame->data[i], plane_size, lav_unref_frame, planeRef, AV_BUFFER_FLAG_READONLY);
        }
        av_buffer_unref(&pFrameBuf);
      }

      m_FilterPrevFrame = *pFrame;
      memset(m_FilterPrevFrame.data, 0, sizeof(m_FilterPrevFrame.data));
      m_FilterPrevFrame.destruct = nullptr;
    } else {
Пример #8
0
static vod_status_t
audio_filter_init_sink(
	request_context_t* request_context,
	AVFilterGraph *filter_graph,
	media_track_t* reference_track,
	const u_char* sink_name,
	audio_filter_sink_t* sink, 
	AVFilterInOut** inputs)
{
	AVCodecContext* encoder;
	AVFilterInOut* input_link;
	enum AVSampleFormat out_sample_fmts[2];
	int64_t out_channel_layouts[2];
	uint64_t channel_layout;
	uint8_t channel_config;
	int out_sample_rates[2];
	int avrc;

	// Note: matching the output to some reference track, may need to change in the future
	//		if filters such as 'join' will be added

	channel_config = reference_track->media_info.u.audio.codec_config.channel_config;
	if (channel_config < vod_array_entries(aac_channel_layout))
	{
		channel_layout = aac_channel_layout[channel_config];
	}
	else
	{
		channel_layout = 0;
	}

	// create the buffer sink
	avrc = avfilter_graph_create_filter(
		&sink->buffer_sink,
		buffersink_filter,
		(char*)sink_name,
		NULL,
		NULL,
		filter_graph);
	if (avrc < 0)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"audio_filter_init_sink: avfilter_graph_create_filter failed %d", avrc);
		return VOD_ALLOC_FAILED;
	}

	// configure the buffer sink
	out_sample_fmts[0] = ENCODER_INPUT_SAMPLE_FORMAT;
	out_sample_fmts[1] = -1;
	avrc = av_opt_set_int_list(
		sink->buffer_sink,
		BUFFERSINK_PARAM_SAMPLE_FORMATS,
		out_sample_fmts,
		-1,
		AV_OPT_SEARCH_CHILDREN);
	if (avrc < 0)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"audio_filter_init_sink: av_opt_set_int_list(sample formats) failed %d", avrc);
		return VOD_UNEXPECTED;
	}

	out_channel_layouts[0] = channel_layout;
	out_channel_layouts[1] = -1;
	avrc = av_opt_set_int_list(
		sink->buffer_sink,
		BUFFERSINK_PARAM_CHANNEL_LAYOUTS,
		out_channel_layouts,
		-1,
		AV_OPT_SEARCH_CHILDREN);
	if (avrc < 0)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"audio_filter_init_sink: av_opt_set_int_list(channel layouts) failed %d", avrc);
		return VOD_UNEXPECTED;
	}

	out_sample_rates[0] = reference_track->media_info.u.audio.sample_rate;
	out_sample_rates[1] = -1;
	avrc = av_opt_set_int_list(
		sink->buffer_sink,
		BUFFERSINK_PARAM_SAMPLE_RATES,
		out_sample_rates,
		-1,
		AV_OPT_SEARCH_CHILDREN);
	if (avrc < 0)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"audio_filter_init_sink: av_opt_set_int_list(sample rates) failed %d", avrc);
		return VOD_UNEXPECTED;
	}

	// init the encoder
	encoder = avcodec_alloc_context3(encoder_codec);
	if (encoder == NULL)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"audio_filter_init_sink: avcodec_alloc_context3 failed");
		return VOD_ALLOC_FAILED;
	}

	sink->encoder = encoder;

	encoder->sample_fmt = ENCODER_INPUT_SAMPLE_FORMAT;
	encoder->sample_rate = reference_track->media_info.u.audio.sample_rate;
	encoder->channel_layout = channel_layout;
	encoder->channels = reference_track->media_info.u.audio.channels;
	encoder->bit_rate = reference_track->media_info.bitrate;
	encoder->flags |= CODEC_FLAG_GLOBAL_HEADER;		// make the codec generate the extra data

	avrc = avcodec_open2(encoder, encoder_codec, NULL);
	if (avrc < 0)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"audio_filter_init_sink: avcodec_open2 failed %d", avrc);
		return VOD_UNEXPECTED;
	}

	// add to the inputs list
	input_link = avfilter_inout_alloc();
	if (input_link == NULL)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"audio_filter_init_sink: avfilter_inout_alloc failed");
		return VOD_ALLOC_FAILED;
	}

	input_link->filter_ctx = sink->buffer_sink;
	input_link->pad_idx = 0;
	input_link->next = *inputs;
	*inputs = input_link;

	input_link->name = av_strdup((const char*)sink_name);
	if (input_link->name == NULL)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"audio_filter_init_source: av_strdup failed");
		return VOD_ALLOC_FAILED;
	}

	return VOD_OK;
}
Пример #9
0
static vod_status_t 
audio_filter_init_filters(
	audio_filter_state_t* state, 
	mpeg_stream_metadata_t* stream_metadata,
	const char *filters_descr)
{
	char filter_args[sizeof(BUFFERSRC_ARGS_FORMAT) + 4 * VOD_INT64_LEN + MAX_SAMPLE_FORMAT_NAME_LEN];
	enum AVSampleFormat out_sample_fmts[2];
	int64_t out_channel_layouts[2];
	int out_sample_rates[2];
	AVFilterInOut *outputs = NULL;
	AVFilterInOut *inputs = NULL;
	int ret;
	int rc;

	// allocate the filter graph
	state->filter_graph = avfilter_graph_alloc();
	if (state->filter_graph == NULL)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: avfilter_graph_alloc failed");
		rc = VOD_ALLOC_FAILED;
		goto end;
	}

	// create the buffer source
	vod_sprintf(filter_args, BUFFERSRC_ARGS_FORMAT,
		state->decoder->time_base.num, 
		state->decoder->time_base.den, 
		state->decoder->sample_rate,
		av_get_sample_fmt_name(state->decoder->sample_fmt), 
		state->decoder->channel_layout);

	ret = avfilter_graph_create_filter(
		&state->buffer_src, 
		buffersrc_filter, 
		INPUT_FILTER_NAME,
		filter_args, 
		NULL, 
		state->filter_graph);
	if (ret < 0)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: avfilter_graph_create_filter(input) failed %d", ret);
		rc = VOD_ALLOC_FAILED;
		goto end;
	}

	// create the buffer sink
	ret = avfilter_graph_create_filter(
		&state->buffer_sink, 
		buffersink_filter, 
		OUTPUT_FILTER_NAME,
		NULL, 
		NULL, 
		state->filter_graph);
	if (ret < 0) 
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: avfilter_graph_create_filter(output) failed %d", ret);
		rc = VOD_ALLOC_FAILED;
		goto end;
	}

	// configure the buffer sink
	out_sample_fmts[0] = ENCODER_INPUT_SAMPLE_FORMAT;
	out_sample_fmts[1] = -1;
	ret = av_opt_set_int_list(
		state->buffer_sink, 
		BUFFERSINK_PARAM_SAMPLE_FORMATS, 
		out_sample_fmts, 
		-1, 
		AV_OPT_SEARCH_CHILDREN);
	if (ret < 0) 
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: av_opt_set_int_list(sample format) failed %d", ret);
		rc = VOD_UNEXPECTED;
		goto end;
	}

	out_channel_layouts[0] = state->decoder->channel_layout;
	out_channel_layouts[1] = -1;
	ret = av_opt_set_int_list(
		state->buffer_sink, 
		BUFFERSINK_PARAM_CHANNEL_LAYOUTS, 
		out_channel_layouts, 
		-1, 
		AV_OPT_SEARCH_CHILDREN);
	if (ret < 0) 
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: av_opt_set_int_list(channel layouts) failed %d", ret);
		rc = VOD_UNEXPECTED;
		goto end;
	}

	out_sample_rates[0] = state->decoder->sample_rate;
	out_sample_rates[1] = -1;
	ret = av_opt_set_int_list(
		state->buffer_sink, 
		BUFFERSINK_PARAM_SAMPLE_RATES, 
		out_sample_rates, 
		-1, 
		AV_OPT_SEARCH_CHILDREN);
	if (ret < 0) 
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: av_opt_set_int_list(sample rates) failed %d", ret);
		rc = VOD_UNEXPECTED;
		goto end;
	}

	// create the filter outputs
	outputs = avfilter_inout_alloc();
	if (outputs == NULL)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: avfilter_inout_alloc failed (1)");
		rc = VOD_ALLOC_FAILED;
		goto end;
	}

	outputs->name = av_strdup(INPUT_FILTER_NAME);
	outputs->filter_ctx = state->buffer_src;
	outputs->pad_idx = 0;
	outputs->next = NULL;

	// create the filter inputs
	inputs = avfilter_inout_alloc();
	if (inputs == NULL)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: avfilter_inout_alloc failed (2)");
		rc = VOD_ALLOC_FAILED;
		goto end;
	}

	inputs->name = av_strdup(OUTPUT_FILTER_NAME);
	inputs->filter_ctx = state->buffer_sink;
	inputs->pad_idx = 0;
	inputs->next = NULL;

	// parse the filter description
	ret = avfilter_graph_parse_ptr(state->filter_graph, filters_descr, &inputs, &outputs, NULL);
	if (ret < 0)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: avfilter_graph_parse_ptr failed %d", ret);
		rc = VOD_UNEXPECTED;
		goto end;
	}

	// validate and configure the graph
	ret = avfilter_graph_config(state->filter_graph, NULL);
	if (ret < 0)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"audio_filter_init_filters: avfilter_graph_config failed %d", ret);
		rc = VOD_UNEXPECTED;
		goto end;
	}

	// set the buffer sink frame size
	if ((state->encoder->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) == 0)
	{
		av_buffersink_set_frame_size(state->buffer_sink, state->encoder->frame_size);
	}

	rc = VOD_OK;

end:
	avfilter_inout_free(&inputs);
	avfilter_inout_free(&outputs);

	return rc;
}
Пример #10
0
static int init_filters(const char *filters_descr)
{
    char args[512];
    int ret = 0;
    AVFilter *buffersrc  = avfilter_get_by_name("buffer");
    AVFilter *buffersink = avfilter_get_by_name("buffersink");
    AVFilterInOut *outputs = avfilter_inout_alloc();
    AVFilterInOut *inputs  = avfilter_inout_alloc();
    AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;
    enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
    AVFilter *vdpau = avfilter_get_by_name("vdpau");

    filter_graph = avfilter_graph_alloc();
    if (!outputs || !inputs || !filter_graph) {
        ret = AVERROR(ENOMEM);
        goto end;
    }

    /* buffer video source: the decoded frames from the decoder will be inserted here. */
    snprintf(args, sizeof(args),
            "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
            dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
            time_base.num, time_base.den,
            dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);

    ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
                                       args, NULL, filter_graph);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
        goto end;
    }

    /* buffer video sink: to terminate the filter chain. */
    ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
                                       NULL, NULL, filter_graph);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
        goto end;
    }

    ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
                              AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
        goto end;
    }


    ret = avfilter_graph_create_filter(&vdpau_ctx, vdpau, "vdpau",
            NULL, NULL, filter_graph);

    vdpau_ctx->hw_device_ctx = device_ref;

    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create vdpau filter.\n");
        goto end;
    }


    /* Connect the filters;
     * in this simple case the filters just form a linear chain. */
    ret = avfilter_link(buffersrc_ctx, 0, vdpau_ctx, 0);
    if (ret >= 0)
        ret = avfilter_link(vdpau_ctx, 0, buffersink_ctx, 0);
    if (ret < 0) {
        fprintf(stderr, "Error connecting filters\n");
        return ret;
    }

    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
        goto end;

end:
    avfilter_inout_free(&inputs);
    avfilter_inout_free(&outputs);

    return ret;
}
Пример #11
0
static int init_filters(AVStream *audio_stream, int audio_stream_index)
{
	AVCodecContext *dec_ctx = audio_stream->codec;

    char args[512];
    int ret = 0;
    AVFilter *abuffersrc  = avfilter_get_by_name("abuffer");
    AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
    AVFilterInOut *outputs = avfilter_inout_alloc();
    AVFilterInOut *inputs  = avfilter_inout_alloc();
    static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
	static const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_STEREO, -1 };
    static const int out_sample_rates[] = { dec_ctx->sample_rate, -1 };
    const AVFilterLink *outlink;
    AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;

    filter_graph = avfilter_graph_alloc();
    if (!outputs || !inputs || !filter_graph) {
        ret = AVERROR(ENOMEM);
        goto end;
    }

    /* buffer audio source: the decoded frames from the decoder will be inserted here. */
    if (!dec_ctx->channel_layout)
        dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels);
    _snprintf_s(args, sizeof(args),
            "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%I64d",
             time_base.num, time_base.den, dec_ctx->sample_rate,
             av_get_sample_fmt_name(dec_ctx->sample_fmt), dec_ctx->channel_layout);
    ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in",
                                       args, NULL, filter_graph);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
        goto end;
    }

    /* buffer audio sink: to terminate the filter chain. */
    ret = avfilter_graph_create_filter(&buffersink_ctx, abuffersink, "out",
                                       NULL, NULL, filter_graph);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
        goto end;
    }

    ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1,
                              AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
        goto end;
    }

    ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
                              AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
        goto end;
    }

    ret = av_opt_set_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1,
                              AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
        goto end;
    }

	last_flt_ctx = buffersink_ctx;
	int index = 1;
	while(filter_descr[index]) {
		const char* name = NULL;
		const char* arg = NULL;

		char tmp[64] = {0};
		char* pos = NULL;
		strncpy_s(tmp, 64, filter_descr[index], 64);
		pos = strchr(tmp, '=');
		if (pos != NULL) {
			*pos = '\0';
			name = tmp;
			arg = pos + 1;
		}
		else {
			name = filter_descr[index];
			arg = NULL;
		}
		insert_filter(name, arg, &last_flt_ctx);
		index++;
	}

    /* Endpoints for the filter graph. */
    outputs->name       = av_strdup("in");
    outputs->filter_ctx = buffersrc_ctx;
    outputs->pad_idx    = 0;
    outputs->next       = NULL;

    inputs->name       = av_strdup("out");
    inputs->filter_ctx = last_flt_ctx;
    inputs->pad_idx    = 0;
    inputs->next       = NULL;

    if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_descr[0],
                                        &inputs, &outputs, NULL)) < 0)
        goto end;

    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
        goto end;

    /* Print summary of the sink buffer
     * Note: args buffer is reused to store channel layout string */
    outlink = buffersink_ctx->inputs[0];
    av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout);
    av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n",
           (int)outlink->sample_rate,
		   (char *)av_x_if_null(av_get_sample_fmt_name((AVSampleFormat)outlink->format), "?"),
           args);

end:
    avfilter_inout_free(&inputs);
    avfilter_inout_free(&outputs);

    return ret;
}
Пример #12
0
int Filters::init(VideoDecoder *decoder)
{
	char args[512];
    int ret = 0;
    AVFilter *buffersrc  = avfilter_get_by_name("buffer");
    AVFilter *buffersink = avfilter_get_by_name("buffersink");
    AVFilterInOut *outputs = avfilter_inout_alloc();
    AVFilterInOut *inputs  = avfilter_inout_alloc();
    enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB8, AV_PIX_FMT_NONE };

    mFilterGraphPtr = avfilter_graph_alloc();
    if (!inputs || !outputs || !mFilterGraphPtr) {
    	LOGE("Alloc filter graph failed");
    	goto end;
    }

    snprintf(args, sizeof(args),
                "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
				decoder->mVideoCodecCtxPtr->width,
				decoder->mVideoCodecCtxPtr->height,
				decoder->mVideoCodecCtxPtr->pix_fmt,
				decoder->mVideoCodecCtxPtr->time_base.num,
				decoder->mVideoCodecCtxPtr->time_base.den,
				decoder->mVideoCodecCtxPtr->sample_aspect_ratio.num,
				decoder->mVideoCodecCtxPtr->sample_aspect_ratio.den);
    LOGD("Buffer args: %s", args);

    ret = avfilter_graph_create_filter(&(mBufSrcCtxPtr), buffersrc, "in",
                                           args, NULL, mFilterGraphPtr);
    if (ret < 0) {
    	LOGE("Create buffer src context failed");
    	goto end;
    }

    ret = avfilter_graph_create_filter(&(mBufSinkCtxPtr), buffersink, "out",
                                           NULL, NULL, mFilterGraphPtr);
    if (ret < 0) {
    	LOGE("Create buffer sink context failed");
    	goto end;
    }

    ret = av_opt_set_int_list(mBufSinkCtxPtr, "pix_fmts", pix_fmts,
                              AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
    	LOGE("Cannot set output pixel format");
        goto end;
    }

    outputs->name       = av_strdup("in");
    outputs->filter_ctx = mBufSrcCtxPtr;
    outputs->pad_idx    = 0;
    outputs->next       = NULL;

    inputs->name       = av_strdup("out");
    inputs->filter_ctx = mBufSinkCtxPtr;
    inputs->pad_idx    = 0;
    inputs->next       = NULL;

    setPixFmt(decoder->mPixFmt);
    LOGD("Filter desc %s", mDesc.c_str());
    if ((ret = avfilter_graph_parse_ptr(mFilterGraphPtr, mDesc.c_str(),
                                        &inputs, &outputs, NULL)) < 0) {
    	LOGE("Parse filter graph failed");
        goto end;
    }

    if ((ret = avfilter_graph_config(mFilterGraphPtr, NULL)) < 0) {
    	LOGE("Config filter graph failed");
        goto end;
    }

end:
	avfilter_inout_free(&inputs);
    avfilter_inout_free(&outputs);
	return ret;
}
Пример #13
0
//初始化滤波器
int init_filters(const char *filters_descr) {
    char args[512];
    int ret = 0;
    AVFilter *buffersrc  = avfilter_get_by_name("buffer");
    AVFilter *buffersink = avfilter_get_by_name("buffersink");
    AVFilterInOut *outputs = avfilter_inout_alloc();
    AVFilterInOut *inputs  = avfilter_inout_alloc();
    AVRational time_base = pFormatCtx->streams[video_stream_index]->time_base;
    enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };

    filter_graph = avfilter_graph_alloc();
    if (!outputs || !inputs || !filter_graph) {
        ret = AVERROR(ENOMEM);
        goto end;
    }

    /* buffer video source: the decoded frames from the decoder will be inserted here. */
    snprintf(args, sizeof(args),
             "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
             pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
             time_base.num, time_base.den,
             pCodecCtx->sample_aspect_ratio.num, pCodecCtx->sample_aspect_ratio.den);

    ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
                                       args, NULL, filter_graph);
    if (ret < 0) {
        LOGE("Cannot create buffer source\n");
        goto end;
    }

    /* buffer video sink: to terminate the filter chain. */
    ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
                                       NULL, NULL, filter_graph);
    if (ret < 0) {
        LOGE("Cannot create buffer sink\n");
        goto end;
    }

    ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
                              AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
    if (ret < 0) {
        LOGE("Cannot set output pixel format\n");
        goto end;
    }

    outputs->name       = av_strdup("in");
    outputs->filter_ctx = buffersrc_ctx;
    outputs->pad_idx    = 0;
    outputs->next       = NULL;

    inputs->name       = av_strdup("out");
    inputs->filter_ctx = buffersink_ctx;
    inputs->pad_idx    = 0;
    inputs->next       = NULL;

    if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
                                        &inputs, &outputs, NULL)) < 0)
        goto end;

    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
        goto end;

    end:
    avfilter_inout_free(&inputs);
    avfilter_inout_free(&outputs);

    return ret;
}