RESOLVIDO - java.lang.ClassCastException: [B cannot be cast

Java

17/03/2010

Olá Pessoal, alguém pode me dizer o que está acontecendo? Segue o código:
 void accessFrame(Buffer frame) {
         // For demo, we'll just print out the frame #, time &
         // data length.
          System.err.println("accessFrame do PreAccess");
         long t = (long) (frame.getTimeStamp() / 10000000f);

         System.err.println("Pre: frame #: " + frame.getSequenceNumber() + ", time: " + ((float) t) / 100f + ", len: " + frame.getLength());

            int buf[] =  (int[]) frame.getData();

		// Grayscaling
		for(int h = 0; h < 240; h++)
			for(int w = 0; w < 320; w++)
				{
					int ofs = h*320+w;
					int p = buf[ofs];
					int gval = (p&0xff) + ((p>>8)&0xff) + ((p>>16)&0xff);
					gval /= 3;
					buf[ofs] = (gval<<16) + (gval<<8) + gval;
				}

         




         
      }
Quando executo pelo NetBeans 6.8 me dá o seguinte erro: java.lang.ClassCastException: [B cannot be cast to [I at FrameAccess$PreAccessCodec.accessFrame(FrameAccess.java:213) at FrameAccess$PreAccessCodec.process(FrameAccess.java:289) Que se refere à linha: int buf[] = (int[]) frame.getData(); O estranho que o erro aparece em tempo de execução e não na compilação! Aguém pode dar um help? :roll:
Andre Menegussi

Andre Menegussi

Curtidas 0

Respostas

Diogo Souza

Diogo Souza

17/03/2010

Essa classe "Buffer" é referente ao pacote java.nio.Buffer, ou você mesmo criou uma?? :!:
GOSTEI 0
Andre Menegussi

Andre Menegussi

17/03/2010

Fala Metal! Na verdade este é um trecho do programa que acessa frames de video usando JMF, mas na verdade nos imports não faz referência a esta classe e dentro do prog a classe Buffer também não é definida! Estou meio perdido!! O código que estou tentando modificar pode ser visto em http://javafree.uol.com.br/topic-875601-JMF-Como-manipular-arquivos-mpeg.htm Valeu :roll:
GOSTEI 0
Diogo Souza

Diogo Souza

17/03/2010

Ok, não mecho com JMF, mas segue um link aqui do JF interessaante: http://javafree.uol.com.br/wiki/JMF E... então que classe Buffer é essa?! :!:
GOSTEI 0
Andre Menegussi

Andre Menegussi

17/03/2010

Então, achei! Pertence à javax.media.Buffer e extende de Object. Segue o link sobre a classe: http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/apidocs/javax/media/Buffer.html :shock:
GOSTEI 0
Carlos Heuberger

Carlos Heuberger

17/03/2010

A mensagem do erro é meio criptografada mas dá para entender. Diz que não é possível fazer um cast de "byte[]" para "int[]", ou seja, não tem como converter diretamente de um array de bytes para um de int. ("[B" é o nome da classe que representa "byte[]", "[I" para "int[]") É possível, alias até desnecessário, fazer um cast de "byte" para "int", mas não de um tipo de array para outro (só se fizer elemento por elemento). O problema deve ser nesse techo "(int[]) frame.getData();", portanto imagino que o "getData()" retorna um array de bytes.... tenta assim
...
            byte buf[] = frame.getData();
...
[]] [quote="Andre Menegussi"]Olá Pessoal, alguém pode me dizer o que está acontecendo? Segue o código:
 void accessFrame(Buffer frame) {
         // For demo, we'll just print out the frame #, time &
         // data length.
          System.err.println("accessFrame do PreAccess");
         long t = (long) (frame.getTimeStamp() / 10000000f);

         System.err.println("Pre: frame #: " + frame.getSequenceNumber() + ", time: " + ((float) t) / 100f + ", len: " + frame.getLength());

            int buf[] =  (int[]) frame.getData();

		// Grayscaling
		for(int h = 0; h < 240; h++)
			for(int w = 0; w < 320; w++)
				{
					int ofs = h*320+w;
					int p = buf[ofs];
					int gval = (p&0xff) + ((p>>8)&0xff) + ((p>>16)&0xff);
					gval /= 3;
					buf[ofs] = (gval<<16) + (gval<<8) + gval;
				}

         




         
      }
Quando executo pelo NetBeans 6.8 me dá o seguinte erro: java.lang.ClassCastException: [B cannot be cast to [I at FrameAccess$PreAccessCodec.accessFrame(FrameAccess.java:213) at FrameAccess$PreAccessCodec.process(FrameAccess.java:289) Que se refere à linha: int buf[] = (int[]) frame.getData(); O estranho que o erro aparece em tempo de execução e não na compilação! Aguém pode dar um help? :roll:
GOSTEI 0
Andre Menegussi

Andre Menegussi

17/03/2010

Então simu, A classe Buffer extende de um Object. Fazendo o teste de instanceof, percebe-se que é um byte[]. Como este código-exemplo é um trecho de aplicação de um filtro de grayscale em frames de video, ele faz o cast para manipulá-lo como int[]. Fazendo como vc sugeriu, o Netbeans marca como erro e pede pra colocar o byte[] na frente de buffer.getdata(). Se vc tiver algum exemplo de manipulação de frames usando JMF eu agradeceria muito. Como sou iniciante em JAVA acho que complica mais ainda! Abc. :roll:
GOSTEI 0
Carlos Heuberger

Carlos Heuberger

17/03/2010

então faz como o Netbeans escreveu:
byte[] buf = (byte[]) frame.getData();
Não conheço nenhum exemplo, não uso nem conheço o JMF... [quote="Andre Menegussi"]Então simu, A classe Buffer extende de um Object. Fazendo o teste de instanceof, percebe-se que é um byte[]. Como este código-exemplo é um trecho de aplicação de um filtro de grayscale em frames de video, ele faz o cast para manipulá-lo como int[]. Fazendo como vc sugeriu, o Netbeans marca como erro e pede pra colocar o byte[] na frente de buffer.getdata(). Se vc tiver algum exemplo de manipulação de frames usando JMF eu agradeceria muito. Como sou iniciante em JAVA acho que complica mais ainda! Abc. :roll:
GOSTEI 0
Andre Menegussi

Andre Menegussi

17/03/2010

Ok simu, Aí não dá erro mas o resto do código não roda pq faz referência ao buffer como int[]. Acho que terei que verificar um passo anterior. Como o buffer extende um objeto, acredito que tenha como definir o tipo do objeto na outra classe que o exemplo não mostra! De qualquer maneira obrigado. Abc :(
GOSTEI 0
André Silva

André Silva

17/03/2010

Cara não vejo sentido em usar um STREAM que é em bytes como integer, não vejo mesmo sentido... afinal de contas para operar em um stream vc sempre utilizará bytes, mesmo no InputStream ou OutputStream...
GOSTEI 0
Andre Menegussi

Andre Menegussi

17/03/2010

[quote="Maveco"]Cara não vejo sentido em usar um STREAM que é em bytes como integer, não vejo mesmo sentido... afinal de contas para operar em um stream vc sempre utilizará bytes, mesmo no InputStream ou OutputStream...
Então, o trecho que segue:
      int buf[] =  (int[]) frame.getData();   
  
      // Grayscaling   
      for(int h = 0; h < 240; h++)   
         for(int w = 0; w < 320; w++)   
            {   
               int ofs = h*320+w;   
               int p = buf[ofs];   
               int gval = (p&0xff) + ((p>>8)&0xff) + ((p>>16)&0xff);   
               gval /= 3;   
               buf[ofs] = (gval<<16) + (gval<<8) + gval;   
            }   
  
      }  
é de um exemplo de um filtro que transforma o frame em escala de cinza e o mesmo funciona no prgrama de exemplo que baixei. Como tb ainda não entendo muito bem, acredito que ele transformou em int[] para trabalhar de 4 em 4 bytes, no caso para montar a componente RGB de cada pixel. Pelo menos é a única idéia que imagino! Se vc tiver algum exemplo de manipulação de frame pra dar uma idéia eu te agradeço! Abc :roll:
GOSTEI 0
André Silva

André Silva

17/03/2010

Cara, as vezes é o jar desatualizado. Mas isso se vc estiver usando uma biblioteca para fazer essas coisas... Exemplo eu não tenho nenhum :\
GOSTEI 0
Carlos Heuberger

Carlos Heuberger

17/03/2010

acho que o problema é como os dados estão sendo codificados. Pode ter um método para indicar essa codificação ou a codificação dependo do formato da média que está sendo processada. Pela documentação tem que usar o "instanceof" para determinar a classe do resultado do getData. O getFormat tambem pode ser interessante... []]
GOSTEI 0
Andre Menegussi

Andre Menegussi

17/03/2010

[quote="simu"]acho que o problema é como os dados estão sendo codificados. Pode ter um método para indicar essa codificação ou a codificação dependo do formato da média que está sendo processada. Pela documentação tem que usar o "instanceof" para determinar a classe do resultado do getData. O getFormat tambem pode ser interessante... []]
Pois é, acho que é algo definido no formato também. Algo como este trecho de código de efeito de rotação do Frame:
 inputFormats = new Format[] {
            new RGBFormat(null,
                          Format.NOT_SPECIFIED,
                          Format.byteArray, // já encontrei alguns como intArray
                          Format.NOT_SPECIFIED,
                          24,
                          3, 2, 1,
                          3, Format.NOT_SPECIFIED,
                          Format.TRUE,
                          Format.NOT_SPECIFIED)
        };

        outputFormats = new Format[] {
            new RGBFormat(null,
                          Format.NOT_SPECIFIED,
                          Format.byteArray, // já encontrei alguns como intArray
                          Format.NOT_SPECIFIED,
                          24,
                          3, 2, 1,
                          3, Format.NOT_SPECIFIED,
                          Format.TRUE,
                          Format.NOT_SPECIFIED)
        };
Vou continuar pesquisando.... Sds :smile:
GOSTEI 0
Andre Menegussi

Andre Menegussi

17/03/2010

Então pessoal, conseguí fazer a coisa funcionar. Realmente o que precisava era configurar o formato de entrada, conforme um dos parâmetros da interface CODEC, passando o tipo de array, no caso o intArray, como segue:
        protected int rMask = 0x000000FF;
	protected int gMask = 0x0000FF00;
	protected int bMask = 0x00FF0000;
   //   protected Format supportedIns[]  = new Format[] { new VideoFormat(null) };
        protected Format supportedIns[] = new Format [] {
		new RGBFormat(null,                    // size
			      Format.NOT_SPECIFIED,    // maxDataLength
			      Format.intArray ,        // buffer type !!! aqui!!!!
			      Format.NOT_SPECIFIED,    // frame rate
			      32,                      // bitsPerPixel
			      rMask,                   // red component mask
			      gMask,                   // green component mask
			      bMask,                   // blue component mask
			      1,                       // pixel stride
			      Format.NOT_SPECIFIED,    // line stride
			      Format.TRUE,            // flipped
			      Format.NOT_SPECIFIED) }; // endian

Deste modo, quando o método process da interface do CODEC é acionada, disponibilizando o buffer com o frame, o mesmo vem no format o int[] e o código abaixo funciona:
void accessFrame(Buffer frame) {   
         // For demo, we'll just print out the frame #, time &   
         // data length.   
          System.err.println("accessFrame do PreAccess");   
         long t = (long) (frame.getTimeStamp() / 10000000f);   
  
         System.err.println("Pre: frame #: " + frame.getSequenceNumber() + ", time: " + ((float) t) / 100f + ", len: " + frame.getLength());   
  
            int buf[] =  (int[]) frame.getData();   
  
      // Grayscaling   
      for(int h = 0; h < height; h++)   
         for(int w = 0; w < width; w++)   
            {   
               int ofs = h*width+w;   
               int p = buf[ofs];   
               int gval = (p&0xff) + ((p>>8)&0xff) + ((p>>16)&0xff);   
               gval /= 3;   
               buf[ofs] = (gval<<16) + (gval<<8) + gval;   
            }   
            
      }  
Valeu a ajuda galera ! Espero que isso ajude alguém! Abc :idea: André Menegussi
GOSTEI 0
POSTAR