Thread is blocked when calls buffer.getFormat()... ( readLine )
Hey guys...
I have a class that detect the webcams conecteds to the computer, and another class that receiving the CaptureDeviceInfo, monitore the webcam images looking for movements...
The MovimentDetector class is instantiated by the Main class in the Menu, that have 3 options
1 - Start moviment detector
2 - Stop moviment detector
3 - Exit program
This menu is printed in console by System.out.println calls, and the choice off the user is received via BufferedReader.readLine method.
When the MovimentDetector is instantiated and activated, the Main class return to the menu waiting for the next desire off the user.
But when the MovimentDetector class have to get an picture from the webcam, the Thread off the MovimentDetector is blocked and keeps waiting the user to get an option in the menu from Main class..
Debuggin the application, I discover exact line that block the Thread:
player = Manager.createRealizedPlayer( camera.getDeviceInfo().getLocator() );
All the code off the app is *** follows...
Here is the MovimentDetector class...
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.IOException;
import javax.media.Buffer;
import javax.media.CannotRealizeException;
import javax.media.CaptureDeviceInfo;
import javax.media.Manager;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.control.FormatControl;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;
import javax.swing.ImageIcon;
publicclass DetectorMovimentoextends Thread{
privatedouble taxaMinima;
privateboolean running =false;
private Camera camera;
private PCIntermediarioModule interPc;
private Player player =null;
private FormatControl formatControl;
protected Dimension imageSize;
public DetectorMovimento( PCIntermediarioModule pInterPc , Camera pCamera ){
super();
System.out.println("Detector sendo inicializado");
camera = pCamera;
interPc = pInterPc;
taxaMinima = 0.15;
inicializa();
}
publicvoid stopDetect(){ running =false;}
publicdouble getTaxaMinima(){return taxaMinima;}
publicvoid setTaxaMinima(double pTm){ taxaMinima = pTm;}
publicboolean isRunning(){return running;}
publicvoid setRunning(boolean pBool){ running = pBool;}
privatevoid inicializa(){
if( camera !=null ){
try{
player = Manager.createRealizedPlayer( camera.getDeviceInfo().getLocator() );
if( player !=null ){
player.start();
formatControl = (FormatControl)player.getControl ("javax.media.control.FormatControl" );
imageSize = ((VideoFormat)formatControl.getFormat()).getSize();
}else{
System.err.println("DETECTOR DE MOVIMENTO - Null player.");
}
}catch (NoPlayerException npE){
System.err.println("DETECTOR DE MOVIMENTO - N鉶 foi poss韛el criar o player.");
System.out.println(npE);
}catch (CannotRealizeException crE){
System.err.println("DETECTOR DE MOVIMENTO - N鉶 foi poss韛el realizar o player.");
System.out.println(crE);
}catch (IOException ioE){
System.err.println("DETECTOR DE MOVIMENTO - Erro ao conectar com a c鈓era.");
System.out.println(ioE);
}
}else{
System.out.println("DETECTOR DE MOVIMENTO - Nenhuma c鈓era definida para detec玢o de movimento.");
}
}
/** Retorna o Buffer necess醨io para que seja */
private Buffer getFrameBuffer( ){
if ( player !=null ){
FrameGrabbingControl fgc = (FrameGrabbingControl)player.getControl ("javax.media.control.FrameGrabbingControl" );
if ( fgc !=null ){
return ( fgc.grabFrame() );
}else{
System.err.println ("DETECTOR DE MOVIMENTO - FrameGrabbingControl is null");
return (null );
}
}else{
System.err.println ("DETECTOR DE MOVIMENTO - Player is null");
return (null );
}
}
private Image getScreenShot(Buffer pBuffer){
if ( pBuffer !=null ){
//Converte o buffer para uma imagem
BufferToImage btoi =new BufferToImage ( (VideoFormat)pBuffer.getFormat() );
if ( btoi !=null ){
Image image = btoi.createImage ( pBuffer );
if ( image !=null ){
return ( image );
}else{
System.err.println ("DETECTOR DE MOVIMENTO - BufferToImage n鉶 pode converter o buffer.");
return (null );
}
}else{
System.err.println ("DETECTOR DE MOVIMENTO - N鉶 foi poss韛el criar uma inst鈔cia de BufferToImage.");
return (null );
}
}else{
System.err.println ("DETECTOR DE MOVIMENTO - Buffer nulo.");
return (null );
}
}
publicstatic BufferedImage toBufferedImage(Image image){
if (imageinstanceof BufferedImage){
return (BufferedImage)image;
}
// This code ensures that all the pixels in the image are loaded
image =new ImageIcon(image).getImage();
// Create a buffered image with a format that's compatible with the screen
BufferedImage bimage =null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try{
// Determine the type of transparency of the new buffered image
int transparency = Transparency.OPAQUE;
// Create the buffered image
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency);
}catch (HeadlessException e){
// The system does not have a screen
}
if (bimage ==null){
// Create a buffered image using the default color model
int type = BufferedImage.TYPE_INT_RGB;
bimage =new BufferedImage(image.getWidth(null), image.getHeight(null), type);
}
// Copy image to buffered image
Graphics g = bimage.createGraphics();
// Paint the image onto the buffered image
g.drawImage(image, 0, 0,null);
g.dispose();
return bimage;
}
privateboolean verificaMovimento( BufferedImage pImage1 , BufferedImage pImage2 ){
boolean move =false;
double difCont = 0, taxaDif;
int cin1, cin2, sub,
height = pImage1.getHeight(),
width = pImage1.getWidth();
for(int x = 0 ; x < height ; x++ )
for(int y = 0 ; y < width ; y++ ){
cin1 = getTomCinza( pImage1.getRGB(y,x) );
cin2 = getTomCinza( pImage2.getRGB(y,x) );
sub = cin1 - cin2;
if( sub < 0 ) sub *= -1;
if( sub >= 30 )
difCont++;
}
taxaDif = difCont / ( height * width );
System.out.println("Taxa " + taxaDif );
if( taxaDif >= taxaMinima )
move =true;
return move;
}
publicvoid run(){
System.out.println("Come鏾 detec玢o");
try{
Thread.sleep(900);
}catch (InterruptedException e){ e.printStackTrace();}
Buffer buffer;
//CS e OP s鉶 usados para converter a foto tirada para tons de cinza.
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op =new ColorConvertOp(cs,null);
//Recupera o Buffer da c鈓era, tira a primeira foto e converte a mesma para tons de cinza.
buffer = getFrameBuffer();
BufferedImage bimg1 = toBufferedImage( getScreenShot(buffer) );
bimg1 = op.filter(bimg1,null);
System.out.println("Tirou primeira foto");
while(isRunning()){
try{
Thread.sleep(400);
}catch (InterruptedException e){ e.printStackTrace();}
//Recupera o Buffer da c鈓era, tira a segunda foto e converte a mesma para tons de cinza.
buffer = getFrameBuffer();
BufferedImage bimg2 = toBufferedImage( getScreenShot(buffer) );
bimg2 = op.filter(bimg2,null);
System.out.println("Tirou segunda foto");
//Verifica a ocorr阯cia de movimento.
if( verificaMovimento( bimg1 , bimg2 ) )
interPc.movimentoDetectado(camera);
bimg1 = bimg2;
}
player.stop();
player.close();
player.deallocate();
}
privateint getTomCinza(int pRgb ){
int red = (pRgb >> 16) & 0xff;
int green = (pRgb >> 8) & 0xff;
int blue = pRgb & 0xff;
return (red + green + blue ) / 3;
}
privatevoid showImage( Image img ){
if ( img !=null ){
MySnapshot snapshot =new MySnapshot ( img,new Dimension ( imageSize ) );
}else{
System.err.println ("Error : Could not grab frame");
}
}
}
And here the Main class..
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Vector;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
publicclass PCIntermediarioModuleextends UnicastRemoteObjectimplements RMIPCIntermediarioInterface{
privatestaticfinallong serialVersionUID = 1;
privateboolean lider;
privateint id;
private RMIServidorInterface centralServer;
private ServidorModule myServer;
private Camera[] myCameras;
private CaptureDeviceInfo[] camerasInfo;
private Vector<DetectorMovimento> detectores;
/**
*Cria uma nova inst鈔cia de PCIntermediarioModule.
**/
public PCIntermediarioModule()throws RemoteException{
//Verifica o sucesso da recupera玢o/cria玢o do Servidor.
if( realizarServidor() ){
detectores =new Vector<DetectorMovimento>();//Inicializa Vector de Detectores de Movimento.
realizarMyCameras();//Detecta webcam ligada ao computador.
//Caso existir uma webcam ligada ao computador, o PCIntermediarioModule se registra no Servidor
//e envia sua lista de c鈓eras.
if( camerasInfo.length > 0 ){
System.out.println("PCIntermediarioModule - " + camerasInfo.length +" c鈓era(s) detectada(s).");
if(lider){
System.out.println("PCIntermediarioModule - Registrando objeto no servidor interno");
myServer.registraInterPc(this );
setMyCamerasAttributes();
myServer.addCameras( myCameras );
}else{
System.out.println("PCIntermediarioModule - Registrando objeto no servidor externo");
centralServer.registraInterPc(this );
setMyCamerasAttributes();
centralServer.addCameras( myCameras );
}
}else{
System.out.println("PCIntermediarioModule - Nenhuma c鈓era detectada.");
}
}
}
/**
*Recupera a refer阯cia para o ServidorModule.
*Caso nenhum objeto servidor esteja registrado ao RMIRegistry, um novo
*ServidorModule ?criado e registrado.
*/
privateboolean realizarServidor(){
//Host e nome do objeto remoto armazenado no RMIRegistry.
String name ="//localhost:/PMServer";
//Verifica se tal objeto est?registrado no RMIRegistry.
//Caso o mesmo n鉶 esteja o PCIntermediarioModule inst鈔cia o servidor e o registra, passando a
//ser o PCIntermediarioModule lider do sistema.
try{
centralServer = (RMIServidorInterface) Naming.lookup(name);
lider =false;
}catch (MalformedURLException muE){
System.out.println("INTERPC - URL incorreta para inst鈔ciar o Servidor remoto.");
returnfalse;
}catch (RemoteException rE){
System.out.println("INTERPC - Erro ao inst鈔ciar o Servidor remoto.");
returnfalse;
}catch (NotBoundException nbE){
try{
myServer =new ServidorModule();
Naming.rebind("//localhost/PMServer", myServer);
lider =true;
}catch (RemoteException rE){
System.out.println("INTERPC - Erro ao inst鈔ciar o Servidor local.");
returnfalse;
}catch (MalformedURLException muE ){
System.out.println("INTERPC - URL incorreta para inst鈔ciar o Servidor local.");
returnfalse;
}
}
returntrue;
}
publicboolean isLider(){
return lider;
}
publicvoid setLider(boolean pLider){
lider = pLider;
}
publicint getId(){
return id;
}
publicvoid setId(int pId){
System.out.println("Sou o Inter PC n?" + pId );
id = pId;
}
/**
* Detecta as c鈓eras ligadas ao computador.
*
*/
privatevoid realizarMyCameras(){
//Recupera a lista de dispositivos de captura de informa珲es.
Vector vet = CaptureDeviceManager.getDeviceList(null);
Vector<CaptureDeviceInfo> vetAux =new Vector<CaptureDeviceInfo>();
//Verifica se algum dos dispositivos retornado ?uma webCam.
//Cada webcam detectada ?adicionada a um Vector auxiliar.
if( vet !=null ){
for(int x = 0 ; x < vet.size() ; x++ ){
if( ( (CaptureDeviceInfo) vet.get(x) ).getName().startsWith("vfw:") )
vetAux.add( (CaptureDeviceInfo) vet.get(x));
}
}
//Inst鈔cia o vetor de informa玢o das c鈓eras, passando os objetos presentes no
//Vector auxiliar para um vetor interno do objeto.
camerasInfo =new CaptureDeviceInfo[ vetAux.size() ];
for(int x = 0 ; x < camerasInfo.length ; x++ ){
camerasInfo[x] = vetAux.get(x);
}
}
/**
* Inicializa o vetor de informa珲es das c鈓eras.
* O usu醨io ?instruido a digitar algumas informa珲es.
*/
privatevoid setMyCamerasAttributes(){
BufferedReader br =new BufferedReader(new InputStreamReader( System.in ) );
myCameras =new Camera[ camerasInfo.length ];
String local;
String desc;
for(int x = 0 ; x < myCameras.length ; x++ ){
System.out.println("Entre com as informa珲es para a c鈓era n?" + x + 1 +".");
try{
System.out.print("Local: ");
local = br.readLine();
System.out.print("Descri玢o: ");
desc = br.readLine();
myCameras[x] =new Camera( x , desc , local,null , this.id, camerasInfo[x] );
}catch( IOException ioE ){
System.out.println("Erro ao capturar dados do teclado...");
System.out.println( ioE );
}
}
}
public Camera[] getMyCameras(){
return myCameras;
}
publicvoid movimentoDetectado(Camera pCamera){
System.out.println("Movimento detectado na c鈓era " + pCamera.getId());
}
publicvoid ativaDetectorMovimento(Camera pCam,boolean pAtivo){
DetectorMovimento dm;
if( pAtivo ){
dm =new DetectorMovimento(this, myCameras[0] );
detectores.add(dm);
dm.setRunning(true);
dm.start();
try{
dm.join();
}catch (InterruptedException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
if(detectores.size() > 0){
dm = detectores.remove(0);
dm.stopDetect();
}else{
System.out.println("Nenhum detector de movimento ativado.");
}
}
}
publicstaticvoid main(String args[] ){
if (System.getSecurityManager() ==null){
System.setSecurityManager(new RMISecurityManager() );
}
try{
PCIntermediarioModule interPc =new PCIntermediarioModule();
interPc.startMenu();
}catch(RemoteException rE ){
System.out.println("PCIntermediarioModule - N鉶 foi poss韛el inst鈔ciar InterPc. ");
}
}
publicvoid startMenu(){
BufferedReader br =new BufferedReader(new InputStreamReader( System.in ) );
int opc = -1;
while( opc != 3 ){
printMenu();
try{
opc = Integer.parseInt(br.readLine());
switchFunc( opc );
}catch (IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
privatevoid switchFunc(int pOpc ){
switch( pOpc ){
case 1:
ativaDetectorMovimento(myCameras[0],true);
break;
case 2:
ativaDetectorMovimento(myCameras[0],false);
break;
case 3:
ativaDetectorMovimento(myCameras[0],false);
break;
default:
System.out.println("Op玢o inv醠ida.");
break;
}
}
privatevoid printMenu(){
clearScreen();
System.out.println("1 - Ativar detector de movimento.");
System.out.println("2 - Desativar detector de movimento.");
System.out.println("3 - Sair.");
System.out.print("Digite a op玢o desejada: ");
}
privatevoid clearScreen(){
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
}
}
Anyone knows what should be happen ?
Thanks..

