public boolean readNextImage() {
    try {
      while (demuxer.read(packet) >= 0) {
        if (packet.getStreamIndex() == videoStreamId) {
          int offset = 0;
          int bytesRead = 0;
          do {
            bytesRead += videoDecoder.decode(picture, packet, offset);
            if (picture.isComplete()) {
              image3ByteBGR = converter.toImage(image3ByteBGR, picture);
              frameIndex++;

              this.presentationTimestamp = packet.getPts();

              dirtyImageRGB = true;
              return true;
            }
            offset += bytesRead;
          } while (offset < packet.getSize());
        }
      }
    } catch (Exception ex) {
      throw new RuntimeException("Failed readNextImage", ex);
    }
    return false;
  }
  private void processConvert(Muxer muxer, Encoder encoder) throws Exception {
    muxer.open(null, null);
    MediaPacket packet = MediaPacket.make();
    MediaAudio samples = beepSamples();
    logger.info(samples.toString());
    if (samples.getSampleRate() != encoder.getSampleRate()
        || samples.getFormat() != encoder.getSampleFormat()
        || samples.getChannelLayout() != encoder.getChannelLayout()) {
      final MediaAudioResampler resampler =
          MediaAudioResampler.make(
              encoder.getChannelLayout(),
              encoder.getSampleRate(),
              encoder.getSampleFormat(),
              samples.getChannelLayout(),
              samples.getSampleRate(),
              samples.getFormat());
      resampler.open();
      MediaAudio spl =
          MediaAudio.make(
              samples.getNumSamples(),
              encoder.getSampleRate(),
              encoder.getChannels(),
              encoder.getChannelLayout(),
              encoder.getSampleFormat());
      resampler.resample(spl, samples);
      logger.info(spl.toString());
      logger.info("{}", spl.getNumSamples());
      Assert.assertEquals(spl.getNumSamples(), samples.getNumSamples());
      samples = spl;
    }
    logger.info(samples.toString());

    // we only have one set of samples.
    encoder.encodeAudio(packet, samples);
    logger.info("{}", packet);
    if (packet.isComplete()) muxer.write(packet, false);

    // Flush the encoders
    do {
      encoder.encodeAudio(packet, null);
      logger.info("{}", packet);
      if (packet.isComplete()) {
        muxer.write(packet, false);
      }
    } while (packet.isComplete());
    muxer.close();
  }
  public void init() {
    try {
      this.demuxer = Demuxer.make();

      demuxer.open(inputFile.getAbsolutePath(), null, false, true, null, null);

      int numStreams = demuxer.getNumStreams();

      videoStreamId = -1;
      videoDecoder = null;
      for (int i = 0; i < numStreams; i++) {
        final DemuxerStream stream = demuxer.getStream(i);
        final Decoder decoder = stream.getDecoder();
        if (decoder != null && decoder.getCodecType() == MediaDescriptor.Type.MEDIA_VIDEO) {
          videoStreamId = i;
          videoDecoder = decoder;
          // stop at the first one.
          break;
        }
      }
      if (videoStreamId == -1) {
        throw new RuntimeException(
            "could not find video stream in video file: '" + inputFile + "'");
      }

      videoDecoder.open(null, null);

      int width = videoDecoder.getWidth();
      int height = videoDecoder.getHeight();
      this.dim = new Dim(width, height);
      picture = MediaPicture.make(width, height, videoDecoder.getPixelFormat());

      // converter to BGR_24 for java swing
      converter =
          MediaPictureConverterFactory.createConverter(
              MediaPictureConverterFactory.HUMBLE_BGR_24, picture);
      image3ByteBGR = null; // new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);

      imageRGB = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
      imageRGBDataInts = ((DataBufferInt) imageRGB.getRaster().getDataBuffer()).getData();

      packet = MediaPacket.make();
    } catch (Exception ex) {
      throw new RuntimeException("Failed init HumbleioPacketReader '" + inputFile + "'", ex);
    }
  }