«EXCEPTION_ACCESS_VIOLATION» выбрасывается при чтении видео из файла с помощью xuggler - PullRequest
1 голос
/ 30 мая 2019

Я пишу код Java, чтобы взять видеофайл в формате mp4, применить к нему эффект, а затем сохранить его в новом файле.Код должен разбить данное видео на его кадры и сохранить их в массиве, чтобы каждый из них мог использовать их для создания эффекта.Эта часть кода обрабатывается xuggler, поэтому мне трудно определить, что происходит не так.

Проблема в том, что даже перед чтением одного изображения видео выдается ошибка, и я понятия не имею, чтоон имеет в виду, и обширный поиск в Google говорит мне, что это как-то связано с ошибкой доступа к памяти.

Еще более странная часть заключается в том, что это происходит только для некоторых файлов mp4, даже если они все в формате mp4 и должны все вести себятаким же образом.

Я пробовал много разных файлов mp4 из разных источников, и некоторые из них работают, некоторые нет, на первый взгляд, наугад.Mp4, к которому меня больше всего интересует применение эффекта, - это один из тех, которые не работают.

В следующем коде я определил с помощью операторов print в различных точках, что часть кодаошибка возникает где-то внутри IMediaListener с именем переменной media.Сам слушатель вызывается линией while(reader.readPacket()==null); внутри ActionListener, в частности, в разделе, вызванном нажатием кнопки «sub».Это единственное место, где он называется.

Я должен отметить, что весь код, связанный с xuggler, не мой, как я нашел его в демонстрациях кода в Интернете.Я не буду притворяться, что понимаю, как работает xuggler.

import java.util.*;
import java.util.concurrent.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.*;
import java.awt.image.*;
import com.xuggle.xuggler.*;
import com.xuggle.mediatool.*;
import com.xuggle.mediatool.event.*;
import java.awt.event.*;
public class mainClass {
    static JFrame win=new JFrame();
    static JPanel dis=new JPanel();
    static JButton sub=new JButton("Submit"),b1=new JButton("Browse"),b2=new JButton("Browse");
    static JTextField input=new JTextField(),output=new JTextField();
    static String savePath="",sourcePath="";
    static JLabel l1=new JLabel("Input:"),l2=new JLabel("Output:");
    static BufferedImage[] images=new BufferedImage[0];
    static Set<Long> timestamps=new HashSet<Long>();
    static int ind=0;
    public static void main(String[]args) {
        win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        win.setResizable(false);
        win.setVisible(true);
        win.add(dis);
        win.setLocation(100,300);
        dis.setPreferredSize(new Dimension(850,80));
        dis.setLayout(null);
        win.pack();
        dis.add(input).setBounds(100,0,550,40);
        dis.add(output).setBounds(100,40,550,40);
        dis.add(sub).setBounds(750,0,100,80);
        dis.add(b1).setBounds(650,0,100,40);
        dis.add(b2).setBounds(650,40,100,40);
        dis.add(l1).setBounds(0,0,100,40);
        dis.add(l2).setBounds(0,40,100,40);
        input.setFocusable(false);
        input.setFont(new Font(Font.SANS_SERIF,Font.PLAIN,22));
        output.setFocusable(false);
        output.setFont(input.getFont());
        sub.setFocusable(false);
        sub.addActionListener(action);
        b1.setFocusable(false);
        b1.addActionListener(action);
        b2.setFocusable(false);
        b2.addActionListener(action);
        l1.setFont(input.getFont());
        l1.setHorizontalAlignment(SwingConstants.CENTER);
        l2.setFont(input.getFont());
        l2.setHorizontalAlignment(SwingConstants.CENTER);
    }
    static IMediaListener media=new MediaListenerAdapter() {
        public void onVideoPicture(IVideoPictureEvent e) {
            timestamps.add(e.getTimeStamp(TimeUnit.MICROSECONDS));
            BufferedImage image=e.getImage();
            BufferedImage[] copy=images;
            images=new BufferedImage[copy.length+1];
            for(int i=0;i<copy.length;i++) {
                images[i]=copy[i];
            }
            images[images.length-1]=image;
        }
    };
    static ActionListener action=new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if(e.getSource()==sub) {
                if(input.getText().length()>0&output.getText().length()>0) {
                    IMediaReader reader=ToolFactory.makeReader(input.getText());
                    reader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
                    reader.addListener(media);
                    while(reader.readPacket()==null);
                    BufferedImage[] pics=images;
                    Long[] times=new Long[timestamps.size()];
                    times=timestamps.toArray(times);
                    for(int i=0;i<pics.length;i++) {
                        int min=i;
                        for(int j=i;j<pics.length;j++) {
                            if(times[j]<times[min]) {
                                min=j;
                            }
                        }
                        Long f1=times[i];
                        times[i]=times[min];
                        times[min]=f1;
                    }
                    timestamps=new HashSet<Long>();
                    long frameSep=(long)(times[times.length-1]/times.length);
                    IMediaWriter writer=ToolFactory.makeWriter(output.getText()+"\\video1.mp4");
                    writer.addVideoStream(0,0,ICodec.ID.CODEC_ID_MPEG4,pics[0].getWidth(),pics[0].getHeight());
                    for(int i=0;i<pics.length+pics[0].getHeight()-1;i++) {
                        BufferedImage image=pics[0];
                        for(int j=0;j<i;j++) {
                            int ind=i-j,ind2=image.getHeight()-j-1;
                            if(ind>=pics.length) {
                                ind=pics.length-1;
                            }
                            if(ind2<0) {
                                ind2=0;
                            }
                            int[] rgbArray=new int[image.getWidth()];
                            pics[ind].getRGB(0, ind2, image.getWidth(), 1, rgbArray, 0, image.getWidth());
                            image.setRGB(0, ind2, image.getWidth(), 1, rgbArray, 0, image.getWidth());
                        }
                        writer.encodeVideo(0, image, frameSep*i, TimeUnit.MICROSECONDS);
                        if(i%((pics.length+pics[0].getHeight()-1)/100)==0) {
                            System.out.println(Double.toString(i/(pics.length+pics[0].getHeight()-1)*100)+" %");
                        }
                    }
                    System.out.println("finished");
                    writer.close();
                }
            }
            if(e.getSource()==b1) {
                JFileChooser fc=new JFileChooser();
                fc.setMultiSelectionEnabled(false);
                fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
                fc.setFileFilter(new FileNameExtensionFilter("mp4 file","mp4"));
                fc.setAcceptAllFileFilterUsed(false);
                if(fc.showOpenDialog(sub)==JFileChooser.APPROVE_OPTION)input.setText(fc.getSelectedFile().getAbsolutePath());
            }
            if(e.getSource()==b2) {
                JFileChooser fc=new JFileChooser();
                fc.setMultiSelectionEnabled(false);
                fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                if(fc.showOpenDialog(sub)==JFileChooser.APPROVE_OPTION)output.setText(fc.getSelectedFile().getAbsolutePath());
            }
        }
    };
}

Для данного mp4, который работает, код завершит применение эффекта, а затем напечатает «Finish», так что я знаю, чтобы пойти и проверить выводпапка, которая может быть указана в графическом интерфейсе, который первоначально появляется.

Для данного mp4, который не работает, в консоль выводится следующее сообщение об ошибке, в точности так:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000006ee76520, pid=2176, tid=0x00000000000000c0
#
# JRE version: Java(TM) SE Runtime Environment (8.0_211-b12) (build 1.8.0_211-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.211-b12 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [xuggle1222138188201648765.dll+0x736520]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\John\eclipse-workspace\Video effects\hs_err_pid2176.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

файл журнала, на который он ссылается, содержит массу сложной информации, которую я не могу понять, говоря о расположении регистров, о виртуальных машинах и т. Д., О которой я не буду претендовать на понимание.

Любая помощь чрезвычайно ценится!

...