]> git.sesse.net Git - nageru/commitdiff
Move some common FFmpeg utilities out into a shared file, instead of having them...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 14 Apr 2017 23:52:05 +0000 (01:52 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 14 Apr 2017 23:52:05 +0000 (01:52 +0200)
Makefile
ffmpeg_capture.cpp
ffmpeg_util.cpp [new file with mode: 0644]
ffmpeg_util.h [new file with mode: 0644]
image_input.cpp
image_input.h

index 20b5f2549b612f9955fca59675ba2a24ad11fc3a..9dc55261a97068601a560001d30be91f7a23bc2a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ AUDIO_MIXER_OBJS = audio_mixer.o alsa_input.o alsa_pool.o ebu_r128_proc.o stereo
 OBJS += chroma_subsampler.o v210_converter.o mixer.o pbo_frame_allocator.o context.o ref_counted_frame.o theme.o httpd.o flags.o image_input.o alsa_output.o disk_space_estimator.o print_latency.o timecode_renderer.o $(AUDIO_MIXER_OBJS)
 
 # Streaming and encoding objects
-OBJS += quicksync_encoder.o x264_encoder.o x264_dynamic.o x264_speed_control.o video_encoder.o metacube2.o mux.o audio_encoder.o ffmpeg_raii.o
+OBJS += quicksync_encoder.o x264_encoder.o x264_dynamic.o x264_speed_control.o video_encoder.o metacube2.o mux.o audio_encoder.o ffmpeg_raii.o ffmpeg_util.o
 
 # DeckLink
 OBJS += decklink_capture.o decklink_util.o decklink_output.o decklink/DeckLinkAPIDispatch.o
index 464b4cb92d292b8b6bb80f458c92715209f6e902..6e672d9d837e1ec6145dda12abc4dcd27eb22b1a 100644 (file)
@@ -28,6 +28,7 @@ extern "C" {
 
 #include "bmusb/bmusb.h"
 #include "ffmpeg_raii.h"
+#include "ffmpeg_util.h"
 #include "flags.h"
 #include "image_input.h"
 
@@ -179,25 +180,14 @@ bool FFmpegCapture::play_video(const string &pathname)
                return false;
        }
 
-       int video_stream_index = -1, audio_stream_index = -1;
-       AVRational video_timebase{ 1, 1 };
-       for (unsigned i = 0; i < format_ctx->nb_streams; ++i) {
-               if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
-                   video_stream_index == -1) {
-                       video_stream_index = i;
-                       video_timebase = format_ctx->streams[i]->time_base;
-               }
-               if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
-                   audio_stream_index == -1) {
-                       audio_stream_index = i;
-               }
-       }
+       int video_stream_index = find_stream_index(format_ctx.get(), AVMEDIA_TYPE_VIDEO);
        if (video_stream_index == -1) {
                fprintf(stderr, "%s: No video stream found\n", pathname.c_str());
                return false;
        }
 
        const AVCodecParameters *codecpar = format_ctx->streams[video_stream_index]->codecpar;
+       AVRational video_timebase = format_ctx->streams[video_stream_index]->time_base;
        AVCodecContextWithDeleter codec_ctx = avcodec_alloc_context3_unique(nullptr);
        if (avcodec_parameters_to_context(codec_ctx.get(), codecpar) < 0) {
                fprintf(stderr, "%s: Cannot fill codec parameters\n", pathname.c_str());
diff --git a/ffmpeg_util.cpp b/ffmpeg_util.cpp
new file mode 100644 (file)
index 0000000..e348d0a
--- /dev/null
@@ -0,0 +1,75 @@
+#include "ffmpeg_util.h"
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include "flags.h"
+
+using namespace std;
+
+string search_for_file(const string &filename)
+{
+       if (!filename.empty() && filename[0] == '/') {
+               // Absolute path.
+               return filename;
+       }
+
+       // See if we match ^[a-z]:/, which is probably a URL of some sort
+       // (FFmpeg understands various forms of these).
+       for (size_t i = 0; i < filename.size() - 1; ++i) {
+               if (filename[i] == ':' && filename[i + 1] == '/') {
+                       return filename;
+               }
+               if (!isalpha(filename[i])) {
+                       break;
+               }
+       }
+
+       // Look for the file in all theme_dirs until we find one;
+       // that will be the permanent resolution of this file, whether
+       // it is actually valid or not.
+       // We store errors from all the attempts, and show them
+       // once we know we can't find any of them.
+       vector<string> errors;
+       for (const string &dir : global_flags.theme_dirs) {
+               string pathname = dir + "/" + filename;
+               if (access(pathname.c_str(), O_RDONLY) == 0) {
+                       return pathname;
+               } else {
+                       char buf[512];
+                       snprintf(buf, sizeof(buf), "%s: %s", pathname.c_str(), strerror(errno));
+                       errors.push_back(buf);
+               }
+       }
+
+       for (const string &error : errors) {
+               fprintf(stderr, "%s\n", error.c_str());
+       }
+       return "";
+}
+
+string search_for_file_or_die(const string &filename)
+{
+       string pathname = search_for_file(filename);
+       if (pathname.empty()) {
+               fprintf(stderr, "Couldn't find %s in any directory in --theme-dirs, exiting.\n",
+                       filename.c_str());
+               exit(1);
+       }
+       return pathname;
+}
+
+int find_stream_index(AVFormatContext *ctx, AVMediaType media_type)
+{
+       for (unsigned i = 0; i < ctx->nb_streams; ++i) {
+               if (ctx->streams[i]->codecpar->codec_type == media_type) {
+                       return i;
+               }
+       }
+       return -1;
+}
+
diff --git a/ffmpeg_util.h b/ffmpeg_util.h
new file mode 100644 (file)
index 0000000..c037a15
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _FFMPEG_UTIL_H
+#define _FFMPEG_UTIL_H 1
+
+// Some common utilities for the two FFmpeg users (ImageInput and FFmpegCapture).
+
+#include <string>
+
+extern "C" {
+#include <libavformat/avformat.h>
+}
+
+// Look for the file in all theme_dirs until we find one;
+// that will be the permanent resolution of this file, whether
+// it is actually valid or not. Returns an empty string on error.
+std::string search_for_file(const std::string &filename);
+
+// Same, but exits on error.
+std::string search_for_file_or_die(const std::string &filename);
+
+// Returns -1 if not found.
+int find_stream_index(AVFormatContext *ctx, AVMediaType media_type);
+
+#endif  // !defined(_FFMPEG_UTIL_H)
index a3a110c6ca293ae8beb12525f574c2c9cf6ad4c1..f6805d3ca86954d3b31cfc863240792b8544cfbe 100644 (file)
@@ -30,6 +30,7 @@ extern "C" {
 #include <vector>
 
 #include "ffmpeg_raii.h"
+#include "ffmpeg_util.h"
 #include "flags.h"
 #include "flat_input.h"
 
@@ -37,58 +38,6 @@ struct SwsContext;
 
 using namespace std;
 
-string search_for_file(const string &filename)
-{
-       if (!filename.empty() && filename[0] == '/') {
-               // Absolute path.
-               return filename;
-       }
-
-       // See if we match ^[a-z]:/, which is probably a URL of some sort
-       // (FFmpeg understands various forms of these).
-       for (size_t i = 0; i < filename.size() - 1; ++i) {
-               if (filename[i] == ':' && filename[i + 1] == '/') {
-                       return filename;
-               }
-               if (!isalpha(filename[i])) {
-                       break;
-               }
-       }
-
-       // Look for the file in all theme_dirs until we find one;
-       // that will be the permanent resolution of this file, whether
-       // it is actually valid or not.
-       // We store errors from all the attempts, and show them
-       // once we know we can't find any of them.
-       vector<string> errors;
-       for (const string &dir : global_flags.theme_dirs) {
-               string pathname = dir + "/" + filename;
-               if (access(pathname.c_str(), O_RDONLY) == 0) {
-                       return pathname;
-               } else {
-                       char buf[512];
-                       snprintf(buf, sizeof(buf), "%s: %s", pathname.c_str(), strerror(errno));
-                       errors.push_back(buf);
-               }
-       }
-
-       for (const string &error : errors) {
-               fprintf(stderr, "%s\n", error.c_str());
-       }
-       return "";
-}
-
-string search_for_file_or_die(const string &filename)
-{
-       string pathname = search_for_file(filename);
-       if (pathname.empty()) {
-               fprintf(stderr, "Couldn't find %s in any directory in --theme-dirs, exiting.\n",
-                       filename.c_str());
-               exit(1);
-       }
-       return pathname;
-}
-
 ImageInput::ImageInput(const string &filename)
        : movit::FlatInput({movit::COLORSPACE_sRGB, movit::GAMMA_sRGB}, movit::FORMAT_RGBA_POSTMULTIPLIED_ALPHA,
                           GL_UNSIGNED_BYTE, 1280, 720),  // Resolution will be overwritten.
@@ -161,13 +110,7 @@ shared_ptr<const ImageInput::Image> ImageInput::load_image_raw(const string &pat
                return nullptr;
        }
 
-       int stream_index = -1;
-       for (unsigned i = 0; i < format_ctx->nb_streams; ++i) {
-               if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
-                       stream_index = i;
-                       break;
-               }
-       }
+       int stream_index = find_stream_index(format_ctx.get(), AVMEDIA_TYPE_VIDEO);
        if (stream_index == -1) {
                fprintf(stderr, "%s: No video stream found\n", pathname.c_str());
                return nullptr;
index f38426441b0691a73dd6b0cd94f2840a3ff3906c..02be497ff40e2dccee5f569a5be2e1e98a6ae4c5 100644 (file)
@@ -46,12 +46,4 @@ private:
        static std::condition_variable threads_should_quit_modified;  // Signals when threads_should_quit is set.
 };
 
-// Look for the file in all theme_dirs until we find one;
-// that will be the permanent resolution of this file, whether
-// it is actually valid or not. Returns an empty string on error.
-std::string search_for_file(const std::string &filename);
-
-// Same, but exits on error.
-std::string search_for_file_or_die(const std::string &filename);
-
 #endif // !defined(_IMAGE_INPUT_H)