2017-06-26 7 views
-3

このコード例を少し変更しました(C++でコンパイルするだけです): https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/transcoding.c動作しませんどのような(ヌルフィルタ)であるとして、フレームレート、のDrawText、のような他のフィルタの数を...トランスコードの例で使用するとスケールフィルタがエラーでクラッシュする

どう働く規模フィルタスケールダウン。

エラーがです:「入力画像: "-1 = IWは、W/2 =スケール" :

は、私は(私も多くの人が試してみた、同じ効果)規模のために、次の構文を使用しますwidth(240)がstride(128)より大きい場合」widthおよびstrideの値は入力に依存します。

その他の環境情報:窓、2017 VS、入力例:RTSP://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov

についてどのような手掛かり何私が間違ってやっていますか?

ありがとうございます!


作業コードサンプル解決策を見つけた


#pragma comment(lib, "avcodec.lib") 
#pragma comment(lib, "avutil.lib") 
#pragma comment(lib, "avformat.lib") 
#pragma comment(lib, "avfilter.lib") 

/* 
* Copyright (c) 2010 Nicolas George 
* Copyright (c) 2011 Stefano Sabatini 
* Copyright (c) 2014 Andrey Utkin 
* 
**** EDITED 2017 for testing (see original here: https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/transcoding.c) 
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy 
* of this software and associated documentation files (the "Software"), to deal 
* in the Software without restriction, including without limitation the rights 
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
* copies of the Software, and to permit persons to whom the Software is 
* furnished to do so, subject to the following conditions: 
* 
* The above copyright notice and this permission notice shall be included in 
* all copies or substantial portions of the Software. 
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
* THE SOFTWARE. 
*/ 

/** 
* @file 
* API example for demuxing, decoding, filtering, encoding and muxing 
* @example transcoding.c 
*/ 

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; 

typedef struct StreamContext { 
    AVCodecContext *dec_ctx; 
    AVCodecContext *enc_ctx; 
} StreamContext; 
static StreamContext *stream_ctx; 

static int open_input_file(const char *filename, int& videoStreamIndex) 
{ 
    int ret; 
    unsigned int i; 

    ifmt_ctx = NULL; 
    if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) { 
     av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n"); 
     return ret; 
    } 

    if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) { 
     av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n"); 
     return ret; 
    } 

    // Just need video 
    videoStreamIndex = -1; 
    for (unsigned int i = 0; i < ifmt_ctx->nb_streams; i++) 
    { 
     if (ifmt_ctx->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) 
      continue; 
     videoStreamIndex = i; 
     break; 
    } 
    if (videoStreamIndex < 0) 
    { 
     av_log(NULL, AV_LOG_ERROR, "Cannot find video stream\n"); 
     return videoStreamIndex; 
    } 


    stream_ctx = (StreamContext*)av_mallocz_array(ifmt_ctx->nb_streams, sizeof(*stream_ctx)); 
    if (!stream_ctx) 
     return AVERROR(ENOMEM); 

    for (i = 0; i < ifmt_ctx->nb_streams; i++) { 

     // Just need video 
     if (i != videoStreamIndex) 
      continue; 


     AVStream *stream = ifmt_ctx->streams[i]; 
     AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id); 
     AVCodecContext *codec_ctx; 
     if (!dec) { 
      av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i); 
      return AVERROR_DECODER_NOT_FOUND; 
     } 
     codec_ctx = avcodec_alloc_context3(dec); 
     if (!codec_ctx) { 
      av_log(NULL, AV_LOG_ERROR, "Failed to allocate the decoder context for stream #%u\n", i); 
      return AVERROR(ENOMEM); 
     } 
     ret = avcodec_parameters_to_context(codec_ctx, stream->codecpar); 
     if (ret < 0) { 
      av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context " 
       "for stream #%u\n", i); 
      return ret; 
     } 
     /* Reencode video & audio and remux subtitles etc. */ 
     if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO 
      || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { 
      if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) 
       codec_ctx->framerate = av_guess_frame_rate(ifmt_ctx, stream, NULL); 
      /* Open decoder */ 
      ret = avcodec_open2(codec_ctx, dec, NULL); 
      if (ret < 0) { 
       av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i); 
       return ret; 
      } 
     } 
     stream_ctx[i].dec_ctx = codec_ctx; 
    } 

    av_dump_format(ifmt_ctx, 0, filename, 0); 
    return 0; 
} 

static int open_output_file(const char *filename, const int videoStreamIndex) 
{ 
    AVStream *out_stream; 
    AVStream *in_stream; 
    AVCodecContext *dec_ctx, *enc_ctx; 
    AVCodec *encoder; 
    int ret; 
    unsigned int i; 

    ofmt_ctx = NULL; 
    avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename); 
    if (!ofmt_ctx) { 
     av_log(NULL, AV_LOG_ERROR, "Could not create output context\n"); 
     return AVERROR_UNKNOWN; 
    } 


    for (i = 0; i < ifmt_ctx->nb_streams; i++) { 
     // Just need video 
     if (i != videoStreamIndex) 
      continue; 

     out_stream = avformat_new_stream(ofmt_ctx, NULL); 
     if (!out_stream) { 
      av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n"); 
      return AVERROR_UNKNOWN; 
     } 

     in_stream = ifmt_ctx->streams[i]; 
     dec_ctx = stream_ctx[i].dec_ctx; 

     if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) { 
      /* in this example, we choose transcoding to same codec */ 
      encoder = avcodec_find_encoder(dec_ctx->codec_id); 
      if (!encoder) { 
       av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n"); 
       return AVERROR_INVALIDDATA; 
      } 
      enc_ctx = avcodec_alloc_context3(encoder); 
      if (!enc_ctx) { 
       av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n"); 
       return AVERROR(ENOMEM); 
      } 

      /* In this example, we transcode to same properties (picture size, 
      * sample rate etc.). These properties can be changed for output 
      * streams easily using filters */ 
      enc_ctx->height = dec_ctx->height; 
      enc_ctx->width = dec_ctx->width; 
      enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio; 
      /* take first format from list of supported formats */ 
      if (encoder->pix_fmts) 
       enc_ctx->pix_fmt = encoder->pix_fmts[0]; 
      else 
       enc_ctx->pix_fmt = dec_ctx->pix_fmt; 

      /* video time_base can be set to whatever is handy and supported by encoder */ 
      //enc_ctx->time_base = av_inv_q(dec_ctx->framerate); 
      enc_ctx->time_base = dec_ctx->time_base; 


      /* Third parameter can be used to pass settings to encoder */ 
      ret = avcodec_open2(enc_ctx, encoder, NULL); 
      if (ret < 0) { 
       av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i); 
       return ret; 
      } 
      ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx); 
      if (ret < 0) { 
       av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream #%u\n", i); 
       return ret; 
      } 
      if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) 
       enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; 

      out_stream->time_base = enc_ctx->time_base; 
      stream_ctx[i].enc_ctx = enc_ctx; 
     } 
     else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) { 
      av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i); 
      return AVERROR_INVALIDDATA; 
     } 
     else { 
      /* if this stream must be remuxed */ 
      ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar); 
      if (ret < 0) { 
       av_log(NULL, AV_LOG_ERROR, "Copying parameters for stream #%u failed\n", i); 
       return ret; 
      } 
      out_stream->time_base = in_stream->time_base; 
     } 

    } 
    av_dump_format(ofmt_ctx, 0, filename, 1); 

    if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) { 
     ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE); 
     if (ret < 0) { 
      av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", filename); 
      return ret; 
     } 
    } 

    /* init muxer, write output file header */ 
    ret = avformat_write_header(ofmt_ctx, NULL); 
    if (ret < 0) { 
     av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n"); 
     return ret; 
    } 

    return 0; 
} 

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; 
     } 

     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, 
      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 { 
     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(const int videoStreamIndex) 
{ 
    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++) { 

     // Just video 
     if (i != videoStreamIndex) 
      continue; 

     filter_ctx[i].buffersrc_ctx = NULL; 
     filter_ctx[i].buffersink_ctx = NULL; 
     filter_ctx[i].filter_graph = NULL; 
     if (!(ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO 
      || ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)) 
      continue; 

     filter_spec = "null"; /* passthrough (dummy) filter for video */ 
     //filter_spec = "scale=w=iw/2:-1"; 
     // filter_spec = "drawtext=fontfile=FreeSerif.ttf: text='%{localtime}': x=w-text_w: y=0: fontsize=24: [email protected]: box=1: [email protected]"; 
     // filter_spec = "drawtext=fontfile=FreeSerif.ttf :text='test': x=w-text_w: y=text_h: fontsize=24: [email protected]: box=1: [email protected]"; 

     ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx, 
      stream_ctx[i].enc_ctx, filter_spec); 
     if (ret) 
      return ret; 
    } 
    return 0; 
} 

static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame, const int videoStreamIndex) { 

    // Just video 
    if (stream_index != videoStreamIndex) 
     return 0; 

    int ret; 
    int got_frame_local; 
    AVPacket enc_pkt; 
    int(*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) = 
     (ifmt_ctx->streams[stream_index]->codecpar->codec_type == 
      AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2; 

    if (!got_frame) 
     got_frame = &got_frame_local; 

    // av_log(NULL, AV_LOG_INFO, "Encoding frame\n"); 
    /* encode filtered frame */ 
    enc_pkt.data = NULL; 
    enc_pkt.size = 0; 
    av_init_packet(&enc_pkt); 

    ret = enc_func(stream_ctx[stream_index].enc_ctx, &enc_pkt, 
     filt_frame, got_frame); 

    av_frame_free(&filt_frame); 
    if (ret < 0) 
     return ret; 
    if (!(*got_frame)) 
     return 0; 

    /* prepare packet for muxing */ 
    /*enc_pkt.stream_index = stream_index; 
    av_packet_rescale_ts(&enc_pkt, stream_ctx[stream_index].enc_ctx->time_base, ofmt_ctx->streams[stream_index]->time_base);*/ 
    enc_pkt.stream_index = 0; 
    av_packet_rescale_ts(&enc_pkt, stream_ctx[stream_index].enc_ctx->time_base, ofmt_ctx->streams[0]->time_base); 

    av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n"); 
    /* mux encoded frame */ 
    ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt); 
    return ret; 
} 

static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index, const int videoStreamIndex) 
{ 
    // Just video, all else crashes 
    if (stream_index != videoStreamIndex) 
     return 0; 

    int ret; 
    AVFrame *filt_frame; 

    // av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n"); 
    /* push the decoded frame into the filtergraph */ 
    ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx, 
     frame, 0); 
    if (ret < 0) { 
     av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n"); 
     return ret; 
    } 

    /* pull filtered frames from the filtergraph */ 
    while (1) { 
     filt_frame = av_frame_alloc(); 
     if (!filt_frame) { 
      ret = AVERROR(ENOMEM); 
      break; 
     } 
     // av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n"); 
     ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx, 
      filt_frame); 
     if (ret < 0) { 
      /* if no more frames for output - returns AVERROR(EAGAIN) 
      * if flushed and no more frames for output - returns AVERROR_EOF 
      * rewrite retcode to 0 to show it as normal procedure completion 
      */ 
      if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) 
       ret = 0; 
      av_frame_free(&filt_frame); 
      break; 
     } 

     filt_frame->pict_type = AV_PICTURE_TYPE_NONE; 
     ret = encode_write_frame(filt_frame, stream_index, NULL, videoStreamIndex); 
     if (ret < 0) 
      break; 
    } 

    return ret; 
} 

static int flush_encoder(unsigned int stream_index, const int videoStreamIndex) 
{ 
    int ret; 
    int got_frame; 

    // Just video 
    if (stream_index != videoStreamIndex) 
     return 0; 

    if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities & 
     AV_CODEC_CAP_DELAY)) 
     return 0; 

    while (1) { 
     av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index); 
     ret = encode_write_frame(NULL, stream_index, &got_frame, videoStreamIndex); 
     if (ret < 0) 
      break; 
     if (!got_frame) 
      return 0; 
    } 
    return ret; 
} 


#include <vector> 

int main(int argc, char **argv) 
{ 
    int ret; 

    AVPacket packet; 
    packet.data = NULL; 
    packet.size = 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 *); 


#ifdef _DEBUG 
    // Hardcoded arguments 
    std::vector<char*> varguments; 
    { 
     varguments.push_back(argv[0]); 

     // Source 
     varguments.push_back("./big_buck_bunny_short.mp4 "); 

     // Destination 
     varguments.push_back("./big_buck_bunny_short-processed.mp4"); 
    } 

    char** arguments = new char*[varguments.size()]; 
    for (unsigned int i = 0; i < varguments.size(); i++) 
    { 
     arguments[i] = varguments[i]; 
    } 
    argc = varguments.size(); 
    argv = arguments; 
#endif // _DEBUG 


    if (argc != 3) { 
     av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <output file>\n", argv[0]); 
     return 1; 
    } 

    av_register_all(); 
    avfilter_register_all(); 

    int videoStreamIndex = -1; 
    if ((ret = open_input_file(argv[1], videoStreamIndex)) < 0) 
     goto end; 
    if ((ret = open_output_file(argv[2], videoStreamIndex)) < 0) 
     goto end; 
    if ((ret = init_filters(videoStreamIndex)) < 0) 
     goto end; 

    // Stop after a couple of frames 
    int framesToGet = 100; 

    /* read all packets */ 
    //while (framesToGet--) 
    while(1) 
    { 
     if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0) 
      break; 
     stream_index = packet.stream_index; 

     // I just need video 
     if (stream_index != videoStreamIndex) { 
      av_packet_unref(&packet); 
      continue; 
     } 

     type = ifmt_ctx->streams[packet.stream_index]->codecpar->codec_type; 
     av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n", 
      stream_index); 

     if (filter_ctx[stream_index].filter_graph) { 
      av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n"); 
      frame = av_frame_alloc(); 
      if (!frame) { 
       ret = AVERROR(ENOMEM); 
       break; 
      } 
      av_packet_rescale_ts(&packet, 
       ifmt_ctx->streams[stream_index]->time_base, 
       stream_ctx[stream_index].dec_ctx->time_base); 
      dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 : 
       avcodec_decode_audio4; 
      ret = dec_func(stream_ctx[stream_index].dec_ctx, frame, 
       &got_frame, &packet); 
      if (ret < 0) { 
       av_frame_free(&frame); 
       av_log(NULL, AV_LOG_ERROR, "Decoding failed\n"); 
       break; 
      } 

      if (got_frame) { 
       frame->pts = frame->best_effort_timestamp; 
       ret = filter_encode_write_frame(frame, stream_index, videoStreamIndex); 
       av_frame_free(&frame); 
       if (ret < 0) 
        goto end; 
      } 
      else { 
       av_frame_free(&frame); 
      } 
     } 
     else { 
      /* remux this frame without reencoding */ 
      av_packet_rescale_ts(&packet, 
       ifmt_ctx->streams[stream_index]->time_base, 
       ofmt_ctx->streams[stream_index]->time_base); 

      ret = av_interleaved_write_frame(ofmt_ctx, &packet); 
      if (ret < 0) 
       goto end; 
     } 
     av_packet_unref(&packet); 
    } 

    /* flush filters and encoders */ 
    for (i = 0; i < ifmt_ctx->nb_streams; i++) { 
     /* flush filter */ 
     if (!filter_ctx[i].filter_graph) 
      continue; 
     ret = filter_encode_write_frame(NULL, i, videoStreamIndex); 
     if (ret < 0) { 
      av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n"); 
      goto end; 
     } 

     /* flush encoder */ 
     ret = flush_encoder(i, videoStreamIndex); 
     if (ret < 0) { 
      av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n"); 
      goto end; 
     } 
    } 

    av_write_trailer(ofmt_ctx); 
end: 
    av_packet_unref(&packet); 
    av_frame_free(&frame); 
    for (i = 0; i < ifmt_ctx->nb_streams; i++) { 
     // Just video 
     if (i != videoStreamIndex) 
      continue; 
     avcodec_free_context(&stream_ctx[i].dec_ctx); 
     if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && stream_ctx[i].enc_ctx) 
      avcodec_free_context(&stream_ctx[i].enc_ctx); 
     if (filter_ctx && filter_ctx[i].filter_graph) 
      avfilter_graph_free(&filter_ctx[i].filter_graph); 
    } 
    av_free(filter_ctx); 
    av_free(stream_ctx); 
    avformat_close_input(&ifmt_ctx); 
    if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) 
     avio_closep(&ofmt_ctx->pb); 
    avformat_free_context(ofmt_ctx); 

    /*if (ret < 0) 
     av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));*/ 

    return ret ? 1 : 0; 
} 
+2

ようこそスタックオーバーフロー。 [The Tour](http://stackoverflow.com/tour)を読み、[ヘルプセンター](http://stackoverflow.com/help/asking)の資料を参考にしてください。ここに聞いてください。 –

+0

このような問題を解決する適切なツールは、デバッガです。スタックオーバーフローを尋ねる前に、コードを一行ずつ進める必要があります。詳しいヘルプは、[小さなプログラムをデバッグする方法(Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を参照してください。少なくとも、問題を再現する[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例と、デバッガでの観察結果を含めるように質問を編集する必要があります。 –

+0

答えはエラーメッセージです。入力画像の幅がストライドよりも大きい。ストライドを正しく設定してください。フレーム上の唯一のストライド@szatmary – szatmary

答えて

0

を追加するように編集。

正確に同じフィルタ文字列を使ってcmd-line ffmpegを呼び出すのはパラメータを追加しなくても動作しますが、コードではスケーリングの際にエンコードコンテキストオプションも設定する必要があります。彼らは次のようになり上記のテストコードで

enc_ctx->height = dec_ctx->height * scale_value; 
enc_ctx->width = dec_ctx->width * scale_value; 

これは、ダウンスケーリング時にエラーをアップスケーリングとするとき、クロッピングの問題の両方を解決するようです。

この度はお返事ありがとうございました&ご迷惑をおかけして申し訳ありませんが、私の投稿は不明です(これは初めてです)。

関連する問題