Bug fix: 368813 Transition is regenerated when overlay duration changes outside the transition

Change-Id: I8217e7fe00392455427e117dc54c3461301f95c5
This commit is contained in:
Gil Dobjanschi
2011-01-19 12:07:01 -08:00
parent fe93351cf1
commit c4edeb5a60
2 changed files with 137 additions and 91 deletions

View File

@@ -93,29 +93,28 @@ public class MediaImageItem extends MediaItem {
*
* @throws IOException
*/
public MediaImageItem(VideoEditor editor, String mediaItemId,
String filename, long durationMs,
int renderingMode) throws IOException {
public MediaImageItem(VideoEditor editor, String mediaItemId, String filename, long durationMs,
int renderingMode) throws IOException {
super(editor, mediaItemId, filename, renderingMode);
mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
mVideoEditor = ((VideoEditorImpl)editor);
try {
final Properties properties =
mMANativeHelper.getMediaProperties(filename);
final Properties properties = mMANativeHelper.getMediaProperties(filename);
switch (mMANativeHelper.getFileType(properties.fileType)) {
case MediaProperties.FILE_JPEG:
case MediaProperties.FILE_PNG: {
break;
case MediaProperties.FILE_PNG:
break;
}
default:
throw new IllegalArgumentException("Unsupported Input File Type");
default: {
throw new IllegalArgumentException("Unsupported Input File Type");
}
}
} catch (Exception e) {
throw new IllegalArgumentException("Unsupported file or file not found");
throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
}
/**
@@ -130,13 +129,13 @@ public class MediaImageItem extends MediaItem {
mDurationMs = durationMs;
mDecodedFilename = String.format(mMANativeHelper.getProjectPath() +
"/" + "decoded" + getId()+ ".rgb");
final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
final DataOutputStream dos = new DataOutputStream(fl);
try {
mAspectRatio = mMANativeHelper.getAspectRatio(mWidth, mHeight);
} catch(IllegalArgumentException e) {
throw new IllegalArgumentException ("Null width and height");
}
mGeneratedClipHeight = 0;
mGeneratedClipWidth = 0;
@@ -146,9 +145,12 @@ public class MediaImageItem extends MediaItem {
*/
final Pair<Integer, Integer>[] resolutions =
MediaProperties.getSupportedResolutions(mAspectRatio);
/**
* Get the highest resolution
*/
final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
final DataOutputStream dos = new DataOutputStream(fl);
final Pair<Integer, Integer> maxResolution = resolutions[resolutions.length - 1];
if (mHeight > maxResolution.second) {
/**
@@ -171,16 +173,16 @@ public class MediaImageItem extends MediaItem {
int mNewHeight = 0;
if ((mScaledWidth % 2 ) != 0) {
mNewWidth = mScaledWidth - 1;
}
else {
} else {
mNewWidth = mScaledWidth;
}
if ((mScaledHeight % 2 ) != 0) {
mNewHeight = mScaledHeight - 1;
}
else {
} else {
mNewHeight = mScaledHeight;
}
final int [] framingBuffer = new int[mNewWidth];
final ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
IntBuffer intBuffer;
@@ -195,6 +197,7 @@ public class MediaImageItem extends MediaItem {
dos.write(array);
tmp += 1;
}
mScaledWidth = mNewWidth;
mScaledHeight = mNewHeight;
scaledImage.recycle();
@@ -204,10 +207,11 @@ public class MediaImageItem extends MediaItem {
+ "/" + "scaled" + getId()+ ".JPG");
if (!((new File(mScaledFilename)).exists())) {
super.mRegenerateClip = true;
FileOutputStream f1 = new FileOutputStream(mScaledFilename);
final FileOutputStream f1 = new FileOutputStream(mScaledFilename);
scaledImage.compress(Bitmap.CompressFormat.JPEG, 50,f1);
f1.close();
}
mScaledWidth = scaledImage.getWidth();
mScaledHeight = scaledImage.getHeight();
@@ -215,17 +219,17 @@ public class MediaImageItem extends MediaItem {
int mNewheight = 0;
if ((mScaledWidth % 2 ) != 0) {
mNewWidth = mScaledWidth - 1;
}
else {
} else {
mNewWidth = mScaledWidth;
}
if ((mScaledHeight % 2 ) != 0) {
mNewheight = mScaledHeight - 1;
}
else {
} else {
mNewheight = mScaledHeight;
}
Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
final Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
final int [] framingBuffer = new int[mNewWidth];
ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
IntBuffer intBuffer;
@@ -240,10 +244,12 @@ public class MediaImageItem extends MediaItem {
dos.write(array);
tmp += 1;
}
mScaledWidth = mNewWidth;
mScaledHeight = mNewheight;
imageBitmap.recycle();
}
fl.close();
System.gc();
}
@@ -286,7 +292,7 @@ public class MediaImageItem extends MediaItem {
/**
* @return The file name of image which is decoded and stored
* in rgb format
* in RGB format
*/
String getDecodedImageFileName() {
return mDecodedFilename;
@@ -447,7 +453,7 @@ public class MediaImageItem extends MediaItem {
* Check if the effect overlaps with the end transition
*/
if (effect.getStartTime() + effect.getDuration() >
mDurationMs - transitionDurationMs) {
mDurationMs - transitionDurationMs) {
mEndTransition.invalidate();
break;
}
@@ -464,7 +470,7 @@ public class MediaImageItem extends MediaItem {
* Check if the overlay overlaps with the end transition
*/
if (overlay.getStartTime() + overlay.getDuration() >
mDurationMs - transitionDurationMs) {
mDurationMs - transitionDurationMs) {
mEndTransition.invalidate();
break;
}
@@ -648,23 +654,24 @@ public class MediaImageItem extends MediaItem {
for (int i = 0; i < thumbnailCount; i++) {
thumbnailArray[i] = thumbnail;
}
return thumbnailArray;
}
else {
} else {
if (startMs > endMs) {
throw new IllegalArgumentException("Start time is greater than end time");
}
if (endMs > mDurationMs) {
throw new IllegalArgumentException("End time is greater than file duration");
}
if (startMs == endMs) {
Bitmap[] bitmap = new Bitmap[1];
bitmap[0] = mMANativeHelper.getPixels(getGeneratedImageClip(),
width, height,startMs);
return bitmap;
}
return mMANativeHelper.getPixelsList(getGeneratedImageClip(), width,
height,startMs,endMs,thumbnailCount);
}
@@ -704,31 +711,51 @@ public class MediaImageItem extends MediaItem {
*/
if (mBeginTransition != null) {
final long transitionDurationMs = mBeginTransition.getDuration();
final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs, 0,
transitionDurationMs);
final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs, 0,
transitionDurationMs);
/**
* If the start time has changed and if the old or the new item
* overlaps with the begin transition, invalidate the transition.
* Invalidate transition if:
*
* 1. New item overlaps the transition, the old one did not
* 2. New item does not overlap the transition, the old one did
* 3. New and old item overlap the transition if begin or end
* time changed
*/
if (((oldStartTimeMs != newStartTimeMs)
|| (oldDurationMs != newDurationMs) )&&
(isOverlapping(oldStartTimeMs, oldDurationMs, 0, transitionDurationMs) ||
isOverlapping(newStartTimeMs, newDurationMs, 0,
transitionDurationMs))) {
if (newOverlap != oldOverlap) { // Overlap has changed
mBeginTransition.invalidate();
} else if (newOverlap) { // Both old and new overlap
if ((oldStartTimeMs != newStartTimeMs) ||
!(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
newStartTimeMs + newDurationMs > transitionDurationMs)) {
mBeginTransition.invalidate();
}
}
}
if (mEndTransition != null) {
final long transitionDurationMs = mEndTransition.getDuration();
final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
mDurationMs - transitionDurationMs, transitionDurationMs);
final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
mDurationMs - transitionDurationMs, transitionDurationMs);
/**
* If the start time + duration has changed and if the old or the new
* item overlaps the end transition, invalidate the transition
* Invalidate transition if:
*
* 1. New item overlaps the transition, the old one did not
* 2. New item does not overlap the transition, the old one did
* 3. New and old item overlap the transition if begin or end
* time changed
*/
if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
(isOverlapping(oldStartTimeMs, oldDurationMs,
mDurationMs - transitionDurationMs, transitionDurationMs) ||
isOverlapping(newStartTimeMs, newDurationMs,
mDurationMs - transitionDurationMs, transitionDurationMs))) {
if (newOverlap != oldOverlap) { // Overlap has changed
mEndTransition.invalidate();
} else if (newOverlap) { // Both old and new overlap
if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
((oldStartTimeMs > mDurationMs - transitionDurationMs) ||
newStartTimeMs > mDurationMs - transitionDurationMs)) {
mEndTransition.invalidate();
}
}
}
}
@@ -743,10 +770,12 @@ public class MediaImageItem extends MediaItem {
setGeneratedImageClip(null);
setRegenerateClip(true);
}
if (mScaledFilename != null) {
new File(mScaledFilename).delete();
mScaledFilename = null;
}
if (mDecodedFilename != null) {
new File(mDecodedFilename).delete();
mDecodedFilename = null;

View File

@@ -78,12 +78,9 @@ public class MediaVideoItem extends MediaItem {
*
* @throws IOException if the file cannot be opened for reading
*/
public MediaVideoItem(VideoEditor editor, String mediaItemId,
String filename,
int renderingMode)
throws IOException {
this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE,
100, false, null);
public MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
int renderingMode) throws IOException {
this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE, 100, false, null);
}
/**
@@ -105,20 +102,22 @@ public class MediaVideoItem extends MediaItem {
* @throws IOException if the file cannot be opened for reading
*/
MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
int renderingMode,
long beginMs, long endMs, int volumePercent, boolean muted,
int renderingMode, long beginMs, long endMs, int volumePercent, boolean muted,
String audioWaveformFilename) throws IOException {
super(editor, mediaItemId, filename, renderingMode);
if (editor instanceof VideoEditorImpl) {
mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
mVideoEditor = ((VideoEditorImpl)editor);
}
Properties properties = null;
final Properties properties;
try {
properties = mMANativeHelper.getMediaProperties(filename);
} catch ( Exception e) {
throw new IllegalArgumentException("Unsupported file or file not found");
throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
}
switch (mMANativeHelper.getFileType(properties.fileType)) {
case MediaProperties.FILE_3GP:
break;
@@ -163,8 +162,7 @@ public class MediaVideoItem extends MediaItem {
mMuted = muted;
mAudioWaveformFilename = audioWaveformFilename;
if (audioWaveformFilename != null) {
mWaveformData =
new SoftReference<WaveformData>(
mWaveformData = new SoftReference<WaveformData>(
new WaveformData(audioWaveformFilename));
} else {
mWaveformData = null;
@@ -190,9 +188,11 @@ public class MediaVideoItem extends MediaItem {
if (beginMs > mDurationMs) {
throw new IllegalArgumentException("setExtractBoundaries: Invalid start time");
}
if (endMs > mDurationMs) {
throw new IllegalArgumentException("setExtractBoundaries: Invalid end time");
}
if ((endMs != -1) && (beginMs >= endMs) ) {
throw new IllegalArgumentException("setExtractBoundaries: Start time is greater than end time");
}
@@ -255,18 +255,18 @@ public class MediaVideoItem extends MediaItem {
*/
@Override
public Bitmap getThumbnail(int width, int height, long timeMs) {
if (timeMs > mDurationMs)
{
if (timeMs > mDurationMs) {
throw new IllegalArgumentException("Time Exceeds duration");
}
if (timeMs < 0)
{
if (timeMs < 0) {
throw new IllegalArgumentException("Invalid Time duration");
}
if ((width <=0) || (height <= 0))
{
if ((width <=0) || (height <= 0)) {
throw new IllegalArgumentException("Invalid Dimensions");
}
return mMANativeHelper.getPixels(super.getFilename(),
width, height,timeMs);
}
@@ -280,18 +280,21 @@ public class MediaVideoItem extends MediaItem {
if (startMs > endMs) {
throw new IllegalArgumentException("Start time is greater than end time");
}
if (endMs > mDurationMs) {
throw new IllegalArgumentException("End time is greater than file duration");
}
if ((height <= 0) || (width <= 0)) {
throw new IllegalArgumentException("Invalid dimension");
}
if (startMs == endMs) {
Bitmap[] bitmap = new Bitmap[1];
bitmap[0] = mMANativeHelper.getPixels(super.getFilename(),
width, height,startMs);
final Bitmap[] bitmap = new Bitmap[1];
bitmap[0] = mMANativeHelper.getPixels(super.getFilename(), width, height,startMs);
return bitmap;
}
return mMANativeHelper.getPixelsList(super.getFilename(), width,
height,startMs,endMs,thumbnailCount);
}
@@ -324,40 +327,58 @@ public class MediaVideoItem extends MediaItem {
* {@inheritDoc}
*/
@Override
void invalidateTransitions(long oldStartTimeMs, long oldDurationMs,
long newStartTimeMs,
void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
long newDurationMs) {
/**
* Check if the item overlaps with the beginning and end transitions
*/
if (mBeginTransition != null) {
final long transitionDurationMs = mBeginTransition.getDuration();
final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
mBeginBoundaryTimeMs, transitionDurationMs);
final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
mBeginBoundaryTimeMs, transitionDurationMs);
/**
* If the start time has changed and if the old or the new item
* overlaps with the begin transition, invalidate the transition.
* Invalidate transition if:
*
* 1. New item overlaps the transition, the old one did not
* 2. New item does not overlap the transition, the old one did
* 3. New and old item overlap the transition if begin or end
* time changed
*/
if (((oldStartTimeMs != newStartTimeMs)
|| (oldDurationMs != newDurationMs) )&&
(isOverlapping(oldStartTimeMs, oldDurationMs,
mBeginBoundaryTimeMs, transitionDurationMs) ||
isOverlapping(newStartTimeMs, newDurationMs,
mBeginBoundaryTimeMs, transitionDurationMs))) {
if (newOverlap != oldOverlap) { // Overlap has changed
mBeginTransition.invalidate();
} else if (newOverlap) { // Both old and new overlap
if ((oldStartTimeMs != newStartTimeMs) ||
!(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
newStartTimeMs + newDurationMs > transitionDurationMs)) {
mBeginTransition.invalidate();
}
}
}
if (mEndTransition != null) {
final long transitionDurationMs = mEndTransition.getDuration();
final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
/**
* If the start time + duration has changed and if the old or the new
* item overlaps the end transition, invalidate the transition
* Invalidate transition if:
*
* 1. New item overlaps the transition, the old one did not
* 2. New item does not overlap the transition, the old one did
* 3. New and old item overlap the transition if begin or end
* time changed
*/
if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
(isOverlapping(oldStartTimeMs, oldDurationMs,
mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs) ||
isOverlapping(newStartTimeMs, newDurationMs,
mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs))) {
if (newOverlap != oldOverlap) { // Overlap has changed
mEndTransition.invalidate();
} else if (newOverlap) { // Both old and new overlap
if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
((oldStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs) ||
newStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs)) {
mEndTransition.invalidate();
}
}
}
}
@@ -434,7 +455,7 @@ public class MediaVideoItem extends MediaItem {
throw new IllegalArgumentException("requested time not correct");
}
Surface surface = surfaceHolder.getSurface();
final Surface surface = surfaceHolder.getSurface();
if (surface == null) {
throw new RuntimeException("Surface could not be retrieved from Surface holder");
}
@@ -442,8 +463,7 @@ public class MediaVideoItem extends MediaItem {
if (mFilename != null) {
return mMANativeHelper.renderMediaItemPreviewFrame(surface,
mFilename,timeMs,mWidth,mHeight);
}
else {
} else {
return 0;
}
}
@@ -462,7 +482,7 @@ public class MediaVideoItem extends MediaItem {
* Audio track
*/
public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener)
throws IOException {
throws IOException {
int frameDuration = 0;
int sampleCount = 0;
final String projectPath = mMANativeHelper.getProjectPath();
@@ -481,19 +501,17 @@ public class MediaVideoItem extends MediaItem {
* Logic to get frame duration = (no. of frames per sample * 1000)/
* sampling frequency
*/
if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
if (mMANativeHelper.getAudioCodecType(mAudioType) ==
MediaProperties.ACODEC_AMRNB ) {
frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRNB*1000)/
MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRNB;
}
else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
} else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
MediaProperties.ACODEC_AMRWB ) {
frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRWB * 1000)/
MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRWB;
}
else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
} else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
MediaProperties.ACODEC_AAC_LC ) {
frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AAC * 1000)/
MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
@@ -682,5 +700,4 @@ public class MediaVideoItem extends MediaItem {
return clipSettings;
}
}