在Android平台上如何实现H264解码

在Android平台上实现H264解码,一般采用开源的ffmpeg来实现,那么这就涉及一个问题:如何在android平台上移植ffmpeg?

这个移植的方法在网上有一大推,本人看得头晕,所以采用了一个取巧的办法:在android平台上编译XBMC的时候,编译成功后,在目录~/xbmc-android/tools/android/packaging/xbmc/lib/armeabi-v7a/ 下面就有编译好的ffmpeg的库,直接提取出来用就可以了

那么有了android平台上ffmpeg的库,如何在android平台上测试H264解码呢?

新建android app工程ffmpeg_android

gedit ./.bashrc

将 /opt/android-sdk-linux/tools 添加到 "PATH"环境变量中

android list targets

android create project --target 1 --name ffmpeg_android --path ~/workspace/ffmpeg_android --package com.modukaikai.ffmpeg --activity ffmpegActivity

 

将xbmc中的ffmpeg源码拷贝到工程ffmpeg_android的jni目录下

mkdir ~/workspace/ffmpeg_android/jni

cp -R ~/xbmc-android/lib/ffmpeg ~/workspace/ffmpeg_android/jni/

 

H264解码器的实现

vim ~/workspace/ffmpeg_android/jni/h264_decoder.h

以下是h264_decoder.h的代码:

#ifndef h264_decoder_h
#define h264_decoder_h

extern "C"
{
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavcodec/avcodec.h"

typedef void (*tp_avcodec_register_all)(void);
typedef AVCodec *(*tp_avcodec_find_decoder)(enum AVCodecID id);
typedef AVCodecContext *(*tp_avcodec_alloc_context3)(const AVCodec *codec);
typedef int (*tp_avcodec_open2)(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
typedef AVFrame *(*tp_avcodec_alloc_frame)(void);
typedef void (*tp_avcodec_free_frame)(AVFrame **frame);
typedef int (*tp_avcodec_decode_video2)(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt);
typedef int (*tp_avcodec_close)(AVCodecContext *avctx);
typedef void (*tp_av_free)(void *ptr);
typedef void (*tp_av_init_packet)(AVPacket *pkt);

class H264DecoderInterface
{
public:
H264DecoderInterface()
{
p_avcodec_register_all = NULL;
p_avcodec_find_decoder = NULL;
p_avcodec_alloc_context3 = NULL;
p_avcodec_open2 = NULL;
p_avcodec_alloc_frame = NULL;
p_avcodec_free_frame = NULL;
p_avcodec_decode_video2 = NULL;
p_avcodec_close = NULL;
p_av_free = NULL;
p_av_init_packet = NULL;
};

~H264DecoderInterface()
{
};

void (*p_avcodec_register_all)(void);
AVCodec *(*p_avcodec_find_decoder)(enum AVCodecID id);
AVCodecContext *(*p_avcodec_alloc_context3)(const AVCodec *codec);
int (*p_avcodec_open2)(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
AVFrame *(*p_avcodec_alloc_frame)(void);
void (*p_avcodec_free_frame)(AVFrame **frame);
int (*p_avcodec_decode_video2)(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt);
int (*p_avcodec_close)(AVCodecContext *avctx);
void (*p_av_free)(void *ptr);
void (*p_av_init_packet)(AVPacket *pkt);
};

class h264_decoder
{
public:
static bool loadLibrary(const char *libDir);
static bool unloadLibrary();

h264_decoder();
~h264_decoder();

bool open_h264_decoder();
unsigned long h264_decoder_process(unsigned char* pSrcData, unsigned long srcDataLen, unsigned char* pDstData, bool& bNoOutputDecData);
bool close_h264_decoder();

void setFrameRate(int frameRate);
void setResolution(int width, int height);

private:
static void* avcodec_handle;
static void* avfilter_handle;
static void* avformat_handle;
static void* avutil_handle;
static void* postproc_handle;
static void* swresample_handle;
static void* swscale_handle;
static H264DecoderInterface *p_H264DecoderInterface;

struct AVCodec *p_AVCodec;
struct AVCodecContext *p_AVCodecContext;
struct AVFrame *p_AVFrame;
struct AVPacket avPacket;

int got_frame;

bool isOpened;

int video_frameRate;
int video_width;
int video_height;
};
}
#endif

相关推荐