| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| package android.media.videoeditor; |
| |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import java.io.DataOutputStream; |
| import java.nio.ByteBuffer; |
| import java.nio.IntBuffer; |
| |
| import android.graphics.Bitmap; |
| import android.media.videoeditor.MediaArtistNativeHelper.ClipSettings; |
| import android.media.videoeditor.MediaArtistNativeHelper.FileType; |
| import android.media.videoeditor.MediaArtistNativeHelper.MediaRendering; |
| |
| /** |
| * This abstract class describes the base class for any MediaItem. Objects are |
| * defined with a file path as a source data. |
| * {@hide} |
| */ |
| public abstract class MediaItem { |
| /** |
| * A constant which can be used to specify the end of the file (instead of |
| * providing the actual duration of the media item). |
| */ |
| public final static int END_OF_FILE = -1; |
| |
| /** |
| * Rendering modes |
| */ |
| /** |
| * When using the RENDERING_MODE_BLACK_BORDER rendering mode video frames |
| * are resized by preserving the aspect ratio until the movie matches one of |
| * the dimensions of the output movie. The areas outside the resized video |
| * clip are rendered black. |
| */ |
| public static final int RENDERING_MODE_BLACK_BORDER = 0; |
| |
| /** |
| * When using the RENDERING_MODE_STRETCH rendering mode video frames are |
| * stretched horizontally or vertically to match the current aspect ratio of |
| * the video editor. |
| */ |
| public static final int RENDERING_MODE_STRETCH = 1; |
| |
| /** |
| * When using the RENDERING_MODE_CROPPING rendering mode video frames are |
| * scaled horizontally or vertically by preserving the original aspect ratio |
| * of the media item. |
| */ |
| public static final int RENDERING_MODE_CROPPING = 2; |
| |
| /** |
| * The unique id of the MediaItem |
| */ |
| private final String mUniqueId; |
| |
| /** |
| * The name of the file associated with the MediaItem |
| */ |
| protected final String mFilename; |
| |
| /** |
| * List of effects |
| */ |
| private final List<Effect> mEffects; |
| |
| /** |
| * List of overlays |
| */ |
| private final List<Overlay> mOverlays; |
| |
| /** |
| * The rendering mode |
| */ |
| private int mRenderingMode; |
| |
| private final MediaArtistNativeHelper mMANativeHelper; |
| |
| private final String mProjectPath; |
| |
| /** |
| * Beginning and end transitions |
| */ |
| protected Transition mBeginTransition; |
| |
| protected Transition mEndTransition; |
| |
| protected String mGeneratedImageClip; |
| |
| protected boolean mRegenerateClip; |
| |
| private boolean mBlankFrameGenerated = false; |
| |
| private String mBlankFrameFilename = null; |
| |
| /** |
| * Constructor |
| * |
| * @param editor The video editor reference |
| * @param mediaItemId The MediaItem id |
| * @param filename name of the media file. |
| * @param renderingMode The rendering mode |
| * @throws IOException if file is not found |
| * @throws IllegalArgumentException if a capability such as file format is |
| * not supported the exception object contains the unsupported |
| * capability |
| */ |
| protected MediaItem(VideoEditor editor, String mediaItemId, String filename, |
| int renderingMode) throws IOException { |
| if (filename == null) { |
| throw new IllegalArgumentException("MediaItem : filename is null"); |
| } |
| File file = new File(filename); |
| if (!file.exists()) { |
| throw new IOException(filename + " not found ! "); |
| } |
| |
| /*Compare file_size with 2GB*/ |
| if (VideoEditor.MAX_SUPPORTED_FILE_SIZE <= file.length()) { |
| throw new IllegalArgumentException("File size is more than 2GB"); |
| } |
| mUniqueId = mediaItemId; |
| mFilename = filename; |
| mRenderingMode = renderingMode; |
| mEffects = new ArrayList<Effect>(); |
| mOverlays = new ArrayList<Overlay>(); |
| mBeginTransition = null; |
| mEndTransition = null; |
| mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext(); |
| mProjectPath = editor.getPath(); |
| mRegenerateClip = false; |
| mGeneratedImageClip = null; |
| } |
| |
| /** |
| * @return The id of the media item |
| */ |
| public String getId() { |
| return mUniqueId; |
| } |
| |
| /** |
| * @return The media source file name |
| */ |
| public String getFilename() { |
| return mFilename; |
| } |
| |
| /** |
| * If aspect ratio of the MediaItem is different from the aspect ratio of |
| * the editor then this API controls the rendering mode. |
| * |
| * @param renderingMode rendering mode. It is one of: |
| * {@link #RENDERING_MODE_BLACK_BORDER}, |
| * {@link #RENDERING_MODE_STRETCH} |
| */ |
| public void setRenderingMode(int renderingMode) { |
| switch (renderingMode) { |
| case RENDERING_MODE_BLACK_BORDER: |
| case RENDERING_MODE_STRETCH: |
| case RENDERING_MODE_CROPPING: |
| break; |
| |
| default: |
| throw new IllegalArgumentException("Invalid Rendering Mode"); |
| } |
| |
| mMANativeHelper.setGeneratePreview(true); |
| |
| mRenderingMode = renderingMode; |
| if (mBeginTransition != null) { |
| mBeginTransition.invalidate(); |
| } |
| |
| if (mEndTransition != null) { |
| mEndTransition.invalidate(); |
| } |
| |
| for (Overlay overlay : mOverlays) { |
| ((OverlayFrame)overlay).invalidateGeneratedFiles(); |
| } |
| } |
| |
| /** |
| * @return The rendering mode |
| */ |
| public int getRenderingMode() { |
| return mRenderingMode; |
| } |
| |
| /** |
| * @param transition The beginning transition |
| */ |
| void setBeginTransition(Transition transition) { |
| mBeginTransition = transition; |
| } |
| |
| /** |
| * @return The begin transition |
| */ |
| public Transition getBeginTransition() { |
| return mBeginTransition; |
| } |
| |
| /** |
| * @param transition The end transition |
| */ |
| void setEndTransition(Transition transition) { |
| mEndTransition = transition; |
| } |
| |
| /** |
| * @return The end transition |
| */ |
| public Transition getEndTransition() { |
| return mEndTransition; |
| } |
| |
| /** |
| * @return The timeline duration. This is the actual duration in the |
| * timeline (trimmed duration) |
| */ |
| public abstract long getTimelineDuration(); |
| |
| /** |
| * @return The is the full duration of the media item (not trimmed) |
| */ |
| public abstract long getDuration(); |
| |
| /** |
| * @return The source file type |
| */ |
| public abstract int getFileType(); |
| |
| /** |
| * @return Get the native width of the media item |
| */ |
| public abstract int getWidth(); |
| |
| /** |
| * @return Get the native height of the media item |
| */ |
| public abstract int getHeight(); |
| |
| /** |
| * Get aspect ratio of the source media item. |
| * |
| * @return the aspect ratio as described in MediaProperties. |
| * MediaProperties.ASPECT_RATIO_UNDEFINED if aspect ratio is not |
| * supported as in MediaProperties |
| */ |
| public abstract int getAspectRatio(); |
| |
| /** |
| * Add the specified effect to this media item. |
| * |
| * Note that certain types of effects cannot be applied to video and to |
| * image media items. For example in certain implementation a Ken Burns |
| * implementation cannot be applied to video media item. |
| * |
| * This method invalidates transition video clips if the |
| * effect overlaps with the beginning and/or the end transition. |
| * |
| * @param effect The effect to apply |
| * @throws IllegalStateException if a preview or an export is in progress |
| * @throws IllegalArgumentException if the effect start and/or duration are |
| * invalid or if the effect cannot be applied to this type of media |
| * item or if the effect id is not unique across all the Effects |
| * added. |
| */ |
| public void addEffect(Effect effect) { |
| |
| if (effect == null) { |
| throw new IllegalArgumentException("NULL effect cannot be applied"); |
| } |
| |
| if (effect.getMediaItem() != this) { |
| throw new IllegalArgumentException("Media item mismatch"); |
| } |
| |
| if (mEffects.contains(effect)) { |
| throw new IllegalArgumentException("Effect already exists: " + effect.getId()); |
| } |
| |
| if (effect.getStartTime() + effect.getDuration() > getDuration()) { |
| throw new IllegalArgumentException( |
| "Effect start time + effect duration > media clip duration"); |
| } |
| |
| mMANativeHelper.setGeneratePreview(true); |
| |
| mEffects.add(effect); |
| |
| invalidateTransitions(effect.getStartTime(), effect.getDuration()); |
| |
| if (effect instanceof EffectKenBurns) { |
| mRegenerateClip = true; |
| } |
| } |
| |
| /** |
| * Remove the effect with the specified id. |
| * |
| * This method invalidates a transition video clip if the effect overlaps |
| * with a transition. |
| * |
| * @param effectId The id of the effect to be removed |
| * |
| * @return The effect that was removed |
| * @throws IllegalStateException if a preview or an export is in progress |
| */ |
| public Effect removeEffect(String effectId) { |
| for (Effect effect : mEffects) { |
| if (effect.getId().equals(effectId)) { |
| mMANativeHelper.setGeneratePreview(true); |
| |
| mEffects.remove(effect); |
| |
| invalidateTransitions(effect.getStartTime(), effect.getDuration()); |
| if (effect instanceof EffectKenBurns) { |
| if (mGeneratedImageClip != null) { |
| /** |
| * Delete the file |
| */ |
| new File(mGeneratedImageClip).delete(); |
| /** |
| * Invalidate the filename |
| */ |
| mGeneratedImageClip = null; |
| } |
| mRegenerateClip = false; |
| } |
| return effect; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Set the filepath of the generated image clip when the effect is added. |
| * |
| * @param The filepath of the generated image clip. |
| */ |
| void setGeneratedImageClip(String generatedFilePath) { |
| mGeneratedImageClip = generatedFilePath; |
| } |
| |
| /** |
| * Get the filepath of the generated image clip when the effect is added. |
| * |
| * @return The filepath of the generated image clip (null if it does not |
| * exist) |
| */ |
| String getGeneratedImageClip() { |
| return mGeneratedImageClip; |
| } |
| |
| /** |
| * Find the effect with the specified id |
| * |
| * @param effectId The effect id |
| * @return The effect with the specified id (null if it does not exist) |
| */ |
| public Effect getEffect(String effectId) { |
| for (Effect effect : mEffects) { |
| if (effect.getId().equals(effectId)) { |
| return effect; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Get the list of effects. |
| * |
| * @return the effects list. If no effects exist an empty list will be |
| * returned. |
| */ |
| public List<Effect> getAllEffects() { |
| return mEffects; |
| } |
| |
| /** |
| * Add an overlay to the storyboard. This method invalidates a transition |
| * video clip if the overlay overlaps with a transition. |
| * |
| * @param overlay The overlay to add |
| * @throws IllegalStateException if a preview or an export is in progress or |
| * if the overlay id is not unique across all the overlays added |
| * or if the bitmap is not specified or if the dimensions of the |
| * bitmap do not match the dimensions of the media item |
| * @throws FileNotFoundException, IOException if overlay could not be saved |
| * to project path |
| */ |
| public void addOverlay(Overlay overlay) throws FileNotFoundException, IOException { |
| if (overlay == null) { |
| throw new IllegalArgumentException("NULL Overlay cannot be applied"); |
| } |
| |
| if (overlay.getMediaItem() != this) { |
| throw new IllegalArgumentException("Media item mismatch"); |
| } |
| |
| if (mOverlays.contains(overlay)) { |
| throw new IllegalArgumentException("Overlay already exists: " + overlay.getId()); |
| } |
| |
| if (overlay.getStartTime() + overlay.getDuration() > getDuration()) { |
| throw new IllegalArgumentException( |
| "Overlay start time + overlay duration > media clip duration"); |
| } |
| |
| if (overlay instanceof OverlayFrame) { |
| final OverlayFrame frame = (OverlayFrame)overlay; |
| final Bitmap bitmap = frame.getBitmap(); |
| if (bitmap == null) { |
| throw new IllegalArgumentException("Overlay bitmap not specified"); |
| } |
| |
| final int scaledWidth, scaledHeight; |
| if (this instanceof MediaVideoItem) { |
| scaledWidth = getWidth(); |
| scaledHeight = getHeight(); |
| } else { |
| scaledWidth = ((MediaImageItem)this).getScaledWidth(); |
| scaledHeight = ((MediaImageItem)this).getScaledHeight(); |
| } |
| |
| /** |
| * The dimensions of the overlay bitmap must be the same as the |
| * media item dimensions |
| */ |
| if (bitmap.getWidth() != scaledWidth || bitmap.getHeight() != scaledHeight) { |
| throw new IllegalArgumentException( |
| "Bitmap dimensions must match media item dimensions"); |
| } |
| |
| mMANativeHelper.setGeneratePreview(true); |
| ((OverlayFrame)overlay).save(mProjectPath); |
| |
| mOverlays.add(overlay); |
| invalidateTransitions(overlay.getStartTime(), overlay.getDuration()); |
| |
| } else { |
| throw new IllegalArgumentException("Overlay not supported"); |
| } |
| } |
| |
| /** |
| * @param flag The flag to indicate if regeneration of clip is true or |
| * false. |
| */ |
| void setRegenerateClip(boolean flag) { |
| mRegenerateClip = flag; |
| } |
| |
| /** |
| * @return flag The flag to indicate if regeneration of clip is true or |
| * false. |
| */ |
| boolean getRegenerateClip() { |
| return mRegenerateClip; |
| } |
| |
| /** |
| * Remove the overlay with the specified id. |
| * |
| * This method invalidates a transition video clip if the overlay overlaps |
| * with a transition. |
| * |
| * @param overlayId The id of the overlay to be removed |
| * |
| * @return The overlay that was removed |
| * @throws IllegalStateException if a preview or an export is in progress |
| */ |
| public Overlay removeOverlay(String overlayId) { |
| for (Overlay overlay : mOverlays) { |
| if (overlay.getId().equals(overlayId)) { |
| mMANativeHelper.setGeneratePreview(true); |
| |
| mOverlays.remove(overlay); |
| if (overlay instanceof OverlayFrame) { |
| ((OverlayFrame)overlay).invalidate(); |
| } |
| invalidateTransitions(overlay.getStartTime(), overlay.getDuration()); |
| return overlay; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Find the overlay with the specified id |
| * |
| * @param overlayId The overlay id |
| * |
| * @return The overlay with the specified id (null if it does not exist) |
| */ |
| public Overlay getOverlay(String overlayId) { |
| for (Overlay overlay : mOverlays) { |
| if (overlay.getId().equals(overlayId)) { |
| return overlay; |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Get the list of overlays associated with this media item |
| * |
| * Note that if any overlay source files are not accessible anymore, |
| * this method will still provide the full list of overlays. |
| * |
| * @return The list of overlays. If no overlays exist an empty list will |
| * be returned. |
| */ |
| public List<Overlay> getAllOverlays() { |
| return mOverlays; |
| } |
| |
| /** |
| * Create a thumbnail at specified time in a video stream in Bitmap format |
| * |
| * @param width width of the thumbnail in pixels |
| * @param height height of the thumbnail in pixels |
| * @param timeMs The time in the source video file at which the thumbnail is |
| * requested (even if trimmed). |
| * |
| * @return The thumbnail as a Bitmap. |
| * |
| * @throws IOException if a file error occurs |
| * @throws IllegalArgumentException if time is out of video duration |
| */ |
| public abstract Bitmap getThumbnail(int width, int height, long timeMs) |
| throws IOException; |
| |
| /** |
| * Get the array of Bitmap thumbnails between start and end. |
| * |
| * @param width width of the thumbnail in pixels |
| * @param height height of the thumbnail in pixels |
| * @param startMs The start of time range in milliseconds |
| * @param endMs The end of the time range in milliseconds |
| * @param thumbnailCount The thumbnail count |
| * @param indices The indices of the thumbnails wanted |
| * @param callback The callback used to pass back the bitmaps |
| * |
| * @throws IOException if a file error occurs |
| */ |
| public abstract void getThumbnailList(int width, int height, |
| long startMs, long endMs, |
| int thumbnailCount, |
| int[] indices, |
| GetThumbnailListCallback callback) |
| throws IOException; |
| |
| public interface GetThumbnailListCallback { |
| public void onThumbnail(Bitmap bitmap, int index); |
| } |
| |
| // This is for compatibility, only used in tests. |
| public Bitmap[] getThumbnailList(int width, int height, |
| long startMs, long endMs, |
| int thumbnailCount) |
| throws IOException { |
| final Bitmap[] bitmaps = new Bitmap[thumbnailCount]; |
| int[] indices = new int[thumbnailCount]; |
| for (int i = 0; i < thumbnailCount; i++) { |
| indices[i] = i; |
| } |
| getThumbnailList(width, height, startMs, endMs, |
| thumbnailCount, indices, new GetThumbnailListCallback() { |
| public void onThumbnail(Bitmap bitmap, int index) { |
| bitmaps[index] = bitmap; |
| } |
| }); |
| |
| return bitmaps; |
| } |
| |
| /* |
| * {@inheritDoc} |
| */ |
| @Override |
| public boolean equals(Object object) { |
| if (!(object instanceof MediaItem)) { |
| return false; |
| } |
| return mUniqueId.equals(((MediaItem)object).mUniqueId); |
| } |
| |
| /* |
| * {@inheritDoc} |
| */ |
| @Override |
| public int hashCode() { |
| return mUniqueId.hashCode(); |
| } |
| |
| /** |
| * Invalidate the start and end transitions if necessary |
| * |
| * @param startTimeMs The start time of the effect or overlay |
| * @param durationMs The duration of the effect or overlay |
| */ |
| abstract void invalidateTransitions(long startTimeMs, long durationMs); |
| |
| /** |
| * Invalidate the start and end transitions if necessary. This method is |
| * typically called when the start time and/or duration of an overlay or |
| * effect is changing. |
| * |
| * @param oldStartTimeMs The old start time of the effect or overlay |
| * @param oldDurationMs The old duration of the effect or overlay |
| * @param newStartTimeMs The new start time of the effect or overlay |
| * @param newDurationMs The new duration of the effect or overlay |
| */ |
| abstract void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, |
| long newStartTimeMs, long newDurationMs); |
| |
| /** |
| * Check if two items overlap in time |
| * |
| * @param startTimeMs1 Item 1 start time |
| * @param durationMs1 Item 1 duration |
| * @param startTimeMs2 Item 2 start time |
| * @param durationMs2 Item 2 end time |
| * @return true if the two items overlap |
| */ |
| protected boolean isOverlapping(long startTimeMs1, long durationMs1, |
| long startTimeMs2, long durationMs2) { |
| if (startTimeMs1 + durationMs1 <= startTimeMs2) { |
| return false; |
| } else if (startTimeMs1 >= startTimeMs2 + durationMs2) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Adjust the duration transitions. |
| */ |
| protected void adjustTransitions() { |
| /** |
| * Check if the duration of transitions need to be adjusted |
| */ |
| if (mBeginTransition != null) { |
| final long maxDurationMs = mBeginTransition.getMaximumDuration(); |
| if (mBeginTransition.getDuration() > maxDurationMs) { |
| mBeginTransition.setDuration(maxDurationMs); |
| } |
| } |
| |
| if (mEndTransition != null) { |
| final long maxDurationMs = mEndTransition.getMaximumDuration(); |
| if (mEndTransition.getDuration() > maxDurationMs) { |
| mEndTransition.setDuration(maxDurationMs); |
| } |
| } |
| } |
| |
| /** |
| * @return MediaArtistNativeHleper context |
| */ |
| MediaArtistNativeHelper getNativeContext() { |
| return mMANativeHelper; |
| } |
| |
| /** |
| * Initialises ClipSettings fields to default value |
| * |
| * @param ClipSettings object |
| *{@link android.media.videoeditor.MediaArtistNativeHelper.ClipSettings} |
| */ |
| void initClipSettings(ClipSettings clipSettings) { |
| clipSettings.clipPath = null; |
| clipSettings.clipDecodedPath = null; |
| clipSettings.clipOriginalPath = null; |
| clipSettings.fileType = 0; |
| clipSettings.endCutTime = 0; |
| clipSettings.beginCutTime = 0; |
| clipSettings.beginCutPercent = 0; |
| clipSettings.endCutPercent = 0; |
| clipSettings.panZoomEnabled = false; |
| clipSettings.panZoomPercentStart = 0; |
| clipSettings.panZoomTopLeftXStart = 0; |
| clipSettings.panZoomTopLeftYStart = 0; |
| clipSettings.panZoomPercentEnd = 0; |
| clipSettings.panZoomTopLeftXEnd = 0; |
| clipSettings.panZoomTopLeftYEnd = 0; |
| clipSettings.mediaRendering = 0; |
| clipSettings.rgbWidth = 0; |
| clipSettings.rgbHeight = 0; |
| } |
| |
| /** |
| * @return ClipSettings object with populated data |
| *{@link android.media.videoeditor.MediaArtistNativeHelper.ClipSettings} |
| */ |
| ClipSettings getClipSettings() { |
| MediaVideoItem mVI = null; |
| MediaImageItem mII = null; |
| ClipSettings clipSettings = new ClipSettings(); |
| initClipSettings(clipSettings); |
| if (this instanceof MediaVideoItem) { |
| mVI = (MediaVideoItem)this; |
| clipSettings.clipPath = mVI.getFilename(); |
| clipSettings.fileType = mMANativeHelper.getMediaItemFileType(mVI. |
| getFileType()); |
| clipSettings.beginCutTime = (int)mVI.getBoundaryBeginTime(); |
| clipSettings.endCutTime = (int)mVI.getBoundaryEndTime(); |
| clipSettings.mediaRendering = mMANativeHelper. |
| getMediaItemRenderingMode(mVI |
| .getRenderingMode()); |
| } else if (this instanceof MediaImageItem) { |
| mII = (MediaImageItem)this; |
| clipSettings = mII.getImageClipProperties(); |
| } |
| return clipSettings; |
| } |
| |
| /** |
| * Generates a black frame to be used for generating |
| * begin transition at first media item in storyboard |
| * or end transition at last media item in storyboard |
| * |
| * @param ClipSettings object |
| *{@link android.media.videoeditor.MediaArtistNativeHelper.ClipSettings} |
| */ |
| void generateBlankFrame(ClipSettings clipSettings) { |
| if (!mBlankFrameGenerated) { |
| int mWidth = 64; |
| int mHeight = 64; |
| mBlankFrameFilename = String.format(mProjectPath + "/" + "ghost.rgb"); |
| FileOutputStream fl = null; |
| try { |
| fl = new FileOutputStream(mBlankFrameFilename); |
| } catch (IOException e) { |
| /* catch IO exception */ |
| } |
| final DataOutputStream dos = new DataOutputStream(fl); |
| |
| final int [] framingBuffer = new int[mWidth]; |
| |
| ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4); |
| IntBuffer intBuffer; |
| |
| byte[] array = byteBuffer.array(); |
| int tmp = 0; |
| while(tmp < mHeight) { |
| intBuffer = byteBuffer.asIntBuffer(); |
| intBuffer.put(framingBuffer,0,mWidth); |
| try { |
| dos.write(array); |
| } catch (IOException e) { |
| /* catch file write error */ |
| } |
| tmp += 1; |
| } |
| |
| try { |
| fl.close(); |
| } catch (IOException e) { |
| /* file close error */ |
| } |
| mBlankFrameGenerated = true; |
| } |
| |
| clipSettings.clipPath = mBlankFrameFilename; |
| clipSettings.fileType = FileType.JPG; |
| clipSettings.beginCutTime = 0; |
| clipSettings.endCutTime = 0; |
| clipSettings.mediaRendering = MediaRendering.RESIZING; |
| |
| clipSettings.rgbWidth = 64; |
| clipSettings.rgbHeight = 64; |
| } |
| |
| /** |
| * Invalidates the blank frame generated |
| */ |
| void invalidateBlankFrame() { |
| if (mBlankFrameFilename != null) { |
| if (new File(mBlankFrameFilename).exists()) { |
| new File(mBlankFrameFilename).delete(); |
| mBlankFrameFilename = null; |
| } |
| } |
| } |
| |
| } |