/** Receives the encoded image, decodes it and displays it on the VideoWindow. * * @author pquiring */ import java.io.*; import java.util.*; import javaforce.*; import javaforce.media.*; import javaforce.voip.*; public class RemoteCamera extends Thread { private volatile boolean active = true; private volatile boolean done = false; public RTPChannel channel; private VideoWindow videoWindow; // private RandomAccessFile raf; public RemoteCamera(RTPChannel channel, VideoWindow vw) { this.channel = channel; this.videoWindow = vw; } public void run() { // try { raf = new RandomAccessFile("media_remote.h264", "rw"); } catch (Exception e) {} remoteImage = new JFImage(); remoteImage.setImageSize(PhonePanel.vx, PhonePanel.vy); videoWindow.addCamera(channel); while (active) { synchronized (lock) { try { lock.wait(); } catch (Exception e) { } } if (imageList.isEmpty()) { continue; } JFImage img = imageList.remove(0); remoteImage.getGraphics().drawImage(img.getImage(), 0, 0, PhonePanel.vx, PhonePanel.vy, null); videoWindow.setRemoteImage(channel, remoteImage); } if (decoder != null) { decoder.stop(); decoder = null; } videoWindow.delCamera(channel); // try { raf.close(); } catch (Exception e) {} done = true; } public void cancel() { active = false; while (!done) { synchronized (lock) { lock.notify(); } JF.sleep(5); } } public void rtp_jpeg_data(byte[] data, int pos, int len) { if (!active) { return; } byte[] jpeg = rtpJpeg.decode(Arrays.copyOfRange(data, pos, pos + len)); if (jpeg != null) { JFImage tmp = new JFImage(); if (!tmp.load(new ByteArrayInputStream(jpeg))) { JFLog.log("RemoteCamera : failed to decode image"); return; } imageList.add(tmp); synchronized (lock) { lock.notify(); } } } public void rtp_h263_data(byte[] data, int pos, int len) { if (!active) { return; } byte[] pack = rtpH263.decode(Arrays.copyOfRange(data, pos, pos + len)); if (pack == null) { return; // printArray("decoded_h263", pack, 0, pack.length); } if (decoder == null) { decoder = new MediaVideoDecoder(); if (!decoder.start(MediaCoder.AV_CODEC_ID_H263, PhonePanel.vx, PhonePanel.vy)) { JFLog.log("H263 Decoder failed to start"); decoder.stop(); decoder = null; return; } } int[] px = decoder.decode(pack); if (px == null) { return; } JFImage img = new JFImage(); img.setSize(PhonePanel.vx, PhonePanel.vy); img.putPixels(px, 0, 0, PhonePanel.vx, PhonePanel.vy, 0); imageList.add(img); synchronized (lock) { lock.notify(); } } public void rtp_h263_1998_data(byte[] data, int pos, int len) { if (!active) { return; } byte[] pack = rtpH263_1998.decode(Arrays.copyOfRange(data, pos, pos + len)); if (pack == null) { return; // printArray("decoded_1998", pack, 0, pack.length); } if (decoder == null) { decoder = new MediaVideoDecoder(); if (!decoder.start(MediaCoder.AV_CODEC_ID_H263, PhonePanel.vx, PhonePanel.vy)) { JFLog.log("H263-1998 Decoder failed to start"); decoder.stop(); decoder = null; return; } } int[] px = decoder.decode(pack); if (px == null) { return; } JFImage img = new JFImage(); img.setSize(PhonePanel.vx, PhonePanel.vy); img.putPixels(px, 0, 0, PhonePanel.vx, PhonePanel.vy, 0); imageList.add(img); synchronized (lock) { lock.notify(); } } public void rtp_h263_2000_data(byte[] data, int pos, int len) { if (!active) { return; } byte[] pack = rtpH263_2000.decode(Arrays.copyOfRange(data, pos, pos + len)); if (pack == null) { return; // printArray("decoded_2000", pack, 0, pack.length); } if (decoder == null) { decoder = new MediaVideoDecoder(); if (!decoder.start(MediaCoder.AV_CODEC_ID_H263, PhonePanel.vx, PhonePanel.vy)) { JFLog.log("H263-2000 Decoder failed to start"); decoder.stop(); decoder = null; return; } } int[] px = decoder.decode(pack); if (px == null) { return; } JFImage img = new JFImage(); img.setSize(PhonePanel.vx, PhonePanel.vy); img.putPixels(px, 0, 0, PhonePanel.vx, PhonePanel.vy, 0); imageList.add(img); synchronized (lock) { lock.notify(); } } public void rtp_h264_data(byte[] data, int pos, int len) { if (!active) { return; } // printArray("i:rtpH264:", data, 0, len); byte[] pack = rtpH264.decode(Arrays.copyOfRange(data, pos, pos + len)); if (pack == null) { return; // printArray("decoded_h264", pack, 0, pack.length); // try { raf.write(pack); } catch (Exception e) {} } if (decoder == null) { decoder = new MediaVideoDecoder(); if (!decoder.start(MediaCoder.AV_CODEC_ID_H264, PhonePanel.vx, PhonePanel.vy)) { JFLog.log("H264 Decoder failed to start"); decoder.stop(); decoder = null; return; } } int[] px = decoder.decode(pack); if (px == null) { return; } // JFLog.log("px[]=" + px[0] + "," + px[1] + "," + px[2]); JFImage img = new JFImage(); img.setSize(PhonePanel.vx, PhonePanel.vy); img.putPixels(px, 0, 0, PhonePanel.vx, PhonePanel.vy, 0); imageList.add(img); synchronized (lock) { lock.notify(); } } public void rtp_vp8_data(byte[] data, int pos, int len) { if (!active) { return; } // printArray("i:rtpVP8:", data, 0, len); byte[] pack = rtpVP8.decode(Arrays.copyOfRange(data, pos, pos + len)); if (pack == null) { return; // printArray("decoded_VP8", pack, 0, pack.length); // try { raf.write(pack); } catch (Exception e) {} } if (decoder == null) { decoder = new MediaVideoDecoder(); if (!decoder.start(MediaCoder.AV_CODEC_ID_VP8, PhonePanel.vx, PhonePanel.vy)) { JFLog.log("VP8 Decoder failed to start"); decoder.stop(); decoder = null; return; } } int[] px = decoder.decode(pack); if (px == null) { return; } // JFLog.log("px[]=" + px[0] + "," + px[1] + "," + px[2]); JFImage img = new JFImage(); img.setSize(PhonePanel.vx, PhonePanel.vy); img.putPixels(px, 0, 0, PhonePanel.vx, PhonePanel.vy, 0); imageList.add(img); synchronized (lock) { lock.notify(); } } private JFImage remoteImage; private final Object lock = new Object(); private RTPJPEG rtpJpeg = new RTPJPEG(); private RTPH263 rtpH263 = new RTPH263(); private RTPH263_1998 rtpH263_1998 = new RTPH263_1998(); private RTPH263_2000 rtpH263_2000 = new RTPH263_2000(); private RTPH264 rtpH264 = new RTPH264(); private RTPVP8 rtpVP8 = new RTPVP8(); private MediaVideoDecoder decoder; private Vector<JFImage> imageList = new Vector<JFImage>(); }