android 渲染bgr24,H264转成RGB24格式-2016.01.21

该代码片段展示了使用FFmpeg库进行H264视频解码并转换为RGB格式的过程。它包含了初始化解码器、解码帧以及将解码后的帧转换为RGB格式的函数。程序首先打开输入的H264视频文件,然后读取数据,解码每一帧,并将结果写入RGB输出文件。整个流程涉及到了AVCodec、AVFrame和Swscale等核心组件。
摘要由CSDN通过智能技术生成

#include "libavcodec/avcodec.h"#include"libswscale/swscale.h"#include"libavutil/opt.h"#include"libavutil/imgutils.h"#include#include#include#includetypedefenum{

FALSE= 0, TRUE = 1,

} C_BOOL;

typedef unsignedcharuint8_t;#define IN_BUFFER_SIZE 4098

#define LOGE(format, ...) __android_log_print(ANDROID_LOG_ERROR, "(>_

#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.rgb24";

FILE*fp_out = fopen(filepath_out, "wb");if (NULL ==fp_out)

{

LOGE("open output yuv 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;

}

typedefstruct{

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;intcur_size;intfirst_time;intgot_picture;intupdate_in_buffer;

} H264DecodeHandler;

JNIEXPORT jint JNICALL Java_com_zhoulee_h264decoder_MainActivity_InitH264Decoder(JNIEnv*env, jobject obj)

{return 0;

}intInitH264Decoder()

{

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->update_in_buffer = 1;return (int) handle;

}void ReleaseH264Decoder(intdecodeHandle)

{

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)

{

}

typedefenum{

DecFailed= 0, DecSuccess = 1, DecNeedMoreData = 2,

} DECODERESULT;

DECODERESULT DecodeOneFrame(intdecodeHandle)

{

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");returnDecNeedMoreData;

}int decode_ret = avcodec_decode_video2(handle->pCodecCtx, handle->pFrame, &(handle->got_picture),&(handle->packet));if (decode_ret < 0)

{

LOGE("avcodec_decode_video2 failed");returnDecFailed;

}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, AV_PIX_FMT_RGB24,

SWS_BICUBIC, NULL, NULL, NULL);

handle->pRGBFrame =av_frame_alloc();

handle->out_buffer = (uint8_t *) av_malloc(

avpicture_get_size(AV_PIX_FMT_RGB24, handle->pCodecCtx->width, handle->pCodecCtx->height));

avpicture_fill((AVPicture*) handle->pRGBFrame, handle->out_buffer, AV_PIX_FMT_RGB24,

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);

}returnDecSuccess;

}

DECODERESULT DecodeH264ToRGB(int decodeHandle, uint8_t* in_buffer, int in_len, uint8_t** out_buffer, int*out_len)

{

H264DecodeHandler* handle = (H264DecodeHandler*) decodeHandle;if(handle->update_in_buffer == 1)

{

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 * 3;

}if (handle->cur_size == 0)

{

handle->update_in_buffer = 1;

}else{

handle->update_in_buffer = 0;

}returndecode_result;

}

C_BOOL __DecodeH264Video(FILE* fp_in, FILE*fp_out)

{

H264DecodeHandler* handle = (H264DecodeHandler*) InitH264Decoder();if (handle ==NULL)

{

LOGE("init h264 decoder failed");returnFALSE;

}

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);returnTRUE;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值