Search code examples
androidcffmpegjava-native-interfacefopen

where can i find the file and android write in JNI


I wirte a test demo for ffmpeg, read a flac file and decoder it to a new pcm file.

after done the work, i could not find the output file.

so I open the output file with a new FILE pointer, and open is ok, does anybody give any tips, thanks.

static int decode_packet(int *got_frame, int cached)
{
    int ret = 0;
    int decoded = pkt.size;

    *got_frame = 0;

    if (pkt.stream_index == audio_stream_idx) {
        /* decode audio frame */
        ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
        if (ret < 0) {
            LOG("Error decoding audio frame (%s)\n", av_err2str(ret));
            return ret;
        }

        decoded = FFMIN(ret, pkt.size);

        if (*got_frame) {
            LOG("frame->format: %d", frame->format);
            size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16/*frame->format*/);
            LOG("audio_frame%s n:%d nb_samples:%d pts:%s\n", cached ? "(cached)" : "", audio_frame_count++, frame->nb_samples,
                   av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));

            fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
        }
    }

    if (*got_frame && api_mode == API_MODE_NEW_API_REF_COUNT)
        av_frame_unref(frame);

    return decoded;
}

    // as convient i write the abspath `/storage/emulated/0` which i got by rountine Environment.getExternalStorageDirectory().getAbsolutePath()
    const char *src_filename = "/storage/emulated/0/pyghlkn.flac";
    const char *audio_dst_filename = "/storage/emulated/0/test.pcm";

    FILE *audio_dst_file = NULL;
    FILE *audio_dump = NULL;

    JNIEXPORT void JNICALL Java_cn_com_longmaster_ffmpeg_encoder
      (JNIEnv *, jobject)
      {
          //......
            /* read frames from the file */
            while (av_read_frame(fmt_ctx, &pkt) >= 0) {
                AVPacket orig_pkt = pkt;
                do {
                    ret = decode_packet(&got_frame, 0);
                    LOG("write decode_packet... pkt.size: %d ", pkt.size);
                    if (ret < 0)
                        break;
                    pkt.data += ret;
                    pkt.size -= ret;
                } while (pkt.size > 0);
                av_free_packet(&orig_pkt);
            }

            /* flush cached frames */
            pkt.data = NULL;
            pkt.size = 0;
            do {
                decode_packet(&got_frame, 1);
                LOG("flush cached frames");
            } while (got_frame);


            if (audio_dump)
            {
                LOG("default audio_dump ready...");
            }
            else
            {
                LOG("default audio_dump not ready...");
            }

            audio_dump = fopen(audio_dst_filename, "rb");
            if (audio_dump) {
                LOG("open pcm file ok...");
            } else {
                LOG("open pcm file fail...");
            }

            avcodec_close(audio_dec_ctx);
            avformat_close_input(&fmt_ctx);
            if (audio_dst_file) {
                fclose(audio_dst_file);
            }

            av_frame_free(&frame);

            return ;

      }

Solution

  • Instead of the hard coded path you should use File dirBase = Environment.getExternalStorageDirectory(); // Root directory of SD card in the java part of your app and pass it on to your C program. This path could be e.g. /storage/sdcard depending on the vendor of your andorid phone. Useing the function will always give you the correct path.