You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Fixed many misc Windows runtime errors and memory-related crashes. Built a few macros for common FFmpeg / LibAV functions that change due to version differences.
This commit is contained in:
@@ -81,4 +81,15 @@
|
||||
#undef av_err2str
|
||||
#define av_err2str(errnum) av_make_error_string(errnum).c_str()
|
||||
|
||||
#if LIBAVFORMAT_VERSION_MAJOR >= 55
|
||||
#define AV_ALLOCATE_FRAME() av_frame_alloc()
|
||||
#define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
|
||||
#define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
|
||||
#else
|
||||
#define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
|
||||
#define AV_RESET_FRAME(av_frame) avcodec_get_frame_defaults(av_frame)
|
||||
#define AV_FREE_FRAME(av_frame) avcodec_free_frame(av_frame)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -686,7 +686,7 @@ bool FFmpegReader::GetAVFrame()
|
||||
int frameFinished = -1;
|
||||
|
||||
// Decode video frame
|
||||
AVFrame *next_frame = avcodec_alloc_frame();
|
||||
AVFrame *next_frame = AV_ALLOCATE_FRAME();
|
||||
#pragma omp critical (packet_cache)
|
||||
avcodec_decode_video2(pCodecCtx, next_frame, &frameFinished, packet);
|
||||
|
||||
@@ -722,7 +722,7 @@ bool FFmpegReader::GetAVFrame()
|
||||
}
|
||||
|
||||
// deallocate the frame
|
||||
avcodec_free_frame(&next_frame);
|
||||
AV_FREE_FRAME(&next_frame);
|
||||
|
||||
// Did we get a video frame?
|
||||
return frameFinished;
|
||||
@@ -822,7 +822,7 @@ void FFmpegReader::ProcessVideoPacket(long int requested_frame)
|
||||
uint8_t *buffer = NULL;
|
||||
|
||||
// Allocate an AVFrame structure
|
||||
pFrameRGB = avcodec_alloc_frame();
|
||||
pFrameRGB = AV_ALLOCATE_FRAME();
|
||||
if (pFrameRGB == NULL)
|
||||
throw OutOfBoundsFrame("Convert Image Broke!", current_frame, video_length);
|
||||
|
||||
@@ -850,7 +850,7 @@ void FFmpegReader::ProcessVideoPacket(long int requested_frame)
|
||||
|
||||
// Free the RGB image
|
||||
av_free(buffer);
|
||||
avcodec_free_frame(&pFrameRGB);
|
||||
AV_FREE_FRAME(&pFrameRGB);
|
||||
|
||||
// Remove frame and packet
|
||||
RemoveAVFrame(my_frame);
|
||||
@@ -898,8 +898,8 @@ void FFmpegReader::ProcessAudioPacket(long int requested_frame, long int target_
|
||||
|
||||
// Init an AVFrame to hold the decoded audio samples
|
||||
int frame_finished = 0;
|
||||
AVFrame *audio_frame = avcodec_alloc_frame();
|
||||
avcodec_get_frame_defaults(audio_frame);
|
||||
AVFrame *audio_frame = AV_ALLOCATE_FRAME();
|
||||
AV_RESET_FRAME(audio_frame);
|
||||
|
||||
int packet_samples = 0;
|
||||
int data_size = 0;
|
||||
@@ -988,8 +988,8 @@ void FFmpegReader::ProcessAudioPacket(long int requested_frame, long int target_
|
||||
AppendDebugMethod("FFmpegReader::ProcessAudioPacket (ReSample)", "packet_samples", packet_samples, "info.channels", info.channels, "info.sample_rate", info.sample_rate, "aCodecCtx->sample_fmt", aCodecCtx->sample_fmt, "AV_SAMPLE_FMT_S16", AV_SAMPLE_FMT_S16, "", -1);
|
||||
|
||||
// Create output frame
|
||||
AVFrame *audio_converted = avcodec_alloc_frame();
|
||||
avcodec_get_frame_defaults(audio_converted);
|
||||
AVFrame *audio_converted = AV_ALLOCATE_FRAME();
|
||||
AV_RESET_FRAME(audio_converted);
|
||||
audio_converted->nb_samples = audio_frame->nb_samples;
|
||||
av_samples_alloc(audio_converted->data, audio_converted->linesize, info.channels, audio_frame->nb_samples, AV_SAMPLE_FMT_S16, 0);
|
||||
|
||||
@@ -1028,10 +1028,9 @@ void FFmpegReader::ProcessAudioPacket(long int requested_frame, long int target_
|
||||
avr = NULL;
|
||||
|
||||
// Free AVFrames
|
||||
avcodec_free_frame(&audio_frame);
|
||||
av_freep(&audio_converted[0]);
|
||||
avcodec_free_frame(&audio_converted);
|
||||
|
||||
AV_FREE_FRAME(&audio_frame);
|
||||
av_free(audio_converted->data[0]);
|
||||
AV_FREE_FRAME(&audio_converted);
|
||||
|
||||
int starting_frame_number = -1;
|
||||
bool partial_frame = true;
|
||||
|
||||
@@ -469,9 +469,9 @@ void FFmpegWriter::write_queued_frames()
|
||||
// Get AVFrame
|
||||
AVFrame *av_frame = av_frames[frame];
|
||||
|
||||
// deallocate AVPicture and AVFrame
|
||||
av_freep(&av_frame[0]); // picture buffer
|
||||
avcodec_free_frame(&av_frame);
|
||||
// Deallocate AVPicture and AVFrame
|
||||
free(av_frame->data[0]); // TODO: Determine why av_free crashes on Windows
|
||||
AV_FREE_FRAME(&av_frame);
|
||||
av_frames.erase(frame);
|
||||
}
|
||||
|
||||
@@ -764,7 +764,7 @@ void FFmpegWriter::add_avframe(tr1::shared_ptr<Frame> frame, AVFrame* av_frame)
|
||||
else
|
||||
{
|
||||
// Do not add, and deallocate this AVFrame
|
||||
avcodec_free_frame(&av_frame);
|
||||
AV_FREE_FRAME(&av_frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1095,8 +1095,8 @@ void FFmpegWriter::write_audio_packets(bool final)
|
||||
AVFrame *audio_frame = NULL;
|
||||
if (!final) {
|
||||
// Create input frame (and allocate arrays)
|
||||
audio_frame = avcodec_alloc_frame();
|
||||
avcodec_get_frame_defaults(audio_frame);
|
||||
audio_frame = AV_ALLOCATE_FRAME();
|
||||
AV_RESET_FRAME(audio_frame);
|
||||
audio_frame->nb_samples = total_frame_samples / channels_in_frame;
|
||||
|
||||
// Fill input frame with sample data
|
||||
@@ -1136,8 +1136,8 @@ void FFmpegWriter::write_audio_packets(bool final)
|
||||
remaining_frame_samples = total_frame_samples;
|
||||
|
||||
// Create output frame (and allocate arrays)
|
||||
AVFrame *audio_converted = avcodec_alloc_frame();
|
||||
avcodec_get_frame_defaults(audio_converted);
|
||||
AVFrame *audio_converted = AV_ALLOCATE_FRAME();
|
||||
AV_RESET_FRAME(audio_converted);
|
||||
audio_converted->nb_samples = total_frame_samples / channels_in_frame;
|
||||
av_samples_alloc(audio_converted->data, audio_converted->linesize, info.channels, audio_converted->nb_samples, output_sample_fmt, 0);
|
||||
|
||||
@@ -1174,11 +1174,11 @@ void FFmpegWriter::write_audio_packets(bool final)
|
||||
memcpy(all_resampled_samples, audio_converted->data[0], nb_samples * info.channels * av_get_bytes_per_sample(output_sample_fmt));
|
||||
|
||||
// Remove converted audio
|
||||
av_freep(&audio_frame[0]); // this deletes the all_queued_samples array
|
||||
free(audio_frame->data[0]); // TODO: Determine why av_free crashes on Windows
|
||||
AV_FREE_FRAME(&audio_frame);
|
||||
av_free(audio_converted->data[0]);
|
||||
AV_FREE_FRAME(&audio_converted);
|
||||
all_queued_samples = NULL; // this array cleared with above call
|
||||
avcodec_free_frame(&audio_frame);
|
||||
av_freep(&audio_converted[0]);
|
||||
avcodec_free_frame(&audio_converted);
|
||||
|
||||
AppendDebugMethod("FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)", "nb_samples", nb_samples, "remaining_frame_samples", remaining_frame_samples, "", -1, "", -1, "", -1, "", -1);
|
||||
}
|
||||
@@ -1212,8 +1212,8 @@ void FFmpegWriter::write_audio_packets(bool final)
|
||||
break;
|
||||
|
||||
// Convert to planar (if needed by audio codec)
|
||||
AVFrame *frame_final = avcodec_alloc_frame();
|
||||
avcodec_get_frame_defaults(frame_final);
|
||||
AVFrame *frame_final = AV_ALLOCATE_FRAME();
|
||||
AV_RESET_FRAME(frame_final);
|
||||
if (av_sample_fmt_is_planar(audio_codec->sample_fmt))
|
||||
{
|
||||
AppendDebugMethod("FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)", "in_sample_fmt", output_sample_fmt, "out_sample_fmt", audio_codec->sample_fmt, "in_sample_rate", info.sample_rate, "out_sample_rate", info.sample_rate, "in_channels", info.channels, "out_channels", info.channels);
|
||||
@@ -1233,8 +1233,8 @@ void FFmpegWriter::write_audio_packets(bool final)
|
||||
}
|
||||
|
||||
// Create input frame (and allocate arrays)
|
||||
audio_frame = avcodec_alloc_frame();
|
||||
avcodec_get_frame_defaults(audio_frame);
|
||||
audio_frame = AV_ALLOCATE_FRAME();
|
||||
AV_RESET_FRAME(audio_frame);
|
||||
audio_frame->nb_samples = audio_input_position / info.channels;
|
||||
|
||||
// Create a new array
|
||||
@@ -1265,8 +1265,8 @@ void FFmpegWriter::write_audio_packets(bool final)
|
||||
memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) * info.channels);
|
||||
|
||||
// deallocate AVFrame
|
||||
av_freep(&audio_frame[0]); // delete final_samples_planar array
|
||||
avcodec_free_frame(&audio_frame);
|
||||
free(audio_frame->data[0]); // TODO: Determine why av_free crashes on Windows
|
||||
AV_FREE_FRAME(&audio_frame);
|
||||
|
||||
AppendDebugMethod("FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)", "nb_samples", nb_samples, "", -1, "", -1, "", -1, "", -1, "", -1);
|
||||
|
||||
@@ -1286,7 +1286,7 @@ void FFmpegWriter::write_audio_packets(bool final)
|
||||
}
|
||||
|
||||
// Increment PTS (in samples)
|
||||
write_audio_count += audio_input_frame_size;
|
||||
write_audio_count += FFMIN(audio_input_frame_size, audio_input_position);
|
||||
frame_final->pts = write_audio_count; // Set the AVFrame's PTS
|
||||
|
||||
// Init the packet
|
||||
@@ -1335,8 +1335,8 @@ void FFmpegWriter::write_audio_packets(bool final)
|
||||
}
|
||||
|
||||
// deallocate AVFrame
|
||||
av_freep(&frame_final[0]); // delete AVFrame internal array OR final_samples array (depending on if its planar or not planar)
|
||||
avcodec_free_frame(&frame_final);
|
||||
free(frame_final->data[0]); // TODO: Determine why av_free crashes on Windows
|
||||
AV_FREE_FRAME(&frame_final);
|
||||
|
||||
// deallocate memory for packet
|
||||
av_free_packet(&pkt);
|
||||
@@ -1366,7 +1366,7 @@ AVFrame* FFmpegWriter::allocate_avframe(PixelFormat pix_fmt, int width, int heig
|
||||
AVFrame *new_av_frame = NULL;
|
||||
|
||||
// Allocate an AVFrame structure
|
||||
new_av_frame = avcodec_alloc_frame();
|
||||
new_av_frame = AV_ALLOCATE_FRAME();
|
||||
if (new_av_frame == NULL)
|
||||
throw OutOfMemory("Could not allocate AVFrame", path);
|
||||
|
||||
@@ -1435,7 +1435,7 @@ void FFmpegWriter::process_video_packet(tr1::shared_ptr<Frame> frame)
|
||||
add_avframe(frame, frame_final);
|
||||
|
||||
// Deallocate memory
|
||||
avcodec_free_frame(&frame_source);
|
||||
AV_FREE_FRAME(&frame_source);
|
||||
|
||||
} // end task
|
||||
|
||||
|
||||
@@ -635,8 +635,8 @@ void FrameMapper::ResampleMappedAudio(tr1::shared_ptr<Frame> frame, long int ori
|
||||
|
||||
|
||||
// Create input frame (and allocate arrays)
|
||||
AVFrame *audio_frame = avcodec_alloc_frame();
|
||||
avcodec_get_frame_defaults(audio_frame);
|
||||
AVFrame *audio_frame = AV_ALLOCATE_FRAME();
|
||||
AV_RESET_FRAME(audio_frame);
|
||||
audio_frame->nb_samples = total_frame_samples / channels_in_frame;
|
||||
|
||||
int error_code = avcodec_fill_audio_frame(audio_frame, channels_in_frame, AV_SAMPLE_FMT_S16, (uint8_t *) frame_samples,
|
||||
@@ -654,8 +654,8 @@ void FrameMapper::ResampleMappedAudio(tr1::shared_ptr<Frame> frame, long int ori
|
||||
AppendDebugMethod("FrameMapper::ResampleMappedAudio (adjust # of samples)", "total_frame_samples", total_frame_samples, "info.sample_rate", info.sample_rate, "sample_rate_in_frame", sample_rate_in_frame, "info.channels", info.channels, "channels_in_frame", channels_in_frame, "original_frame_number", original_frame_number);
|
||||
|
||||
// Create output frame (and allocate arrays)
|
||||
AVFrame *audio_converted = avcodec_alloc_frame();
|
||||
avcodec_get_frame_defaults(audio_converted);
|
||||
AVFrame *audio_converted = AV_ALLOCATE_FRAME();
|
||||
AV_RESET_FRAME(audio_converted);
|
||||
audio_converted->nb_samples = total_frame_samples;
|
||||
av_samples_alloc(audio_converted->data, audio_converted->linesize, info.channels, total_frame_samples, AV_SAMPLE_FMT_S16, 0);
|
||||
|
||||
@@ -697,11 +697,11 @@ void FrameMapper::ResampleMappedAudio(tr1::shared_ptr<Frame> frame, long int ori
|
||||
memcpy(resampled_samples, audio_converted->data[0], (nb_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16) * info.channels));
|
||||
|
||||
// Free frames
|
||||
av_freep(&audio_frame[0]);
|
||||
avcodec_free_frame(&audio_frame);
|
||||
free(audio_frame->data[0]); // TODO: Determine why av_free crashes on Windows
|
||||
AV_FREE_FRAME(&audio_frame);
|
||||
av_free(audio_converted->data[0]);
|
||||
AV_FREE_FRAME(&audio_converted);
|
||||
frame_samples = NULL;
|
||||
av_freep(&audio_converted[0]);
|
||||
avcodec_free_frame(&audio_converted);
|
||||
|
||||
// Resize the frame to hold the right # of channels and samples
|
||||
int channel_buffer_size = nb_samples;
|
||||
|
||||
@@ -60,12 +60,12 @@ int main(int argc, char* argv[])
|
||||
// Open Timeline
|
||||
r9.Open();
|
||||
|
||||
// cout << " --> 1" << endl;
|
||||
// t.GetFrame(1);
|
||||
// cout << " --> 500" << endl;
|
||||
// t.GetFrame(500);
|
||||
// cout << "1034" << endl;
|
||||
// t.GetFrame(1034);
|
||||
cout << " --> 1" << endl;
|
||||
r9.GetFrame(1);
|
||||
cout << " --> 500" << endl;
|
||||
r9.GetFrame(500);
|
||||
cout << "1034" << endl;
|
||||
r9.GetFrame(1034);
|
||||
// cout << "1" << endl;
|
||||
// t.GetFrame(1);
|
||||
// cout << "1200" << endl;
|
||||
@@ -186,15 +186,17 @@ int main(int argc, char* argv[])
|
||||
//map.Open();
|
||||
|
||||
/* WRITER ---------------- */
|
||||
FFmpegWriter w9("C:\\Users\\Jonathan\\test-output.webm");
|
||||
w9.debug = true;
|
||||
FFmpegWriter w9("C:\\Users\\Jonathan\\test-output.avi");
|
||||
w9.debug = false;
|
||||
//ImageWriter w9("/home/jonathan/output.gif");
|
||||
|
||||
// Set options
|
||||
//w9.SetVideoOptions(true, "mpeg4", r9.info.fps, r9.info.width, r9.info.height, Fraction(1,1), false, false, 1000000);
|
||||
//w9.SetAudioOptions(true, "mp2", r9.info.sample_rate, r9.info.channels, r9.info.channel_layout, 64000);
|
||||
w9.SetAudioOptions(true, "libvorbis", r9.info.sample_rate, r9.info.channels, r9.info.channel_layout, 128000);
|
||||
w9.SetVideoOptions(true, "libvpx", r9.info.fps, r9.info.width, r9.info.height, Fraction(1,1), false, false, 3000000);
|
||||
w9.SetVideoOptions(true, "libx264", r9.info.fps, r9.info.width, r9.info.height, Fraction(1,1), false, false, 1000000);
|
||||
w9.SetAudioOptions(true, "mp2", r9.info.sample_rate, r9.info.channels, r9.info.channel_layout, 64000);
|
||||
//w9.SetAudioOptions(true, "libvorbis", r9.info.sample_rate, r9.info.channels, r9.info.channel_layout, 128000);
|
||||
//w9.SetVideoOptions(true, "libvpx", r9.info.fps, r9.info.width, r9.info.height, Fraction(1,1), false, false, 3000000);
|
||||
//w9.SetAudioOptions(true, "libmp3lame", 22050, r9.info.channels, r9.info.channel_layout, 120000);
|
||||
//w9.SetVideoOptions(true, "libx264", t10.info.fps, t10.info.width, t10.info.height, t10.info.pixel_ratio, false, false, 1500000);
|
||||
//w9.SetVideoOptions(true, "rawvideo", r9.info.fps, 400, 2, r9.info.pixel_ratio, false, false, 20000000);
|
||||
@@ -208,7 +210,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
// w9.SetOption(VIDEO_STREAM, "qmin", "2" );
|
||||
// w9.SetOption(VIDEO_STREAM, "qmax", "30" );
|
||||
w9.SetOption(VIDEO_STREAM, "crf", "10" );
|
||||
// w9.SetOption(VIDEO_STREAM, "crf", "10" );
|
||||
// w9.SetOption(VIDEO_STREAM, "rc_min_rate", "2000000" );
|
||||
// w9.SetOption(VIDEO_STREAM, "rc_max_rate", "4000000" );
|
||||
// w9.SetOption(VIDEO_STREAM, "max_b_frames", "10" );
|
||||
|
||||
Reference in New Issue
Block a user