2014-07-23 1 views
0

J'essaie d'ouvrir un objet IContainer qui lit à partir d'un tampon d'entrée personnalisé plutôt que de lire à partir d'un fichier multimédia. L'implémentation de ce tampon d'entrée personnalisé est la suivante.IContainer.open() échoue lors de l'utilisation avec ByteChannel personnalisé à lire

Le code pour créer et ouvrir le conteneur est le suivant.

// Open up the container for READING 
mInputCStore = new CStore(); 

IContainerFormat format = IContainerFormat.make(); 
if (format.setInputFormat("flv") < 0) { 
    throw new IllegalArgumentException("Failed to initialize the input format"); 
} 

// Open up the container 
mInputContainer = IContainer.make(); 
int retval = mInputContainer.open(mPlaybackContainerStore, IContainer.Type.READ, format);  
if (retval < 0) { 
    // This little trick converts the non friendly integer return value into 
    // a slightly more friendly object to get a human-readable error name 
    IError error = IError.make(retval); 
    throw new IllegalArgumentException("could not open input container: " + mPlaybackContainerStore + "; Error: " + error.getDescription()); 
} 

Le code ci-dessus lancer une exception en disant que -

Exception in thread "main" java.lang.IllegalArgumentException: could not open input container: [email protected]; Error: Operation not permitted 

Le même tampon personnalisé lors utilisé lors de l'écriture au conteneur travaille avec succès. Quelqu'un peut-il m'aider à comprendre ce qui manque dans l'implémentation du tampon personnalisé, aussi loin que l'utiliser en mode READ et pourquoi la raison de l'échec?

package test; 

import java.io.IOException; 
import java.nio.ByteBuffer; 
import java.nio.channels.ByteChannel; 
import java.util.concurrent.ConcurrentLinkedQueue; 

public class CStore implements ByteChannel { 
    private ConcurrentLinkedQueue<DataChunk> mChunkQueue = null; 
    private int mQueueSize = 0; 

    // constructor 
    public CStore(String type) { 
     mQueueSize = 0; 
     mChunkQueue = new ConcurrentLinkedQueue<DataChunk>(); 
     mChunkQueue.clear(); 
    } 

    @Override 
    public void close() throws IOException { 
     return; 
    } 

    @Override 
    public boolean isOpen() { 
     return false; 
    } 

    @Override 
    public int write(ByteBuffer buffer) throws IOException { 
     DataChunk chunk = new DataChunk(buffer); 
     mChunkQueue.add(chunk); 
     mQueueSize += chunk.getLength(); 
     return 0; 
    } 

    public int read(ByteBuffer buffer) throws IOException { 

     int result = 0; 

     DataChunk chunk = mChunkQueue.poll(); 
     if (chunk != null) { 
      buffer = chunk.getBuffer(); 
      if (buffer != null) { 
       result = 0; 
      } else { 
       result = 1; 
      } 
     } 

     return result; 
    } 
} 
+0

Est-ce que quelqu'un peut m'aider à résoudre ce problème? Cette approche est-elle correcte? – AnilJ

Répondre

0

J'ai résolu ce problème en réimplémentant la méthode read() comme ci-dessous.

public int read(ByteBuffer buffer) { 
    int bytesRead = 0; 

    if (buffer == null) 
     return 0; 

    while (buffer.hasRemaining()) { 
     byte b = mBuff.get(); 
     buffer.put(b); 
     bytesRead++; 
    } 

    return bytesRead; 
} 

Notez que avant d'appeler cette fonction, je suis en train de convertir le mChunkQueue en ByteBuffer mBuff. Il y a toujours une marge pour nettoyer cette classe/implémentation. Mais c'est résolu pour le moment.

0

J'ai ouvert un IContainer pour lire des implémentations personnalisées d'InputStream. Pour ce faire, vous devez définir manuellement les informations normalement détectées automatiquement lors de la lecture d'un fichier (c'est-à-dire: format d'entrée, codec, détails du codec).

// Example input stream (raw audio encoded with mulaw). 
InputStream input = new FileInputStream("/tmp/test.ul"); 

// Manually set the input format. 
IContainerFormat inputFormat = IContainerFormat.make(); 
inputFormat.setInputFormat("mulaw"); 

// Open the container. 
IContainer container = IContainer.make(); 
container.open(input, inputFormat); 

// Initialize the decoder. 
IStreamCoder coder = container.getStream(0).getStreamCoder(); 
coder.setSampleRate(8000); 
coder.setChannels(1); 
coder.open(null, null); 

Vous êtes maintenant en mesure de lire à partir du conteneur comme vous le feriez normalement [i.e. .: container.readNextPacket (paquet)].

+0

J'ai déjà ce flux d'entrée basé sur un fichier, où je peux lire les données. Ce que j'essaie de faire est ceci - Considérons un cas de streaming vidéo en temps réel, par exemple. appel vidéo où vous n'avez pas encore ce flux de données. J'essaye d'initialiser le IContainer pour décoder ceci pour arriver flux visuel dans mon code. Je présume que c'est valide et correct. C'est la raison pour laquelle je fournis l'objet CStore (qui implémente ByteChannel) en tant que premier argument de la méthode container.open(). À ce stade mon code échoue. Je prévois alors d'écrire sur le canal byte car je reçois un flux vidéo en temps réel. – AnilJ

+0

Je suis désolé, mais je n'ai jamais utilisé un canal d'octets. Je suppose, cependant, que vous aurez besoin de définir votre format d'entrée avant d'ouvrir le conteneur. – 11101101b

+0

salut, quelqu'un a déjà essayé cela? toute idée ou solution aidera grandement dans cette situation. – AnilJ

Questions connexes