Skip to content

Commit

Permalink
add audio_decoder to separate class
Browse files Browse the repository at this point in the history
  • Loading branch information
havlenapetr committed Jul 30, 2010
1 parent 3910e7f commit 53ff5b7
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 30 deletions.
5 changes: 3 additions & 2 deletions jni/libmediaplayer/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ LOCAL_C_INCLUDES += \

LOCAL_SRC_FILES += \
mediaplayer.cpp \
packetqueue.cpp
packetqueue.cpp \
decoder_audio.cpp

LOCAL_LDLIBS := -llog

Expand All @@ -19,4 +20,4 @@ LOCAL_STATIC_LIBRARIES := libavcodec libavformat libavutil libpostproc libswscal

LOCAL_MODULE := libmediaplayer

include $(BUILD_STATIC_LIBRARY)
include $(BUILD_STATIC_LIBRARY)
123 changes: 123 additions & 0 deletions jni/libmediaplayer/decoder_audio.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#include <android/log.h>
#include "decoder_audio.h"

// map system drivers methods
#include <drivers_map.h>

extern "C" {

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"

} // end of extern C

#define TAG "FFMpegAudioDecoder"

static DecoderAudio* sInstance;

DecoderAudio::DecoderAudio(PacketQueue* queue,
AVCodecContext* codec_ctx,
struct DecoderAudioConfig* config)
{
mQueue = queue;
mCodecCtx = codec_ctx;
mConfig = config;
sInstance = this;
}

DecoderAudio::~DecoderAudio()
{
if(mDecoding)
{
stop();
}
}

bool DecoderAudio::start(const char* err)
{
if(!prepare(err))
{
return false;
}

pthread_create(&mThread, NULL, startDecoding, NULL);
return true;
}

void DecoderAudio::stop()
{
mQueue->abort();
__android_log_print(ANDROID_LOG_INFO, TAG, "waiting on end of audio decoder");
int ret = -1;
if((ret = pthread_join(mThread, NULL)) != 0) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "Couldn't cancel audio decoder: %i", ret);
return;
}
__android_log_print(ANDROID_LOG_INFO, TAG, "audio decoder stopped");
}

void* DecoderAudio::startDecoding(void* ptr)
{
__android_log_print(ANDROID_LOG_INFO, TAG, "starting audio thread");
sInstance->decode(ptr);
}

bool DecoderAudio::prepare(const char *err)
{
mSamplesSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
mSamples = (int16_t *) av_malloc(mSamplesSize);

if(AudioDriver_set(mConfig->streamType,
mConfig->sampleRate,
mConfig->format,
mConfig->channels) != ANDROID_AUDIOTRACK_RESULT_SUCCESS) {
err = "Couldnt' set audio track";
return false;
}
if(AudioDriver_start() != ANDROID_AUDIOTRACK_RESULT_SUCCESS) {
err = "Couldnt' start audio track";
return false;
}
return true;
}

bool DecoderAudio::process(AVPacket *packet)
{
int size = mSamplesSize;
int len = avcodec_decode_audio3(mCodecCtx, mSamples, &size, packet);
if(AudioDriver_write(mSamples, size) <= 0) {
return false;
}
return true;
}

void DecoderAudio::decode(void* ptr)
{
AVPacket pPacket;

__android_log_print(ANDROID_LOG_INFO, TAG, "decoding audio");

mDecoding = true;
while(mDecoding)
{
if(mQueue->get(&pPacket, true) < 0)
{
mDecoding = false;
continue;
}
if(!process(&pPacket))
{
mDecoding = false;
continue;
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&pPacket);
}

__android_log_print(ANDROID_LOG_INFO, TAG, "decoding audio ended");

AudioDriver_unregister();

// Free audio samples buffer
av_free(mSamples);
}
43 changes: 43 additions & 0 deletions jni/libmediaplayer/decoder_audio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef FFMPEG_DECODER_AUDIO_H
#define FFMPEG_DECODER_AUDIO_H

#include <pthread.h>

#include "packetqueue.h"

struct DecoderAudioConfig
{
int streamType;
int sampleRate;
int format;
int channels;
};

class DecoderAudio
{
public:
DecoderAudio(PacketQueue* queue,
AVCodecContext* codec_ctx,
struct DecoderAudioConfig* config);

~DecoderAudio();

bool start(const char* err);
void stop();

private:
PacketQueue* mQueue;
AVCodecContext* mCodecCtx;
struct DecoderAudioConfig* mConfig;
bool mDecoding;
pthread_t mThread;
int16_t* mSamples;
int mSamplesSize;

bool prepare(const char *err);
void decode(void* ptr);
bool process(AVPacket *packet);
static void* startDecoding(void* ptr);
};

#endif //FFMPEG_DECODER_AUDIO_H
54 changes: 28 additions & 26 deletions jni/libmediaplayer/mediaplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,43 +290,45 @@ bool MediaPlayer::shouldCancel(PacketQueue* queue)
&& queue->size() == 0));
}


/*
timeval pTime;
int frames = 0;
double t1 = -1;
double t2 = -1;
gettimeofday(&pTime, NULL);
t2=pTime.tv_sec+(pTime.tv_usec/1000000.0);
if(t1 == -1 || t2 > t1 + 1)
{
__android_log_print(ANDROID_LOG_ERROR, TAG, "Video frame rate: %ifps", frames);
t1=t2;
frames = 0;
}
frames++;
*/
void MediaPlayer::decodeVideo(void* ptr)
{
AVPacket pPacket;
AVFrame* pFrameRGB;
timeval pTime;
int frames = 0;
double t1 = -1;
double t2 = -1;
bool run = true;
bool run = true;

if((pFrameRGB = createAndroidFrame()) == NULL) {
mCurrentState = MEDIA_PLAYER_STATE_ERROR;
}

__android_log_print(ANDROID_LOG_INFO, TAG, "decoding video");
__android_log_print(ANDROID_LOG_INFO, TAG, "decoding video");

while (run)
{
/*
gettimeofday(&pTime, NULL);
t2=pTime.tv_sec+(pTime.tv_usec/1000000.0);
if(t1 == -1 || t2 > t1 + 1)
{
__android_log_print(ANDROID_LOG_ERROR, TAG, "Video frame rate: %ifps", frames);
t1=t2;
frames = 0;
}
frames++;
*/
if(mCurrentState == MEDIA_PLAYER_PAUSED) {
usleep(50);
continue;
}
if (shouldCancel(mVideoQueue)) {
run = false;
continue;
}
if(mCurrentState == MEDIA_PLAYER_PAUSED) {
usleep(50);
continue;
}
if (shouldCancel(mVideoQueue)) {
run = false;
continue;
}
if(mVideoQueue->get(&pPacket, true) < 0)
{
mCurrentState = MEDIA_PLAYER_STATE_ERROR;
Expand Down Expand Up @@ -495,7 +497,7 @@ void* MediaPlayer::startAudioDecoding(void* ptr)

void* MediaPlayer::startPlayer(void* ptr)
{
__android_log_print(ANDROID_LOG_INFO, TAG, "starting main player thread");
__android_log_print(ANDROID_LOG_INFO, TAG, "starting main player thread");
sPlayer->decodeMovie(ptr);
}

Expand Down
5 changes: 3 additions & 2 deletions jni/libmediaplayer/packetqueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ int PacketQueue::get(AVPacket *pkt, bool block)

void PacketQueue::abort()
{
pthread_mutex_lock(&mLock);
pthread_mutex_lock(&mLock);
mAbortRequest = true;
pthread_cond_signal(&mCondition);
pthread_mutex_unlock(&mLock);
}
}

0 comments on commit 53ff5b7

Please sign in to comment.