歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

在Android平台上如何實現H264解碼

在Android平台上實現H264解碼,一般采用開源的ffmpeg來實現,那麼這就涉及一個問題:如何在android平台上移植ffmpeg?

這個移植的方法在網上有一大推,本人看得頭暈,所以采用了一個取巧的辦法:在android平台上編譯XBMC的時候,編譯成功後,在目錄~/xbmc-android/tools/android/packaging/xbmc/lib/armeabi-v7a/ 下面就有編譯好的ffmpeg的庫,直接提取出來用就可以了

注:關於如何在android平台上編譯XBMC,請看我之前的博文: http://www.linuxidc.com/Linux/2013-08/88544.htm

那麼有了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

接下來請看第2頁精彩內容:http://www.linuxidc.com/Linux/2013-08/88545p2.htm

Copyright © Linux教程網 All Rights Reserved