public void read(Buffer buf) {
    synchronized (buffers) {
      while (buffers.size() == 0 && notDone) {
        try {
          buffers.wait();
        } catch (InterruptedException ex) {
          ex.printStackTrace();
        }
      }

      if (buffers.size() > 0) {
        Buffer newBuf = (Buffer) buffers.get(0);
        int[] newData = (int[]) newBuf.getData();
        buf.setData(newData);
        buf.setLength(newBuf.getLength());
        buf.setOffset(0);
        buf.setFormat(vFormat);
        buf.setFlags(Buffer.FLAG_KEY_FRAME | Buffer.FLAG_NO_DROP);
        buffers.remove(0);
        // System.out.println("Removing buffer: size = " + buffers.size());
      } else {
        buf.setEOM(true);
        buf.setOffset(0);
        buf.setLength(0);
        synchronized (buffers) {
          buffers.notify();
        }
      }
    }
  }
  /**
   * Blocks and reads into a <tt>Buffer</tt> from this <tt>PullBufferStream</tt>.
   *
   * @param buffer the <tt>Buffer</tt> this <tt>PullBufferStream</tt> is to read into
   * @throws IOException if an I/O error occurs while this <tt>PullBufferStream</tt> reads into the
   *     specified <tt>Buffer</tt>
   * @see AbstractVideoPullBufferStream#doRead(Buffer)
   */
  @Override
  protected void doRead(Buffer buffer) throws IOException {
    /*
     * Determine the Format in which we're expected to output. We cannot
     * rely on the Format always being specified in the Buffer because it is
     * not its responsibility, the DataSource of this ImageStream knows the
     * output Format.
     */
    Format format = buffer.getFormat();

    if (format == null) {
      format = getFormat();
      if (format != null) buffer.setFormat(format);
    }

    if (format instanceof AVFrameFormat) {
      Object o = buffer.getData();
      AVFrame frame;

      if (o instanceof AVFrame) frame = (AVFrame) o;
      else {
        frame = new AVFrame();
        buffer.setData(frame);
      }

      AVFrameFormat avFrameFormat = (AVFrameFormat) format;
      Dimension size = avFrameFormat.getSize();
      ByteBuffer data = readScreenNative(size);

      if (data != null) {
        if (frame.avpicture_fill(data, avFrameFormat) < 0) {
          data.free();
          throw new IOException("avpicture_fill");
        }
      } else {
        /*
         * This can happen when we disconnect a monitor from computer
         * before or during grabbing.
         */
        throw new IOException("Failed to grab screen.");
      }
    } else {
      byte[] bytes = (byte[]) buffer.getData();
      Dimension size = ((VideoFormat) format).getSize();

      bytes = readScreen(bytes, size);

      buffer.setData(bytes);
      buffer.setOffset(0);
      buffer.setLength(bytes.length);
    }

    buffer.setHeader(null);
    buffer.setTimeStamp(System.nanoTime());
    buffer.setSequenceNumber(seqNo);
    buffer.setFlags(Buffer.FLAG_SYSTEM_TIME | Buffer.FLAG_LIVE_DATA);
    seqNo++;
  }
  /**
   * Copies the content of the most recently received packet into <tt>data</tt>.
   *
   * @param buffer an optional <tt>Buffer</tt> instance associated with the specified <tt>data</tt>,
   *     <tt>offset</tt> and <tt>length</tt> and provided to the method in case the implementation
   *     would like to provide additional <tt>Buffer</tt> properties such as <tt>flags</tt>
   * @param data the <tt>byte[]</tt> that we'd like to copy the content of the packet to.
   * @param offset the position where we are supposed to start writing in <tt>data</tt>.
   * @param length the number of <tt>byte</tt>s available for writing in <tt>data</tt>.
   * @return the number of bytes read
   * @throws IOException if <tt>length</tt> is less than the size of the packet.
   */
  protected int read(Buffer buffer, byte[] data, int offset, int length) throws IOException {
    if (data == null) throw new NullPointerException("data");

    if (ioError) return -1;

    RawPacket pkt;

    synchronized (pktSyncRoot) {
      pkt = this.pkt;
      this.pkt = null;
    }

    int pktLength;

    if (pkt == null) {
      pktLength = 0;
    } else {
      // By default, pkt will be returned to the pool after it was read.
      boolean poolPkt = true;

      try {
        pktLength = pkt.getLength();
        if (length < pktLength) {
          /*
           * If pkt is still the latest RawPacket made available to
           * reading, reinstate it for the next invocation of read;
           * otherwise, return it to the pool.
           */
          poolPkt = false;
          throw new IOException("Input buffer not big enough for " + pktLength);
        } else {
          byte[] pktBuffer = pkt.getBuffer();

          if (pktBuffer == null) {
            throw new NullPointerException(
                "pkt.buffer null, pkt.length " + pktLength + ", pkt.offset " + pkt.getOffset());
          } else {
            System.arraycopy(pkt.getBuffer(), pkt.getOffset(), data, offset, pktLength);
            if (buffer != null) buffer.setFlags(pkt.getFlags());
          }
        }
      } finally {
        if (!poolPkt) {
          synchronized (pktSyncRoot) {
            if (this.pkt == null) this.pkt = pkt;
            else poolPkt = true;
          }
        }
        if (poolPkt) {
          // Return pkt to the pool because it was successfully read.
          poolRawPacket(pkt);
        }
      }
    }

    return pktLength;
  }
Beispiel #4
0
  public int process(Buffer inBuffer, Buffer outBuffer) {
    try {
      if (frameConverter == null) {
        frameConverter = new BufferToImage((VideoFormat) inBuffer.getFormat());
      }

      // Convert the Buffer to an AWT Image.
      Image frameImage = frameConverter.createImage(inBuffer);

      // Derive a JAI image from the AWT image.
      PlanarImage jaiImage = JAI.create("AWTImage", frameImage);

      int index;
      boolean emboss = false;
      if (control != null) {
        index = control.getEffectIndex();
        if (control.getEffectName().equals("None")) {
          outBuffer.setData(inBuffer.getData());
          outBuffer.setFormat(inBuffer.getFormat());
          outBuffer.setFlags(inBuffer.getFlags());
          outBuffer.setLength(inBuffer.getLength());
          return BUFFER_PROCESSED_OK;
        }
        if (control.getEffectName().equals("Emboss")) {
          emboss = true; // Special case
        }
      } else index = 0;

      if (kernels[index] == null) {
        kernels[index] = new KernelJAI(3, 3, matrices[index]);
      }

      jaiImage = JAI.create("convolve", jaiImage, kernels[index]);

      if (emboss) { // add 128 to make it brighter
        double[] constants = new double[] {128., 128., 128.};
        ParameterBlock pb = new ParameterBlock();
        pb.addSource(jaiImage);
        pb.add(constants);
        jaiImage = JAI.create("addconst", pb, null);
      }

      // Now convert the image to a buffer
      BufferedImage bim = jaiImage.getAsBufferedImage();

      Buffer out = ImageToBuffer.createBuffer(bim, 15.F);
      if (out == null) {
        if (debug) {
          System.out.println("ImageToBuffer returned null");
        }
        return BUFFER_PROCESSED_FAILED;
      }

      outBuffer.setData(out.getData());
      outBuffer.setFormat(out.getFormat());
      outBuffer.setFlags(out.getFlags());
      outBuffer.setLength(out.getLength());
    } catch (Exception e) {
      System.err.println(e);
      return BUFFER_PROCESSED_FAILED;
    } catch (Error e) {
      System.err.println(e);
      return BUFFER_PROCESSED_FAILED;
    }
    return BUFFER_PROCESSED_OK;
  }