FFmpegfs Fuse Multi Media Filesystem 2.19
Loading...
Searching...
No Matches
ffmpeg_transcoder.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017-2026 by Norbert Schlia (nschlia@oblivion-software.de)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 * On Debian systems, the complete text of the GNU General Public License
19 * Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
20 */
21
32#ifndef FFMPEG_TRANSCODER_H
33#define FFMPEG_TRANSCODER_H
34
35#pragma once
36
37#include "ffmpeg_base.h"
38#include "ffmpeg_audiofifo.h"
39#include "ffmpeg_frame.h"
41#include "ffmpeg_swrcontext.h"
42#include "ffmpeg_swscontext.h"
43#include "ffmpeg_packet.h"
44#include "ffmpeg_subtitle.h"
45#include "id3v1tag.h"
46#include "fileio.h"
47#include "ffmpeg_profiles.h"
48
49#include <queue>
50#include <mutex>
51#include <variant>
52#include <functional>
53#include <optional>
54#include <atomic>
55#include <utility>
56
57class Buffer;
58struct AVFilterContext;
59struct AVFilterGraph;
60struct AVCodecContext;
61struct AVSubtitle;
62
67{
68 DEC_ERROR = -1,
69 DEC_SUCCESS = 0,
71};
79{
80protected:
84 typedef struct BUFFER_DATA
85 {
86 uint8_t * ptr;
87 size_t size;
88 } BUFFER_DATA;
89
90#define MAX_PRORES_FRAMERATE 2
95 typedef struct PRORES_BITRATE
96 {
97 int m_width;
113 std::array<int, 6> m_bitrate;
114 } PRORES_BITRATE, *LPPRORES_BITRATE;
118 {
119 public:
120 StreamRef();
121 virtual ~StreamRef();
122
127 void set_codec_ctx(AVCodecContext *codec_ctx);
128
132 void reset();
133
134 public:
135 std::shared_ptr<AVCodecContext> m_codec_ctx;
136 AVStream * m_stream;
138 int64_t m_start_time;
139 };
140
141 typedef std::map<int, StreamRef> StreamRef_map;
143 struct INPUTFILE
144 {
145 INPUTFILE() :
146 m_filetype(FILETYPE::UNKNOWN),
148 m_pix_fmt(AV_PIX_FMT_NONE)
149 {}
150
157 AVPixelFormat m_pix_fmt;
160 std::vector<StreamRef> m_album_art;
161 };
162
163 // Output file
164 struct OUTPUTFILE : public INPUTFILE
165 {
166 OUTPUTFILE() :
167 m_audio_pts(0),
168 m_video_pts(0),
169 m_last_mux_dts(AV_NOPTS_VALUE)
170 {
171 std::memset(&m_id3v1, 0, sizeof(m_id3v1));
172 }
173
174 int64_t m_audio_pts;
175 int64_t m_video_pts;
179 };
180
181 typedef std::map<AVHWDeviceType, AVPixelFormat> DEVICETYPE_MAP;
183 enum class HWACCELMODE
184 {
185 NONE,
186 ENABLED,
187 FALLBACK
188 };
189
190 typedef std::variant<FFmpeg_Frame, FFmpeg_Subtitle> MULTIFRAME;
191 typedef std::multimap<int64_t, MULTIFRAME> MULTIFRAME_MAP;
192 typedef std::map<int, int> STREAM_MAP;
194public:
198 explicit FFmpeg_Transcoder();
203 virtual ~FFmpeg_Transcoder();
204
210 bool is_open() const;
221 int open_input_file(LPVIRTUALFILE virtualfile, std::shared_ptr<FileIO> fio = nullptr);
227 int open_output_file(Buffer* buffer);
241 int encode_finish();
245 void closeio();
250 time_t mtime() const;
255 int64_t duration() const;
260 size_t predicted_filesize() const;
265 uint32_t video_frame_count() const;
270 uint32_t segment_count() const;
275 const ID3v1 * id3v1tag() const;
280 virtual const char * filename() const override;
285 virtual const char * destname() const override;
290 virtual const char * virtname() const override;
302 static bool audio_size(size_t *filesize, AVCodecID codec_id, BITRATE bit_rate, int64_t duration, int channels, int sample_rate, AVSampleFormat sample_format);
315 static bool video_size(size_t *filesize, AVCodecID codec_id, BITRATE bit_rate, int64_t duration, int width, int height, bool interleaved, const AVRational & framerate);
322 static bool total_overhead(size_t *filesize, FILETYPE filetype);
327 bool close_output_file();
332 bool close_input_file();
333
339 int stack_seek_frame(uint32_t frame_no);
345 int stack_seek_segment(uint32_t segment_no);
350 bool is_multiformat() const;
355 bool is_frameset() const;
360 bool is_hls() const;
365 bool have_seeked() const;
369 void flush_buffers();
382
387 int64_t pts() const;
388
393 uint32_t last_seek_frame_no() const;
394
395protected:
402 int copy_audio_to_frame_buffer(int *finished);
411 int open_bestmatch_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int *stream_idx, AVMediaType type);
430 int open_subtitles();
435 int open_albumarts();
443#if IF_DECLARED_CONST
444 AVPixelFormat get_hw_pix_fmt(const AVCodec *codec, AVHWDeviceType dev_type, bool use_device_ctx) const;
445#else // !IF_DECLARED_CONST
446 AVPixelFormat get_hw_pix_fmt(AVCodec *codec, AVHWDeviceType dev_type, bool use_device_ctx) const;
447#endif // !IF_DECLARED_CONST
457#if IF_DECLARED_CONST
458 int open_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int stream_idx, const AVCodec *input_codec, AVMediaType mediatype);
459#else // !IF_DECLARED_CONST
460 int open_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int stream_idx, AVCodec *input_codec, AVMediaType mediatype);
461#endif // !IF_DECLARED_CONST
467 int open_output_frame_set(Buffer *buffer);
473 int open_output(Buffer *buffer);
479 int process_output();
485 bool is_video() const;
492 int update_codec(void *opt, const PROFILE_OPTION_VEC & profile_option_vec) const;
499 int prepare_codec(void *opt, FILETYPE filetype) const;
505 int add_stream(AVCodecID codec_id);
513 int add_subtitle_stream(AVCodecID codec_id, StreamRef & input_streamref, const std::optional<std::string> &language = std::nullopt);
520 int add_stream_copy(AVCodecID codec_id, AVMediaType codec_type);
526 int add_albumart_stream(const AVCodecContext *input_codec_ctx);
533 int add_albumart_frame(AVStream *output_stream, AVPacket *pkt_in);
541 int open_output_filestreams(Buffer *buffer);
550 template <size_t size>
551 const char * tagcpy(char (&out) [ size ], const std::string & in) const;
560 template <class T>
561 const T & tagcpy(T & out, const std::string & in) const;
572 void copy_metadata(AVDictionary **metadata_out, const AVDictionary *metadata_in, bool contentstream = true);
577 int process_metadata();
582 int process_albumarts();
589 int init_resampler();
594 int init_audio_fifo();
601 int update_format(AVDictionary** dict, const PROFILE_OPTION_VEC & option_vec) const;
608 int prepare_format(AVDictionary **dict, FILETYPE filetype) const;
620 int store_packet(AVPacket *pkt, AVMediaType mediatype);
627 int decode_audio_frame(AVPacket *pkt, int *decoded);
634 int decode_video_frame(AVPacket *pkt, int *decoded);
641 int decode_subtitle(AVPacket *pkt, int *decoded);
650 int decode_subtitle(AVCodecContext *codec_ctx, AVPacket *pkt, int *decoded, int out_stream_idx);
658 void make_pts(AVPacket *pkt, int64_t *cur_ts) const;
664 int decode_frame(AVPacket *pkt);
673 int init_converted_samples(uint8_t ***converted_input_samples, int frame_size);
684 int convert_samples(uint8_t **input_data, int in_samples, uint8_t **converted_data, int *out_samples);
691 int add_samples_to_fifo(uint8_t **converted_input_samples, int frame_size);
696 int flush_frames_all(bool use_flush_packet);
703 int flush_frames_single(int stream_idx, bool use_flush_packet);
709 int read_decode_convert_and_store(int *finished);
717 int init_audio_output_frame(AVFrame *frame, int frame_size) const;
726 int alloc_picture(AVFrame *frame, AVPixelFormat pix_fmt, int width, int height) const;
732 void produce_audio_dts(AVPacket * pkt);
744 int decode(AVCodecContext *codec_ctx, AVFrame *frame, int *got_frame, const AVPacket *pkt) const;
750 int create_audio_frame(int frame_size);
757 int encode_audio_frame(const AVFrame *frame, int *data_present);
764 int encode_video_frame(const AVFrame *frame, int *data_present);
772 int encode_subtitle(const AVSubtitle *sub, int out_stream_idx, int *data_present);
779 int encode_image_frame(const AVFrame *frame, int *data_present);
795 static int input_read(void * opaque, unsigned char * data, int size);
803#if LAVF_WRITEPACKET_CONST
804 static int output_write(void * opaque, const uint8_t * data, int size);
805#else
806 static int output_write(void * opaque, unsigned char * data, int size);
807#endif
818 static int64_t seek(void * opaque, int64_t offset, int whence);
819
829 static BITRATE get_prores_bitrate(int width, int height, const AVRational &framerate, bool interleaved, PRORESLEVEL profile);
833 size_t calculate_predicted_filesize() const;
840 bool get_video_size(int *output_width, int *output_height) const;
848 static bool get_output_sample_rate(int input_sample_rate, int max_sample_rate, int * output_sample_rate = nullptr);
856 static bool get_output_bit_rate(BITRATE input_bit_rate, BITRATE max_bit_rate, BITRATE * output_bit_rate = nullptr);
865 bool get_aspect_ratio(int width, int height, const AVRational & sar, AVRational * ar) const;
866
875 int init_deinterlace_filters(AVCodecContext *codec_ctx, AVPixelFormat pix_fmt, const AVRational &avg_frame_rate, const AVRational &time_base);
882 int send_filters(FFmpeg_Frame * srcframe, int &ret);
886 void free_filters();
892 bool can_copy_stream(const AVStream *stream) const;
897 bool close_resample();
908 int init_rescaler(AVPixelFormat in_pix_fmt, int in_width, int in_height, AVPixelFormat out_pix_fmt, int out_width, int out_height);
913 int purge_audio_fifo();
918 size_t purge_multiframe_map();
923 size_t purge_hls_fifo();
927 void purge();
935 int do_seek_frame(uint32_t frame_no);
942 int skip_decoded_frames(uint32_t frame_no, bool forced_seek);
949 void get_pix_formats(AVPixelFormat *in_pix_fmt, AVPixelFormat *out_pix_fmt, AVCodecContext* output_codec_ctx = nullptr) const;
950
951 // Hardware de/encoding
966 static enum AVPixelFormat get_format_static(AVCodecContext *input_codec_ctx, const enum AVPixelFormat *pix_fmts);
981 enum AVPixelFormat get_format(AVCodecContext *input_codec_ctx, const enum AVPixelFormat *pix_fmts) const;
1003 int hwdevice_ctx_create(AVBufferRef **hwaccel_enc_device_ctx, AVHWDeviceType dev_type, const std::string & device) const;
1009 int hwdevice_ctx_add_ref(AVCodecContext *input_codec_ctx);
1014 void hwdevice_ctx_free(AVBufferRef **hwaccel_device_ctx);
1024 int hwframe_ctx_set(AVCodecContext *output_codec_ctx, AVCodecContext *input_codec_ctx, AVBufferRef *hw_device_ctx) const;
1032 int hwframe_copy_from_hw(AVCodecContext *output_codec_ctx, FFmpeg_Frame *sw_frame, const AVFrame *hw_frame) const;
1040 int hwframe_copy_to_hw(AVCodecContext *output_codec_ctx, FFmpeg_Frame *hw_frame, const AVFrame *sw_frame) const;
1049 int get_hw_decoder_name(AVCodecID codec_id, std::string *codec_name = nullptr) const;
1058 int get_hw_encoder_name(AVCodecID codec_id, std::string *codec_name = nullptr) const;
1065 int get_hw_vaapi_codec_name(AVCodecID codec_id, std::string *codec_name) const;
1072 int get_hw_mmal_decoder_name(AVCodecID codec_id, std::string *codec_name) const;
1073 /*
1074 * @brief Determine video for linux decoder codec name
1075 * @param[in] codec_id - Id of encoder/decoder codec
1076 * @param[out] codec_name - Name of the codec.
1077 * @return 0 on success, AVERROR_DECODER_NOT_FOUND if no codec available.
1078 */
1079 //int get_hw_v4l2m2m_decoder_name(AVCodecID codec_id, std::string *codec_name) const;
1086 int get_hw_omx_encoder_name(AVCodecID codec_id, std::string *codec_name) const;
1093 int get_hw_v4l2m2m_encoder_name(AVCodecID codec_id, std::string *codec_name) const;
1099 static AVPixelFormat find_sw_fmt_by_hw_type(AVHWDeviceType type);
1105 uint32_t get_next_segment(int64_t pos) const;
1111 bool goto_next_segment(uint32_t next_segment) const;
1112
1119 int create_fake_wav_header() const;
1126 int create_fake_aiff_header() const;
1136 int read_aiff_chunk(Buffer *buffer, size_t *buffoffset, const char *ID, uint8_t *chunk, size_t *size) const;
1142 bool is_audio_stream(int stream_idx) const;
1148 bool is_video_stream(int stream_idx) const;
1154 bool is_subtitle_stream(int stream_idx) const;
1160 StreamRef * get_out_subtitle_stream(int stream_idx);
1166 bool stream_exists(int stream_idx) const;
1167
1173 void add_stream_map(int in_stream_idx, int out_stream_idx);
1174
1180 int map_in_to_out_stream(int in_stream_idx) const;
1181
1188
1193 int seek_frame();
1194
1199 int start_new_segment();
1200
1208 static int read_packet(void *opaque, uint8_t *buf, int buf_size);
1220 int add_external_subtitle_stream(const std::string & subtitle_file, const std::optional<std::string> & language);
1229 int foreach_subtitle_file(const std::string& search_path, const std::regex& regex, int depth, const std::function<int (const std::string &, const std::optional<std::string> &)> & f);
1230
1231private:
1232 std::shared_ptr<FileIO> m_fileio;
1233 time_t m_mtime;
1234 std::recursive_mutex m_seek_to_fifo_mutex;
1235 std::queue<uint32_t> m_seek_to_fifo;
1236 std::atomic_uint32_t m_last_seek_frame_no;
1243 // Audio conversion and buffering
1244 AVSampleFormat m_cur_sample_fmt;
1246#if LAVU_DEP_OLD_CHANNEL_LAYOUT
1247 AVChannelLayout m_cur_ch_layout;
1248#else // !LAVU_DEP_OLD_CHANNEL_LAYOUT
1249 uint64_t m_cur_channel_layout;
1250#endif // !LAVU_DEP_OLD_CHANNEL_LAYOUT
1254 // Video conversion and buffering
1256 AVFilterContext * m_buffer_sink_context;
1257 AVFilterContext * m_buffer_source_context;
1258 AVFilterGraph * m_filter_graph;
1259 int64_t m_pts;
1260 int64_t m_pos;
1262 // Common things for audio/video/subtitles
1270 // If the audio and/or video stream is copied, packets will be stuffed into the packet queue.
1274 // Time stamps
1282 uint32_t m_reset_pts;
1285 static const std::vector<PRORES_BITRATE> m_prores_bitrate;
1287 // Hardware acceleration
1288 static const DEVICETYPE_MAP m_devicetype_map;
1295 AVPixelFormat m_enc_hw_pix_fmt;
1296 AVPixelFormat m_dec_hw_pix_fmt;
1298#define FFMPEGFS_AUDIO static_cast<uint32_t>(0x0001)
1299#define FFMPEGFS_VIDEO static_cast<uint32_t>(0x0002)
1300#define FFMPEGFS_SUBTITLE static_cast<uint32_t>(0x0004)
1304 std::queue<FFmpeg_Packet> m_hls_packet_fifo;
1305};
1306
1307#endif // FFMPEG_TRANSCODER_H
The Buffer class.
Definition buffer.h:56
RAII wrapper for AVAudioFifo.
The FFmpeg_Base class.
Definition ffmpeg_base.h:46
RAII wrapper for AVFormatContext.
@ INPUT
Input context closed with avformat_close_input().
The FFmpeg_Frame class.
The FFmpeg_Profiles class.
std::vector< PROFILE_OPTION > PROFILE_OPTION_VEC
PROFILE_OPTION array.
RAII wrapper for SwrContext.
RAII wrapper for SwsContext.
In/output stream reference data.
int m_stream_idx
Stream index in AVFormatContext.
int64_t m_start_time
Start time of the stream in stream time base units, may be 0.
AVStream * m_stream
AVStream for this encoder stream.
void reset()
Close (reset) AVCodecContext pointer.
void set_codec_ctx(AVCodecContext *codec_ctx)
Set the AVCodecContext pointer. Will be shared and deleted after the last consumer freed it.
std::shared_ptr< AVCodecContext > m_codec_ctx
AVCodecContext for this encoder stream.
The FFmpeg_Transcoder class.
int add_samples_to_fifo(uint8_t **converted_input_samples, int frame_size)
Add converted input audio samples to the FIFO buffer for later processing.
uint32_t m_current_segment
HLS only: Segment file number currently being encoded.
static bool video_size(size_t *filesize, AVCodecID codec_id, BITRATE bit_rate, int64_t duration, int width, int height, bool interleaved, const AVRational &framerate)
Predict video file size. This may (better will surely) be inaccurate.
int add_subtitle_stream(AVCodecID codec_id, StreamRef &input_streamref, const std::optional< std::string > &language=std::nullopt)
Add new subtitle stream to output file.
HWACCELMODE
Currently active hardware acceleration mode.
@ NONE
Hardware acceleration not active.
@ ENABLED
Hardware acceleration is active.
@ FALLBACK
Hardware acceleration selected, but fell back to software.
bool m_hwaccel_enable_enc_buffering
Enable hardware acceleration frame buffers for encoder.
int open_albumarts()
open_albumarts
static const DEVICETYPE_MAP m_devicetype_map
List of AVPixelFormats mapped to hardware acceleration types.
int open_output(Buffer *buffer)
Open output file. Data will actually be written to buffer and copied by FUSE when accessed.
int flush_frames_all(bool use_flush_packet)
Flush the remaining frames for all streams.
int stack_seek_frame(uint32_t frame_no)
Seek to a specific frame. Does not actually perform the seek, this is done asynchronously by the tran...
int get_hw_vaapi_codec_name(AVCodecID codec_id, std::string *codec_name) const
Determine VAAPI codec name.
int purge_audio_fifo()
Purge all samples in audio FIFO.
int open_bestmatch_audio()
Open the best match audio stream.
virtual const char * filename() const override
Return source filename.
int get_hw_omx_encoder_name(AVCodecID codec_id, std::string *codec_name) const
Determine OMX encoder codec name.
int process_single_fr(DECODER_STATUS *status)
PRORES_BITRATE const * LPCPRORES_BITRATE
Pointer to const version of PRORES_BITRATE.
bool can_copy_stream(const AVStream *stream) const
Check if stream can be copied from input to output (AUTOCOPY option).
static int input_read(void *opaque, unsigned char *data, int size)
Custom read function for FFmpeg.
std::multimap< int64_t, MULTIFRAME > MULTIFRAME_MAP
Audio frame/video frame/subtitle buffer.
size_t purge_multiframe_map()
Purge all frames in buffer.
int get_hw_mmal_decoder_name(AVCodecID codec_id, std::string *codec_name) const
Determine MMAL decoder codec name.
bool m_hwaccel_enable_dec_buffering
Enable hardware acceleration frame buffers for decoder.
AVSampleFormat m_cur_sample_fmt
Currently selected audio sample format.
int store_packet(AVPacket *pkt, AVMediaType mediatype)
Store packet in output stream.
void purge()
Purge FIFO and map buffers and report lost packets/frames/samples.
int add_stream_copy(AVCodecID codec_id, AVMediaType codec_type)
Add new stream copy to output file.
std::queue< FFmpeg_Packet > m_hls_packet_fifo
HLS packet FIFO.
const FFmpegfs_Format * m_current_format
Currently used output format(s)
int map_in_to_out_stream(int in_stream_idx) const
Map input stream index to output stream index.
static bool audio_size(size_t *filesize, AVCodecID codec_id, BITRATE bit_rate, int64_t duration, int channels, int sample_rate, AVSampleFormat sample_format)
Predict audio file size. This may (better will surely) be inaccurate.
bool have_seeked() const
Check if we made a seek operation.
int add_external_subtitle_streams()
Scan for external subtitle files.
int init_deinterlace_filters(AVCodecContext *codec_ctx, AVPixelFormat pix_fmt, const AVRational &avg_frame_rate, const AVRational &time_base)
Initialise video filters.
int prepare_format(AVDictionary **dict, FILETYPE filetype) const
Prepare format optimisations.
StreamRef * get_out_subtitle_stream(int stream_idx)
Get subtitle stream for the stream index.
INPUTFILE m_in
Input file information.
FFmpeg_SwrContext m_audio_resample_ctx
SwResample context for audio resampling.
int decode_video_frame(AVPacket *pkt, int *decoded)
Decode one video frame.
int decode_subtitle(AVPacket *pkt, int *decoded)
Decode one subtitle.
bool m_copy_video
If true, copy video stream from source to target (just remux, no recode).
uint32_t m_inhibit_stream_msk
HLS: Currently inhibited streams bit mask. Packets temporarly go to m_hls_packet_fifo and will be pre...
std::queue< uint32_t > m_seek_to_fifo
Stack of seek requests. Will be processed FIFO.
uint32_t get_next_segment(int64_t pos) const
Calculate next HLS segment from position.
int open_subtitles()
Open all subtitles streams, if present in input file and if supported by output file....
int open_bestmatch_video()
Open the best match video stream, if present in input file.
static AVPixelFormat find_sw_fmt_by_hw_type(AVHWDeviceType type)
Get the software pixel format for the given hardware acceleration.
int send_filters(FFmpeg_Frame *srcframe, int &ret)
Send video frame to the filters.
bool m_insert_keyframe
HLS only: Allow insertion of 1 keyframe.
FFmpeg_AudioFifo m_audio_fifo
Audio sample FIFO.
int init_converted_samples(uint8_t ***converted_input_samples, int frame_size)
Initialise a temporary storage for the specified number of audio samples. The conversion requires tem...
struct FFmpeg_Transcoder::PRORES_BITRATE * LPPRORES_BITRATE
Pointer version of PRORES_BITRATE.
static int output_write(void *opaque, const uint8_t *data, int size)
Custom write function for FFmpeg.
static bool get_output_sample_rate(int input_sample_rate, int max_sample_rate, int *output_sample_rate=nullptr)
Calculate output sample rate based on user option.
bool close_input_file()
Closes the input file if open. Can safely be called again after the file was already closed or if the...
std::map< int, int > STREAM_MAP
Map input subtitle stream to output stream.
void copy_metadata(AVDictionary **metadata_out, const AVDictionary *metadata_in, bool contentstream=true)
Process the metadata in the FFmpeg file. This should be called at the beginning, before reading audio...
int update_codec(void *opt, const PROFILE_OPTION_VEC &profile_option_vec) const
Prepare codec options.
void flush_buffers()
Flush FFmpeg's input buffers.
int add_external_subtitle_stream(const std::string &subtitle_file, const std::optional< std::string > &language)
add_external_subtitle_stream
std::map< int, StreamRef > StreamRef_map
Map stream index to StreamRef.
AVFilterGraph * m_filter_graph
Video filter graph.
bool get_aspect_ratio(int width, int height, const AVRational &sar, AVRational *ar) const
Calculate aspect ratio for width/height and sample aspect ratio (sar).
enum AVPixelFormat get_format(AVCodecContext *input_codec_ctx, const enum AVPixelFormat *pix_fmts) const
uint32_t m_reset_pts
We have to reset audio/video pts to the new position.
AVBufferRef * m_hwaccel_dec_device_ctx
Hardware acceleration device context for decoder.
int init_resampler()
Initialize the audio resampler based on the input and output codec settings. If the input and output ...
Buffer * m_buffer
Pointer to cache buffer object.
int encode_video_frame(const AVFrame *frame, int *data_present)
Encode one frame worth of video to the output file.
std::shared_ptr< FileIO > m_fileio
FileIO object of input file.
bool m_skip_next_frame
After seek, skip next video frame.
void closeio()
Close transcoder, free all ressources.
int read_decode_convert_and_store(int *finished)
Read frame from source file, decode and store in FIFO.
int add_albumart_frame(AVStream *output_stream, AVPacket *pkt_in)
Add album art to stream.
int get_hw_encoder_name(AVCodecID codec_id, std::string *codec_name=nullptr) const
Get the hardware codec name as string. This is required, because e.g. the name for the software codec...
uint32_t video_frame_count() const
Get the number of video frames in file.
bool is_hls() const
Check for HLS format.
int copy_audio_to_frame_buffer(int *finished)
Copy data from audio FIFO to frame buffer. Divides WAV data into proper chunks to be fed into the enc...
FFmpeg_SwsContext m_sws_ctx
Context for video filtering.
int create_fake_aiff_header() const
Create a fake AIFF header Create a fake AIFF header. Inserts predicted file sizes to allow playback t...
int read_aiff_chunk(Buffer *buffer, size_t *buffoffset, const char *ID, uint8_t *chunk, size_t *size) const
Read AIFF chunk.
bool is_audio_stream(int stream_idx) const
Check for audio stream.
MULTIFRAME_MAP m_frame_map
Audio/video/subtitle frame map.
bool goto_next_segment(uint32_t next_segment) const
Check if segment number is next designated segment.
size_t predicted_filesize() const
Try to predict the recoded file size. This may (better will surely) be inaccurate.
bool is_video_stream(int stream_idx) const
Check for video stream.
static bool total_overhead(size_t *filesize, FILETYPE filetype)
Predict overhead in file size. This may (better will surely) be inaccurate.
bool is_subtitle_stream(int stream_idx) const
Check for subtitle stream.
int add_albumart_stream(const AVCodecContext *input_codec_ctx)
Add a stream for an album art.
int64_t m_pos
Generated position.
bool m_have_seeked
After seek operations this is set to make sure the trancoding result is marked RESULTCODE_INCOMPLETE ...
AVPixelFormat get_hw_pix_fmt(const AVCodec *codec, AVHWDeviceType dev_type, bool use_device_ctx) const
Determine the hardware pixel format for the codec, if applicable.
int flush_delayed_audio()
Flush delayed audio packets, if there are any.
int do_seek_frame(uint32_t frame_no)
Actually perform seek for frame. This function ensures that it is positioned at a key frame,...
int decode(AVCodecContext *codec_ctx, AVFrame *frame, int *got_frame, const AVPacket *pkt) const
const ID3v1 * id3v1tag() const
Assemble an ID3v1 file tag.
size_t calculate_predicted_filesize() const
Try to predict final file size.
int init_audio_output_frame(AVFrame *frame, int frame_size) const
Initialise one input frame for writing to the output file. The frame will be exactly frame_size sampl...
int encode_image_frame(const AVFrame *frame, int *data_present)
Encode frame to image.
static BITRATE get_prores_bitrate(int width, int height, const AVRational &framerate, bool interleaved, PRORESLEVEL profile)
Calculate the appropriate bitrate for a ProRes file given several parameters.
static int64_t seek(void *opaque, int64_t offset, int whence)
Custom seek function for FFmpeg.
uint32_t segment_count() const
Get the number of HLS segments of file.
int get_hw_v4l2m2m_encoder_name(AVCodecID codec_id, std::string *codec_name) const
Determine video for linux encoder codec name.
bool m_is_video
true if input is a video file
int alloc_picture(AVFrame *frame, AVPixelFormat pix_fmt, int width, int height) const
Allocate memory for one picture.
AVBufferRef * m_hwaccel_enc_device_ctx
Hardware acceleration device context for encoder.
static const std::vector< PRORES_BITRATE > m_prores_bitrate
ProRes bitrate table. Used for file size prediction.
int prepare_codec(void *opt, FILETYPE filetype) const
Prepare codec options for a file type.
void add_stream_map(int in_stream_idx, int out_stream_idx)
Add entry to input stream to output stream map.
int decode_frame(AVPacket *pkt)
Decode one frame.
int add_subtitle_streams()
Add all subtitle streams. Already existing streams are not added again.
int open_output_filestreams(Buffer *buffer)
Open an output file and the required encoder. Also set some basic encoder parameters....
int64_t m_cur_video_ts
If the video stream is copied and the time stamps are absent from the input stream,...
bool stream_exists(int stream_idx) const
Check if stream exists.
std::variant< FFmpeg_Frame, FFmpeg_Subtitle > MULTIFRAME
Combined audio/videoframe and subtitle.
bool is_multiformat() const
Check for an export frame format.
HWACCELMODE m_hwaccel_dec_mode
Current hardware acceleration mode for decoder.
int skip_decoded_frames(uint32_t frame_no, bool forced_seek)
Skip decoded frames or force seek to frame_no.
STREAM_MAP m_stream_map
Input stream to output stream map.
int create_audio_frame(int frame_size)
Load one audio frame from the FIFO buffer and store in frame buffer.
int write_output_file_header()
Write the header of the output file container.
int hwdevice_ctx_create(AVBufferRef **hwaccel_enc_device_ctx, AVHWDeviceType dev_type, const std::string &device) const
virtual const char * virtname() const override
Return virtual filename. Same as destination filename, but with virtual (mount) path....
void free_filters()
Free filter sinks.
virtual const char * destname() const override
Return destination filename.
uint32_t m_fake_frame_no
The MJEPG codec requires monotonically growing PTS values so we fake some to avoid them going backwar...
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
FFmpeg_Transcoder::read_packet.
int flush_frames_single(int stream_idx, bool use_flush_packet)
Flush the remaining frames.
AVFilterContext * m_buffer_sink_context
Video filter sink context.
int open_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int stream_idx, const AVCodec *input_codec, AVMediaType mediatype)
Open codec context for stream_idx.
int write_output_file_trailer()
Write the trailer of the output file container.
int create_fake_wav_header() const
Create a fake WAV header Create a fake WAV header. Inserts predicted file sizes to allow playback to ...
bool close_resample()
Close and free the resampler context.
int process_albumarts()
Copy all album arts from source to target.
int get_hw_decoder_name(AVCodecID codec_id, std::string *codec_name=nullptr) const
Get the hardware codec name as string. This is required, because e.g. the name for the software codec...
int64_t m_pts
Generated PTS.
int decode_audio_frame(AVPacket *pkt, int *decoded)
Decode one audio frame.
AVPixelFormat m_enc_hw_pix_fmt
Requested encoder hardware pixel format.
OUTPUTFILE m_out
Output file information.
int64_t m_cur_audio_ts
If the audio stream is copied and the time stamps are absent from the input stream,...
std::atomic_uint32_t m_last_seek_frame_no
If not 0, this is the last frame that we seeked to. Video sources only.
AVPixelFormat m_dec_hw_pix_fmt
Requested decoder hardware pixel format.
uint32_t last_seek_frame_no() const
Current seek frame if available.
int flush_delayed_subtitles()
Flush delayed subtitle packets, if there are any.
AVChannelLayout m_cur_ch_layout
Currently selected audio channel layout.
int process_metadata()
Copy metadata from source to target.
int init_rescaler(AVPixelFormat in_pix_fmt, int in_width, int in_height, AVPixelFormat out_pix_fmt, int out_width, int out_height)
Init image size rescaler and pixel format converter.
const char * tagcpy(char(&out)[size], const std::string &in) const
Safely copy a tag to a target buffer. If the input buffer size is larger than output the data will be...
int hwframe_copy_to_hw(AVCodecContext *output_codec_ctx, FFmpeg_Frame *hw_frame, const AVFrame *sw_frame) const
int hwframe_ctx_set(AVCodecContext *output_codec_ctx, AVCodecContext *input_codec_ctx, AVBufferRef *hw_device_ctx) const
Adds a reference to an existing decoder hardware frame context or allocates a new AVHWFramesContext t...
int open_output_file(Buffer *buffer)
Open output file. Data will actually be written to buffer and copied by FUSE when accessed.
int open_bestmatch_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int *stream_idx, AVMediaType type)
Find best match stream and open codec context for it.
time_t mtime() const
Get last modification time of file.
bool close_output_file()
Closes the output file if open and reports lost packets. Can safely be called again after the file wa...
static enum AVPixelFormat get_format_static(AVCodecContext *input_codec_ctx, const enum AVPixelFormat *pix_fmts)
std::map< AVHWDeviceType, AVPixelFormat > DEVICETYPE_MAP
Map device types to pixel formats.
int64_t duration() const
Get the file duration.
size_t purge_hls_fifo()
Purge all packets in HLS FIFO buffer.
int init_audio_fifo()
Initialise a FIFO buffer for the audio samples to be encoded.
bool is_frameset() const
Check for an export frame format.
int process_output()
Process headers of output file Write file header, process meta data and add album arts.
int start_new_segment()
HLS only: start a new HLS segment.
AVFilterContext * m_buffer_source_context
Video filter source context.
int convert_samples(uint8_t **input_data, int in_samples, uint8_t **converted_data, int *out_samples)
Convert the input audio samples into the output sample format. The conversion happens on a per-frame ...
int64_t pts() const
Get PTS (presentation time stamp) of decoded audio/video so far.
std::recursive_mutex m_seek_to_fifo_mutex
Access mutex for seek FIFO.
int flush_delayed_video()
Flush delayed video packets, if there are any.
int hwdevice_ctx_add_ref(AVCodecContext *input_codec_ctx)
Add reference to hardware device context.
int m_cur_sample_rate
Currently selected audio sample rate.
int update_format(AVDictionary **dict, const PROFILE_OPTION_VEC &option_vec) const
Update format options.
bool m_copy_audio
If true, copy audio stream from source to target (just remux, no recode).
int open_input_file(LPVIRTUALFILE virtualfile, std::shared_ptr< FileIO > fio=nullptr)
void make_pts(AVPacket *pkt, int64_t *cur_ts) const
Create PTS/DTS and update the packet. If the update packet lacks time stamps, create a fictitious PTS...
int stack_seek_segment(uint32_t segment_no)
Seek to a specific HLS segment. Does not actually perform the seek, this is done asynchronously by th...
time_t m_mtime
Modified time of input file.
void produce_audio_dts(AVPacket *pkt)
Produce audio dts/pts. This is required because the target codec usually has a different frame size t...
int hwframe_copy_from_hw(AVCodecContext *output_codec_ctx, FFmpeg_Frame *sw_frame, const AVFrame *hw_frame) const
int foreach_subtitle_file(const std::string &search_path, const std::regex &regex, int depth, const std::function< int(const std::string &, const std::optional< std::string > &)> &f)
foreach_subititle_file
uint32_t m_active_stream_msk
HLS: Currently active streams bit mask. Set FFMPEGFS_AUDIO and/or FFMPEGFS_VIDEO.
static bool get_output_bit_rate(BITRATE input_bit_rate, BITRATE max_bit_rate, BITRATE *output_bit_rate=nullptr)
Calculate output bit rate based on user option.
void get_pix_formats(AVPixelFormat *in_pix_fmt, AVPixelFormat *out_pix_fmt, AVCodecContext *output_codec_ctx=nullptr) const
Get correct input and output pixel format.
int seek_frame()
Frame sets only: perform seek to a certain frame.
HWACCELMODE m_hwaccel_enc_mode
Current hardware acceleration mode for encoder.
void hwdevice_ctx_free(AVBufferRef **hwaccel_device_ctx)
Free (remove reference) to hardware device context.
bool get_video_size(int *output_width, int *output_height) const
Get the size of the output video based on user selection and apsect ratio.
int add_stream(AVCodecID codec_id)
Add new stream to output file.
int encode_subtitle(const AVSubtitle *sub, int out_stream_idx, int *data_present)
Encode one subtitle frame to the output file.
int encode_audio_frame(const AVFrame *frame, int *data_present)
Create one frame worth of audio to the output file.
The FFmpegfs_Format class.
FFmpeg AVAudioFifo RAII wrapper.
FFmpeg transcoder base.
FFmpeg AVFormatContext RAII wrapper.
FFmpeg AVFrame extension.
FFmpeg AVPacket RAII wrapper.
FFmpeg encoder profiles.
FFmpeg AVSubtitle extension.
FFmpeg SwrContext RAII wrapper.
FFmpeg SwsContext RAII wrapper.
#define MAX_PRORES_FRAMERATE
Number of selectable fram rates.
DECODER_STATUS const * LPCDECODER_STATUS
Pointer to const version of DECODER_STATUS.
DECODER_STATUS * LPDECODER_STATUS
Pointer version of DECODER_STATUS.
DECODER_STATUS
Decoder status codes. Can be error, success or end of file.
@ DEC_ERROR
Decoder error, see return code.
@ DEC_EOF
Read to end of file.
@ DEC_SUCCESS
Frame decoded successfully.
PRORESLEVEL
#define BITRATE
For FFmpeg bit rate is an int.
FILETYPE
FileIO class.
ID3v1 tag structure
Buffer structure, used in FFmpeg_Transcoder::read_packet.
size_t size
Size left in the buffer.
uint8_t * ptr
Pointer to buffer.
StreamRef_map m_subtitle
Subtitle stream information.
AVPixelFormat m_pix_fmt
Video stream pixel format.
std::vector< StreamRef > m_album_art
Album art stream.
StreamRef m_audio
Audio stream information.
FFmpeg_FormatContext m_format_ctx
Format context.
StreamRef m_video
Video stream information.
FILETYPE m_filetype
File type, MP3, MP4, OPUS etc.
int64_t m_video_pts
Global timestamp for the video frames in output video stream time base units
ID3v1 m_id3v1
mp3 only, can be referenced at any time
int64_t m_audio_pts
Global timestamp for the audio frames in output audio stream time base units
int64_t m_last_mux_dts
Last muxed DTS.
Predicted bitrates for Apple Prores, see https://www.apple.com/final-cut-pro/docs/Apple_ProRes_White_...
struct FFmpeg_Transcoder::PRORES_BITRATE::PRORES_FRAMERATE m_framerate[MAX_PRORES_FRAMERATE]
Array of frame rates.
std::array< int, 6 > m_bitrate
Bitrates for this format.
ID3 version 1 tag
Definition id3v1tag.h:42
Virtual file definition.
Definition fileio.h:123