Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</activity>

</application>
<uses-sdk android:minSdkVersion="3" />
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
13 changes: 13 additions & 0 deletions default.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.

# Project target.
target=android-4
# Indicates whether an apk should be generated for each density.
split.density=false
17 changes: 9 additions & 8 deletions jni/include/android/surface.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2011 Petr Havlena havlenapetr@gmail.com
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -20,13 +21,13 @@
#include <stdint.h>
#include <jni.h>

#define ANDROID_SURFACE_RESULT_SUCCESS 0
#define ANDROID_SURFACE_RESULT_NOT_VALID -1
#define ANDROID_SURFACE_RESULT_COULDNT_LOCK -2
#define ANDROID_SURFACE_RESULT_COULDNT_UNLOCK_AND_POST -3
#define ANDROID_SURFACE_RESULT_COULDNT_INIT_BITMAP_SURFACE -4
#define ANDROID_SURFACE_RESULT_COULDNT_INIT_BITMAP_CLIENT -5
#define ANDROID_SURFACE_RESULT_JNI_EXCEPTION -6
#define ANDROID_SURFACE_RESULT_SUCCESS 0
#define ANDROID_SURFACE_RESULT_NOT_VALID -1
#define ANDROID_SURFACE_RESULT_COULDNT_LOCK -2
#define ANDROID_SURFACE_RESULT_COULDNT_UNLOCK_AND_POST -3
#define ANDROID_SURFACE_RESULT_COULDNT_INIT_BITMAP_SURFACE -4
#define ANDROID_SURFACE_RESULT_COULDNT_INIT_BITMAP_CLIENT -5
#define ANDROID_SURFACE_RESULT_JNI_EXCEPTION -6

#ifdef __cplusplus
extern "C" {
Expand All @@ -36,7 +37,7 @@ int AndroidSurface_register(JNIEnv* env, jobject jsurface);

int AndroidSurface_getPixels(int width, int height, void** pixels);

int AndroidSurface_updateSurface();
int AndroidSurface_updateSurface(bool autoscale = true);

int AndroidSurface_unregister();

Expand Down
38 changes: 31 additions & 7 deletions jni/jni/com_media_ffmpeg_FFMpegPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ static MediaPlayer* setMediaPlayer(JNIEnv* env, jobject thiz, MediaPlayer* playe
{
MediaPlayer* old = (MediaPlayer*)env->GetIntField(thiz, fields.context);
if (old != NULL) {
__android_log_print(ANDROID_LOG_INFO, TAG, "freeing old mediaplayer object");
free(old);
}
__android_log_print(ANDROID_LOG_INFO, TAG, "freeing old mediaplayer object");
free(old);
}
env->SetIntField(thiz, fields.context, (int)player);
return old;
}
Expand All @@ -100,12 +100,12 @@ static MediaPlayer* setMediaPlayer(JNIEnv* env, jobject thiz, MediaPlayer* playe
static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
{
if (exception == NULL) { // Don't throw exception. Instead, send an event.
/*
/*
if (opStatus != (status_t) OK) {
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
if (mp != 0) mp->notify(MEDIA_ERROR, opStatus, 0);
}
*/
*/
} else { // Throw exception!
if ( opStatus == (status_t) INVALID_OPERATION ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
Expand Down Expand Up @@ -172,8 +172,8 @@ com_media_ffmpeg_FFMpegPlayer_setVideoSurface(JNIEnv *env, jobject thiz, jobject
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
process_media_player_call( env, thiz, mp->setVideoSurface(env, jsurface),
"java/io/IOException", "Set video surface failed.");
process_media_player_call( env, thiz, mp->setVideoSurface(env, jsurface),
"java/io/IOException", "Set video surface failed.");
}

static void
Expand Down Expand Up @@ -220,6 +220,28 @@ com_media_ffmpeg_FFMpegPlayer_pause(JNIEnv *env, jobject thiz)
process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
}

static void
com_media_ffmpeg_FFMpegPlayer_setResolution(JNIEnv *env, jobject thiz, jint width, jint height)
{
MediaPlayer* mp = getMediaPlayer(env, thiz);
if (mp == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
process_media_player_call( env, thiz, mp->setResolution(width, height), NULL, NULL );
}

static void
com_media_ffmpeg_FFMpegPlayer_setAutoscale(JNIEnv *env, jobject thiz, jboolean value)
{
MediaPlayer* mp = getMediaPlayer(env, thiz);
if (mp == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
process_media_player_call( env, thiz, mp->setAutoscale(value), NULL, NULL );
}

static jboolean
com_media_ffmpeg_FFMpegPlayer_isPlaying(JNIEnv *env, jobject thiz)
{
Expand Down Expand Up @@ -406,6 +428,8 @@ static JNINativeMethod gMethods[] = {
{"prepare", "()V", (void *)com_media_ffmpeg_FFMpegPlayer_prepare},
{"_start", "()V", (void *)com_media_ffmpeg_FFMpegPlayer_start},
{"_stop", "()V", (void *)com_media_ffmpeg_FFMpegPlayer_stop},
{"_setResolution", "(II)V", (void *)com_media_ffmpeg_FFMpegPlayer_setResolution},
{"_setAutoscale", "(Z)V", (void *)com_media_ffmpeg_FFMpegPlayer_setAutoscale},
{"getVideoWidth", "()I", (void *)com_media_ffmpeg_FFMpegPlayer_getVideoWidth},
{"getVideoHeight", "()I", (void *)com_media_ffmpeg_FFMpegPlayer_getVideoHeight},
{"seekTo", "(I)V", (void *)com_media_ffmpeg_FFMpegPlayer_seekTo},
Expand Down
28 changes: 14 additions & 14 deletions jni/libmediaplayer/decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,49 @@

IDecoder::IDecoder(AVStream* stream)
{
mQueue = new PacketQueue();
mStream = stream;
mQueue = new PacketQueue();
mStream = stream;
}

IDecoder::~IDecoder()
{
if(mRunning)
if(mRunning)
{
stop();
}
free(mQueue);
avcodec_close(mStream->codec);
free(mQueue);
avcodec_close(mStream->codec);
}

void IDecoder::enqueue(AVPacket* packet)
{
mQueue->put(packet);
mQueue->put(packet);
}

int IDecoder::packets()
{
return mQueue->size();
return mQueue->size();
}

void IDecoder::stop()
{
mQueue->abort();
__android_log_print(ANDROID_LOG_INFO, TAG, "waiting on end of decoder thread");
int ret = -1;
if((ret = wait()) != 0) {
if((ret = join()) != 0) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "Couldn't cancel IDecoder: %i", ret);
return;
}
}

void IDecoder::handleRun(void* ptr)
void IDecoder::run()
{
if(!prepare())
if(!prepare())
{
__android_log_print(ANDROID_LOG_INFO, TAG, "Couldn't prepare decoder");
__android_log_print(ANDROID_LOG_INFO, TAG, "Couldn't prepare decoder");
return;
}
decode(ptr);
decode();
}

bool IDecoder::prepare()
Expand All @@ -57,10 +57,10 @@ bool IDecoder::prepare()

bool IDecoder::process(AVPacket *packet)
{
return false;
return false;
}

bool IDecoder::decode(void* ptr)
bool IDecoder::decode()
{
return false;
}
23 changes: 12 additions & 11 deletions jni/libmediaplayer/decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,22 @@ extern "C" {
class IDecoder : public Thread
{
public:
IDecoder(AVStream* stream);
~IDecoder();
IDecoder(AVStream* stream);
~IDecoder();

void stop();
void enqueue(AVPacket* packet);
int packets();
void stop();
void enqueue(AVPacket* packet);
int packets();

protected:
PacketQueue* mQueue;
AVStream* mStream;
PacketQueue* mQueue;
AVStream* mStream;

virtual bool prepare();
virtual bool decode(void* ptr);
virtual bool process(AVPacket *packet);
void handleRun(void* ptr);
virtual bool prepare();
virtual bool decode();
virtual bool process(AVPacket *packet);

virtual void run();
};

#endif //FFMPEG_DECODER_H
8 changes: 5 additions & 3 deletions jni/libmediaplayer/decoder_audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

#define TAG "FFMpegAudioDecoder"

DecoderAudio::DecoderAudio(AVStream* stream) : IDecoder(stream)
DecoderAudio::DecoderAudio(AVStream* stream, DecoderAudioCallback* callback) : IDecoder(stream)
{
mCallback = callback;
}

DecoderAudio::~DecoderAudio()
{
delete mCallback;
}

bool DecoderAudio::prepare()
Expand All @@ -27,12 +29,12 @@ bool DecoderAudio::process(AVPacket *packet)
int len = avcodec_decode_audio3(mStream->codec, mSamples, &size, packet);

//call handler for posting buffer to os audio driver
onDecode(mSamples, size);
mCallback->onDecode(mSamples, size);

return true;
}

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

Expand Down
21 changes: 12 additions & 9 deletions jni/libmediaplayer/decoder_audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,27 @@

#include "decoder.h"

typedef void (*AudioDecodingHandler) (int16_t*,int);
class DecoderAudioCallback
{
public:
virtual void onDecode(int16_t* buffer, int buffer_size);
};

class DecoderAudio : public IDecoder
{
public:
DecoderAudio(AVStream* stream);

DecoderAudio(AVStream* stream, DecoderAudioCallback* callback);
~DecoderAudio();

AudioDecodingHandler onDecode;

private:
int16_t* mSamples;
int mSamplesSize;
int16_t* mSamples;
int mSamplesSize;
DecoderAudioCallback* mCallback;

bool prepare();
bool decode(void* ptr);
bool process(AVPacket *packet);
bool prepare();
bool decode();
bool process(AVPacket *packet);
};

#endif //FFMPEG_DECODER_AUDIO_H
28 changes: 14 additions & 14 deletions jni/libmediaplayer/decoder_video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,25 @@

static uint64_t global_video_pkt_pts = AV_NOPTS_VALUE;

DecoderVideo::DecoderVideo(AVStream* stream) : IDecoder(stream)
DecoderVideo::DecoderVideo(AVStream* stream, DecoderVideoCallback* callback) : IDecoder(stream)
{
mStream->codec->get_buffer = getBuffer;
mStream->codec->release_buffer = releaseBuffer;
mCallback = callback;
mStream->codec->get_buffer = getBuffer;
mStream->codec->release_buffer = releaseBuffer;
}

DecoderVideo::~DecoderVideo()
{
delete mCallback;
}

bool DecoderVideo::prepare()
{
mFrame = avcodec_alloc_frame();
if (mFrame == NULL) {
return false;
}
return true;
mFrame = avcodec_alloc_frame();
if (mFrame == NULL) {
return false;
}
return true;
}

double DecoderVideo::synchronize(AVFrame *src_frame, double pts) {
Expand Down Expand Up @@ -67,19 +69,17 @@ bool DecoderVideo::process(AVPacket *packet)

if (completed) {
pts = synchronize(mFrame, pts);

onDecode(mFrame, pts);

mCallback->onDecode(mFrame, pts);
return true;
}
return false;
}

bool DecoderVideo::decode(void* ptr)
bool DecoderVideo::decode()
{
AVPacket pPacket;
AVPacket pPacket;

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

while(mRunning)
{
Expand Down
Loading