X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=nageru%2Fffmpeg_capture.h;h=c7b8a6159797b69cd9c16fa6ac619afe94b09b42;hb=23da824e1d61e37fbe0cc1c0f4d32052022a50ba;hp=31e94ab41fefc103b150b5319877554450dfa720;hpb=b563b8903fa84bb7fd62d7d0b84b70cb26843dbf;p=nageru diff --git a/nageru/ffmpeg_capture.h b/nageru/ffmpeg_capture.h index 31e94ab..c7b8a61 100644 --- a/nageru/ffmpeg_capture.h +++ b/nageru/ffmpeg_capture.h @@ -17,6 +17,11 @@ // changes parameters midway, which is allowed in some formats. // // You can get out the audio either as decoded or in raw form (Kaeru uses this). +// +// If there's a subtitle track, you can also get out the last subtitle at the +// point of the frame. Note that once we get a video frame, we don't look for +// subtitle, so if subtitles and a frame comes at the same time, you might not +// see the subtitle until the next frame. #include #include @@ -31,7 +36,7 @@ #include extern "C" { -#include +#include #include #include #include @@ -164,6 +169,18 @@ public: return current_frame_ycbcr_format; } + // Only valid to call during the frame callback. + std::string get_last_subtitle() const + { + return last_subtitle; + } + + // Same. + bool get_has_last_subtitle() const + { + return has_last_subtitle; + } + void set_dequeue_thread_callbacks(std::function init, std::function cleanup) override { dequeue_init_callback = init; @@ -218,7 +235,7 @@ private: // Returns nullptr if no frame was decoded (e.g. EOF). AVFrameWithDeleter decode_frame(AVFormatContext *format_ctx, AVCodecContext *video_codec_ctx, AVCodecContext *audio_codec_ctx, - const std::string &pathname, int video_stream_index, int audio_stream_index, + const std::string &pathname, int video_stream_index, int audio_stream_index, int subtitle_stream_index, bmusb::FrameAllocator::Frame *audio_frame, bmusb::AudioFormat *audio_format, int64_t *audio_pts, bool *error); void convert_audio(const AVFrame *audio_avframe, bmusb::FrameAllocator::Frame *audio_frame, bmusb::AudioFormat *audio_format); @@ -237,6 +254,7 @@ private: bool running = false; int card_index = -1; double rate = 1.0; + bool play_as_fast_as_possible = false; // Activated iff rate >= 10.0. std::atomic should_interrupt{false}; bool last_frame_was_connected = true; @@ -255,6 +273,7 @@ private: int sws_last_width = -1, sws_last_height = -1, sws_last_src_format = -1; AVPixelFormat sws_dst_format = AVPixelFormat(-1); // In practice, always initialized. AVRational video_timebase, audio_timebase; + bool is_mjpeg = false; QuittableSleeper producer_thread_should_quit; std::thread producer_thread; @@ -270,11 +289,14 @@ private: std::vector command_queue; // Protected by . // Audio resampler. - AVAudioResampleContext *resampler = nullptr; + SwrContext *resampler = nullptr; AVSampleFormat last_src_format, last_dst_format; int64_t last_channel_layout; int last_sample_rate; + // Subtitles (no decoding done, really). + bool has_last_subtitle = false; + std::string last_subtitle; }; #endif // !defined(_FFMPEG_CAPTURE_H)