提交 63f2ae28 编写于 作者: R raymondzheng

ijkplayer: android support soundtouch

上级 c41d9db4
......@@ -8,6 +8,7 @@ ios/openssl-*
extra
.DS_Store
ijkmedia/ijkyuv/
ijkmedia/ijksoundtouch
ijkprof/android-ndk-profiler/
# built application files
......
......@@ -246,6 +246,7 @@ ijkplayer required features are based on or derives from projects below:
- [FFmpeg](http://git.videolan.org/?p=ffmpeg.git)
- [libVLC](http://git.videolan.org/?p=vlc.git)
- [kxmovie](https://github.com/kolyvan/kxmovie)
- [soundtouch](http://www.surina.net/soundtouch/sourcecode.html)
- zlib license
- [SDL](http://www.libsdl.org)
- BSD-style license
......
......@@ -185,6 +185,7 @@ public final class IjkMediaPlayer extends AbstractMediaPlayer {
libLoader.loadLibrary("ijkffmpeg");
libLoader.loadLibrary("ijksdl");
libLoader.loadLibrary("ijksoundtouch");
libLoader.loadLibrary("ijkplayer");
mIsLibLoaded = true;
}
......
......@@ -74,7 +74,7 @@ LOCAL_SRC_FILES += ijkavutil/ijktree.c
LOCAL_SRC_FILES += ijkavutil/ijkfifo.c
LOCAL_SRC_FILES += ijkavutil/ijkstl.cpp
LOCAL_SHARED_LIBRARIES := ijkffmpeg ijksdl
LOCAL_SHARED_LIBRARIES := ijkffmpeg ijksdl ijksoundtouch
LOCAL_STATIC_LIBRARIES := android-ndk-profiler
LOCAL_MODULE := ijkplayer
......
......@@ -70,6 +70,9 @@
#include "ijkmeta.h"
#include "ijkversion.h"
#include <stdatomic.h>
#if defined(__ANDROID__)
#include "ijksoundtouch/ijksoundtouch_wrap.h"
#endif
#ifndef AV_CODEC_FLAG2_FAST
#define AV_CODEC_FLAG2_FAST CODEC_FLAG2_FAST
......@@ -817,6 +820,12 @@ static void stream_close(FFPlayer *ffp)
#ifdef FFP_MERGE
sws_freeContext(is->sub_convert_ctx);
#endif
#if defined(__ANDROID__)
if (ffp->soundtouch_enable && is->handle != NULL) {
ijk_soundtouch_destroy(is->handle);
}
#endif
av_free(is->filename);
av_free(is);
ffp->is = NULL;
......@@ -2086,6 +2095,7 @@ static int audio_decode_frame(FFPlayer *ffp)
av_unused double audio_clock0;
int wanted_nb_samples;
Frame *af;
int translate_time = 1;
if (is->paused || is->step)
return -1;
......@@ -2104,7 +2114,7 @@ static int audio_decode_frame(FFPlayer *ffp)
return -1;
}
}
reload:
do {
#if defined(_WIN32) || defined(__APPLE__)
while (frame_queue_nb_remaining(&is->sampq) == 0) {
......@@ -2182,6 +2192,7 @@ static int audio_decode_frame(FFPlayer *ffp)
}
}
av_fast_malloc(&is->audio_buf1, &is->audio_buf1_size, out_size);
if (!is->audio_buf1)
return AVERROR(ENOMEM);
len2 = swr_convert(is->swr_ctx, out, out_count, in, af->frame->nb_samples);
......@@ -2195,7 +2206,27 @@ static int audio_decode_frame(FFPlayer *ffp)
swr_free(&is->swr_ctx);
}
is->audio_buf = is->audio_buf1;
resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
int bytes_per_sample = av_get_bytes_per_sample(is->audio_tgt.fmt);
resampled_data_size = len2 * is->audio_tgt.channels * bytes_per_sample;
#if defined(__ANDROID__)
if (ffp->soundtouch_enable && ffp->pf_playback_rate != 1.0f) {
av_fast_malloc(&is->audio_new_buf, &is->audio_new_buf_size, out_size * translate_time);
for (int i = 0; i < (resampled_data_size / 2); i++)
{
is->audio_new_buf[i] = (is->audio_buf1[i * 2] | (is->audio_buf1[i * 2 + 1] << 8));
}
int ret_len = ijk_soundtouch_translate(is->handle, is->audio_new_buf, (float)(ffp->pf_playback_rate), (float)(1.0f/ffp->pf_playback_rate),
resampled_data_size / 2, bytes_per_sample, is->audio_tgt.channels, af->frame->sample_rate);
if (ret_len > 0) {
is->audio_buf = (uint8_t*)is->audio_new_buf;
resampled_data_size = ret_len;
} else {
translate_time++;
goto reload;
}
}
#endif
} else {
is->audio_buf = af->frame->data[0];
resampled_data_size = data_size;
......@@ -2244,7 +2275,13 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
if (ffp->pf_playback_rate_changed) {
ffp->pf_playback_rate_changed = 0;
#if defined(__ANDROID__)
if (!ffp->soundtouch_enable) {
SDL_AoutSetPlaybackRate(ffp->aout, ffp->pf_playback_rate);
}
#else
SDL_AoutSetPlaybackRate(ffp->aout, ffp->pf_playback_rate);
#endif
}
if (ffp->pf_playback_volume_changed) {
ffp->pf_playback_volume_changed = 0;
......@@ -3157,7 +3194,11 @@ static VideoState *stream_open(FFPlayer *ffp, const char *filename, AVInputForma
is->iformat = iformat;
is->ytop = 0;
is->xleft = 0;
#if defined(__ANDROID__)
if (ffp->soundtouch_enable) {
is->handle = ijk_soundtouch_create();
}
#endif
/* start video display */
if (frame_queue_init(&is->pictq, &is->videoq, ffp->pictq_size, 1) < 0)
goto fail;
......
......@@ -287,7 +287,7 @@ typedef struct VideoState {
int audio_stream;
int av_sync_type;
void *handle;
double audio_clock;
int audio_clock_serial;
double audio_diff_cum; /* used for AV difference average computation */
......@@ -299,8 +299,10 @@ typedef struct VideoState {
int audio_hw_buf_size;
uint8_t *audio_buf;
uint8_t *audio_buf1;
short *audio_new_buf; /* for soundtouch buf */
unsigned int audio_buf_size; /* in bytes */
unsigned int audio_buf1_size;
unsigned int audio_new_buf_size;
int audio_buf_index; /* in bytes */
int audio_write_buf_size;
int audio_volume;
......@@ -646,6 +648,7 @@ typedef struct FFPlayer {
int mediacodec_auto_rotate;
int opensles;
int soundtouch_enable;
char *iformat_name;
......@@ -774,6 +777,7 @@ inline static void ffp_reset_internal(FFPlayer *ffp)
ffp->mediacodec_auto_rotate = 0; // option
ffp->opensles = 0; // option
ffp->soundtouch_enable = 0; // option
ffp->iformat_name = NULL; // option
......
......@@ -181,6 +181,8 @@ static const AVOption ffp_context_options[] = {
OPTION_OFFSET(mediacodec_handle_resolution_change), OPTION_INT(0, 0, 1) },
{ "opensles", "OpenSL ES: enable",
OPTION_OFFSET(opensles), OPTION_INT(0, 0, 1) },
{ "soundtouch", "SoundTouch: enable",
OPTION_OFFSET(soundtouch_enable), OPTION_INT(0, 0, 1) },
{ NULL }
};
......
#! /usr/bin/env bash
#
# Copyright (C) 2013-2015 Bilibili
# Copyright (C) 2013-2015 Zhang Rui <bbcallen@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
IJK_SOUNDTOUCH_UPSTREAM=https://github.com/Bilibili/soundtouch.git
IJK_SOUNDTOUCH_FORK=https://github.com/Bilibili/soundtouch.git
IJK_SOUNDTOUCH_COMMIT=ijk-r0.1.0-dev
IJK_SOUNDTOUCH_LOCAL_REPO=extra/soundtouch
set -e
TOOLS=tools
echo "== pull soundtouch base =="
sh $TOOLS/pull-repo-base.sh $IJK_SOUNDTOUCH_UPSTREAM $IJK_SOUNDTOUCH_LOCAL_REPO
echo "== pull soundtouch fork =="
sh $TOOLS/pull-repo-ref.sh $IJK_SOUNDTOUCH_FORK ijkmedia/ijksoundtouch ${IJK_SOUNDTOUCH_LOCAL_REPO}
cd ijkmedia/ijksoundtouch
git checkout ${IJK_SOUNDTOUCH_COMMIT}
cd -
......@@ -47,3 +47,4 @@ pull_fork "x86_64"
./init-config.sh
./init-android-libyuv.sh
./init-android-soundtouch.sh
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册