You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Fixed a big bug on frame rate mapping, due to incorrect # of samples being copied into the new frame. Also, implemented interalacing support, and full pulldown support (in the frame mapper).
This commit is contained in:
@@ -75,6 +75,9 @@ namespace openshot
|
||||
/// Add (or replace) pixel data to the frame
|
||||
void AddImage(tr1::shared_ptr<Magick::Image> new_image);
|
||||
|
||||
/// Add (or replace) pixel data to the frame (for only the odd or even lines)
|
||||
void AddImage(tr1::shared_ptr<Magick::Image> new_image, bool only_odd_lines);
|
||||
|
||||
/// Add audio samples to a specific channel
|
||||
void AddAudio(int destChannel, int destStartSample, const float* source, int numSamples, float gainToApplyToSource);
|
||||
|
||||
|
||||
@@ -451,6 +451,36 @@ void Frame::AddImage(tr1::shared_ptr<Magick::Image> new_image)
|
||||
image = new_image;
|
||||
}
|
||||
|
||||
// Add (or replace) pixel data to the frame (for only the odd or even lines)
|
||||
void Frame::AddImage(tr1::shared_ptr<Magick::Image> new_image, bool only_odd_lines)
|
||||
{
|
||||
// Replace image (if needed)
|
||||
if (image->columns() == 1)
|
||||
image = new_image;
|
||||
|
||||
// Loop through each odd or even line, and copy it to the image
|
||||
int starting_row = 0;
|
||||
if (!only_odd_lines)
|
||||
// even rows
|
||||
starting_row = 1;
|
||||
|
||||
// Replace some rows of pixels
|
||||
for (int row = starting_row; row < new_image->rows(); row += 2)
|
||||
{
|
||||
// Get row of pixels from original image
|
||||
Magick::PixelPacket* row_pixels = image->getPixels(0, row, image->columns(), 1);
|
||||
const Magick::PixelPacket* new_row_pixels = new_image->getConstPixels(0, row, image->columns(), 1);
|
||||
|
||||
// Copy pixels
|
||||
for (int col = 0; col < image->columns(); col++)
|
||||
row_pixels[col] = new_row_pixels[col];
|
||||
|
||||
// Replace them with updated pixels
|
||||
image->syncPixels();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Add audio samples to a specific channel
|
||||
void Frame::AddAudio(int destChannel, int destStartSample, const float* source, int numSamples, float gainToApplyToSource = 1.0f)
|
||||
{
|
||||
|
||||
@@ -250,7 +250,10 @@ tr1::shared_ptr<Frame> FrameMapper::GetFrame(int requested_frame) throw(ReaderCl
|
||||
tr1::shared_ptr<Frame> frame(new Frame(requested_frame, 1, 1, "#000000", samples_in_frame, info.channels));
|
||||
|
||||
// Copy the image from the odd field (TODO: make this copy each field from the correct frames)
|
||||
frame->AddImage(reader->GetFrame(mapped.Odd.Frame)->GetImage());
|
||||
frame->AddImage(reader->GetFrame(mapped.Odd.Frame)->GetImage(), true);
|
||||
if (mapped.Odd.Frame != mapped.Even.Frame)
|
||||
// Add even lines (if different than the previous image)
|
||||
frame->AddImage(reader->GetFrame(mapped.Even.Frame)->GetImage(), false);
|
||||
|
||||
// Copy the samples
|
||||
int samples_copied = 0;
|
||||
@@ -258,6 +261,7 @@ tr1::shared_ptr<Frame> FrameMapper::GetFrame(int requested_frame) throw(ReaderCl
|
||||
while (samples_copied < mapped.Samples.total)
|
||||
{
|
||||
// init number of samples to copy this iteration
|
||||
int remaining_samples = mapped.Samples.total - samples_copied;
|
||||
int number_to_copy = 0;
|
||||
|
||||
// Loop through each channel
|
||||
@@ -270,20 +274,31 @@ tr1::shared_ptr<Frame> FrameMapper::GetFrame(int requested_frame) throw(ReaderCl
|
||||
if (starting_frame == mapped.Samples.frame_start)
|
||||
{
|
||||
// Starting frame (take the ending samples)
|
||||
number_to_copy = (original_samples - mapped.Samples.sample_start) + 1;
|
||||
cout << "Fixing to copy audio: frame: " << starting_frame << ", channel: " << channel << ", original_samples: " << original_samples << ", sample_start: " << mapped.Samples.sample_start << ", number_to_copy: " << number_to_copy << ", first value: " << original_frame->GetAudioSamples(channel)[0] << endl;
|
||||
frame->AddAudio(channel, samples_copied, original_frame->GetAudioSamples(channel) + mapped.Samples.sample_start, 10, 1.0);
|
||||
number_to_copy = original_samples - mapped.Samples.sample_start;
|
||||
if (number_to_copy > remaining_samples)
|
||||
number_to_copy = remaining_samples;
|
||||
|
||||
// Add samples to new frame
|
||||
frame->AddAudio(channel, samples_copied, original_frame->GetAudioSamples(channel) + mapped.Samples.sample_start, number_to_copy, 1.0);
|
||||
}
|
||||
else if (starting_frame > mapped.Samples.frame_start && starting_frame < mapped.Samples.frame_end)
|
||||
{
|
||||
// Middle frame (take all samples)
|
||||
number_to_copy = original_samples;
|
||||
if (number_to_copy > remaining_samples)
|
||||
number_to_copy = remaining_samples;
|
||||
|
||||
// Add samples to new frame
|
||||
frame->AddAudio(channel, samples_copied, original_frame->GetAudioSamples(channel), number_to_copy, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ending frame (take the beginning samples)
|
||||
number_to_copy = mapped.Samples.sample_end;
|
||||
if (number_to_copy > remaining_samples)
|
||||
number_to_copy = remaining_samples;
|
||||
|
||||
// Add samples to new frame
|
||||
frame->AddAudio(channel, samples_copied, original_frame->GetAudioSamples(channel), number_to_copy, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ int main()
|
||||
// openshot::FFmpegReader r("/home/jonathan/Aptana Studio Workspace/OpenShotLibrary/src/examples/asdf.wdf");
|
||||
|
||||
|
||||
openshot::FrameMapper r(&r1, Framerate(30,1), PULLDOWN_NONE);
|
||||
openshot::FrameMapper r(&r1, Framerate(30,1), PULLDOWN_CLASSIC);
|
||||
|
||||
// Display debug info
|
||||
r.Open();
|
||||
@@ -179,7 +179,7 @@ int main()
|
||||
//Frame *f = r.GetFrame(1);
|
||||
|
||||
//for (int frame = 131; frame >= 1; frame--)
|
||||
for (int frame = 1; frame <= 2000; frame++)
|
||||
for (int frame = 1; frame <= 500; frame++)
|
||||
{
|
||||
tr1::shared_ptr<Frame> f = r.GetFrame(frame);
|
||||
//f->AddOverlayNumber(0);
|
||||
|
||||
Reference in New Issue
Block a user