/** * encode a buffer and add in RTP input * * @param data */ private void encode(byte[] data) { // Set timestamp timeStamp = SystemClock.uptimeMillis() - videoStartTime; // Encode frame byte[] encoded; if (frameBuffer.dataSrcWidth != 0 && frameBuffer.dataSrcHeight != 0) { encoded = NativeH264Encoder.ResizeAndEncodeFrame( data, timeStamp, mirroring, frameBuffer.dataSrcWidth, frameBuffer.dataSrcHeight); } else { encoded = NativeH264Encoder.EncodeFrame(data, timeStamp, mirroring, frameBuffer.dataScaleFactor); } int encodeResult = NativeH264Encoder.getLastEncodeStatus(); if ((encodeResult == 0) && (encoded.length > 0)) { // Send SPS/PPS if IDR or first frame if (!nalInit || isIdrFrame(encoded)) { rtpInput.addFrame(sps, timeStamp); rtpInput.addFrame(pps, timeStamp); nalInit = true; } VideoOrientation videoOrientation = null; if (orientationHeaderId > 0) { videoOrientation = new VideoOrientation( orientationHeaderId, CameraOptions.convert(cameraId), mOrientation); } rtpInput.addFrame(encoded, timeStamp, videoOrientation); } }
/** Close the player */ public void close() { if (!opened) { // Already closed return; } // Close the RTP layer rtpInput.close(); rtpSender.stopSession(); try { // Close the video encoder NativeH264Encoder.DeinitEncoder(); } catch (UnsatisfiedLinkError e) { if (logger.isActivated()) { logger.error("Can't close correctly the encoder", e); } } // Player is closed opened = false; notifyPlayerEventClosed(); listeners.clear(); }
/** * Open the player * * @param remoteHost Remote host * @param remotePort Remote port */ public void open(String remoteHost, int remotePort) { if (opened) { // Already opened return; } // Check video codec if (selectedVideoCodec == null) { notifyPlayerEventError("Video codec not selected"); return; } // Init video encoder try { NativeH264EncoderParams nativeH264EncoderParams = new NativeH264EncoderParams(); // Codec dimensions nativeH264EncoderParams.setFrameWidth(selectedVideoCodec.getWidth()); nativeH264EncoderParams.setFrameHeight(selectedVideoCodec.getHeight()); nativeH264EncoderParams.setFrameRate(selectedVideoCodec.getFramerate()); nativeH264EncoderParams.setBitRate(selectedVideoCodec.getBitrate()); // Codec profile and level nativeH264EncoderParams.setProfilesAndLevel(selectedVideoCodec.getCodecParams()); // Codec settings optimization nativeH264EncoderParams.setEncMode(NativeH264EncoderParams.ENCODING_MODE_STREAMING); nativeH264EncoderParams.setSceneDetection(false); if (logger.isActivated()) { logger.info( "Init H264Encoder " + selectedVideoCodec.getCodecParams() + " " + selectedVideoCodec.getWidth() + "x" + selectedVideoCodec.getHeight() + " " + selectedVideoCodec.getFramerate() + " " + selectedVideoCodec.getBitrate()); } int result = NativeH264Encoder.InitEncoder(nativeH264EncoderParams); if (result != 0) { notifyPlayerEventError("Encoder init failed with error code " + result); return; } } catch (UnsatisfiedLinkError e) { notifyPlayerEventError(e.getMessage()); return; } // Init the RTP layer try { releasePort(); rtpSender = new VideoRtpSender(videoFormat, localRtpPort); rtpInput = new MediaRtpInput(); rtpInput.open(); if (videoRenderer != null) { // The video renderer is supposed to be opened and so we used its RTP stream if (logger.isActivated()) { logger.debug("Player shares the renderer RTP stream"); } rtpSender.prepareSession( rtpInput, remoteHost, remotePort, videoRenderer.getRtpInputStream(), this); } else { // The video renderer doesn't exist and so we create a new RTP stream rtpSender.prepareSession(rtpInput, remoteHost, remotePort, this); } } catch (Exception e) { notifyPlayerEventError(e.getMessage()); return; } // Player is opened opened = true; notifyPlayerEventOpened(); }