You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Many small improvements, bug fixes, and build system fixes for newer systems that have both qt4 and qt5.
This commit is contained in:
@@ -9,65 +9,66 @@
|
||||
|
||||
# FindAvformat
|
||||
FIND_PATH( AVFORMAT_INCLUDE_DIR libavformat/avformat.h
|
||||
PATHS /usr/include/
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
PATHS /usr/include/
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
|
||||
FIND_LIBRARY( AVFORMAT_LIBRARY avformat
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
#FindAvcodec
|
||||
FIND_PATH( AVCODEC_INCLUDE_DIR libavcodec/avcodec.h
|
||||
PATHS /usr/include/
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
|
||||
FIND_LIBRARY( AVCODEC_LIBRARY avcodec
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
#FindAvutil
|
||||
FIND_PATH( AVUTIL_INCLUDE_DIR libavutil/avutil.h
|
||||
PATHS /usr/include/
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
|
||||
FIND_LIBRARY( AVUTIL_LIBRARY avutil
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
|
||||
#FindAvdevice
|
||||
FIND_PATH( AVDEVICE_INCLUDE_DIR libavdevice/avdevice.h
|
||||
PATHS /usr/include/
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
|
||||
FIND_LIBRARY( AVDEVICE_LIBRARY avdevice
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
|
||||
#FindSwscale
|
||||
FIND_PATH( SWSCALE_INCLUDE_DIR libswscale/swscale.h
|
||||
PATHS /usr/include/
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
/usr/include/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/include/
|
||||
$ENV{FFMPEGDIR}/include/ffmpeg/ )
|
||||
|
||||
FIND_LIBRARY( SWSCALE_LIBRARY swscale
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
PATHS /usr/lib/
|
||||
/usr/lib/ffmpeg/
|
||||
$ENV{FFMPEGDIR}/lib/
|
||||
$ENV{FFMPEGDIR}/lib/ffmpeg/ )
|
||||
|
||||
SET( FFMPEG_FOUND FALSE )
|
||||
|
||||
@@ -121,4 +122,4 @@ include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set FFMPEG_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(FFMPEG DEFAULT_MSG
|
||||
FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIR)
|
||||
FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIR)
|
||||
|
||||
12
doc/known_bugs.txt
Normal file
12
doc/known_bugs.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
These are the known bugs in the OpenShot Library
|
||||
-------------------------------------------------
|
||||
1) (CRITICAL) FFmpegReader - Issues with audio continuity and GetAudioPTSLocation(). For some reason, there are skipped
|
||||
audio samples, gaps in PTS timecodes, and generally "Poppy" and "Crackly" audio in WebM files. WebM files
|
||||
seem to have more audio issues than other codecs, for some reason.
|
||||
2) (CRITICAL) FFmpegReader - Issues with OpenMP and the nested ImageMagick++ OpenMP implementation. On my 8 core system,
|
||||
If I don't call omp_set_num_threads(4... or less), an ImageMagick++ error is raised. I have posted this
|
||||
issue on the ImageMagick forum: http://www.imagemagick.org/discourse-server/viewtopic.php?f=23&t=24036
|
||||
3) (CRITICAL) FFmpegReader - OpenMP issue if more tasks are created than the number of processors. For example, on
|
||||
ReadStream(), if minimum_packets = 8 and omp_set_num_threads(4), than potentially more than 4 tasks will
|
||||
be running at the same time, and some tasks just seem to disappear (or never actually start).
|
||||
4)
|
||||
@@ -58,6 +58,7 @@ namespace openshot
|
||||
FFmpegReader *local_reader;
|
||||
chunk_location previous_location;
|
||||
ChunkVersion version;
|
||||
tr1::shared_ptr<Frame> last_frame;
|
||||
|
||||
/// Check if folder path existing
|
||||
bool does_folder_exist(string path);
|
||||
|
||||
@@ -92,6 +92,7 @@ namespace openshot
|
||||
AVPacket *packet;
|
||||
AVPicture *pFrame;
|
||||
bool is_open;
|
||||
bool is_duration_known;
|
||||
|
||||
bool check_interlace;
|
||||
bool check_fps;
|
||||
|
||||
@@ -29,7 +29,8 @@ include_directories(${SDL_INCLUDE_DIR})
|
||||
|
||||
################# QT4 ###################
|
||||
# Find QT4 libraries
|
||||
FIND_PACKAGE(Qt4 REQUIRED)
|
||||
SET(QT_QMAKE_EXECUTABLE '/usr/bin/qmake-qt4') # DEBUB, WORK-AROUND: Force the use of QT4 (when multiple versions are installed)
|
||||
FIND_PACKAGE(Qt4)
|
||||
|
||||
# Include Qt headers (needed for compile)
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
@@ -214,8 +214,14 @@ tr1::shared_ptr<Frame> ChunkReader::GetFrame(int requested_frame) throw(ReaderCl
|
||||
previous_location = location;
|
||||
}
|
||||
|
||||
// Return the frame (from the current reader)
|
||||
return local_reader->GetFrame(location.frame);
|
||||
// Get the frame (from the current reader)
|
||||
last_frame = local_reader->GetFrame(location.frame);
|
||||
|
||||
// Update the frame number property
|
||||
last_frame->number = requested_frame;
|
||||
|
||||
// Return the frame
|
||||
return last_frame;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
using namespace openshot;
|
||||
|
||||
ChunkWriter::ChunkWriter(string path, FileReaderBase *reader) throw (InvalidFile, InvalidFormat, InvalidCodec, InvalidOptions, OutOfMemory) :
|
||||
local_reader(reader), path(path), chunk_size(24 * 3), chunk_count(1), frame_count(1), is_writing(false),
|
||||
local_reader(reader), path(path), chunk_size(24*3), chunk_count(1), frame_count(1), is_writing(false),
|
||||
default_extension(".webm"), default_vcodec("libvpx"), default_acodec("libvorbis")
|
||||
{
|
||||
// Init FileInfo struct (clear all values)
|
||||
@@ -62,22 +62,21 @@ void ChunkWriter::WriteFrame(tr1::shared_ptr<Frame> frame)
|
||||
// Create FFmpegWriter (FINAL quality)
|
||||
create_folder(get_chunk_path(chunk_count, "final", ""));
|
||||
writer_final = new FFmpegWriter(get_chunk_path(chunk_count, "final", default_extension));
|
||||
writer_final->SetAudioOptions(true, default_acodec, info.sample_rate, info.channels, info.audio_bit_rate);
|
||||
writer_final->SetAudioOptions(true, default_acodec, info.sample_rate, info.channels, 128000);
|
||||
writer_final->SetVideoOptions(true, default_vcodec, info.fps, info.width, info.height, info.pixel_ratio, false, false, info.video_bit_rate);
|
||||
|
||||
// Create FFmpegWriter (PREVIEW quality)
|
||||
create_folder(get_chunk_path(chunk_count, "preview", ""));
|
||||
writer_preview = new FFmpegWriter(get_chunk_path(chunk_count, "preview", default_extension));
|
||||
writer_preview->SetAudioOptions(true, default_acodec, info.sample_rate, info.channels, info.audio_bit_rate);
|
||||
writer_preview->SetAudioOptions(true, default_acodec, info.sample_rate, info.channels, 128000);
|
||||
writer_preview->SetVideoOptions(true, default_vcodec, info.fps, info.width * 0.5, info.height * 0.5, info.pixel_ratio, false, false, info.video_bit_rate * 0.5);
|
||||
|
||||
// Create FFmpegWriter (LOW quality)
|
||||
create_folder(get_chunk_path(chunk_count, "thumb", ""));
|
||||
writer_thumb = new FFmpegWriter(get_chunk_path(chunk_count, "thumb", default_extension));
|
||||
writer_thumb->SetAudioOptions(true, default_acodec, info.sample_rate, info.channels, info.audio_bit_rate);
|
||||
writer_thumb->SetAudioOptions(true, default_acodec, info.sample_rate, info.channels, 128000);
|
||||
writer_thumb->SetVideoOptions(true, default_vcodec, info.fps, info.width * 0.25, info.height * 0.25, info.pixel_ratio, false, false, info.video_bit_rate * 0.25);
|
||||
|
||||
|
||||
// Prepare Streams
|
||||
writer_final->PrepareStreams();
|
||||
writer_preview->PrepareStreams();
|
||||
@@ -97,12 +96,22 @@ void ChunkWriter::WriteFrame(tr1::shared_ptr<Frame> frame)
|
||||
writer_preview->WriteFrame(frame);
|
||||
writer_thumb->WriteFrame(frame);
|
||||
|
||||
// Increment frame counter
|
||||
frame_count++;
|
||||
|
||||
// Write the frames once it reaches the correct chunk size
|
||||
if (frame_count % chunk_size == 0 && frame_count >= chunk_size)
|
||||
{
|
||||
cout << "Done with chunk" << endl;
|
||||
cout << "frame_count: " << frame_count << endl;
|
||||
cout << "chunk_size: " << chunk_size << endl;
|
||||
|
||||
// Pad an additional 12 frames
|
||||
for (int z = 0; z<12; z++)
|
||||
{
|
||||
// Repeat frame
|
||||
writer_final->WriteFrame(frame);
|
||||
writer_preview->WriteFrame(frame);
|
||||
writer_thumb->WriteFrame(frame);
|
||||
}
|
||||
|
||||
// Write Footer
|
||||
writer_final->WriteTrailer();
|
||||
writer_preview->WriteTrailer();
|
||||
@@ -120,6 +129,9 @@ void ChunkWriter::WriteFrame(tr1::shared_ptr<Frame> frame)
|
||||
is_writing = false;
|
||||
}
|
||||
|
||||
// Increment frame counter
|
||||
frame_count++;
|
||||
|
||||
// Keep track of the last frame added
|
||||
last_frame = frame;
|
||||
}
|
||||
@@ -156,6 +168,39 @@ void ChunkWriter::WriteFrame(int start, int length)
|
||||
// Close the writer
|
||||
void ChunkWriter::Close()
|
||||
{
|
||||
// Write the frames once it reaches the correct chunk size
|
||||
if (is_writing)
|
||||
{
|
||||
cout << "Final chunk" << endl;
|
||||
cout << "frame_count: " << frame_count << endl;
|
||||
cout << "chunk_size: " << chunk_size << endl;
|
||||
|
||||
// Pad an additional 12 frames
|
||||
for (int z = 0; z<12; z++)
|
||||
{
|
||||
// Repeat frame
|
||||
writer_final->WriteFrame(last_frame);
|
||||
writer_preview->WriteFrame(last_frame);
|
||||
writer_thumb->WriteFrame(last_frame);
|
||||
}
|
||||
|
||||
// Write Footer
|
||||
writer_final->WriteTrailer();
|
||||
writer_preview->WriteTrailer();
|
||||
writer_thumb->WriteTrailer();
|
||||
|
||||
// Close writer & reader
|
||||
writer_final->Close();
|
||||
writer_preview->Close();
|
||||
writer_thumb->Close();
|
||||
|
||||
// Increment chunk count
|
||||
chunk_count++;
|
||||
|
||||
// Stop writing chunk
|
||||
is_writing = false;
|
||||
}
|
||||
|
||||
// Reset frame counters
|
||||
chunk_count = 0;
|
||||
frame_count = 0;
|
||||
|
||||
@@ -7,7 +7,7 @@ FFmpegReader::FFmpegReader(string path) throw(InvalidFile, NoStreamsFound, Inval
|
||||
audio_pts_offset(99999), video_pts_offset(99999), path(path), is_video_seek(true), check_interlace(false),
|
||||
check_fps(false), enable_seek(true), rescaler_position(0), num_of_rescalers(32), is_open(false),
|
||||
seek_audio_frame_found(-1), seek_video_frame_found(-1), resampleCtx(NULL), prev_samples(0), prev_pts(0),
|
||||
pts_total(0), pts_counter(0), display_debug(false) {
|
||||
pts_total(0), pts_counter(0), display_debug(false), is_duration_known(false) {
|
||||
|
||||
// Init FileInfo struct (clear all values)
|
||||
InitFileInfo();
|
||||
@@ -273,12 +273,32 @@ void FFmpegReader::UpdateVideoInfo()
|
||||
// Set the duration in seconds, and video length (# of frames)
|
||||
info.duration = pStream->duration * info.video_timebase.ToDouble();
|
||||
|
||||
// Check for valid duration
|
||||
// Check for valid duration (if found)
|
||||
if (info.duration <= 0.0f && pFormatCtx->duration >= 0)
|
||||
// Use the format's duration
|
||||
info.duration = pFormatCtx->duration / AV_TIME_BASE;
|
||||
|
||||
info.video_length = round(info.duration * info.fps.ToDouble());
|
||||
// Calculate duration from filesize and bitrate (if any)
|
||||
if (info.duration <= 0.0f && info.video_bit_rate > 0 && info.file_size > 0)
|
||||
// Estimate from bitrate, total bytes, and framerate
|
||||
info.duration = (info.file_size / info.video_bit_rate);
|
||||
|
||||
// No duration found in stream of file
|
||||
if (info.duration <= 0.0f)
|
||||
{
|
||||
// No duration is found in the video stream
|
||||
info.duration = -1;
|
||||
info.video_length = -1;
|
||||
is_duration_known = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Yes, a duration was found
|
||||
is_duration_known = true;
|
||||
|
||||
// Calculate number of frames
|
||||
info.video_length = round(info.duration * info.fps.ToDouble());
|
||||
}
|
||||
|
||||
// Override an invalid framerate
|
||||
if (info.fps.ToFloat() > 120.0f)
|
||||
@@ -295,7 +315,9 @@ void FFmpegReader::UpdateVideoInfo()
|
||||
|
||||
tr1::shared_ptr<Frame> FFmpegReader::GetFrame(int requested_frame) throw(ReaderClosed, TooManySeeks)
|
||||
{
|
||||
//cout << "GET FRAME " << requested_frame << ", last_frame: " << last_frame << endl;
|
||||
if (display_debug)
|
||||
cout << "GET FRAME " << requested_frame << ", last_frame: " << last_frame << endl;
|
||||
|
||||
// Check for open reader (or throw exception)
|
||||
if (!is_open)
|
||||
throw ReaderClosed("The FFmpegReader is closed. Call Open() before calling this method.", path);
|
||||
@@ -311,20 +333,20 @@ tr1::shared_ptr<Frame> FFmpegReader::GetFrame(int requested_frame) throw(ReaderC
|
||||
// Adjust for a requested frame that is too small or too large
|
||||
if (requested_frame < 1)
|
||||
requested_frame = 1;
|
||||
if (requested_frame > info.video_length)
|
||||
if (requested_frame > info.video_length && is_duration_known)
|
||||
requested_frame = info.video_length;
|
||||
if (info.has_video && info.video_length == 0)
|
||||
// Invalid duration of video file
|
||||
throw InvalidFile("Could not detect the duration of the video or audio stream.", path);
|
||||
|
||||
// Reset seek count
|
||||
seek_count = 0;
|
||||
|
||||
// Check for first frame (always need to get frame 1 before other frames, to correctly calculate offsets)
|
||||
if (last_frame == 0 && requested_frame != 1)
|
||||
// Get first frame
|
||||
ReadStream(1);
|
||||
|
||||
// Reset seek count
|
||||
seek_count = 0;
|
||||
|
||||
// Are we within 30 frames of the requested frame?
|
||||
int diff = requested_frame - last_frame;
|
||||
if (diff >= 1 && diff <= 30)
|
||||
@@ -366,12 +388,13 @@ tr1::shared_ptr<Frame> FFmpegReader::ReadStream(int requested_frame)
|
||||
|
||||
// Minimum number of packets to process (for performance reasons)
|
||||
int packets_processed = 0;
|
||||
int minimum_packets = omp_get_num_procs();
|
||||
|
||||
//omp_set_num_threads(1);
|
||||
int minimum_packets = omp_get_num_procs() / 2; // DEBUG, WORK-AROUND for an ImageMagick bug (preventing use of all 8 cores)
|
||||
omp_set_num_threads(minimum_packets); // DEBUG, WORK-AROUND for an ImageMagick bug (preventing use of all 8 cores)
|
||||
omp_set_nested(true);
|
||||
|
||||
#pragma omp parallel
|
||||
{
|
||||
|
||||
#pragma omp single
|
||||
{
|
||||
// Loop through the stream until the correct frame is found
|
||||
|
||||
@@ -329,7 +329,7 @@ void FFmpegWriter::write_queued_frames()
|
||||
spooled_video_frames.clear();
|
||||
spooled_audio_frames.clear();
|
||||
|
||||
//omp_set_num_threads(1);
|
||||
omp_set_num_threads(4);
|
||||
omp_set_nested(true);
|
||||
#pragma omp parallel
|
||||
{
|
||||
|
||||
31
src/Main.cpp
31
src/Main.cpp
@@ -20,10 +20,26 @@ void FrameReady(int number)
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Create a chunkwriter
|
||||
//FFmpegReader *r3 = new FFmpegReader("/home/jonathan/Videos/sintel_trailer-720p.mp4");
|
||||
//ChunkWriter cw1("/home/jonathan/apps/chunks/chunk1/", r3);
|
||||
//cw1.WriteFrame(r3, 1, r3->info.video_length);
|
||||
//cw1.Close();
|
||||
// FFmpegReader *r3 = new FFmpegReader("/home/jonathan/Videos/sintel_trailer-720p.mp4");
|
||||
// r3->DisplayInfo();
|
||||
// ChunkWriter cw1("/home/jonathan/apps/chunks/chunk1/", r3);
|
||||
// cw1.WriteFrame(r3, 1, r3->info.video_length);
|
||||
// cw1.Close();
|
||||
// return 0;
|
||||
|
||||
// FFmpegReader to test 1 part of a chunk
|
||||
// FFmpegReader *r10 = new FFmpegReader("/home/jonathan/apps/chunks/chunk1/final/000001.webm");
|
||||
// r10->enable_seek = false;
|
||||
// r10->Open();
|
||||
//// r10->GetFrame(1)->Display();
|
||||
//// r10->GetFrame(2)->Display();
|
||||
//// r10->GetFrame(3)->Display();
|
||||
//// r10->GetFrame(1)->Display();
|
||||
// for (int z1 = 20; z1 <= 24*3; z1++)
|
||||
// if (z1 >= 65)
|
||||
// r10->GetFrame(z1)->DisplayWaveform();
|
||||
// return 0;
|
||||
|
||||
|
||||
// Create a chunkreader
|
||||
cout << "Start Chunk Reader" << endl;
|
||||
@@ -35,11 +51,11 @@ int main(int argc, char* argv[])
|
||||
//cr1.GetFrame(300)->Display();
|
||||
|
||||
/* WRITER ---------------- */
|
||||
FFmpegWriter w9("/home/jonathan/fromchunks.webm");
|
||||
FFmpegWriter w9("/home/jonathan/fromchunks.mp3");
|
||||
|
||||
// Set options
|
||||
w9.SetAudioOptions(true, cr1.info.acodec, cr1.info.sample_rate, cr1.info.channels, cr1.info.audio_bit_rate);
|
||||
w9.SetVideoOptions(true, cr1.info.vcodec, cr1.info.fps, cr1.info.width, cr1.info.height, cr1.info.pixel_ratio, false, false, cr1.info.video_bit_rate);
|
||||
w9.SetAudioOptions(true, "libmp3lame", cr1.info.sample_rate, cr1.info.channels, cr1.info.audio_bit_rate);
|
||||
//w9.SetVideoOptions(true, cr1.info.vcodec, cr1.info.fps, cr1.info.width, cr1.info.height, cr1.info.pixel_ratio, false, false, cr1.info.video_bit_rate);
|
||||
|
||||
// Prepare Streams
|
||||
w9.PrepareStreams();
|
||||
@@ -57,6 +73,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
|
||||
cout << "End Chunk Reader" << endl;
|
||||
return 0;
|
||||
|
||||
// Qt Test Code
|
||||
if (argc == 2)
|
||||
|
||||
@@ -35,6 +35,7 @@ include_directories(${SDL_INCLUDE_DIR})
|
||||
|
||||
################# QT4 ###################
|
||||
# Find QT4 libraries
|
||||
SET(QT_QMAKE_EXECUTABLE '/usr/bin/qmake-qt4') # DEBUB, WORK-AROUND: Force the use of QT4 (when multiple versions are installed)
|
||||
FIND_PACKAGE(Qt4 REQUIRED)
|
||||
|
||||
# Include Qt headers (needed for compile)
|
||||
|
||||
Reference in New Issue
Block a user