2016-08-16 2 views
0

J'essaie de décoder h264 flux utiliser MediaCodec sur Android. J'utilise csd-0, csd-1 pour définir sps et pps comme ceci. Je configure le décodeur avec une surface de sortie pour restituer les données de sortie.memdiacodec décodeur travaillant sur Android 5.0 mais pas sur Android 4.4

decoder.configure(format, surface, null, 0); 

Ensuite, je commence juste un thread pour décoder les données que j'ai reçues du réseau en utilisant cette boucle.

while (running) { 
    if (!isEOS) { 
     int inIndex = decoder.dequeueInputBuffer(10000); 
     if (inIndex >= 0) { 
      ByteBuffer buffer = inputBuffers[inIndex]; 
      byte[] data = getVideoPacket(); // native method that get data from network 
      buffer.put(data); 

      decoder.queueInputBuffer(inIndex, 0, data.length, 0L, 0); 
     } 
    } 

    int outIndex = decoder.dequeueOutputBuffer(info, 10000); 
    switch (outIndex) { 
     case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: 
      Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED"); 
      outputBuffers = decoder.getOutputBuffers(); 
      break; 
     case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: 
      Log.d("DecodeActivity", "New format " + decoder.getOutputFormat()); 
      MediaFormat format = decoder.getOutputFormat(); 
      break; 
     case MediaCodec.INFO_TRY_AGAIN_LATER: 
      Log.d("DecodeActivity", "dequeueOutputBuffer timed out!"); 
      break; 
     default: 
      ByteBuffer buffer = outputBuffers[outIndex]; 
      Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer); 

      decoder.releaseOutputBuffer(outIndex, true); // render 
      break; 
    } 

    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { 
     Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM"); 
     break; 
    } 
} 

Notez que j'utilise 0 pour presentationTimestamp de queueInputBuffer puisque les données que j'ai obtenu est de la prise réseau, et je ne sais pas comment calculer l'horodatage approprié.

j'ai obtenu ce que je veux sur android 5.0 (et ci-dessus), mais quand je cours ce code sur android 4.4, rien n'apparaît sur la surface (en fait je peux voir parfois le même fragment d'image, mais la plupart du temps est juste noir).

J'ai essayé de remplir le tampon d'entrée avec les données récupérées à partir du fichier (utilisez MediaExtractor), et cela fonctionne bien sur android 5.0 et 4.4.

toute aide serait appréciée.

Répondre

0

il semble que le problème est la façon d'extraire des données. je l'ai utilisé pour get données de couche native:

public static native byte[] getVideoPacket(); 

et maintenant i push données de couche native à la couche java:

env->CallVoidMethod(..., data); 

tout simplement travailler maintenant. Je ne sais pas pourquoi, mais ça marche pour moi.