mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge pull request #5721 from dannysmyda/6069-gstreamer-crash-with-review-fixes
6069 gstreamer crash with review fixes
This commit is contained in:
commit
496939e684
@ -45,7 +45,6 @@ file.reference.jericho-html-3.3.jar=release/modules/ext/jericho-html-3.3.jar
|
||||
file.reference.jgraphx-v3.8.0.jar=release/modules/ext/jgraphx-v3.8.0.jar
|
||||
file.reference.jhighlight-1.0.3.jar=release\\modules\\ext\\jhighlight-1.0.3.jar
|
||||
file.reference.jmatio-1.5.jar=release\\modules\\ext\\jmatio-1.5.jar
|
||||
file.reference.jna-5.1.0.jar=release\\modules\\ext\\jna-5.1.0.jar
|
||||
file.reference.json-simple-1.1.1.jar=release\\modules\\ext\\json-simple-1.1.1.jar
|
||||
file.reference.jsoup-1.11.3.jar=release\\modules\\ext\\jsoup-1.11.3.jar
|
||||
file.reference.jul-to-slf4j-1.7.25.jar=release\\modules\\ext\\jul-to-slf4j-1.7.25.jar
|
||||
@ -97,7 +96,6 @@ file.reference.xz-1.8.jar=release\\modules\\ext\\xz-1.8.jar
|
||||
file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar
|
||||
file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar
|
||||
file.reference.commons-validator-1.6.jar=release/modules/ext/commons-validator-1.6.jar
|
||||
file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar
|
||||
file.reference.api-common-1.7.0.jar=release/modules/ext/api-common-1.7.0.jar
|
||||
file.reference.gax-1.44.0.jar=release/modules/ext/gax-1.44.0.jar
|
||||
file.reference.gax-grpc-1.44.0.jar=release/modules/ext/gax-grpc-1.44.0.jar
|
||||
|
@ -615,10 +615,6 @@
|
||||
<runtime-relative-path>ext/commons-validator-1.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-validator-1.6.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jna-5.1.0.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jna-5.1.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jbig2-imageio-3.0.2.jar</runtime-relative-path>
|
||||
<binary-origin>release\modules\ext\jbig2-imageio-3.0.2.jar</binary-origin>
|
||||
|
@ -41,6 +41,7 @@ MediaFileViewer.AccessibleContext.accessibleDescription=
|
||||
MediaFileViewer.title=Media
|
||||
MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, audio)
|
||||
MediaPlayerPanel.noSupport=File not supported.
|
||||
MediaPlayerPanel.playbackDisabled=A problem was encountered with the video and audio playback service. Video and audio playback will be disabled for the remainder of the session.
|
||||
MediaPlayerPanel.timeFormat=%02d:%02d:%02d
|
||||
MediaPlayerPanel.unknownTime=Unknown
|
||||
MediaViewImagePanel.createTagOption=Create
|
||||
@ -168,7 +169,7 @@ MediaPlayerPanel.playBackSpeedLabel.text=Speed:
|
||||
SQLiteViewer.readTable.errorText=Error getting rows for table: {0}
|
||||
# {0} - tableName
|
||||
SQLiteViewer.selectTable.errorText=Error getting row count for table: {0}
|
||||
TextTranslatableComponent.setPanelContent.onSetContentError=Unable to display text at this time.
|
||||
TextTranslatableComponent.setTranslated.onTranslateError=Unable to translate text at this time.
|
||||
TranslatablePanel.comboBoxOption.originalText=Original Text
|
||||
TranslatablePanel.comboBoxOption.translatedText=Translated Text
|
||||
# {0} - exception message
|
||||
TranslatablePanel.onSetContentError.text=There was an error displaying the text: {0}
|
||||
|
@ -194,6 +194,6 @@ class MediaFileViewer extends javax.swing.JPanel implements FileTypeViewer {
|
||||
|
||||
@Override
|
||||
public boolean isSupported(AbstractFile file){
|
||||
return true;
|
||||
return mediaPlayerPanel.isSupported(file) || imagePanel.isSupported(file);
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="progressLabel" max="32767" attributes="0"/>
|
||||
<Component id="playBackPanel" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="playBackPanel" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -129,12 +129,6 @@
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="MediaPlayerPanel.playButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[53, 29]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[53, 29]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[49, 29]"/>
|
||||
</Property>
|
||||
|
@ -74,7 +74,9 @@ import org.freedesktop.gstreamer.Format;
|
||||
import org.freedesktop.gstreamer.GstException;
|
||||
import org.freedesktop.gstreamer.event.SeekFlags;
|
||||
import org.freedesktop.gstreamer.event.SeekType;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.contentviewers.utils.GstLoader;
|
||||
import org.sleuthkit.autopsy.contentviewers.utils.GstLoader.GstStatus;
|
||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||
|
||||
/**
|
||||
* This is a video player that is part of the Media View layered pane. It uses
|
||||
@ -213,6 +215,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
||||
//and the TrackListener on the slider itself.
|
||||
private final Semaphore sliderLock;
|
||||
|
||||
private static volatile boolean IS_GST_ENABLED = true;
|
||||
|
||||
/**
|
||||
* Creates a new MediaPlayerPanel
|
||||
*/
|
||||
@ -222,18 +226,10 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
||||
//True for fairness. In other words,
|
||||
//acquire() calls are processed in order of invocation.
|
||||
sliderLock = new Semaphore(1, true);
|
||||
|
||||
/**
|
||||
* See JIRA-5888 for details. Initializing gstreamer here is more stable
|
||||
* on Windows.
|
||||
*/
|
||||
if (PlatformUtil.isWindowsOS()) {
|
||||
Gst.init();
|
||||
}
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
progressSlider.setEnabled(false); // disable slider; enable after user plays vid
|
||||
enableComponents(false);
|
||||
progressSlider.setMinimum(0);
|
||||
progressSlider.setMaximum(PROGRESS_SLIDER_SIZE);
|
||||
progressSlider.setValue(0);
|
||||
@ -390,13 +386,16 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
||||
}
|
||||
timer.stop();
|
||||
if (gstPlayBin != null) {
|
||||
gstPlayBin.stop();
|
||||
gstPlayBin.getBus().disconnect(endOfStreamListener);
|
||||
gstPlayBin.getBus().disconnect(stateChangeListener);
|
||||
gstPlayBin.getBus().disconnect(errorListener);
|
||||
gstPlayBin.dispose();
|
||||
fxAppSink.clear();
|
||||
gstPlayBin = null;
|
||||
Gst.getExecutor().submit(() -> {
|
||||
gstPlayBin.stop();
|
||||
gstPlayBin.getBus().disconnect(endOfStreamListener);
|
||||
gstPlayBin.getBus().disconnect(stateChangeListener);
|
||||
gstPlayBin.getBus().disconnect(errorListener);
|
||||
gstPlayBin.getBus().dispose();
|
||||
gstPlayBin.dispose();
|
||||
fxAppSink.clear();
|
||||
gstPlayBin = null;
|
||||
});
|
||||
}
|
||||
videoPanel.removeAll();
|
||||
resetComponents();
|
||||
@ -425,6 +424,10 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
||||
|
||||
@Override
|
||||
public boolean isSupported(AbstractFile file) {
|
||||
if (!IS_GST_ENABLED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String extension = file.getNameExtension();
|
||||
/**
|
||||
* Although it seems too restrictive, requiring both a supported
|
||||
@ -542,6 +545,11 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
||||
/*
|
||||
* Initialize the playback components if the extraction was successful.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"MediaPlayerPanel.playbackDisabled=A problem was encountered with"
|
||||
+ " the video and audio playback service. Video and audio "
|
||||
+ "playback will be disabled for the remainder of the session."
|
||||
})
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
@ -551,44 +559,49 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize Gstreamer. It is safe to call this for every file.
|
||||
// It was moved here from the constructor because having it happen
|
||||
// earlier resulted in conflicts on Linux. See JIRA-5888.
|
||||
if (!PlatformUtil.isWindowsOS()) {
|
||||
Gst.init();
|
||||
GstStatus loadStatus = GstLoader.tryLoad();
|
||||
if (loadStatus == GstStatus.FAILURE) {
|
||||
MessageNotifyUtil.Message.error(Bundle.MediaPlayerPanel_playbackDisabled());
|
||||
|
||||
// This will disable the panel for future use.
|
||||
IS_GST_ENABLED = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//Video is ready for playback. Create new components
|
||||
gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI());
|
||||
//Configure event handling
|
||||
if (gstPlayBin != null) {
|
||||
Gst.getExecutor().submit(() -> {
|
||||
//Video is ready for playback. Create new components
|
||||
gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI());
|
||||
//Configure event handling
|
||||
Bus playBinBus = gstPlayBin.getBus();
|
||||
playBinBus.connect(endOfStreamListener);
|
||||
playBinBus.connect(stateChangeListener);
|
||||
playBinBus.connect(errorListener);
|
||||
}
|
||||
|
||||
if (this.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
if (this.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
JFXPanel fxPanel = new JFXPanel();
|
||||
videoPanel.removeAll();
|
||||
videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS));
|
||||
videoPanel.add(fxPanel);
|
||||
fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel);
|
||||
if (gstPlayBin != null) {
|
||||
gstPlayBin.setVideoSink(fxAppSink);
|
||||
}
|
||||
if (this.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
if (gstPlayBin != null) {
|
||||
gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0);
|
||||
gstPlayBin.pause();
|
||||
}
|
||||
timer.start();
|
||||
enableComponents(true);
|
||||
JFXPanel fxPanel = new JFXPanel();
|
||||
videoPanel.removeAll();
|
||||
videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS));
|
||||
videoPanel.add(fxPanel);
|
||||
fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel);
|
||||
if (gstPlayBin != null) {
|
||||
gstPlayBin.setVideoSink(fxAppSink);
|
||||
}
|
||||
if (this.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
if (gstPlayBin != null) {
|
||||
gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0);
|
||||
gstPlayBin.pause();
|
||||
}
|
||||
|
||||
timer.start();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
enableComponents(true);
|
||||
});
|
||||
});
|
||||
} catch (CancellationException ex) {
|
||||
logger.log(Level.INFO, "Media buffering was canceled."); //NON-NLS
|
||||
} catch (InterruptedException ex) {
|
||||
@ -607,23 +620,29 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (!progressSlider.getValueIsAdjusting() && gstPlayBin != null) {
|
||||
sliderLock.acquireUninterruptibly();
|
||||
long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||
long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS);
|
||||
/**
|
||||
* Duration may not be known until there is video data in the
|
||||
* pipeline. We start this updater when data-flow has just been
|
||||
* initiated so buffering may still be in progress.
|
||||
*/
|
||||
if (duration >= 0 && position >= 0) {
|
||||
double relativePosition = (double) position / duration;
|
||||
progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE));
|
||||
}
|
||||
Gst.getExecutor().submit(() -> {
|
||||
try {
|
||||
sliderLock.acquireUninterruptibly();
|
||||
long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||
long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS);
|
||||
/**
|
||||
* Duration may not be known until there is video data
|
||||
* in the pipeline. We start this updater when data-flow
|
||||
* has just been initiated so buffering may still be in
|
||||
* progress.
|
||||
*/
|
||||
if (duration >= 0 && position >= 0) {
|
||||
double relativePosition = (double) position / duration;
|
||||
progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE));
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
updateTimeLabel(position, duration);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
updateTimeLabel(position, duration);
|
||||
});
|
||||
} finally {
|
||||
sliderLock.release();
|
||||
}
|
||||
});
|
||||
sliderLock.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -643,7 +662,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
||||
* thumb at the given width and height. It also paints the track blue as
|
||||
* the thumb progresses.
|
||||
*
|
||||
* @param slider JSlider component
|
||||
* @param slider JSlider component
|
||||
* @param thumbDimension
|
||||
*/
|
||||
public CircularJSliderUI(JSlider slider, Dimension thumbDimension) {
|
||||
@ -991,96 +1010,104 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed
|
||||
if (gstPlayBin != null) {
|
||||
long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||
//Skip 30 seconds.
|
||||
long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS);
|
||||
//Ensure new video position is within bounds
|
||||
long newTime = Math.max(currentTime - rewindDelta, 0);
|
||||
double playBackRate = getPlayBackRate();
|
||||
gstPlayBin.seek(playBackRate,
|
||||
Format.TIME,
|
||||
//FLUSH - flushes the pipeline
|
||||
//ACCURATE - video will seek exactly to the position requested
|
||||
EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE),
|
||||
//Set the start position to newTime
|
||||
SeekType.SET, newTime,
|
||||
//Do nothing for the end position
|
||||
SeekType.NONE, -1);
|
||||
}
|
||||
}//GEN-LAST:event_rewindButtonActionPerformed
|
||||
|
||||
private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed
|
||||
if (gstPlayBin != null) {
|
||||
long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS);
|
||||
long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||
//Skip 30 seconds.
|
||||
long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS);
|
||||
//Don't allow skipping within 2 seconds of video ending. Skipping right to
|
||||
//the end causes undefined behavior for some gstreamer plugins.
|
||||
long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS);
|
||||
if ((duration - currentTime) <= twoSecondsInNano) {
|
||||
return;
|
||||
}
|
||||
|
||||
long newTime;
|
||||
if (currentTime + fastForwardDelta >= duration) {
|
||||
//If there are less than 30 seconds left, only fast forward to the midpoint.
|
||||
newTime = currentTime + (duration - currentTime) / 2;
|
||||
} else {
|
||||
newTime = currentTime + fastForwardDelta;
|
||||
}
|
||||
|
||||
double playBackRate = getPlayBackRate();
|
||||
gstPlayBin.seek(playBackRate,
|
||||
Format.TIME,
|
||||
//FLUSH - flushes the pipeline
|
||||
//ACCURATE - video will seek exactly to the position requested
|
||||
EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE),
|
||||
//Set the start position to newTime
|
||||
SeekType.SET, newTime,
|
||||
//Do nothing for the end position
|
||||
SeekType.NONE, -1);
|
||||
}
|
||||
}//GEN-LAST:event_fastForwardButtonActionPerformed
|
||||
|
||||
private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed
|
||||
if (gstPlayBin != null) {
|
||||
if (gstPlayBin.isPlaying()) {
|
||||
gstPlayBin.pause();
|
||||
} else {
|
||||
double playBackRate = getPlayBackRate();
|
||||
Gst.getExecutor().submit(() -> {
|
||||
if (gstPlayBin != null) {
|
||||
long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||
//Set playback rate before play.
|
||||
//Skip 30 seconds.
|
||||
long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS);
|
||||
//Ensure new video position is within bounds
|
||||
long newTime = Math.max(currentTime - rewindDelta, 0);
|
||||
double playBackRate = getPlayBackRate();
|
||||
gstPlayBin.seek(playBackRate,
|
||||
Format.TIME,
|
||||
//FLUSH - flushes the pipeline
|
||||
//ACCURATE - video will seek exactly to the position requested
|
||||
EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE),
|
||||
//Set the start position to newTime
|
||||
SeekType.SET, currentTime,
|
||||
SeekType.SET, newTime,
|
||||
//Do nothing for the end position
|
||||
SeekType.NONE, -1);
|
||||
gstPlayBin.play();
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_playButtonActionPerformed
|
||||
});
|
||||
}//GEN-LAST:event_rewindButtonActionPerformed
|
||||
|
||||
private void playBackSpeedComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playBackSpeedComboBoxActionPerformed
|
||||
if (gstPlayBin != null) {
|
||||
double playBackRate = getPlayBackRate();
|
||||
long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||
gstPlayBin.seek(playBackRate,
|
||||
Format.TIME,
|
||||
//FLUSH - flushes the pipeline
|
||||
//ACCURATE - video will seek exactly to the position requested
|
||||
EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE),
|
||||
//Set the position to the currentTime, we are only adjusting the
|
||||
//playback rate.
|
||||
SeekType.SET, currentTime,
|
||||
SeekType.NONE, 0);
|
||||
}
|
||||
}//GEN-LAST:event_playBackSpeedComboBoxActionPerformed
|
||||
private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
Gst.getExecutor().submit(() -> {
|
||||
if (gstPlayBin != null) {
|
||||
long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS);
|
||||
long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||
//Skip 30 seconds.
|
||||
long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS);
|
||||
//Don't allow skipping within 2 seconds of video ending. Skipping right to
|
||||
//the end causes undefined behavior for some gstreamer plugins.
|
||||
long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS);
|
||||
if ((duration - currentTime) <= twoSecondsInNano) {
|
||||
return;
|
||||
}
|
||||
|
||||
long newTime;
|
||||
if (currentTime + fastForwardDelta >= duration) {
|
||||
//If there are less than 30 seconds left, only fast forward to the midpoint.
|
||||
newTime = currentTime + (duration - currentTime) / 2;
|
||||
} else {
|
||||
newTime = currentTime + fastForwardDelta;
|
||||
}
|
||||
|
||||
double playBackRate = getPlayBackRate();
|
||||
gstPlayBin.seek(playBackRate,
|
||||
Format.TIME,
|
||||
//FLUSH - flushes the pipeline
|
||||
//ACCURATE - video will seek exactly to the position requested
|
||||
EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE),
|
||||
//Set the start position to newTime
|
||||
SeekType.SET, newTime,
|
||||
//Do nothing for the end position
|
||||
SeekType.NONE, -1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
Gst.getExecutor().submit(() -> {
|
||||
if (gstPlayBin != null) {
|
||||
if (gstPlayBin.isPlaying()) {
|
||||
gstPlayBin.pause();
|
||||
} else {
|
||||
double playBackRate = getPlayBackRate();
|
||||
long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||
//Set playback rate before play.
|
||||
gstPlayBin.seek(playBackRate,
|
||||
Format.TIME,
|
||||
//FLUSH - flushes the pipeline
|
||||
//ACCURATE - video will seek exactly to the position requested
|
||||
EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE),
|
||||
//Set the start position to newTime
|
||||
SeekType.SET, currentTime,
|
||||
//Do nothing for the end position
|
||||
SeekType.NONE, -1);
|
||||
gstPlayBin.play();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void playBackSpeedComboBoxActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
Gst.getExecutor().submit(() -> {
|
||||
if (gstPlayBin != null) {
|
||||
double playBackRate = getPlayBackRate();
|
||||
long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||
gstPlayBin.seek(playBackRate,
|
||||
Format.TIME,
|
||||
//FLUSH - flushes the pipeline
|
||||
//ACCURATE - video will seek exactly to the position requested
|
||||
EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE),
|
||||
//Set the position to the currentTime, we are only adjusting the
|
||||
//playback rate.
|
||||
SeekType.SET, currentTime,
|
||||
SeekType.NONE, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JLabel VolumeIcon;
|
||||
|
74
Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java
Executable file
74
Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java
Executable file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* 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 org.sleuthkit.autopsy.contentviewers.utils;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import org.freedesktop.gstreamer.Gst;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* A utility class that loads the gstreamer bindings.
|
||||
*/
|
||||
public final class GstLoader {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(GstLoader.class.getName());
|
||||
private static GstStatus status;
|
||||
|
||||
/**
|
||||
* Attempts to load the gstreamer bindings. Only one attempt will be
|
||||
* performed per Autopsy process. Clients should not attempt to interact
|
||||
* with the gstreamer bindings unless the load was successful.
|
||||
*
|
||||
* @return Status - SUCCESS or FAILURE
|
||||
*/
|
||||
public synchronized static GstStatus tryLoad() {
|
||||
// Null is our 'unknown' status. Prior to the first call, the status
|
||||
// is unknown.
|
||||
if (status != null) {
|
||||
return status;
|
||||
}
|
||||
|
||||
try {
|
||||
// Setting the following property causes the GST
|
||||
// Java bindings to call dispose() on the GST
|
||||
// service thread instead of running it in the GST
|
||||
// Native Object Reaper thread.
|
||||
System.setProperty("glib.reapOnEDT", "true");
|
||||
Gst.init();
|
||||
status = GstStatus.SUCCESS;
|
||||
} catch (Throwable ex) {
|
||||
status = GstStatus.FAILURE;
|
||||
logger.log(Level.WARNING, "Failed to load gsteamer bindings", ex);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* The various init statuses that tryLoad can return.
|
||||
*/
|
||||
public enum GstStatus {
|
||||
SUCCESS, FAILURE
|
||||
}
|
||||
|
||||
private GstLoader() {
|
||||
|
||||
}
|
||||
}
|
@ -14,8 +14,7 @@
|
||||
|
||||
<!-- for viewers -->
|
||||
<dependency conf="autopsy_core->*" org="org.freedesktop.gstreamer" name="gst1-java-core" rev="1.0.0"/>
|
||||
<dependency conf="autopsy_core->*" org="net.java.dev.jna" name="jna" rev="3.4.0"/>
|
||||
<dependency conf="autopsy_core->*" org="net.java.dev.jna" name="platform" rev="3.4.0"/>
|
||||
<dependency conf="autopsy_core->*" org="net.java.dev.jna" name="jna-platform" rev="5.5.0"/>
|
||||
|
||||
<!-- for file search -->
|
||||
<dependency conf="autopsy_core->*" org="com.github.lgooddatepicker" name="LGoodDatePicker" rev="10.3.1"/>
|
||||
@ -73,8 +72,5 @@
|
||||
<dependency conf="autopsy_core->default" org="com.googlecode.plist" name="dd-plist" rev="1.20"/>
|
||||
|
||||
<exclude org="*" ext="*" type="javadoc"/>
|
||||
<!-- conflict resolutions for multiple JAR versions -->
|
||||
<conflict org="net.java.dev.jna" module="jna" rev="3.4.0"/>
|
||||
<conflict org="net.java.dev.jna" module="platform" rev="3.4.0"/>
|
||||
</dependencies>
|
||||
</ivy-module>
|
||||
|
@ -21,7 +21,6 @@ file.reference.dom4j-1.6.1.jar=release/modules/ext/dom4j-1.6.1.jar
|
||||
file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.1_spec-1.0.jar
|
||||
file.reference.gson-2.8.5.jar=release/modules/ext/gson-2.8.5.jar
|
||||
file.reference.gst1-java-core-1.0.0.jar=release\\modules\\ext\\gst1-java-core-1.0.0.jar
|
||||
file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar
|
||||
file.reference.guava-19.0.jar=release/modules/ext/guava-19.0.jar
|
||||
file.reference.imageio-bmp-3.2.jar=release/modules/ext/imageio-bmp-3.2.jar
|
||||
file.reference.imageio-core-3.2.jar=release/modules/ext/imageio-core-3.2.jar
|
||||
@ -44,6 +43,8 @@ file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-
|
||||
file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar
|
||||
file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar
|
||||
file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar
|
||||
file.reference.jna-5.5.0.jar=release\\modules\\ext\\jna-5.5.0.jar
|
||||
file.reference.jna-platform-5.5.0.jar=release\\modules\\ext\\jna-platform-5.5.0.jar
|
||||
file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar
|
||||
file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar
|
||||
file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar
|
||||
@ -52,7 +53,6 @@ file.reference.logkit-1.0.1.jar=release/modules/ext/logkit-1.0.1.jar
|
||||
file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar
|
||||
file.reference.opencv-248.jar=release/modules/ext/opencv-248.jar
|
||||
file.reference.openjfx-dialogs-1.0.2.jar=release/modules/ext/openjfx-dialogs-1.0.3.jar
|
||||
file.reference.platform-3.4.0.jar=release/modules/ext/platform-3.4.0.jar
|
||||
file.reference.poi-4.0.1.jar=release\\modules\\ext\\poi-4.0.1.jar
|
||||
file.reference.poi-excelant-4.0.1.jar=release\\modules\\ext\\poi-excelant-4.0.1.jar
|
||||
file.reference.poi-ooxml-4.0.1.jar=release\\modules\\ext\\poi-ooxml-4.0.1.jar
|
||||
|
@ -806,10 +806,6 @@
|
||||
<runtime-relative-path>ext/sigar-1.6.4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/sigar-1.6.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jna-3.4.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jna-3.4.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/gson-2.8.5.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/gson-2.8.5.jar</binary-origin>
|
||||
@ -902,6 +898,10 @@
|
||||
<runtime-relative-path>ext/commons-csv-1.4.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-csv-1.4.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jna-5.5.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jna-5.5.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/imageio-sgi-3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/imageio-sgi-3.2.jar</binary-origin>
|
||||
@ -946,10 +946,6 @@
|
||||
<runtime-relative-path>ext/imageio-bmp-3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/imageio-bmp-3.2.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/platform-3.4.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/platform-3.4.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/commons-lang-2.6.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/commons-lang-2.6.jar</binary-origin>
|
||||
@ -1018,6 +1014,10 @@
|
||||
<runtime-relative-path>ext/dom4j-1.6.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/dom4j-1.6.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/jna-platform-5.5.0.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/jna-platform-5.5.0.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/imageio-metadata-3.2.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/imageio-metadata-3.2.jar</binary-origin>
|
||||
|
Loading…
x
Reference in New Issue
Block a user