/**
   * 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++;
  }
    public VideoTrack(PullSourceStream stream) throws ResourceUnavailableException {
      super();

      this.stream = stream;
      // set format

      // read first frame to determine format
      final Buffer buffer = new Buffer();
      readFrame(buffer);
      if (buffer.isDiscard() || buffer.isEOM())
        throw new ResourceUnavailableException("Unable to read first frame");
      // TODO: catch runtime exception too?

      // parse jpeg
      final java.awt.Image image;
      try {
        image =
            ImageIO.read(
                new ByteArrayInputStream(
                    (byte[]) buffer.getData(), buffer.getOffset(), buffer.getLength()));
      } catch (IOException e) {
        logger.log(Level.WARNING, "" + e, e);
        throw new ResourceUnavailableException("Error reading image: " + e);
      }

      if (image == null) {
        logger.log(Level.WARNING, "Failed to read image (ImageIO.read returned null).");
        throw new ResourceUnavailableException();
      }

      if (frameContentType.equals("image/jpeg"))
        format =
            new JPEGFormat(
                new Dimension(image.getWidth(null), image.getHeight(null)),
                Format.NOT_SPECIFIED,
                Format.byteArray,
                -1.f,
                Format.NOT_SPECIFIED,
                Format.NOT_SPECIFIED);
      else if (frameContentType.equals("image/gif"))
        format =
            new GIFFormat(
                new Dimension(image.getWidth(null), image.getHeight(null)),
                Format.NOT_SPECIFIED,
                Format.byteArray,
                -1.f);
      else if (frameContentType.equals("image/png"))
        format =
            new PNGFormat(
                new Dimension(image.getWidth(null), image.getHeight(null)),
                Format.NOT_SPECIFIED,
                Format.byteArray,
                -1.f);
      else
        throw new ResourceUnavailableException(
            "Unsupported frame content type: " + frameContentType);
      // TODO: this discards first image. save and return first time
      // readFrame is called.

    }
  private void newImage(Buffer buffer) {
    Object data = buffer.getData();
    if (!(data instanceof int[])) return;
    RGBFormat format = (RGBFormat) buffer.getFormat();

    DirectColorModel dcm =
        new DirectColorModel(
            format.getBitsPerPixel(),
            format.getRedMask(),
            format.getGreenMask(),
            format.getBlueMask());

    sourceImage =
        new MemoryImageSource(
            format.getLineStride(),
            format.getSize().height,
            dcm,
            (int[]) data,
            0,
            format.getLineStride());
    sourceImage.setAnimated(true);
    sourceImage.setFullBufferUpdates(true);
    if (component != null) {
      destImage = component.createImage(sourceImage);
      component.prepareImage(destImage, component);
    }
  }
Beispiel #4
0
  /** decode the buffer * */
  public int process(Buffer inputBuffer, Buffer outputBuffer) {

    if (!checkInputBuffer(inputBuffer)) {
      return BUFFER_PROCESSED_FAILED;
    }

    if (isEOM(inputBuffer)) {
      propagateEOM(outputBuffer);
      return BUFFER_PROCESSED_OK;
    }

    Object outData = outputBuffer.getData();
    outputBuffer.setData(inputBuffer.getData());
    inputBuffer.setData(outData);
    outputBuffer.setLength(inputBuffer.getLength());
    outputBuffer.setFormat(outputFormat);
    outputBuffer.setOffset(inputBuffer.getOffset());
    return BUFFER_PROCESSED_OK;
  }
Beispiel #5
0
  @Override
  public int process(Buffer input, Buffer output) {
    if (!checkInputBuffer(input)) {
      return BUFFER_PROCESSED_FAILED;
    }

    if (isEOM(input)) {
      propagateEOM(output); // TODO: what about data? can there be any?
      return BUFFER_PROCESSED_OK;
    }

    try {
      // TODO: this is very inefficient - it allocates a new byte array
      // (or more) every time
      final ByteArrayInputStream is =
          new ByteArrayInputStream((byte[]) input.getData(), input.getOffset(), input.getLength());
      final BufferedImage image = ImageIO.read(is);
      is.close();
      final Buffer b =
          ImageToBuffer.createBuffer(image, ((VideoFormat) outputFormat).getFrameRate());

      output.setData(b.getData());
      output.setOffset(b.getOffset());
      output.setLength(b.getLength());
      output.setFormat(b.getFormat()); // TODO: this is a bit hacky, this
      // format will be more specific
      // than the actual set output
      // format, because now we know what
      // ImageIO gave us for a
      // BufferedImage as far as pixel
      // masks, etc.

      return BUFFER_PROCESSED_OK;

    } catch (IOException e) {
      output.setDiscard(true);
      output.setLength(0);
      return BUFFER_PROCESSED_FAILED;
    }
  }
  // @Override
  @Override
  public int read() throws IOException {
    // TODO: how do we detect IOException?
    fillBuffer();
    if (buffer.getLength() == 0 && buffer.isEOM()) // TODO: will always be
      // EOM if length is 0
      return -1;
    final byte[] data = (byte[]) buffer.getData();
    final int result = data[buffer.getOffset()] & 0xff;
    buffer.setOffset(buffer.getOffset() + 1);
    buffer.setLength(buffer.getLength() - 1);

    return result;
  }
  public void processBufferData(Buffer buffer) {

    CompositeDataPacket cdp = new CompositeDataPacket();
    cdp.setPrimaryStream(buffer.getData());

    if (buffer instanceof CompositeDataBuffer) {
      CompositeDataBuffer cb = (CompositeDataBuffer) buffer;
      cdp.setSecondaryStreams(cb.getBufferCompositeData());
    }
    buffer.reset();

    count++;

    if (count % 100 == 0) System.out.println(name + ": processed " + count + " buffers");
  }
  // @Override
  @Override
  public int read(byte[] b, int off, int len) throws IOException {
    // TODO: how do we detect IOException?
    fillBuffer();
    if (buffer.getLength() == 0 && buffer.isEOM()) // TODO: will always be
      // EOM if length is 0
      return -1;
    final byte[] data = (byte[]) buffer.getData();

    int lengthToCopy = buffer.getLength() < len ? buffer.getLength() : len;
    System.arraycopy(data, buffer.getOffset(), b, off, lengthToCopy);
    buffer.setOffset(buffer.getOffset() + lengthToCopy);
    buffer.setLength(buffer.getLength() - lengthToCopy);

    return lengthToCopy;
  }
    /**
     * Reads media data from this <tt>PullBufferStream</tt> into a specific <tt>Buffer</tt> with
     * blocking.
     *
     * @param buffer the <tt>Buffer</tt> in which media data is to be read from this
     *     <tt>PullBufferStream</tt>
     * @throws IOException if anything goes wrong while reading media data from this
     *     <tt>PullBufferStream</tt> into the specified <tt>buffer</tt>
     * @see javax.media.protocol.PullBufferStream#read(javax.media.Buffer)
     */
    public void read(Buffer buffer) throws IOException {
      if (setThreadPriority) {
        setThreadPriority = false;
        setThreadPriority();
      }

      Object data = buffer.getData();
      int length = this.length;

      if (data instanceof byte[]) {
        if (((byte[]) data).length < length) data = null;
      } else data = null;
      if (data == null) {
        data = new byte[length];
        buffer.setData(data);
      }

      int toRead = length;
      byte[] bytes = (byte[]) data;
      int offset = 0;

      buffer.setLength(0);
      while (toRead > 0) {
        int read;

        synchronized (this) {
          if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING)
            read = audioRecord.read(bytes, offset, toRead);
          else break;
        }

        if (read < 0) {
          throw new IOException(
              AudioRecord.class.getName() + "#read(byte[], int, int) returned " + read);
        } else {
          buffer.setLength(buffer.getLength() + read);
          offset += read;
          toRead -= read;
        }
      }
      buffer.setOffset(0);

      // Apply software gain.
      if (gainControl != null) {
        BasicVolumeControl.applyGain(gainControl, bytes, buffer.getOffset(), buffer.getLength());
      }
    }
  /** Processes the data and renders it to a component */
  public synchronized int process(Buffer buffer) {
    if (component == null) return BUFFER_PROCESSED_FAILED;

    Format inf = buffer.getFormat();
    if (inf == null) return BUFFER_PROCESSED_FAILED;

    if (inf != inputFormat || !buffer.getFormat().equals(inputFormat)) {
      if (setInputFormat(inf) != null) return BUFFER_PROCESSED_FAILED;
    }

    Object data = buffer.getData();
    if (!(data instanceof int[])) return BUFFER_PROCESSED_FAILED;

    if (lastBuffer != buffer) {
      lastBuffer = buffer;
      newImage(buffer);
    }

    sourceImage.newPixels(0, 0, inWidth, inHeight);

    Graphics g = component.getGraphics();
    if (g != null) {
      if (reqBounds == null) {
        bounds = component.getBounds();
        bounds.x = 0;
        bounds.y = 0;
      } else bounds = reqBounds;
      g.drawImage(
          destImage,
          bounds.x,
          bounds.y,
          bounds.width,
          bounds.height,
          0,
          0,
          inWidth,
          inHeight,
          component);
    }

    return BUFFER_PROCESSED_OK;
  }
Beispiel #11
0
 public byte[] getData() {
   return buffer.getData();
 }
Beispiel #12
0
  /** {@inheritDoc} */
  @Override
  protected int doProcess(Buffer inBuffer, Buffer outBuffer) {
    byte[] inData = (byte[]) inBuffer.getData();
    int inOffset = inBuffer.getOffset();

    if (!VP8PayloadDescriptor.isValid(inData, inOffset)) {
      logger.warn("Invalid RTP/VP8 packet discarded.");
      outBuffer.setDiscard(true);
      return BUFFER_PROCESSED_FAILED; // XXX: FAILED or OK?
    }

    long inSeq = inBuffer.getSequenceNumber();
    long inRtpTimestamp = inBuffer.getRtpTimeStamp();
    int inPictureId = VP8PayloadDescriptor.getPictureId(inData, inOffset);
    boolean inMarker = (inBuffer.getFlags() & Buffer.FLAG_RTP_MARKER) != 0;
    boolean inIsStartOfFrame = VP8PayloadDescriptor.isStartOfFrame(inData, inOffset);
    int inLength = inBuffer.getLength();
    int inPdSize = VP8PayloadDescriptor.getSize(inData, inOffset);
    int inPayloadLength = inLength - inPdSize;

    if (empty && lastSentSeq != -1 && seqNumComparator.compare(inSeq, lastSentSeq) != 1) {
      if (logger.isInfoEnabled()) logger.info("Discarding old packet (while empty) " + inSeq);
      outBuffer.setDiscard(true);
      return BUFFER_PROCESSED_OK;
    }

    if (!empty) {
      // if the incoming packet has a different PictureID or timestamp
      // than those of the current frame, then it belongs to a different
      // frame.
      if ((inPictureId != -1 && pictureId != -1 && inPictureId != pictureId)
          | (timestamp != -1 && inRtpTimestamp != -1 && inRtpTimestamp != timestamp)) {
        if (seqNumComparator.compare(inSeq, firstSeq) != 1) // inSeq <= firstSeq
        {
          // the packet belongs to a previous frame. discard it
          if (logger.isInfoEnabled()) logger.info("Discarding old packet " + inSeq);
          outBuffer.setDiscard(true);
          return BUFFER_PROCESSED_OK;
        } else // inSeq > firstSeq (and also presumably isSeq > lastSeq)
        {
          // the packet belongs to a subsequent frame (to the one
          // currently being held). Drop the current frame.

          if (logger.isInfoEnabled())
            logger.info(
                "Discarding saved packets on arrival of"
                    + " a packet for a subsequent frame: "
                    + inSeq);

          // TODO: this would be the place to complain about the
          // not-well-received PictureID by sending a RTCP SLI or NACK.
          reinit();
        }
      }
    }

    // a whole frame in a single packet. avoid the extra copy to
    // this.data and output it immediately.
    if (empty && inMarker && inIsStartOfFrame) {
      byte[] outData = validateByteArraySize(outBuffer, inPayloadLength, false);
      System.arraycopy(inData, inOffset + inPdSize, outData, 0, inPayloadLength);
      outBuffer.setOffset(0);
      outBuffer.setLength(inPayloadLength);
      outBuffer.setRtpTimeStamp(inBuffer.getRtpTimeStamp());

      if (TRACE) logger.trace("Out PictureID=" + inPictureId);

      lastSentSeq = inSeq;

      return BUFFER_PROCESSED_OK;
    }

    // add to this.data
    Container container = free.poll();
    if (container == null) container = new Container();
    if (container.buf == null || container.buf.length < inPayloadLength)
      container.buf = new byte[inPayloadLength];

    if (data.get(inSeq) != null) {
      if (logger.isInfoEnabled())
        logger.info("(Probable) duplicate packet detected, discarding " + inSeq);
      outBuffer.setDiscard(true);
      return BUFFER_PROCESSED_OK;
    }

    System.arraycopy(inData, inOffset + inPdSize, container.buf, 0, inPayloadLength);
    container.len = inPayloadLength;
    data.put(inSeq, container);

    // update fields
    frameLength += inPayloadLength;
    if (firstSeq == -1 || (seqNumComparator.compare(firstSeq, inSeq) == 1)) firstSeq = inSeq;
    if (lastSeq == -1 || (seqNumComparator.compare(inSeq, lastSeq) == 1)) lastSeq = inSeq;

    if (empty) {
      // the first received packet for the current frame was just added
      empty = false;
      timestamp = inRtpTimestamp;
      pictureId = inPictureId;
    }

    if (inMarker) haveEnd = true;
    if (inIsStartOfFrame) haveStart = true;

    // check if we have a full frame
    if (frameComplete()) {
      byte[] outData = validateByteArraySize(outBuffer, frameLength, false);
      int ptr = 0;
      Container b;
      for (Map.Entry<Long, Container> entry : data.entrySet()) {
        b = entry.getValue();
        System.arraycopy(b.buf, 0, outData, ptr, b.len);
        ptr += b.len;
      }

      outBuffer.setOffset(0);
      outBuffer.setLength(frameLength);
      outBuffer.setRtpTimeStamp(inBuffer.getRtpTimeStamp());

      if (TRACE) logger.trace("Out PictureID=" + inPictureId);
      lastSentSeq = lastSeq;

      // prepare for the next frame
      reinit();

      return BUFFER_PROCESSED_OK;
    } else {
      // frame not complete yet
      outBuffer.setDiscard(true);
      return OUTPUT_BUFFER_NOT_FILLED;
    }
  }
Beispiel #13
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;
  }
 public ByteBuffer[] getData() {
   return buffers.getData();
 }
  public int process(Buffer inputBuffer, Buffer outputBuffer) {

    if (pendingFrames > 0) {
      // System.out.println("packetizing");
      return BUFFER_PROCESSED_OK;
    }

    if (!checkInputBuffer(inputBuffer)) {
      return BUFFER_PROCESSED_FAILED;
    }

    if (isEOM(inputBuffer)) {
      propagateEOM(outputBuffer);
      return BUFFER_PROCESSED_OK;
    }

    int inpOffset = inputBuffer.getOffset();
    int inpLength = inputBuffer.getLength();
    int outLength = 0;
    int outOffset = 0;
    byte[] inpData = (byte[]) inputBuffer.getData();
    byte[] outData =
        validateByteArraySize(outputBuffer, calculateOutputSize(inpData.length + historySize));
    int historyLength = history.getLength();
    byte[] historyData = validateByteArraySize(history, historySize);
    int framesNumber = calculateFramesNumber(inpData.length + historySize);

    if ((regions == null) || (regions.length < framesNumber + 1))
      regions = new int[framesNumber + 1];

    if ((regionsTypes == null) || (regionsTypes.length < framesNumber))
      regionsTypes = new int[framesNumber];

    if (historyLength != 0) {
      int bytesToCopy = (historyData.length - historyLength);
      if (bytesToCopy > inpLength) {
        bytesToCopy = inpLength;
      }

      System.arraycopy(inpData, inpOffset, historyData, historyLength, bytesToCopy);

      codecProcess(
          historyData,
          0,
          outData,
          outOffset,
          historyLength + bytesToCopy,
          readBytes,
          writeBytes,
          frameNumber,
          regions,
          regionsTypes);

      if (readBytes[0] <= 0) {
        if (writeBytes[0] <= 0) {
          // System.err.println("Returning output buffer not filled");
          return OUTPUT_BUFFER_NOT_FILLED;
        } else {
          updateOutput(outputBuffer, outputFormat, writeBytes[0], 0);
          // System.err.println("Returning OK");
          return BUFFER_PROCESSED_OK;
        }
      }

      // System.out.println("1: "+inpLength+" "+readBytes[0]+" "+writeBytes[0]);

      outOffset += writeBytes[0];
      outLength += writeBytes[0];

      inpOffset += (readBytes[0] - historyLength);
      inpLength += (historyLength - readBytes[0]);
    }

    codecProcess(
        inpData,
        inpOffset,
        outData,
        outOffset,
        inpLength,
        readBytes,
        writeBytes,
        frameNumber,
        regions,
        regionsTypes);
    // System.out.println("2: "+inpLength+" "+readBytes[0]+" "+writeBytes[0]);

    // debug
    // for (int i=0; i<frameNumber[0];i++ ) {
    // System.out.println(i+" "+regions[i]+" - "+regions[i+1]+" type "+regionsTypes[i]);
    // }

    outLength += writeBytes[0];

    inpOffset += readBytes[0];
    inpLength -= readBytes[0];

    System.arraycopy(inpData, inpOffset, historyData, 0, inpLength);
    history.setLength(inpLength);

    updateOutput(outputBuffer, outputFormat, outLength, 0);

    return BUFFER_PROCESSED_OK;
  }