#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libavutil/opt.h"
#include "libavutil/imgutils.h"
#include <stdio.h>
#include <string.h>
#include <jni.h>
#include <android/log.h> typedef enum
{
FALSE = 0, TRUE = 1,
} C_BOOL; typedef unsigned char uint8_t; #define IN_BUFFER_SIZE 2048
#define TARGET_VIDEO_TYPE AV_PIX_FMT_RGB565 #define LOGE(format, ...) __android_log_print(ANDROID_LOG_ERROR, "(>_<)", format, ##__VA_ARGS__)
#define LOGD(format, ...) __android_log_print(ANDROID_LOG_DEBUG, "(-_-)", format, ##__VA_ARGS__) static C_BOOL __DecodeH264Video(FILE* fp_in, FILE* fp_out); JNIEXPORT jboolean JNICALL Java_com_zhoulee_h264decoder_MainActivity_DecodeH264Video(JNIEnv *env, jobject obj)
{
char filepath_in[] = "/data/video/bxjg_352x288.h264";
FILE *fp_in = fopen(filepath_in, "rb");
if (NULL == fp_in)
{
LOGE("open input h264 video file failed, filename [%s]", filepath_in);
return (jboolean) FALSE;
} char filepath_out[] = "/data/video/bxjg_352x288.rgb565";
FILE *fp_out = fopen(filepath_out, "wb");
if (NULL == fp_out)
{
LOGE("open output rgb video file failed, filename [%s]", filepath_out);
return (jboolean) FALSE;
} LOGD("open input and output file success"); if (TRUE == __DecodeH264Video(fp_in, fp_out))
{
LOGD("decode h264 video success");
}
else
{
LOGE("decode h264 video failed");
return (jboolean) FALSE;
} fclose(fp_in);
fclose(fp_out); return (jboolean) TRUE;
} typedef struct
{
AVCodec *pCodec;
AVCodecContext *pCodecCtx;
AVCodecParserContext *pCodecParserCtx;
AVFrame *pFrame;
AVFrame *pRGBFrame;
struct SwsContext *img_convert_ctx;
uint8_t *out_buffer;
uint8_t *cur_ptr;
AVPacket packet;
int cur_size;
int first_time;
int got_picture;
int dst_bpp; //bytes of pixel of destination format
} H264DecodeHandler; JNIEXPORT jint JNICALL Java_com_zhoulee_h264decoder_MainActivity_InitH264Decoder(JNIEnv *env, jobject obj)
{
return 0;
} int InitH264Decoder()
{
H264DecodeHandler *handle = (H264DecodeHandler*) malloc(sizeof(H264DecodeHandler));
if (NULL == handle)
{
LOGE("malloc H264DecodeHandler failed");
return 0;
} avcodec_register_all();
handle->pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (NULL == handle->pCodec)
{
LOGE("avcodec_find_decoder failed");
return 0;
} handle->pCodecCtx = avcodec_alloc_context3(handle->pCodec);
if (NULL == handle->pCodecCtx)
{
LOGE("avcodec_alloc_context3 failed");
return 0;
} handle->pCodecParserCtx = av_parser_init(AV_CODEC_ID_H264);
if (NULL == handle->pCodecParserCtx)
{
LOGE("av_parser_init failed");
return 0;
} if (avcodec_open2(handle->pCodecCtx, handle->pCodec, NULL) < 0)
{
LOGE("avcodec_open2 failed");
return 0;
} handle->pFrame = av_frame_alloc();
if (NULL == handle->pFrame)
{
LOGE("av_frame_alloc failed");
return 0;
} av_init_packet(&(handle->packet)); handle->cur_size = 0;
handle->got_picture = 0;
handle->first_time = 1;
handle->dst_bpp = av_get_bits_per_pixel(av_pix_fmt_desc_get(TARGET_VIDEO_TYPE)) / 8; LOGD("bytes of pixel of destination format is [%d]", handle->dst_bpp); return (int) handle;
} void ReleaseH264Decoder(int decodeHandle)
{
H264DecodeHandler* handle = (H264DecodeHandler*) decodeHandle;
sws_freeContext(handle->img_convert_ctx);
av_frame_free(&(handle->pRGBFrame));
av_parser_close(handle->pCodecParserCtx);
av_frame_free(&(handle->pRGBFrame));
avcodec_close(handle->pCodecCtx);
av_free(handle->pCodecCtx);
free(handle);
} JNIEXPORT jint JNICALL Java_com_zhoulee_h264decoder_MainActivity_ReleaseH264Decoder(JNIEnv *env, jobject obj,
jint handle)
{ } typedef enum
{
DecFailed = 0, DecSuccess = 1, DecNeedMoreData = 2,
} DECODERESULT; DECODERESULT DecodeOneFrame(int decodeHandle)
{
H264DecodeHandler* handle = (H264DecodeHandler*) decodeHandle; int parse_len = av_parser_parse2(handle->pCodecParserCtx, handle->pCodecCtx, &(handle->packet.data),
&(handle->packet.size), handle->cur_ptr, handle->cur_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE); LOGD("current size is [%d], parse size is [%d], handle->packet.size [%d]",
handle->cur_size, parse_len, handle->packet.size); handle->cur_ptr += parse_len;
handle->cur_size -= parse_len; if (0 == handle->packet.size)
{
LOGD("handle->packet.size is 0, need read more data");
return DecNeedMoreData;
} int decode_ret = avcodec_decode_video2(handle->pCodecCtx, handle->pFrame, &(handle->got_picture),
&(handle->packet)); if (decode_ret < 0)
{
LOGE("avcodec_decode_video2 failed");
return DecFailed;
} if (handle->got_picture)
{
if (handle->first_time)
{
LOGD("CodecCtx->codec->long_name [%s]", handle->pCodecCtx->codec->long_name);
LOGD("CodecCtx->width [%d], CodecCtx->height [%d]", handle->pCodecCtx->width, handle->pCodecCtx->height); handle->img_convert_ctx = sws_getContext(handle->pCodecCtx->width, handle->pCodecCtx->height,
handle->pCodecCtx->pix_fmt, handle->pCodecCtx->width, handle->pCodecCtx->height, TARGET_VIDEO_TYPE,
SWS_BICUBIC, NULL, NULL, NULL); handle->pRGBFrame = av_frame_alloc(); handle->out_buffer = (uint8_t *) av_malloc(
avpicture_get_size(TARGET_VIDEO_TYPE, handle->pCodecCtx->width, handle->pCodecCtx->height)); avpicture_fill((AVPicture *) handle->pRGBFrame, handle->out_buffer, TARGET_VIDEO_TYPE,
handle->pCodecCtx->width, handle->pCodecCtx->height); handle->first_time = 0;
} sws_scale(handle->img_convert_ctx, (const uint8_t* const *) handle->pFrame->data, handle->pFrame->linesize, 0,
handle->pCodecCtx->height, handle->pRGBFrame->data, handle->pRGBFrame->linesize);
} return DecSuccess;
} DECODERESULT DecodeH264ToRGB(int decodeHandle, uint8_t* in_buffer, int in_len, uint8_t** out_buffer, int* out_len)
{
H264DecodeHandler* handle = (H264DecodeHandler*) decodeHandle; if(handle->cur_size == 0)
{
handle->cur_ptr = in_buffer;
handle->cur_size = in_len;
} DECODERESULT decode_result = DecodeOneFrame((int) handle); if (DecSuccess == decode_result)
{
*out_buffer = handle->pRGBFrame->data[0];
*out_len = handle->pCodecCtx->width * handle->pCodecCtx->height * handle->dst_bpp;
} return decode_result;
} C_BOOL __DecodeH264Video(FILE* fp_in, FILE* fp_out)
{
H264DecodeHandler* handle = (H264DecodeHandler*) InitH264Decoder();
if (handle == NULL)
{
LOGE("init h264 decoder failed");
return FALSE;
} uint8_t in_buffer[IN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
memset(in_buffer, 0, sizeof(in_buffer)); C_BOOL need_read_from_file = TRUE;
int read_size = 0;
int frame_index = 0;
uint8_t* out_buffer = NULL;
int out_len = 0;
while (TRUE)
{
if (need_read_from_file == TRUE)
{
if ((read_size = fread(in_buffer, 1, IN_BUFFER_SIZE, fp_in)) == 0)
{
LOGD("read all data from file, end!!!");
break;
}
LOGD("read from file size is [%d]", read_size);
} DECODERESULT decode_result = DecodeH264ToRGB((int) handle, in_buffer, read_size, &out_buffer, &out_len); if (DecFailed == decode_result)
{
LOGE("decode one frame failed");
break;
} if (DecSuccess == decode_result)
{
fwrite(out_buffer, 1, out_len, fp_out);
++frame_index;
LOGD("succeed to decode one frame, frame index [%d]", frame_index);
} if (DecNeedMoreData == decode_result)
{
need_read_from_file = TRUE;
}
else
{
need_read_from_file = FALSE;
}
} ReleaseH264Decoder((int) handle); return TRUE;
}

H264转成RGB24格式-2016.01.21的更多相关文章

  1. 详解H264视频格式-2016.01.28

    专业名词解释 VCL(Video Coding Layer)视频编码层 NAL(Network Abstraction Layer)网络提取层 SPS(Sequence Parameter Set) ...

  2. H264编码 封装成MP4格式 视频流 RTP封包

    H264编码 封装成MP4格式 视频流 RTP封包         分类:             多媒体编程              2013-02-20 21:31     3067人阅读    ...

  3. MySQL Binlog Mixed模式记录成Row格式

    背景: 一个简单的主从结构,主的binlog format是Mixed模式,在执行一条简单的导入语句时,通过mysqlbinlog导出发现记录的Binlog全部变成了Row的格式(明明设置的是Mixe ...

  4. [官方软件] Easy Sysprep v4.3.29.602 【系统封装部署利器】(2016.01.22)--skyfree大神

    [官方软件] Easy Sysprep v4.3.29.602 [系统封装部署利器](2016.01.22) Skyfree 发表于 2016-1-22 13:55:55 https://www.it ...

  5. FFMpeg ver 20160219-git-98a0053 滤镜中英文对照 2016.02.21 by 1CM

    FFMpeg ver 20160219-git-98a0053 滤镜中英文对照 2016.02.21 by 1CM T.. = Timeline support 支持时间轴 .S. = Slice t ...

  6. 将jpg压缩成webp格式的图片

    cwebp名称 cwebp -压缩图像文件为的WebP文件概要 cwebp [选项] INPUT_FILE -o output_file.webp描述 cwebp压缩使用的WebP格式的图像.输入格式 ...

  7. 关于springmvc下服务器文件打包成zip格式下载功能

    关于springmvc下服务器文件打包成zip格式下载功能 2016年09月21日 11:22:14 toxic_guantou 阅读数:5731更多 个人分类: 技术点存储   版权声明:本文为博主 ...

  8. CAFFE学习笔记(四)将自己的jpg数据转成lmdb格式

    1 引言 1-1 以example_mnist为例,如何加载属于自己的测试集? 首先抛出一个问题:在example_mnist这个例子中,测试集是人家给好了的.那么如果我们想自己试着手写几个数字然后验 ...

  9. [转] 将DOS格式文本文件转换成UNIX格式

    点击此处阅读原文 用途说明 dos2unix命令用来将DOS格式的文本文件转换成UNIX格式的(DOS/MAC to UNIX text file format converter).DOS下的文本文 ...

随机推荐

  1. ExtJs4 SpringMvc3 实现Grid 分页

    新建一个Maven webapp项目,webxml以及spring配置没什么需要注意的,不再赘述. Maven依赖:(个人习惯,有用没用的都加上...) <project xmlns=" ...

  2. pycharm 格式化代码

    有时候将空格键和tab键混用,在windows上没什么事情,但是如果移动到linux就会有问题,所以我们在移动到linux上之前要先格式化一下代码: ctrl+alt+L可以格式化,但是和锁屏快捷键冲 ...

  3. uboot 的内存命令使用 mw (修改) md (显示)

    修改:mw [内存地址] [值] [长度] 例如:mw 0x02000000 0 128 表示修改地址为0x02000000~0x02000000+128的内存值为0. 显示:md [内存地址] [长 ...

  4. 【转】H264编码原理以及I帧B帧P帧

    前言 H264是新一代的编码标准,以高压缩高质量和支持多种网络的流媒体传输著称,在编码方面,我理解的他的理论依据是:参照一段时间内图像的统计结果表明,在相邻几幅图像画面中,一般有差别的像素只有10%以 ...

  5. mapreduce执行流程

    角色描述:JobClient:执行任务的客户端JobTracker:任务调度器TaskTracker:任务跟踪器Task:具体的任务(Map OR Reduce) 从生命周期的角度来看,mapredu ...

  6. Condition的优点

    那么引入本篇的主角,Condition,Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现 ...

  7. GDI+ 中发生一般性错误。

    GDI+ 中发生一般性错误. “/wechat”应用程序中的服务器错误. GDI+ 中发生一般性错误. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及 ...

  8. mongoDB索引使用

    for(var i=0;i<10000;i++){ db.user.insert({name:"user"+i,age:i}) }添加这么多数据 db.user.find({ ...

  9. mysql索引之四(索引使用注意规则:索引失效--存在索引但不使用索引)

    但是如果是同样的sql如果在之前能够使用到索引,那么现在使用不到索引,以下几种主要情况: 1. 随着表的增长,where条件出来的数据太多,大于15%,使得索引失效(会导致CBO计算走索引花费大于走全 ...

  10. 微信中得到的GPS经纬度放在百度,腾迅地图中不准的原因及处理

    微信中可以得到两种GPS坐标信息  默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' 一种是全球的正常GPS坐标信息 wgs84 . GPS,W ...