]> git.sesse.net Git - nageru/blob - nageru/ffmpeg_util.cpp
Fix a dangling reference (found by GCC 14).
[nageru] / nageru / ffmpeg_util.cpp
1 #include "ffmpeg_util.h"
2
3 #include <errno.h>
4 #include <stddef.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <ctype.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10
11 #include <string>
12 #include <vector>
13
14 extern "C" {
15 #include <libavformat/avformat.h>
16 #include <libavutil/avutil.h>
17 #include <libavutil/common.h>
18 }
19
20 #include "flags.h"
21
22 using namespace std;
23
24 string search_for_file(const string &filename)
25 {
26         if (!filename.empty() && filename[0] == '/') {
27                 // Absolute path.
28                 return filename;
29         }
30
31         // See if we match ^[a-z]:/, which is probably a URL of some sort
32         // (FFmpeg understands various forms of these).
33         for (size_t i = 0; i < filename.size() - 1; ++i) {
34                 if (filename[i] == ':' && filename[i + 1] == '/') {
35                         return filename;
36                 }
37                 if (!isalpha(filename[i])) {
38                         break;
39                 }
40         }
41
42         // Look for the file in all theme_dirs until we find one;
43         // that will be the permanent resolution of this file, whether
44         // it is actually valid or not.
45         // We store errors from all the attempts, and show them
46         // once we know we can't find any of them.
47         vector<string> errors;
48         for (const string &dir : global_flags.theme_dirs) {
49                 string pathname = dir + "/" + filename;
50                 if (access(pathname.c_str(), O_RDONLY) == 0) {
51                         return pathname;
52                 } else {
53                         char buf[512];
54                         snprintf(buf, sizeof(buf), "%s: %s", pathname.c_str(), strerror(errno));
55                         errors.push_back(buf);
56                 }
57         }
58
59         for (const string &error : errors) {
60                 fprintf(stderr, "%s\n", error.c_str());
61         }
62         return "";
63 }
64
65 string search_for_file_or_die(const string &filename)
66 {
67         string pathname = search_for_file(filename);
68         if (pathname.empty()) {
69                 fprintf(stderr, "Couldn't find %s in any directory in --theme-dirs, exiting.\n",
70                         filename.c_str());
71                 abort();
72         }
73         return pathname;
74 }
75
76 int find_stream_index(AVFormatContext *ctx, AVMediaType media_type)
77 {
78         for (unsigned i = 0; i < ctx->nb_streams; ++i) {
79                 if (ctx->streams[i]->codecpar->codec_type == media_type) {
80                         return i;
81                 }
82         }
83         return -1;
84 }
85