title: Audio playback using ffmpeg and audiotrack android
body: <p>I am trying to play mp3 audio in android using ffmpeg and audiotrack. But i'm getting only garbled audio output. Can anyone suggest where could be the problem ?. Here entire player runs in JNI code.
  All other ffmpeg and audio track initializations are also done before starting this thread.</p>
  
  <pre><code>void *decode_audio_thread(void *arg){
  AVPacket packet;
  AVFrame *decoded_frame;
  int index,i=0,ret;  
  bool isEOS = false;
  struct timeval tp;
  int startMs;
  JNIEnv* env = NULL;
  jlong timeout = 100000;
  int got_frame,len,data_size,size;
  uint8_t **src_data = NULL, **dst_data = NULL;
  int src_rate = 48000, dst_rate = 44100;
  int src_nb_channels = 0, dst_nb_channels = 0;
  int src_linesize, dst_linesize;
  int src_nb_samples = 1024, dst_nb_samples, max_dst_nb_samples;
  enum AVSampleFormat src_sample_fmt, dst_sample_fmt;
  int64_t src_ch_layout, dst_ch_layout;
  int dst_bufsize;
  
    (*myVm)-&gt;AttachCurrentThread(myVm, &amp;env, NULL);
  
    LOGV("Allocating avframe");
    decoded_frame = av_frame_alloc();
    if(decoded_frame)
      LOGV("Allocation done");
  
    av_init_packet(&amp;packet);
  
    while(stop){
  
      ret = av_read_frame(mDataSource, &amp;packet);
      if (ret &lt; 0) {
        LOGV("av_read_frame : returned %d ERROR_END_OF_STREAM=%d\n",ret);
        isEOS = true;
        break;
      }
      LOGV("av_read_frame (%d) size=%d index=%d mAudioIndex=%d\n",i++,packet.size,packet.stream_index,mAudioIndex);
  
      if(packet.stream_index == mAudioIndex) {
        //LOGV("Decoding Frame size=%d",packet.size);
  
        len = avcodec_decode_audio4(mAudioTrack,decoded_frame, &amp;got_frame,&amp;packet);
        if(len &lt; 0) {
        LOGV("Error frame skiping");
        continue;
        }
        LOGV("avcodec_decode_audio4 ret=%d got_fram=%d packet.size=%d  format decoded %d= configured %d",len,got_frame,packet.size,decoded_frame-&gt;format,AV_SAMPLE_FMT_S16);
        if(got_frame){
  
        data_size = av_samples_get_buffer_size(NULL,mAudioTrack-&gt;channels , decoded_frame-&gt;nb_samples,mAudioTrack-&gt;sample_fmt, 1);
        LOGV("av_samples_get_buffer_size data_size=%d decode_len=%d avpacket.len=%d ",data_size,len,packet.size);
  
        jbyteArray samples_byte_array;
  
        if(decoded_frame-&gt;format != AV_SAMPLE_FMT_S16) {
           src_nb_samples = decoded_frame-&gt;nb_samples;
           src_linesize = (int) decoded_frame-&gt;linesize;
           src_data = decoded_frame-&gt;data;
           if (decoded_frame-&gt;channel_layout == 0) {
             decoded_frame-&gt;channel_layout = av_get_default_channel_layout(decoded_frame-&gt;channels);
           }
           /* create resampler context */
           swr_ctx = swr_alloc();
           if (!swr_ctx) {
             LOGV("sw_ctx allocation failed");
             break;
           }
           src_rate = decoded_frame-&gt;sample_rate;
           dst_rate = decoded_frame-&gt;sample_rate;
           src_ch_layout = decoded_frame-&gt;channel_layout;
           dst_ch_layout = decoded_frame-&gt;channel_layout;
           av_opt_set_int(swr_ctx, "in_channel_layout", src_ch_layout, 0);
           av_opt_set_int(swr_ctx, "out_channel_layout", dst_ch_layout, 0);
           av_opt_set_int(swr_ctx, "in_sample_rate", src_rate, 0);
           av_opt_set_int(swr_ctx, "out_sample_rate", dst_rate, 0);
           src_sample_fmt = decoded_frame-&gt;format;
           dst_sample_fmt = AV_SAMPLE_FMT_S16;
           av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", decoded_frame-&gt;format, 0);
           av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
           LOGV("Swr_init : src_rate=%d dst_rate=%d src_ch_layout=%d dst_ch_layout=%d src_sample_fmt=%d %d dst_sample_fmt=%d %d",
            src_rate,dst_rate,src_ch_layout,dst_ch_layout,src_sample_fmt,decoded_frame-&gt;format,dst_sample_fmt,AV_SAMPLE_FMT_S16);
           /* initialize the resampling context */
           if ((ret = swr_init(swr_ctx)) &lt; 0) {
             LOGV("Failed to initialize the resampling context\n");
             break;
           }
           /* allocate source and destination samples buffers */
           src_nb_channels = av_get_channel_layout_nb_channels(src_ch_layout);
           ret = av_samples_alloc_array_and_samples(&amp;src_data, &amp;src_linesize, src_nb_channels,
                                src_nb_samples, src_sample_fmt, 0);
           if (ret &lt; 0) {
             LOGV("Could not allocate source samples\n");
             break;
           }
           /* compute the number of converted samples: buffering is avoided
            * ensuring that the output buffer will contain at least all the
            * converted input samples */
           max_dst_nb_samples = dst_nb_samples =
           av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
           /* buffer is going to be directly written to a rawaudio file, no alignment */
           dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
           ret = av_samples_alloc_array_and_samples(&amp;dst_data, &amp;dst_linesize, dst_nb_channels,
                                dst_nb_samples, dst_sample_fmt, 0);
           if (ret &lt; 0) {
             LOGV("Could not allocate destination samples\n");
             //goto end;
           }
           /* compute destination number of samples */
           dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
           src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
           /* convert to destination format */
           ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)decoded_frame-&gt;data, src_nb_samples);
           if (ret &lt; 0) {
             LOGV("Error while converting\n");
             break;
           }
           dst_bufsize = av_samples_get_buffer_size(&amp;dst_linesize, dst_nb_channels,
                                ret, dst_sample_fmt, 1);
           if (dst_bufsize &lt; 0) {
             LOGV("Could not get sample buffer size\n");
             //goto end;
           }
           //jbyteArray 
           samples_byte_array = (*env)-&gt;NewByteArray(env, dst_bufsize);
           if (samples_byte_array == NULL) {
          LOGV("Cannot Allocate byte array");
          break;
           }
           jbyte *jni_samples = (*env)-&gt;GetByteArrayElements(env, samples_byte_array, NULL);
           LOGV("Coping Data %d ",dst_bufsize);
           memcpy(jni_samples,dst_data[0], dst_bufsize);
           LOGV("Releasing jni_samples");
           (*env)-&gt;ReleaseByteArrayElements(env, samples_byte_array, jni_samples, 0);
           swr_free(&amp;swr_ctx);
  
        }  
        else  {
  
            //jbyteArray 
            samples_byte_array = (*env)-&gt;NewByteArray(env, data_size);
            if (samples_byte_array == NULL) {
          LOGV("Cannot Allocate byte array");
          break;
            }
            jbyte *jni_samples = (*env)-&gt;GetByteArrayElements(env, samples_byte_array, NULL);
            LOGV("Coping Data %d ",data_size);
            memcpy(jni_samples,decoded_frame-&gt;data[0], len);
            LOGV("Releasing jni_samples");
            (*env)-&gt;ReleaseByteArrayElements(env, samples_byte_array, jni_samples, 0);
  
        }
        //(*env)-&gt;SetByteArrayRegion(env, p_sys-&gt;jb_array[0], 0, data_size, audio_frame-&gt;data[0]);
  
        LOGV("Audio: AudioTrack.write size=%d\n",len);
        int ret = (*env)-&gt;CallIntMethod(env, p_sys-&gt;audio_track, p_sys-&gt;aud_write,samples_byte_array,0, len);
        if ((*env)-&gt;ExceptionOccurred(env)) {
            LOGV( "Exception in AudioTrack.write failed ret=%d",ret);
            (*env)-&gt;ExceptionClear(env);
            p_sys-&gt;error_state = true;
            goto error;
        }
        LOGV("Audio: ret=%d Done AudioTrack...Aud deleting localref\n",ret);
       (*env)-&gt;DeleteLocalRef(env, samples_byte_array);       
        }    
      }
      av_free_packet(&amp;packet);
    }
  error:  
    LOGV("Closing");
    avformat_close_input(&amp;mDataSource);
    avcodec_close(mAudioTrack);
    av_free(mDataSource);
    av_free(decoded_frame);
    LOGV("DetachCurrentThread\n");
    (*myVm)-&gt;DetachCurrentThread(myVm);
    return;
  }
  </code></pre>