このコードは、ffmpegdocの1つのサンプルコードである_video.cのフィルタリングとほぼ同じです。
元のサンプルファイルには、多くのグローバル静的変数があります。これが最初のバージョンコードの1つのスニペットです(元のサンプルと同じです):
static AVFormatContext *fmt_ctx;
static AVCodecContext *dec_ctx;
int main(int argc, char **argv) {
// .... other code
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
// .... other code
}
これらの変数はすべてビデオファイルを開くために役立つので、私はそれらをグループ化することを好みます。したがって、私のコードの目的は、これらの変数を再配置して、ソースファイルをより構造化することです。
最初に頭に浮かんだのは、構造体を使用することです。
struct structForInVFile {
AVFormatContext *inFormatContext;
AVCodecContext *inCodecContext;
AVCodec* inCodec;
AVPacket inPacket;
AVFrame *inFrame;
int video_stream_index;
int inFrameRate;
int in_got_frame;
};
これで、コードの2番目のバージョンは次のようになります。
int main(int argc, char **argv) {
// .... other code
structForInVFile inStruct;
if ((ret = avformat_open_input(&inStruct.inFormatContext, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
// .... other code
}
2番目のバージョンの結果:コードはavformat_open_inputで機能しません。エラー情報はありません。プログラムはサイレントに終了します。デバッグを通じて、次のことがわかりました。inStruct.inFormatContext:0xffffefbd22b60000
コードの3番目のバージョンでは、inStructをグローバル変数として設定しました。コードは次のようになります。
structForInVFile inStruct;
int main(int argc, char **argv) {
// .... other code
if ((ret = avformat_open_input(&inStruct.inFormatContext, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
// .... other code
}
3番目のバージョンの結果:コードは機能します。デバッグを通して、私はそれを見つけます:inStruct.inFormatContext:0x0
したがって、その理由は次のとおりです。avformat_open_inputが機能するには、AVFormatContextをゼロで初期化する必要があります。さて、問題は次のとおりです。
AVFormatContextポインタが非グローバル構造体オブジェクトで初期化されているのに、グローバルオブジェクトでゼロ初期化されているのはなぜですか?
グローバル変数と非グローバル変数としての構造体オブジェクトの定義の違いはわかりません。