android调用jni使用ffmeg把h264转yuv数据

jni代码部分:


#include <stdio.h>
#include <time.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavutil/log.h"
#include "libavutil/frame.h"

#ifdef ANDROID
#include <jni.h>
#include <android/log.h>
#define LOGE(format, ...)  __android_log_print(ANDROID_LOG_ERROR, "(>_<)", format, ##__VA_ARGS__)
#define LOGI(format, ...)  __android_log_print(ANDROID_LOG_INFO,  "(^_^)", format, ##__VA_ARGS__)
#else
#define LOGE(format, ...)  printf("(>_<) " format "\n", ##__VA_ARGS__)
#define LOGI(format, ...)  printf("(^_^) " format "\n", ##__VA_ARGS__)
#endif

AVFormatContext *pFormatCtx;
int             i, videoindex;
AVCodecContext  *pCodecCtx;
AVCodec         *pCodec;
AVFrame *pFrame;
uint8_t *out_buffer;
AVPacket packet;
int y_size;
int ret, got_picture;
struct SwsContext *img_convert_ctx;
int frame_cnt;
clock_t time_start, time_finish;
double  time_duration = 0.0;

char input_str[500]={0};
char info[1000]={0};
//Output FFmpeg's av_log()
void custom_log(void *ptr, int level, const char* fmt, va_list vl){
    FILE *fp=fopen("/storage/emulated/0/av_log.txt","a+");
    if(fp){
        vfprintf(fp,fmt,vl);
        fflush(fp);
        fclose(fp);
    }
}

JNIEXPORT jint JNICALL Java_com_aac_utils_DecodeYUV_init
        (JNIEnv *env, jobject obj)
{
    av_log_set_callback(custom_log);
    av_register_all();
    pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
    pCodecCtx = avcodec_alloc_context3(pCodec);
    if(pCodec==NULL){
        LOGE("Couldn't find Codec.\n");
        return -1;
    }
    if(avcodec_open2(pCodecCtx, pCodec,NULL)<0){
        LOGE("Couldn't open codec.\n");
        return -1;
    }
    pFrame= avcodec_alloc_frame();
    pCodecCtx->flags |= CODEC_FLAG_LOW_DELAY;
    pCodecCtx->debug |= FF_DEBUG_MMCO;
    pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
}

JNIEXPORT jint JNICALL Java_com_aac_utils_DecodeYUV_decode
        (JNIEnv *env, jobject obj, jbyteArray jin_packet,jbyteArray jout_packet,jint jwidth,jint jheight)
{
    av_init_packet(&packet);
    unsigned char  *in_array =(*env)->GetByteArrayElements(env,jin_packet, 0);
    jbyte *out_array =(*env)->GetByteArrayElements(env,jout_packet, 0);
    jsize  *length = (*env)->GetArrayLength(env,jin_packet);

    packet.size = length;
    packet.data = in_array;
    int width =jwidth;
    int height = jheight;

        ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);
        av_free_packet(&packet);
        if(ret < 0){
            LOGE("Decode Error.\n");
            return -1;
        }

        if(got_picture){
            y_size=width*height;

            unsigned char *buf = (unsigned char *)malloc(y_size*3/2);
            memset(buf, 0, y_size*3/2);
            memcpy(buf,pFrame->data[0], y_size);
            memcpy(buf+y_size,pFrame->data[1], y_size / 4);
            memcpy(buf+y_size*5/4,pFrame->data[2], y_size / 4);

            jbyte *buff;
            buff = (jbyte*)buf;
            (*env)->ReleaseByteArrayElements(env,jout_packet, out_array, 0);
            (*env)->SetByteArrayRegion(env,jout_packet, 0, y_size*3/2, buff);

            free(buf);
        }


    //flush decoder
    //FIX: Flush Frames remained in Codec
    return 0;
}
JNIEXPORT jint JNICALL Java_com_aac_utils_DecodeYUV_close
        (JNIEnv *env, jobject obj)
{
    av_frame_free(&pFrame);
    avcodec_close(pCodecCtx);
    av_free(pCodecCtx);
}


java调用函数.

public class DecodeYUV {
    //JNI
    public static native int close();
    public static native int init();
    public static native int decode(byte[] inarray,byte[] outarray,int width,int height);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值