2017-03-27 15 views
1

FFMPEG Webサイトでホストされているtranscoding.cサンプルを実装します。しかし、avfilter_graph_create_filter関数は、戻りコード-22(行175)で失敗しました。ソースコードをマイナーチェンジして、C++コンソールアプリケーションで実行可能にしました。私もオンラインで検索しましたが、役に立つ情報は見つかりませんでした。FFMPEG:フィルタを初期化するときにavfilter_graph_create_filterメソッドが失敗しました

extern "C" 
{ 
#include <libavcodec/avcodec.h> 
#include <libavformat/avformat.h> 
#include <libavfilter/avfiltergraph.h> 
#include <libavfilter/buffersink.h> 
#include <libavfilter/buffersrc.h> 
#include <libavutil/opt.h> 
#include <libavutil/pixdesc.h> 
} 
static AVFormatContext *ifmt_ctx; 
static AVFormatContext *ofmt_ctx; 
typedef struct FilteringContext { 
    AVFilterContext *buffersink_ctx; 
    AVFilterContext *buffersrc_ctx; 
    AVFilterGraph *filter_graph; 
} FilteringContext; 
static FilteringContext *filter_ctx; 

static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx, 
    AVCodecContext *enc_ctx, const char *filter_spec) 
{ 
    char args[512]; 
    int ret = 0; 
    AVFilter *buffersrc = NULL; 
    AVFilter *buffersink = NULL; 
    AVFilterContext *buffersrc_ctx = NULL; 
    AVFilterContext *buffersink_ctx = NULL; 
    AVFilterInOut *outputs = avfilter_inout_alloc(); 
    AVFilterInOut *inputs = avfilter_inout_alloc(); 
    AVFilterGraph *filter_graph = avfilter_graph_alloc(); 
    if (!outputs || !inputs || !filter_graph) { 
     ret = AVERROR(ENOMEM); 
     goto end; 
    } 
    if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) { 
     buffersrc = avfilter_get_by_name("buffer"); 
     buffersink = avfilter_get_by_name("buffersink"); 
     if (!buffersrc || !buffersink) { 
      av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n"); 
      ret = AVERROR_UNKNOWN; 
      goto end; 
     } 
     /*sprintf(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, 
      dec_ctx->time_base.num, dec_ctx->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; 
     } 
     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_bin(buffersink_ctx, "pix_fmts", 
      (uint8_t*)&enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt), 
      AV_OPT_SEARCH_CHILDREN); 
     if (ret < 0) { 
      av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n"); 
      goto end; 
     } 
    } 
    else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { 
     buffersrc = avfilter_get_by_name("abuffer"); 
     buffersink = avfilter_get_by_name("abuffersink"); 
     if (!buffersrc || !buffersink) { 
      av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n"); 
      ret = AVERROR_UNKNOWN; 
      goto end; 
     } 
     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, 
      dec_ctx->time_base.num, dec_ctx->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, buffersrc, "in", 
      args, NULL, filter_graph); 
     if (ret < 0) { 
      av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n"); 
      goto end; 
     } 
     ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "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_bin(buffersink_ctx, "sample_fmts", 
      (uint8_t*)&enc_ctx->sample_fmt, sizeof(enc_ctx->sample_fmt), 
      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_bin(buffersink_ctx, "channel_layouts", 
      (uint8_t*)&enc_ctx->channel_layout, 
      sizeof(enc_ctx->channel_layout), 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_bin(buffersink_ctx, "sample_rates", 
      (uint8_t*)&enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate), 
      AV_OPT_SEARCH_CHILDREN); 
     if (ret < 0) { 
      av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n"); 
      goto end; 
     } 
    } 
    else { 
     ret = AVERROR_UNKNOWN; 
     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 (!outputs->name || !inputs->name) { 
     ret = AVERROR(ENOMEM); 
     goto end; 
    } 
    if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec, 
     &inputs, &outputs, NULL)) < 0) 
     goto end; 
    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) 
     goto end; 
    /* Fill FilteringContext */ 
    fctx->buffersrc_ctx = buffersrc_ctx; 
    fctx->buffersink_ctx = buffersink_ctx; 
    fctx->filter_graph = filter_graph; 
end: 
    avfilter_inout_free(&inputs); 
    avfilter_inout_free(&outputs); 
    return ret; 
} 
static int init_filters(void) 
{ 
    const char *filter_spec; 
    unsigned int i; 
    int ret; 
    filter_ctx = (FilteringContext *)av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx)); 
    if (!filter_ctx) 
     return AVERROR(ENOMEM); 
    for (i = 0; i < ifmt_ctx->nb_streams; i++) { 
     filter_ctx[i].buffersrc_ctx = NULL; 
     filter_ctx[i].buffersink_ctx = NULL; 
     filter_ctx[i].filter_graph = NULL; 
     if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO 
      || ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)) 
      continue; 
     if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) 
      filter_spec = "null"; /* passthrough (dummy) filter for video */ 
     else 
      filter_spec = "anull"; /* passthrough (dummy) filter for audio */ 
     ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec, 
      ofmt_ctx->streams[i]->codec, filter_spec); 
     if (ret) 
      return ret; 
    } 
    return 0; 
} 

int main(int argc, char **argv) 
{ 
    int ret; 
    AVPacket packet = { NULL, 0 }; 
    AVFrame *frame = NULL; 
    enum AVMediaType type; 
    unsigned int stream_index; 
    unsigned int i; 
    int got_frame; 
    int(*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *); 

    av_register_all(); 
    avfilter_register_all(); 

    if ((ret = init_filters()) < 0) 
     goto end; 
    /*...*/ 
    system("Pause"); 
    return ret ? 1 : 0; 
} 
+1

コードを編集して問題の[mcve]に減らしてください。あなたの現在のコードには、問題の周辺にあるものが多く含まれています。通常、最小単位のサンプルは良い単位テストと似ています。 –

+0

返信ありがとう、私はこの質問に無関係だと思うコードを削除しました。 –

答えて

1

-22またはEINVALは、1つまたは複数の無効な引数の場合に返されるエラーコード: 以下は私のコードです。 buffersrcフィルタを作成しようとすると、入力ビデオのサイズとフォーマットを記述する追加の引数文字列(args)が使用されます。エラーが発生した文字列の作成をコメントします。

// this should not be comment out, or replaced with way of setting the arguments 
/*sprintf(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, 
      dec_ctx->time_base.num, dec_ctx->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); 

フィルタは、例えば、これらにレイアウトされている方法は?そこに3つのRGBチャネルまたは3つのYUVチャネルでどのように大きな着信フレームがあり、どのように読み取り値を解釈する(知らない場合、すなわち、それらは平面またはパックされています?)それからどうやってそれらを読むべきですか?そうですね、それはできませんし、エラーメッセージでそれを伝えようとします。

+0

ええ、そうです。私はそれが私のC + +コードでコンパイラエラーが発生したので、私は2番目のパラメータを削除することによってそれを修正し、今は期待どおりに動作するので、それをコメントアウトした。 –

+0

より良い解決策は 'sizeof args'を維持することですが、' snprintf() 'を呼び出すことです。これは意図されているようです。 –

関連する問題