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:
Jonathan Thomas
2012-10-18 02:58:09 -05:00
parent 129a2fccd7
commit 5e5ca2a55c
4 changed files with 54 additions and 6 deletions

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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);
}
}

View File

@@ -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);