ffmpeg에서 동영상을 디코딩 후 자바 단으로 데이터를 넘겨주어 음원을 플레이시켜주고 싶은데 생각보다 잘 안되네요.

 

 public class AudioPlayerActivity extends Activity 
{ 
    private AudioTrack track; 
    private FileOutputStream os; 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.main); 
        
        createEngine(); 
        
 
        int bufSize = AudioTrack.getMinBufferSize(44100, 
                                                  AudioFormat.CHANNEL_OUT_MONO,  
                                                  AudioFormat.ENCODING_PCM_16BIT); 
 
        Log.d("test", "aaaaaaaaaaaaaaaaaaaaa "+bufSize);
        track = new AudioTrack(AudioManager.STREAM_MUSIC,  
                               44100,  
                               AudioFormat.CHANNEL_OUT_MONO,  
                               AudioFormat.ENCODING_PCM_16BIT,  
                               bufSize, 
                               AudioTrack.MODE_STREAM); 
 
        byte[] bytes = new byte[bufSize*2]; 
        
        try { 
            os = new FileOutputStream("/mnt/sdcard/test.out",false); 
        } catch (FileNotFoundException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
        
        //loadFile("/mnt/sdcard/test.mp3", bytes);
       // String file = "/mnt/sdcard/Wildlife.wmv";
        String file = "/mnt/sdcard/VIDEO0002.3gp";
        loadFile(file, bytes);
        
        try { 
            os.close(); 
        } catch (IOException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
        
    } 
 
    void playSound(byte[] buf, int size) {   
      
        if(track.getPlayState()!=AudioTrack.PLAYSTATE_PLAYING) {   
         
         track.play();
         
        }
        Log.d("test", "aaaaaaaaaaaaaaaaaaaaa");
        track.write(buf, 0, size);
        Log.d("test", "aaaaaaaaaaaaaaaaaaaaa");
        try { 
            os.write(buf,0,size); 
        } catch (IOException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
    } 
 
 
    private native void createEngine(); 
    private native int loadFile(String file, byte[] array); 
 
    /** Load jni .so on initialization*/  
    static { 
     System.loadLibrary("audioplayer");
    } 
} 


자바 쪽 소스 코드입니다.

 

 

 jint Java_team_tj_audio_AudioPlayerActivity_loadFile(JNIEnv* env, jobject obj, jstring file, jbyteArray array)
{
 AVFormatContext *gFormatCtx = NULL;
 AVCodecContext *gAudioCodecCtx = NULL;
 AVCodec *gAudioCodec = NULL;
 int gAudioStreamIdx = -1;
 char *gAudioBuffer = NULL;
 int i, outsize = 0;
 AVPacket packet;
 const char *str;
 str = (*env)->GetStringUTFChars(env, file, NULL);
 jclass cls = (*env)->GetObjectClass(env, obj);
 jmethodID play = (*env)->GetMethodID(env, cls, "playSound", "([BI)V");
 if (gFormatCtx != NULL)
  return -1;
 if (av_open_input_file(&gFormatCtx, str, NULL, 0, NULL) != 0)
  return -2;
 if (av_find_stream_info(gFormatCtx) < 0)
  return -3;
 for (i = 0; i < gFormatCtx->nb_streams; i++) {
  if (gFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
   gAudioStreamIdx = i;
   break;
  }
 }
 if (gAudioStreamIdx == -1)
  return -4;
 gAudioCodecCtx = gFormatCtx->streams[gAudioStreamIdx]->codec;
 gAudioCodec = avcodec_find_decoder(gAudioCodecCtx->codec_id);
 if (gAudioCodec == NULL)
  return -5;
 if (avcodec_open(gAudioCodecCtx, gAudioCodec) < 0)
  return -6;
 gAudioBuffer =  (char *) av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * 2);
 int decode = 0;
 while (av_read_frame(gFormatCtx, &packet) >= 0) {
  if (gFormatCtx-> streams[packet.stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
  {
   int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
      int size=packet.size;
      while(size > 0)
      {
       int len = avcodec_decode_audio3(gAudioCodecCtx,
         (int16_t *) gAudioBuffer, &data_size, &packet);
          if (data_size > 0) {
           jbyte *bytes = (*env)->GetByteArrayElements(env, array, NULL);
              memcpy(bytes + decode, (int16_t *)gAudioBuffer, size);
              (*env)->ReleaseByteArrayElements(env, array, bytes, 0);
              (*env)->CallVoidMethod(env, obj, play, array, data_size);
              size -= len;
              decode += len;
          }
      }
  }
  av_free_packet(&packet);
 }
 av_close_input_file(gFormatCtx);
 return 0;
}

 

native 쪽 소스 코드입니다.

 

어느 부분이 잘못 되었는지 알려주시면 감사하겠습니다.