X264编码实现
H264
H264的官方测试源码,由德国hhi研究所负责开发。
特点:实现了264所有的特性,由于是官方的测试源码,所以学术研究的算法都是在JM基础上实现并和JM进行比较。但其程序结构冗长,
只考虑引入各种新特性以提高编码性能,忽视了编码复杂度,其编码复杂度极高,不宜实用。
X264
网上自由组织联合开发的兼容264标准码流的编码器,创始人是一个法国人。X264在网上的口碑极佳。
特点:注重实用。和JM相比,在不明显降低编码性能的前提下,努力降低编码的计算复杂度,故X264摈弃了264中一些对编码性能贡献
微笑但计算复杂度极高的新特性,如多参考帧、帧间预测中不必要的块模式、CABAC等。
编码格式输出:
总的来说H264的码流的打包方式有两种,一种为annex-b byte stream format的格式,这个是绝大部分编码器的默认输出格式,就是
每个帧的开头的3~4个字节是H264的start_code,0x00000001或者0x000001。
另一种是原始的NAL打包格式,就是开始的若干字节(1,2,4字节)是NAL的长度,而不是start_code,此时必须借助某个全局的数据
来获得编码器的profile,level,PPS,SPS等信息才可以解码。
h264encoder.h
/**
*
* Created on: Dec 10, 2010
* Author: Henry.wen
*/
#ifndef _H264ENCODER_H
#define _H264ENCODER_H #include <stdint.h>
#include <inttypes.h> extern "C"
{
#include "matroska.h"
} void save_image(const char* filePath, const void* bufferBase, int width, int height); int encoder_init(const char* filePath, int width, int height); int encoder_frame(const void* frame); void encoder_close(); #endif
h264encoder.cpp
extern "C"
{
#include <matroska.h>
} #include <skia/core/SkBitmap.h>
#include <skia/images/SkImageEncoder.h> #include <android_runtime/AndroidRuntime.h> #include "h264encoder.h" #ifndef X264_MAX
#define X264_MAX( a, b ) ( (a) < (b) ? (b) : (a))
#endif x264_param_t g_param;
x264_picture_t g_pic_in;
x264_picture_t g_pic_out;
x264_t *g_encoder = NULL;
int g_width = 0;
int g_height = 0;
FILE* g_file = 0;
int64_t g_pts = 0;
int g_flagInit = 0; using namespace android;
static Mutex sg_mutexLock; #ifndef LOGI
#define LOGI(...) ((void)__android_log_print("H264ENCODE", MOBIHEARTCAMERA_LOG_TAG, __VA_ARGS__))
#endif void save_image(const char* filePath, const void* bufferBase, int width, int height)
{
Mutex::Autolock lock(sg_mutexLock);
SkBitmap b;
b.setConfig(SkBitmap::kARGB_8888_Config, width, height);
b.setPixels((void*)bufferBase);
SkImageEncoder::EncodeFile(filePath, b, SkImageEncoder::kJPEG_Type, SkImageEncoder::kDefaultQuality);
} int encoder_init(const char* filePath, int width, int height)
{
LOGI("encoder_init ============begin");
if(g_flagInit != 0)
{
LOGI("encoder_init have encoding!");
return 0;
} Mutex::Autolock lock(sg_mutexLock); x264_param_default_preset(&g_param, "fast", "zerolatency"); g_param.i_width = width;
g_param.i_height = height;
g_param.i_fps_num = 25;
g_param.i_fps_den = 1; g_width = width;
g_height = height; g_param.i_keyint_max = 25;
g_param.b_intra_refresh = 1;
g_param.b_annexb = 1; x264_param_apply_profile(&g_param, x264_profile_names[0]); g_encoder = x264_encoder_open(&g_param);
if(g_encoder == 0)
{
LOGI("encoder_init open encoder fail!");
return -1;
}
g_param.rc.i_lookahead = 0; if( 0 != x264_picture_alloc(&g_pic_in, X264_CSP_I420, width, height))//X264_CSP_I420
{
LOGI("encoder_init alloc picture fail!");
x264_encoder_close(g_encoder);
g_encoder = 0;
return -1;
} g_file = fopen(filePath, "w+b");
if(g_file == NULL)
{
x264_encoder_close(g_encoder);
g_encoder = 0;
return -1;
} g_flagInit = 1;
g_pts = 0; return 0;
} int encoder_frame(const void* frame)
{
LOGI("encoder_frame ============begin");
if(g_flagInit > 0)
{
Mutex::Autolock lock(sg_mutexLock); g_pic_in.img.plane[0] = (uint8_t*)frame; uint8_t* tmpBuffer_uv = g_pic_in.img.plane[0] + g_width * g_height;
uint8_t* tmpBuffer_u = g_pic_in.img.plane[1];
uint8_t* tmpBuffer_v = g_pic_in.img.plane[2]; int index = 0;
for(int j = 0, nCount = (g_height >> 1) * g_width; j < nCount; j +=2)
{
*(tmpBuffer_u + index) = *(tmpBuffer_uv + index);
*(tmpBuffer_v + index + 1) = *(tmpBuffer_uv + index + 1); ++index;
} int nnal;
x264_nal_t *nals; g_pic_in.i_pts = g_pts;
g_pic_in.i_type = X264_TYPE_AUTO; int ret = x264_encoder_encode(g_encoder, &nals, &nnal, &g_pic_in, &g_pic_out);
if( ret < 0)
{
LOGI("encoder_frame encode frame fail, ret = %d", ret);
return 0;
}
++g_pts; fwrite(nals[0].p_payload, ret, 1, g_file );
}
LOGI("encoder_frame ============end");
return 0;
} void encoder_close()
{
LOGI("encoder_close ============begin");
Mutex::Autolock lock(sg_mutexLock); if(g_encoder)
x264_encoder_close(g_encoder); g_encoder = 0; if(g_file)
fclose(g_file); g_file = 0; g_flagInit = 0;
LOGI("encoder_close ============end");
}
X264编码实现的更多相关文章
- WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码
转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...
- Android camera采集视频 X264编码
参考 http://blog.csdn.net/zblue78/article/details/6058147 感谢 ExperiencesOfCode 硬件平台:CPU Intel G630 @2. ...
- x264编码的图像出现乱码的问题
将YUV进行x264编码的时候,建议将 i_threads 参数设置成 X264_SYNC_LOOKAHEAD_AUTO//* 取空缓冲区继续使用不死锁的保证. 否则有可能编码出来的数据会出现IDR_ ...
- X264编码流程详解(转)
http://blog.csdn.net/xingyu19871124/article/details/7671634 对H.264编码标准一直停留在理解原理的基础上,对于一个实际投入使用的编码器是如 ...
- 视频x264编码浅析
声明 x264_param_t 结构体变量: x264_param_t params; x264_param_default_preset(¶ms, "ultrafast&q ...
- 使用良好的自定义X264编码,取得极佳质量!《转》
原帖地址:http://www.xspliter.com/forum.php?mod=viewthread&tid=447 一般直播时使用A设定即可.你尝试设置并找出你最满意的设定 A为最需最 ...
- ffmpeg,X264编码结果I帧QP比P帧还大
enc_ctx->profile =FF_PROFILE_H264_MAIN ; enc_ctx->time_base.den = 24; enc_ctx->time_base.nu ...
- 使用X264编码yuv格式的视频帧使用ffmpeg解码h264视频帧
前面一篇博客介绍在centos上搭建点击打开链接ffmpeg及x264开发环境.以下就来问个样例: 1.利用x264库将YUV格式视频文件编码为h264格式视频文件 2.利用ffmpeh库将h264格 ...
- 用X264编码以后的H264数据
输入的数据准备好了,编码后的数据都在x264_nal_t的数组.我这里设置的参数是Baseline Profile,所以编码后没有B帧,将编码后的数据保存分析后发现,第一次编码的时候会有4个NAl,分 ...
- x264 编码数配置
记录项目中用到一组x264快速编码参数配置,具体如下: param->i_frame_reference = 1; param->i_scenecut_threshold = 0; par ...
随机推荐
- (转)Openlayers 2.X加载高德地图
http://blog.csdn.net/gisshixisheng/article/details/44853881 概述: 前面的有篇文章介绍了Openlayers 2.X下加载天地图,本节介绍O ...
- Java Web_过滤器
过滤器分类: Servlet2.5: request:用户直接访问页面时,Web容器将会调用过滤器. forward:目标资源是通过RequestDispatcher的forward访问时,该过滤器将 ...
- 在Android 上运行 openCV ,并做灰度变化的一个例子
OpenCVImageProcessing1. 导入Opencv的 androrid SDK灰度算法 OpenCVImageProcessing 导入opencv Jar包,配置OpenCVLibra ...
- qbxt 考前集训 Day1
立方数(cubic) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是立方数 ...
- Oracle SQL语句之常见优化方法总结
1.用EXISTS替换DISTINCT 当SQL包含一对多表查询时,避免在SELECT子句中使用DISTINCT,一般用EXIST替换,EXISTS(低效): SELECT DISTINCT USER ...
- 爬虫系列(八) 用requests实现天气查询
这篇文章我们将使用 requests 调用天气查询接口,实现一个天气查询的小模块,下面先贴上最终的效果图 1.接口分析 虽然现在网络上有很多免费的天气查询接口,但是有很多网站都是需要注册登陆的,过程比 ...
- 【Codeforces Round #519 by Botan Investments E】Train Hard, Win Easy
[链接] 我是链接,点我呀:) [题意] [题解] 设每个人做第一题.第二题的分数分别为x,y 我们先假设没有仇视关系. 即每两个人都能进行一次训练. 那么 对于第i个人. 考虑第j个人对它的贡献 如 ...
- HTTP基本认证(Basic Authentication)的JAVA演示样例
大家在登录站点的时候.大部分时候是通过一个表单提交登录信息.可是有时候浏览器会弹出一个登录验证的对话框.例如以下图,这就是使用HTTP基本认证.以下来看看一看这个认证的工作过程:第一步: clien ...
- JAVA版本号微信公众账号开源项目版本号公布-jeewx1.0(捷微)
JeeWx, 敏捷微信开发,简称"捷微". 捷微是一款免费开源的微信公众账号开发平台. 平台介绍: 一.简单介绍 jeewx是一个开源,高效.敏捷的微信开发平台採用JAVA语言,它 ...
- 聚类k-means/k-means++/fcm学习笔记
聚类主要是一种无监督学习.用来发现未标注数据的隐藏结构,主要是用来给数据分组.聚类算法一般有硬聚类(k-means,k-means++)和软聚类FCM(fuzzy c-means).聚类眼下广泛应用于 ...