FFmpegfs Fuse Multi Media Filesystem 2.16
ffmpeg_transcoder.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017-2024 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_frame.h"
39#include "ffmpeg_subtitle.h"
40#include "id3v1tag.h"
41#include "fileio.h"
42#include "ffmpeg_profiles.h"
43
44#include <queue>
45#include <mutex>
46#include <variant>
47#include <functional>
48#include <optional>
49#include <atomic>
50
51class Buffer;
52struct SwrContext;
53struct SwsContext;
54struct AVFilterContext;
55struct AVFilterGraph;
56struct AVAudioFifo;
57struct AVCodecContext;
58struct AVSubtitle;
59
64{
65 DEC_ERROR = -1,
66 DEC_SUCCESS = 0,
67 DEC_EOF = 1
68};
76{
77protected:
81 typedef struct BUFFER_DATA
82 {
83 uint8_t * ptr;
84 size_t size;
86
87#define MAX_PRORES_FRAMERATE 2
92 typedef struct PRORES_BITRATE
93 {
94 int m_width;
97 {
110 std::array<int, 6> m_bitrate;
115 {
116 public:
117 StreamRef();
118 virtual ~StreamRef();
119
124 void set_codec_ctx(AVCodecContext *codec_ctx);
125
129 void reset();
130
131 public:
132 std::shared_ptr<AVCodecContext> m_codec_ctx;
133 AVStream * m_stream;
135 int64_t m_start_time;
136 };
137
138 typedef std::map<int, StreamRef> StreamRef_map;
140 struct INPUTFILE
141 {
142 INPUTFILE() :
143 m_filetype(FILETYPE::UNKNOWN),
144 m_format_ctx(nullptr),
145 m_pix_fmt(AV_PIX_FMT_NONE)
146 {}
147
150 AVFormatContext * m_format_ctx;
154 AVPixelFormat m_pix_fmt;
157 std::vector<StreamRef> m_album_art;
158 };
159
160 // Output file
161 struct OUTPUTFILE : public INPUTFILE
162 {
163 OUTPUTFILE() :
164 m_audio_pts(0),
165 m_video_pts(0),
166 m_last_mux_dts(AV_NOPTS_VALUE)
167 {
168 std::memset(&m_id3v1, 0, sizeof(m_id3v1));
169 }
170
171 int64_t m_audio_pts;
172 int64_t m_video_pts;
176 };
177
178 typedef std::map<AVHWDeviceType, AVPixelFormat> DEVICETYPE_MAP;
180 enum class HWACCELMODE
181 {
182 NONE,
183 ENABLED,
184 FALLBACK
185 };
186
187 typedef std::variant<FFmpeg_Frame, FFmpeg_Subtitle> MULTIFRAME;
188 typedef std::multimap<int64_t, MULTIFRAME> MULTIFRAME_MAP;
189 typedef std::map<int, int> STREAM_MAP;
191public:
195 explicit FFmpeg_Transcoder();
200 virtual ~FFmpeg_Transcoder();
201
207 bool is_open() const;
218 int open_input_file(LPVIRTUALFILE virtualfile, std::shared_ptr<FileIO> fio = nullptr);
224 int open_output_file(Buffer* buffer);
238 int encode_finish();
242 void closeio();
247 time_t mtime() const;
252 int64_t duration() const;
257 size_t predicted_filesize() const;
262 uint32_t video_frame_count() const;
267 uint32_t segment_count() const;
272 const ID3v1 * id3v1tag() const;
277 virtual const char * filename() const override;
282 virtual const char * destname() const override;
287 virtual const char * virtname() const override;
299 static bool audio_size(size_t *filesize, AVCodecID codec_id, BITRATE bit_rate, int64_t duration, int channels, int sample_rate, AVSampleFormat sample_format);
312 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);
319 static bool total_overhead(size_t *filesize, FILETYPE filetype);
324 bool close_output_file();
329 bool close_input_file();
330
336 int stack_seek_frame(uint32_t frame_no);
342 int stack_seek_segment(uint32_t segment_no);
347 bool is_multiformat() const;
352 bool is_frameset() const;
357 bool is_hls() const;
362 bool have_seeked() const;
366 void flush_buffers();
379
384 int64_t pts() const;
385
390 uint32_t last_seek_frame_no() const;
391
392protected:
399 int copy_audio_to_frame_buffer(int *finished);
408 int open_bestmatch_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int *stream_idx, AVMediaType type);
427 int open_subtitles();
432 int open_albumarts();
440#if IF_DECLARED_CONST
441 AVPixelFormat get_hw_pix_fmt(const AVCodec *codec, AVHWDeviceType dev_type, bool use_device_ctx) const;
442#else // !IF_DECLARED_CONST
443 AVPixelFormat get_hw_pix_fmt(AVCodec *codec, AVHWDeviceType dev_type, bool use_device_ctx) const;
444#endif // !IF_DECLARED_CONST
454#if IF_DECLARED_CONST
455 int open_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int stream_idx, const AVCodec *input_codec, AVMediaType mediatype);
456#else // !IF_DECLARED_CONST
457 int open_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int stream_idx, AVCodec *input_codec, AVMediaType mediatype);
458#endif // !IF_DECLARED_CONST
464 int open_output_frame_set(Buffer *buffer);
470 int open_output(Buffer *buffer);
476 int process_output();
482 bool is_video() const;
489 int update_codec(void *opt, const PROFILE_OPTION_VEC & profile_option_vec) const;
496 int prepare_codec(void *opt, FILETYPE filetype) const;
502 int add_stream(AVCodecID codec_id);
510 int add_subtitle_stream(AVCodecID codec_id, StreamRef & input_streamref, const std::optional<std::string> &language = std::nullopt);
517 int add_stream_copy(AVCodecID codec_id, AVMediaType codec_type);
523 int add_albumart_stream(const AVCodecContext *input_codec_ctx);
530 int add_albumart_frame(AVStream *output_stream, AVPacket *pkt_in);
538 int open_output_filestreams(Buffer *buffer);
547 template <size_t size>
548 const char * tagcpy(char (&out) [ size ], const std::string & in) const;
557 template <class T>
558 const T & tagcpy(T & out, const std::string & in) const;
569 void copy_metadata(AVDictionary **metadata_out, const AVDictionary *metadata_in, bool contentstream = true);
574 int process_metadata();
579 int process_albumarts();
586 int init_resampler();
591 int init_audio_fifo();
598 int update_format(AVDictionary** dict, const PROFILE_OPTION_VEC & option_vec) const;
605 int prepare_format(AVDictionary **dict, FILETYPE filetype) const;
617 int store_packet(AVPacket *pkt, AVMediaType mediatype);
624 int decode_audio_frame(AVPacket *pkt, int *decoded);
631 int decode_video_frame(AVPacket *pkt, int *decoded);
638 int decode_subtitle(AVPacket *pkt, int *decoded);
647 int decode_subtitle(AVCodecContext *codec_ctx, AVPacket *pkt, int *decoded, int out_stream_idx);
655 void make_pts(AVPacket *pkt, int64_t *cur_ts) const;
661 int decode_frame(AVPacket *pkt);
670 int init_converted_samples(uint8_t ***converted_input_samples, int frame_size);
681 int convert_samples(uint8_t **input_data, int in_samples, uint8_t **converted_data, int *out_samples);
688 int add_samples_to_fifo(uint8_t **converted_input_samples, int frame_size);
693 int flush_frames_all(bool use_flush_packet);
700 int flush_frames_single(int stream_idx, bool use_flush_packet);
706 int read_decode_convert_and_store(int *finished);
714 int init_audio_output_frame(AVFrame *frame, int frame_size) const;
723 int alloc_picture(AVFrame *frame, AVPixelFormat pix_fmt, int width, int height) const;
729 void produce_audio_dts(AVPacket * pkt);
741 int decode(AVCodecContext *codec_ctx, AVFrame *frame, int *got_frame, const AVPacket *pkt) const;
747 int create_audio_frame(int frame_size);
754 int encode_audio_frame(const AVFrame *frame, int *data_present);
761 int encode_video_frame(const AVFrame *frame, int *data_present);
769 int encode_subtitle(const AVSubtitle *sub, int out_stream_idx, int *data_present);
776 int encode_image_frame(const AVFrame *frame, int *data_present);
792 static int input_read(void * opaque, unsigned char * data, int size);
800#if LAVF_WRITEPACKET_CONST
801 static int output_write(void * opaque, const uint8_t * data, int size);
802#else
803 static int output_write(void * opaque, unsigned char * data, int size);
804#endif
815 static int64_t seek(void * opaque, int64_t offset, int whence);
816
826 static BITRATE get_prores_bitrate(int width, int height, const AVRational &framerate, bool interleaved, PRORESLEVEL profile);
830 size_t calculate_predicted_filesize() const;
837 bool get_video_size(int *output_width, int *output_height) const;
845 static bool get_output_sample_rate(int input_sample_rate, int max_sample_rate, int * output_sample_rate = nullptr);
853 static bool get_output_bit_rate(BITRATE input_bit_rate, BITRATE max_bit_rate, BITRATE * output_bit_rate = nullptr);
862 bool get_aspect_ratio(int width, int height, const AVRational & sar, AVRational * ar) const;
863
872 int init_deinterlace_filters(AVCodecContext *codec_ctx, AVPixelFormat pix_fmt, const AVRational &avg_frame_rate, const AVRational &time_base);
879 int send_filters(FFmpeg_Frame * srcframe, int &ret);
883 void free_filters();
889 bool can_copy_stream(const AVStream *stream) const;
894 bool close_resample();
905 int init_rescaler(AVPixelFormat in_pix_fmt, int in_width, int in_height, AVPixelFormat out_pix_fmt, int out_width, int out_height);
910 int purge_audio_fifo();
915 size_t purge_multiframe_map();
920 size_t purge_hls_fifo();
924 void purge();
932 int do_seek_frame(uint32_t frame_no);
939 int skip_decoded_frames(uint32_t frame_no, bool forced_seek);
946 void get_pix_formats(AVPixelFormat *in_pix_fmt, AVPixelFormat *out_pix_fmt, AVCodecContext* output_codec_ctx = nullptr) const;
947
948 // Hardware de/encoding
963 static enum AVPixelFormat get_format_static(AVCodecContext *input_codec_ctx, const enum AVPixelFormat *pix_fmts);
978 enum AVPixelFormat get_format(AVCodecContext *input_codec_ctx, const enum AVPixelFormat *pix_fmts) const;
1000 int hwdevice_ctx_create(AVBufferRef **hwaccel_enc_device_ctx, AVHWDeviceType dev_type, const std::string & device) const;
1006 int hwdevice_ctx_add_ref(AVCodecContext *input_codec_ctx);
1011 void hwdevice_ctx_free(AVBufferRef **hwaccel_device_ctx);
1021 int hwframe_ctx_set(AVCodecContext *output_codec_ctx, AVCodecContext *input_codec_ctx, AVBufferRef *hw_device_ctx) const;
1029 int hwframe_copy_from_hw(AVCodecContext *output_codec_ctx, FFmpeg_Frame *sw_frame, const AVFrame *hw_frame) const;
1037 int hwframe_copy_to_hw(AVCodecContext *output_codec_ctx, FFmpeg_Frame *hw_frame, const AVFrame *sw_frame) const;
1046 int get_hw_decoder_name(AVCodecID codec_id, std::string *codec_name = nullptr) const;
1055 int get_hw_encoder_name(AVCodecID codec_id, std::string *codec_name = nullptr) const;
1062 int get_hw_vaapi_codec_name(AVCodecID codec_id, std::string *codec_name) const;
1069 int get_hw_mmal_decoder_name(AVCodecID codec_id, std::string *codec_name) const;
1070 /*
1071 * @brief Determine video for linux decoder codec name
1072 * @param[in] codec_id - Id of encoder/decoder codec
1073 * @param[out] codec_name - Name of the codec.
1074 * @return 0 on success, AVERROR_DECODER_NOT_FOUND if no codec available.
1075 */
1076 //int get_hw_v4l2m2m_decoder_name(AVCodecID codec_id, std::string *codec_name) const;
1083 int get_hw_omx_encoder_name(AVCodecID codec_id, std::string *codec_name) const;
1090 int get_hw_v4l2m2m_encoder_name(AVCodecID codec_id, std::string *codec_name) const;
1096 static AVPixelFormat find_sw_fmt_by_hw_type(AVHWDeviceType type);
1102 uint32_t get_next_segment(int64_t pos) const;
1108 bool goto_next_segment(uint32_t next_segment) const;
1109
1116 int create_fake_wav_header() const;
1123 int create_fake_aiff_header() const;
1133 int read_aiff_chunk(Buffer *buffer, size_t *buffoffset, const char *ID, uint8_t *chunk, size_t *size) const;
1139 bool is_audio_stream(int stream_idx) const;
1145 bool is_video_stream(int stream_idx) const;
1151 bool is_subtitle_stream(int stream_idx) const;
1157 StreamRef * get_out_subtitle_stream(int stream_idx);
1163 bool stream_exists(int stream_idx) const;
1164
1170 void add_stream_map(int in_stream_idx, int out_stream_idx);
1171
1177 int map_in_to_out_stream(int in_stream_idx) const;
1178
1185
1190 int seek_frame();
1191
1196 int start_new_segment();
1197
1205 static int read_packet(void *opaque, uint8_t *buf, int buf_size);
1217 int add_external_subtitle_stream(const std::string & subtitle_file, const std::optional<std::string> & language);
1226 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);
1227
1228private:
1229 std::shared_ptr<FileIO> m_fileio;
1230 time_t m_mtime;
1231 std::recursive_mutex m_seek_to_fifo_mutex;
1232 std::queue<uint32_t> m_seek_to_fifo;
1233 std::atomic_uint32_t m_last_seek_frame_no;
1240 // Audio conversion and buffering
1241 AVSampleFormat m_cur_sample_fmt;
1243#if LAVU_DEP_OLD_CHANNEL_LAYOUT
1244 AVChannelLayout m_cur_ch_layout;
1245#else // !LAVU_DEP_OLD_CHANNEL_LAYOUT
1246 uint64_t m_cur_channel_layout;
1247#endif // !LAVU_DEP_OLD_CHANNEL_LAYOUT
1249 AVAudioFifo * m_audio_fifo;
1251 // Video conversion and buffering
1252 SwsContext * m_sws_ctx;
1253 AVFilterContext * m_buffer_sink_context;
1254 AVFilterContext * m_buffer_source_context;
1255 AVFilterGraph * m_filter_graph;
1256 int64_t m_pts;
1257 int64_t m_pos;
1259 // Common things for audio/video/subtitles
1267 // If the audio and/or video stream is copied, packets will be stuffed into the packet queue.
1271 // Time stamps
1279 uint32_t m_reset_pts;
1282 static const std::vector<PRORES_BITRATE> m_prores_bitrate;
1284 // Hardware acceleration
1292 AVPixelFormat m_enc_hw_pix_fmt;
1293 AVPixelFormat m_dec_hw_pix_fmt;
1295#define FFMPEGFS_AUDIO static_cast<uint32_t>(0x0001)
1296#define FFMPEGFS_VIDEO static_cast<uint32_t>(0x0002)
1297#define FFMPEGFS_SUBTITLE static_cast<uint32_t>(0x0004)
1301 std::queue<AVPacket*> m_hls_packet_fifo;
1302};
1303
1304#endif // FFMPEG_TRANSCODER_H
@ NONE
No result code available.
The Buffer class.
Definition: buffer.h:56
The FFmpeg_Base class.
Definition: ffmpeg_base.h:46
The FFmpeg_Frame class.
Definition: ffmpeg_frame.h:43
The FFmpeg_Profiles class.
std::vector< PROFILE_OPTION > PROFILE_OPTION_VEC
PROFILE_OPTION array.
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.
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.
AVAudioFifo * m_audio_fifo
Audio sample FIFO.
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.
struct FFmpeg_Transcoder::BUFFER_DATA BUFFER_DATA
Buffer structure, used in FFmpeg_Transcoder::read_packet.
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.
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.
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....
std::queue< AVPacket * > m_hls_packet_fifo
HLS packet FIFO.
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.
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...
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.
struct FFmpeg_Transcoder::PRORES_BITRATE PRORES_BITRATE
Predicted bitrates for Apple Prores, see https://www.apple.com/final-cut-pro/docs/Apple_ProRes_White_...
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.
SwrContext * m_audio_resample_ctx
SwResample context for audio resampling.
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...
SwsContext * m_sws_ctx
Context for video filtering.
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.
Definition: ffmpeg_utils.h:388
FFmpeg transcoder base.
FFmpeg AVFrame extension.
FFmpeg encoder profiles.
FFmpeg AVSubtitle extension.
#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
Definition: ffmpeg_utils.h:210
#define BITRATE
For FFmpeg bit rate is an int.
Definition: ffmpeg_utils.h:145
FILETYPE
Definition: ffmpeg_utils.h:154
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.
Input file definition.
AVFormatContext * m_format_ctx
Output format context.
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.
StreamRef m_video
Video stream information.
FILETYPE m_filetype
File type, MP3, MP4, OPUS etc.
Output file definition.
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