x264软编码(jni接口)
来源:互联网 发布:日本推理电影 知乎 编辑:程序博客网 时间:2024/06/01 19:04
//
// x264.c
// jni
//
//
// create by yuanchunsi.
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <pthread.h>
#include "stdint.h"
#include "utils_jni.h"
#include "utils/log.h"
#include "utils/queue.h"
#if defined ( __cplusplus)
extern "C"
{
#include "x264.h"
};
#else
#include "x264.h"
#endif
typedef struct _Encoder{
x264_param_t * param;
x264_t *handle;
x264_picture_t * picture;
x264_nal_t *nal;
} Encoder;
typedef struct _packet{
char *in;
int insize;
} packet_t;
Encoder * encoder = NULL;
static queue_t * queue = NULL;
static pthread_t encoder_id;
static bool encoder_stop ;
static FILE* fp_dst = NULL;
static void* encoder_run(void *data) {
int ret;
int y_size;
//int i,j;
//int iNal = -1;
//int frame_num = 0;
pthread_detach(pthread_self());
pthread_t thid;
struct sched_param param;
thid = pthread_self();
param.sched_priority = sched_get_priority_max(SCHED_RR);
pthread_setschedparam(thid,SCHED_RR,¶m);
Encoder *en = (Encoder*)data;
if (NULL == en) {
ERROR("Invaid data\n");
return NULL;
}
//fp_dst = fopen("/mnt/sdcard/eques/test.h264", "ab");
x264_picture_t pPic_out ;
packet_t packet;
y_size = en->param->i_width * en->param->i_height;
while(queue->ndata < 5) {
WARN("queue is free,waiting for....\n");
usleep(10*1000);
}
while(!encoder_stop) {
int i = 0;
int j = 0;
int iNal = -1;
int frame_num = 0;
memset(&packet,0,sizeof(packet_t));
fp_dst = fopen("/mnt/sdcard/test.h264", "ab");
ret = queue_peek(queue,&packet,sizeof(packet_t));
if(0 != ret) {
usleep(30*1000);
continue;
}
/*---------------------detect frame number------------------*/
if(frame_num==0){
switch(en->param->i_csp){
case X264_CSP_I444:frame_num=packet.insize/(y_size*3);break;
case X264_CSP_I420:frame_num=packet.insize/(y_size*3/2);break;
default:ERROR("Colorspace Not Support.\n");return NULL;
}
}
/*---------------------Loop to Encode------------------*/
for( i=0;i<frame_num;i++) {
switch(en->param->i_csp){
case X264_CSP_I444:{
memcpy(en->picture->img.plane[0],packet.in,y_size);//Y
memcpy(en->picture->img.plane[1],packet.in+y_size,y_size);//U
memcpy(en->picture->img.plane[2],packet.in+y_size+y_size,y_size);//V
break;
}
case X264_CSP_I420:{
memcpy(en->picture->img.plane[0],packet.in,y_size);//Y
memcpy(en->picture->img.plane[1],packet.in+y_size,y_size/4);//U
memcpy(en->picture->img.plane[2],packet.in+y_size+(y_size/4),y_size/4);//V
break;
}
default:{
ERROR("Colorspace Not Support.\n");
encoder_stop = true;
return NULL;
}
}
en->picture->i_pts = i;
#if 1
ret = x264_encoder_encode(en->handle, &(en->nal), &iNal, en->picture,&pPic_out);
if (ret < 0) {
ERROR("x264 encoder encode error.\n");
encoder_stop = true;
return NULL;
}
for ( j = 0; j < iNal; ++j) {
fwrite(en->nal[j].p_payload, 1,en->nal[j].i_payload, fp_dst);
}
#endif
}
fclose(fp_dst);
fp_dst = NULL;
INFO("Encode dnoe\n");
}
}
JNIEXPORT jlong Java_com_eques_device_ui_hardware_X264JNI_X264CompressBegin(JNIEnv* env,jobject thiz,jint width, jint height) {
int type = 1;
int csp = 0;
if (1 == type) {
csp = X264_CSP_I420;
} else if (2 == type) {
csp = X264_CSP_I444;
}
//Encoder * encoder = (Encoder *)malloc(sizeof(Encoder));
encoder = (Encoder *)malloc(sizeof(Encoder));
encoder->param = (x264_param_t *)malloc(sizeof(x264_param_t));
encoder->picture = (x264_picture_t *)malloc(sizeof(x264_picture_t));
x264_param_default(encoder->param); //set default param
encoder->param->i_csp=csp;
encoder->param->i_width = width; //set frame width
encoder->param->i_height = height; //set frame
encoder->param->i_log_level = X264_LOG_NONE;
encoder->param->i_threads = 4; // 4 cpu kernel
/*
encoder->param->rc.i_lookahead =0;
encoder->param->rc.i_rc_method = X264_RC_CQP;
encoder->param->i_log_level = X264_LOG_NONE;
encoder->param->i_bframe=0;
encoder->param->i_fps_num =5;
encoder->param->i_fps_den = 1;
*/
x264_param_apply_profile(encoder->param, x264_profile_names[0]);
if ((encoder->handle = x264_encoder_open(encoder->param)) == 0) {
ERROR("x264_econder_open failed\n");
return 0;
}
/* Create a new pic */
x264_picture_alloc(encoder->picture,X264_CSP_I420,encoder->param->i_width,encoder->param->i_height);
//fp_dst = fopen("/mnt/sdcard/eques/test.h264", "ab");
if (0 != queue_create(&queue,sizeof(packet_t),300)) {
ERROR("queue create failed\n");
return -1;
}
if (0 != pthread_create(&encoder_id,NULL,encoder_run,encoder)){
ERROR("pthread create failed\n");
return -1;
}
encoder_stop = false;
INFO("x264Encoder CompressBegin done\n");
return (jlong)PTR(encoder);
}
JNIEXPORT jint Java_com_eques_device_ui_hardware_X264JNI_X264CompressEnd(JNIEnv* env,jobject thiz,jlong handle)
{
Encoder* en = (Encoder *)PTR(handle);
encoder_stop = true;
if(en->picture)
{
x264_picture_clean(en->picture);
free(en->picture);
en->picture = 0;
}
if(en->param)
{
free(en->param);
en->param=0;
}
if(en->handle)
{
x264_encoder_close(en->handle);
}
free(en);
queue_destroy(queue);
en = NULL;
queue = NULL;
//fclose(fp_dst);
//fp_dst = NULL;
INFO("x264Encoder CompressEnd done\n");
return 0;
}
JNIEXPORT jint Java_com_eques_device_ui_hardware_X264JNI_X264CompressBuffer(JNIEnv* env,jobject thiz,jlong handle,jbyteArray DataIn,jint insize)
{
if (0 == handle || NULL == DataIn || 0 > insize) {
ERROR("Invaild data\n");
return -1;
}
int ret = 0;
Encoder* en = (Encoder *)PTR(handle);
packet_t* packet = (packet_t*)malloc(sizeof(packet_t));
packet->in = (char*)(*env)->GetByteArrayElements(env,DataIn,NULL);
if (NULL == packet->in) {
ERROR("NO data input\n");
return -1;
}else {
packet->insize = insize;
INFO("Get data success\n");
}
if (queue->ndata >250) {
WARN("queue is full ,waiting for....\n");
usleep(30*1000);
}
ret = queue_write(queue,(void*)packet,sizeof(packet_t));
if (0 != ret) {
return -1;
}
(*env)->ReleaseByteArrayElements(env,DataIn,packet->in,0);
INFO("x264Encoder Compressbuffer done\n");
return ret;
}
// x264.c
// jni
//
//
// create by yuanchunsi.
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <pthread.h>
#include "stdint.h"
#include "utils_jni.h"
#include "utils/log.h"
#include "utils/queue.h"
#if defined ( __cplusplus)
extern "C"
{
#include "x264.h"
};
#else
#include "x264.h"
#endif
typedef struct _Encoder{
x264_param_t * param;
x264_t *handle;
x264_picture_t * picture;
x264_nal_t *nal;
} Encoder;
typedef struct _packet{
char *in;
int insize;
} packet_t;
Encoder * encoder = NULL;
static queue_t * queue = NULL;
static pthread_t encoder_id;
static bool encoder_stop ;
static FILE* fp_dst = NULL;
static void* encoder_run(void *data) {
int ret;
int y_size;
//int i,j;
//int iNal = -1;
//int frame_num = 0;
pthread_detach(pthread_self());
pthread_t thid;
struct sched_param param;
thid = pthread_self();
param.sched_priority = sched_get_priority_max(SCHED_RR);
pthread_setschedparam(thid,SCHED_RR,¶m);
Encoder *en = (Encoder*)data;
if (NULL == en) {
ERROR("Invaid data\n");
return NULL;
}
//fp_dst = fopen("/mnt/sdcard/eques/test.h264", "ab");
x264_picture_t pPic_out ;
packet_t packet;
y_size = en->param->i_width * en->param->i_height;
while(queue->ndata < 5) {
WARN("queue is free,waiting for....\n");
usleep(10*1000);
}
while(!encoder_stop) {
int i = 0;
int j = 0;
int iNal = -1;
int frame_num = 0;
memset(&packet,0,sizeof(packet_t));
fp_dst = fopen("/mnt/sdcard/test.h264", "ab");
ret = queue_peek(queue,&packet,sizeof(packet_t));
if(0 != ret) {
usleep(30*1000);
continue;
}
/*---------------------detect frame number------------------*/
if(frame_num==0){
switch(en->param->i_csp){
case X264_CSP_I444:frame_num=packet.insize/(y_size*3);break;
case X264_CSP_I420:frame_num=packet.insize/(y_size*3/2);break;
default:ERROR("Colorspace Not Support.\n");return NULL;
}
}
/*---------------------Loop to Encode------------------*/
for( i=0;i<frame_num;i++) {
switch(en->param->i_csp){
case X264_CSP_I444:{
memcpy(en->picture->img.plane[0],packet.in,y_size);//Y
memcpy(en->picture->img.plane[1],packet.in+y_size,y_size);//U
memcpy(en->picture->img.plane[2],packet.in+y_size+y_size,y_size);//V
break;
}
case X264_CSP_I420:{
memcpy(en->picture->img.plane[0],packet.in,y_size);//Y
memcpy(en->picture->img.plane[1],packet.in+y_size,y_size/4);//U
memcpy(en->picture->img.plane[2],packet.in+y_size+(y_size/4),y_size/4);//V
break;
}
default:{
ERROR("Colorspace Not Support.\n");
encoder_stop = true;
return NULL;
}
}
en->picture->i_pts = i;
#if 1
ret = x264_encoder_encode(en->handle, &(en->nal), &iNal, en->picture,&pPic_out);
if (ret < 0) {
ERROR("x264 encoder encode error.\n");
encoder_stop = true;
return NULL;
}
for ( j = 0; j < iNal; ++j) {
fwrite(en->nal[j].p_payload, 1,en->nal[j].i_payload, fp_dst);
}
#endif
}
fclose(fp_dst);
fp_dst = NULL;
INFO("Encode dnoe\n");
}
}
JNIEXPORT jlong Java_com_eques_device_ui_hardware_X264JNI_X264CompressBegin(JNIEnv* env,jobject thiz,jint width, jint height) {
int type = 1;
int csp = 0;
if (1 == type) {
csp = X264_CSP_I420;
} else if (2 == type) {
csp = X264_CSP_I444;
}
//Encoder * encoder = (Encoder *)malloc(sizeof(Encoder));
encoder = (Encoder *)malloc(sizeof(Encoder));
encoder->param = (x264_param_t *)malloc(sizeof(x264_param_t));
encoder->picture = (x264_picture_t *)malloc(sizeof(x264_picture_t));
x264_param_default(encoder->param); //set default param
encoder->param->i_csp=csp;
encoder->param->i_width = width; //set frame width
encoder->param->i_height = height; //set frame
encoder->param->i_log_level = X264_LOG_NONE;
encoder->param->i_threads = 4; // 4 cpu kernel
/*
encoder->param->rc.i_lookahead =0;
encoder->param->rc.i_rc_method = X264_RC_CQP;
encoder->param->i_log_level = X264_LOG_NONE;
encoder->param->i_bframe=0;
encoder->param->i_fps_num =5;
encoder->param->i_fps_den = 1;
*/
x264_param_apply_profile(encoder->param, x264_profile_names[0]);
if ((encoder->handle = x264_encoder_open(encoder->param)) == 0) {
ERROR("x264_econder_open failed\n");
return 0;
}
/* Create a new pic */
x264_picture_alloc(encoder->picture,X264_CSP_I420,encoder->param->i_width,encoder->param->i_height);
//fp_dst = fopen("/mnt/sdcard/eques/test.h264", "ab");
if (0 != queue_create(&queue,sizeof(packet_t),300)) {
ERROR("queue create failed\n");
return -1;
}
if (0 != pthread_create(&encoder_id,NULL,encoder_run,encoder)){
ERROR("pthread create failed\n");
return -1;
}
encoder_stop = false;
INFO("x264Encoder CompressBegin done\n");
return (jlong)PTR(encoder);
}
JNIEXPORT jint Java_com_eques_device_ui_hardware_X264JNI_X264CompressEnd(JNIEnv* env,jobject thiz,jlong handle)
{
Encoder* en = (Encoder *)PTR(handle);
encoder_stop = true;
if(en->picture)
{
x264_picture_clean(en->picture);
free(en->picture);
en->picture = 0;
}
if(en->param)
{
free(en->param);
en->param=0;
}
if(en->handle)
{
x264_encoder_close(en->handle);
}
free(en);
queue_destroy(queue);
en = NULL;
queue = NULL;
//fclose(fp_dst);
//fp_dst = NULL;
INFO("x264Encoder CompressEnd done\n");
return 0;
}
JNIEXPORT jint Java_com_eques_device_ui_hardware_X264JNI_X264CompressBuffer(JNIEnv* env,jobject thiz,jlong handle,jbyteArray DataIn,jint insize)
{
if (0 == handle || NULL == DataIn || 0 > insize) {
ERROR("Invaild data\n");
return -1;
}
int ret = 0;
Encoder* en = (Encoder *)PTR(handle);
packet_t* packet = (packet_t*)malloc(sizeof(packet_t));
packet->in = (char*)(*env)->GetByteArrayElements(env,DataIn,NULL);
if (NULL == packet->in) {
ERROR("NO data input\n");
return -1;
}else {
packet->insize = insize;
INFO("Get data success\n");
}
if (queue->ndata >250) {
WARN("queue is full ,waiting for....\n");
usleep(30*1000);
}
ret = queue_write(queue,(void*)packet,sizeof(packet_t));
if (0 != ret) {
return -1;
}
(*env)->ReleaseByteArrayElements(env,DataIn,packet->in,0);
INFO("x264Encoder Compressbuffer done\n");
return ret;
}
0 0
- x264软编码(jni接口)
- X264编码(上)
- X264编码(下)
- X264编码(1)
- X264编码(2)
- X264编码(3)
- X264编码
- X264编码
- X264编码
- X264编码
- X264编码
- x264编码在zedboard上的实现(软编码)(四)
- JNI wrapper for x264
- x264编码详细文字全过程(转载)
- arm6410 ffmpeg+x264软编码+硬件编码 jrtplib发送
- JNI接口学习(一)JNI数据类型
- FFmpeg x264 编码向导
- x264的编码示例
- Strust2优点之全局异常处理器+拦截器
- Promise/A+规范
- 解决maven中jar包无法下载
- gpu/cuda-03-cuda memory
- 这一年
- x264软编码(jni接口)
- Hdu 5469 Antonidas(只需要判断可不可行的树分治)
- Java 线程实现C/S会话
- IMP-00013: only a DBA can import a file exported by another DBA 问题及解决方案
- Swift傻傻分不清楚系列(四)基本运算符 o_O!???
- HTTP 协议入门知识
- Cypher查询语言--Neo4j中的SQL(5)
- Struts2拦截器
- oracle创建用户ORA-01045:user lacks CREATE SESSION privilege;logon denied..的问题