C ++ avformat_open_input返回空的编解码器,宽度和高度

时间:2019-02-26 00:44:21

标签: c++ ffmpeg ubuntu-18.04

我从未在自己的笔记本电脑上使用过ffmpeg。一切正常,但在这里我遇到了一个丑陋的问题:库有效,但无奈:) Ubuntu 18.04,ffmpeg 4.1(下载的源代码,。/ configure,make,sudo make install),似乎还可以。

应用程序返回: 文件/home/ahlininv/Desktop/video_example.mp4是带有''编解码器的编码器,w = 0,h = 0

我在调试器下运行它。如果我将format设置为零,则在调用 avformat_open_input(&format,file,0,&dict)之后,指针会发生变化,因此它可以正常工作,并且也许可以正常工作。

编译器认为 av_register_all,avcodec_register_all 已过时,也许起了任何作用,但我认为这不是一个重大问题。

我尝试更改ffmpeg的版本(尝试使用apt-get安装,版本3.somenumber可用),没有任何更改。

我尝试运行另一个视频文件(.avi),也没有任何变化。

人,help =)如何正确获取此文件的信息?

main.cpp:

#include "filereader.h"

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

    std::string filename = "/home/ahlininv/Desktop/video_example.mp4";

    std::string codec;
    int w, h;
    bool open_ok = get_file_info(filename.c_str(), codec, w, h);
    if (!open_ok) {
        std::cout << "Failed to open file" << "\n";
        return 1;
    }

    std::cout << "File " << filename << " is encoded with '" << codec << "' codec, w = " << w << ", h = " << h << "\n";

    return 0;
}

filereader.h:

#ifndef FILEREADER_H
#define FILEREADER_H

#include <string>
#include <iostream>

extern "C" {
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include "libavcodec/avcodec.h"
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
}

bool get_file_info(const char* file, std::string& codec, int& w, int& h);

#endif // FILEREADER_H

filereader.cpp

#include "filereader.h"


bool get_file_info(const char* file, std::string& codec, int& w, int& h)
{
    codec = "";
    w = h = 0;

    av_register_all();
    avcodec_register_all();

    AVDictionary* dict = 0;
    AVFormatContext* format = avformat_alloc_context();

    char errbuf[256];
    int r = avformat_open_input(&format, file, 0, &dict);
    if (r!=0){
        av_strerror(r, errbuf, sizeof(errbuf));
        std::cout << "avformat_open_input error: " << errbuf << "\n";
    }

    if (r == AVERROR(EIO) || r == AVERROR(ENOEXEC) || !format)
        return false;

    for (size_t c = 0; c < format->nb_streams; ++c)
    {
        if (format->streams[c]->codecpar && format->streams[c]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            if (format->streams[c]->codecpar->codec_id != AV_CODEC_ID_NONE &&
                    format->streams[c]->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO)
            {
                w = format->streams[c]->codecpar->width;
                h = format->streams[c]->codecpar->height;
                codec = avcodec_get_name(format->streams[c]->codecpar->codec_id);
            }
        }
    }
    avformat_close_input(&format);
    return true;
}

编译:

g++ -o filereader main.cpp filereader.cpp -lavutil -lavformat -lavcodec -lavdevice -lz -lm -pthread -lswresample -lm -lz -I /usr/local/include/ -Wl,-rpath /usr/lib/x86_64-linux-gnu/

1 个答案:

答案 0 :(得分:0)

您可以在 filereader.cpp 上的for循环之前添加这些行,以查看是否有区别。

if (avformat_find_stream_info(format, NULL) < 0)
{
    //handle error
}