Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/FFmpegWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ namespace openshot {
AVStream *audio_st, *video_st;
AVCodecContext *video_codec;
AVCodecContext *audio_codec;
SwsContext *img_convert_ctx;
double audio_pts, video_pts;
int16_t *samples;
uint8_t *audio_outbuf;
Expand Down Expand Up @@ -242,12 +241,15 @@ namespace openshot {
/// write all queued frames
void write_queued_frames();

void free_resources();
public:

/// @brief Constructor for FFmpegWriter. Throws one of the following exceptions.
/// @param path The file path of the video file you want to open and read
FFmpegWriter(std::string path);

~FFmpegWriter();

/// Close the writer
void Close();

Expand Down
74 changes: 61 additions & 13 deletions src/FFmpegWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx, int6
FFmpegWriter::FFmpegWriter(std::string path) :
path(path), fmt(NULL), oc(NULL), audio_st(NULL), video_st(NULL), audio_pts(0), video_pts(0), samples(NULL),
audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0),
initial_audio_input_frame_size(0), img_convert_ctx(NULL), cache_size(8), num_of_rescalers(32),
initial_audio_input_frame_size(0), cache_size(8), num_of_rescalers(32),
rescaler_position(0), video_codec(NULL), audio_codec(NULL), is_writing(false), write_video_count(0), write_audio_count(0),
original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false),
write_header(false), write_trailer(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL) {
Expand All @@ -102,6 +102,10 @@ FFmpegWriter::FFmpegWriter(std::string path) :
auto_detect_format();
}

FFmpegWriter::~FFmpegWriter() {
free_resources();
}

// Open the writer
void FFmpegWriter::Open() {
if (!is_open) {
Expand Down Expand Up @@ -272,6 +276,7 @@ void FFmpegWriter::SetVideoOptions(bool has_video, std::string codec, Fraction f
info.display_ratio.den = size.den;

ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::SetVideoOptions (" + codec + ")", "width", width, "height", height, "size.num", size.num, "size.den", size.den, "fps.num", fps.num, "fps.den", fps.den);
AV_FREE_CONTEXT(video_codec);

// Enable / Disable video
info.has_video = has_video;
Expand Down Expand Up @@ -992,17 +997,16 @@ void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
}
}

// Close the writer
void FFmpegWriter::Close() {
// Write trailer (if needed)
if (!write_trailer)
WriteTrailer();

void FFmpegWriter::free_resources() {
// Close each codec
if (video_st)
if (video_st) {
close_video(oc, video_st);
if (audio_st)
video_st = NULL;
}
if (audio_st) {
close_audio(oc, audio_st);
audio_st = NULL;
}

// Deallocate image scalers
if (image_rescalers.size() > 0)
Expand All @@ -1013,14 +1017,57 @@ void FFmpegWriter::Close() {
avio_close(oc->pb);
}

// be sure to free any allocated AVFrames
for (auto pair : av_frames) {
AVFrame *frame = pair.second;
AV_FREE_FRAME(&frame);
}

spooled_audio_frames.clear();
spooled_video_frames.clear();
queued_audio_frames.clear();
queued_video_frames.clear();
processed_frames.clear();
deallocate_frames.clear();
av_frames.clear();

#if (LIBAVFORMAT_VERSION_MAJOR >= 58)
if (video_codec) {
AV_FREE_CONTEXT(video_codec);
video_codec = NULL;
}
if (audio_codec) {
AV_FREE_CONTEXT(audio_codec);
audio_codec = NULL;
}

#elif (LIBAVFORMAT_VERSION_MAJOR <= 55)
if (video_codec) {
AV_FREE_CONTEXT(video_codec);
video_codec = NULL;
}
if (audio_codec) {
AV_FREE_CONTEXT(audio_codec);
audio_codec = NULL;
}
#endif

if (oc) {
avformat_free_context(oc);
oc = NULL;
}
}

// Close the writer
void FFmpegWriter::Close() {
// Write trailer (if needed)
if (!write_trailer)
WriteTrailer();

// Reset frame counters
write_video_count = 0;
write_audio_count = 0;

// Free the context which frees the streams too
avformat_free_context(oc);
oc = NULL;

// Close writer
is_open = false;
prepare_streams = false;
Expand Down Expand Up @@ -2122,6 +2169,7 @@ void FFmpegWriter::InitScalers(int source_width, int source_height) {
scale_mode = SWS_BICUBIC;
}

SwsContext *img_convert_ctx;
// Init software rescalers vector (many of them, one for each thread)
for (int x = 0; x < num_of_rescalers; x++) {
// Init the software scaler from FFMpeg
Expand Down