Reputation: 51
I haven't ever used ffmpeg on my own laptop. All's ok at work, but here I met an ugly problem: library works but helpless:) Ubuntu 18.04, ffmpeg 4.1 (downloaded sources, ./configure, make, sudo make install), it seems to be ok.
Application returns: File /home/ahlininv/Desktop/video_example.mp4 is encodec with '' codec, w = 0, h = 0
I ran it under debugger. If I set format to zero, pointer changes after calling avformat_open_input(&format, file, 0, &dict), so it works and maybe works correct.
Maybe it plays any role that compiler says that av_register_all, avcodec_register_all are deprecated, but I thought it's not significant problem.
I tried to change version of ffmpeg (tried to install it with apt-get, version 3.somenumber is available), nothing changed.
I tried to run another video file (.avi), nothing changed, too.
Guys, help=) How to this file's info correctly?
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;
}
Compile:
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/
Upvotes: 2
Views: 1220
Reputation: 1988
Can you add these lines Before for
loop on filereader.cpp to see if it makes any difference.
if (avformat_find_stream_info(format, NULL) < 0)
{
//handle error
}
Upvotes: 2