#include
<jni.h>
#include
<string.h>
#include
<stdio.h>
#include
<android/log.h>
#include
<android/bitmap.h>
#include
<libavcodec/avcodec.h>
#include
<libavformat/avformat.h>
#include
<libswscale/swscale.h>
#define
LOG_TAG "FFMPEGSample"
#define
LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define
LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
AVFormatContext
*pFormatCtx;
AVCodecContext
*pCodecCtx;
AVFrame
*pFrame;
AVFrame
*pFrameRGB;
int
videoStream;
static
void
fill_bitmap(AndroidBitmapInfo* info,
void
*pixels, AVFrame *pFrame)
{
uint8_t
*frameLine;
int
yy;
for
(yy = 0; yy < info->height; yy++) {
uint8_t*
line = (uint8_t*)pixels;
frameLine
= (uint8_t *)pFrame->data[0] + (yy * pFrame->linesize[0]);
int
xx;
for
(xx = 0; xx < info->width; xx++) {
int
out_offset = xx * 4;
int
in_offset = xx * 3;
line[out_offset]
= frameLine[in_offset];
line[out_offset+1]
= frameLine[in_offset+1];
line[out_offset+2]
= frameLine[in_offset+2];
line[out_offset+3]
= 0;
}
pixels
= (
char
*)pixels
+ info->stride;
}
}
void
Java_com_churnlabs_ffmpegsample_MainActivity_openFile(JNIEnv * env, jobject
this
)
{
int
ret;
int
err;
int
i;
AVCodec
*pCodec;
uint8_t
*buffer;
int
numBytes;
av_register_all();
LOGE(
"Registered
formats"
);
err
= av_open_input_file(&pFormatCtx,
"file:/sdcard/vid.3gp"
,
NULL, 0, NULL);
LOGE(
"Called
open file"
);
if
(err!=0)
{
LOGE(
"Couldn't
open file"
);
return
;
}
LOGE(
"Opened
file"
);
if
(av_find_stream_info(pFormatCtx)<0)
{
LOGE(
"Unable
to get stream info"
);
return
;
}
videoStream
= -1;
for
(i=0; i<pFormatCtx->nb_streams; i++) {
if
(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
{
videoStream
= i;
break
;
}
}
if
(videoStream==-1)
{
LOGE(
"Unable
to find video stream"
);
return
;
}
LOGI(
"Video
stream is [%d]"
,
videoStream);
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if
(pCodec==NULL)
{
LOGE(
"Unsupported
codec"
);
return
;
}
if
(avcodec_open(pCodecCtx,
pCodec)<0) {
LOGE(
"Unable
to open codec"
);
return
;
}
pFrame=avcodec_alloc_frame();
pFrameRGB=avcodec_alloc_frame();
LOGI(
"Video
size is [%d x %d]"
,
pCodecCtx->width, pCodecCtx->height);
numBytes=avpicture_get_size(PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);
分配空间
buffer=(uint8_t
*)av_malloc(numBytes*
sizeof
(uint8_t));
avpicture_fill((AVPicture
*)pFrameRGB, buffer, PIX_FMT_RGB24,
pCodecCtx->width,
pCodecCtx->height);
}
void
Java_com_churnlabs_ffmpegsample_MainActivity_drawFrame(JNIEnv * env, jobject
this
,
jstring bitmap)
{
AndroidBitmapInfo
info;
void
*
pixels;
int
ret;
int
err;
int
i;
int
frameFinished = 0;
AVPacket
packet;
static
struct
SwsContext *img_convert_ctx;
int64_t
seek_target;
if
((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE(
"AndroidBitmap_getInfo()
failed ! error=%d"
,
ret);
return
;
}
LOGE(
"Checked
on the bitmap"
);
if
((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
LOGE(
"AndroidBitmap_lockPixels()
failed ! error=%d"
,
ret);
}
LOGE(
"Grabbed
the pixels"
);
i
= 0;
while
((i==0)
&& (av_read_frame(pFormatCtx, &packet)>=0)) {
if
(packet.stream_index==videoStream)
{
avcodec_decode_video2(pCodecCtx,
pFrame, &frameFinished, &packet);
if
(frameFinished)
{
LOGE(
"packet
pts %llu"
,
packet.pts);
int
target_width = 320;
int
target_height = 240;
img_convert_ctx
= sws_getContext(pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt,
target_width,
target_height, PIX_FMT_RGB24, SWS_BICUBIC,
NULL,
NULL, NULL);
if
(img_convert_ctx
== NULL) {
LOGE(
"could
not initialize conversion context\n"
);
return
;
}
sws_scale(img_convert_ctx,
(
const
uint8_t*
const
*)pFrame->data,
pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
fill_bitmap(&info,
pixels, pFrameRGB);
i
= 1;
}
}
av_free_packet(&packet);
}
AndroidBitmap_unlockPixels(env,
bitmap);
}
int
seek_frame(
int
tsms)
{
int64_t
frame;
frame
= av_rescale(tsms,pFormatCtx->streams[videoStream]->time_base.den,pFormatCtx->streams[videoStream]->time_base.num);
frame/=1000;
if
(avformat_seek_file(pFormatCtx,videoStream,0,frame,frame,AVSEEK_FLAG_FRAME)<0)
{
return
0;
}
avcodec_flush_buffers(pCodecCtx);
return
1;
}
void
Java_com_churnlabs_ffmpegsample_MainActivity_drawFrameAt(JNIEnv * env, jobject
this
,
jstring bitmap, jint secs)
{
AndroidBitmapInfo
info;
void
*
pixels;
int
ret;
int
err;
int
i;
int
frameFinished = 0;
AVPacket
packet;
static
struct
SwsContext *img_convert_ctx;
int64_t
seek_target;
if
((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE(
"AndroidBitmap_getInfo()
failed ! error=%d"
,
ret);
return
;
}
LOGE(
"Checked
on the bitmap"
);
if
((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
LOGE(
"AndroidBitmap_lockPixels()
failed ! error=%d"
,
ret);
}
LOGE(
"Grabbed
the pixels"
);
seek_frame(secs
* 1000);
i
= 0;
while
((i== 0) && (av_read_frame(pFormatCtx, &packet)>=0)) {
if
(packet.stream_index==videoStream)
{
avcodec_decode_video2(pCodecCtx,
pFrame, &frameFinished, &packet);
if
(frameFinished)
{
int
target_width = 320;
int
target_height = 240;
img_convert_ctx
= sws_getContext(pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt,
target_width,
target_height, PIX_FMT_RGB24, SWS_BICUBIC,
NULL,
NULL, NULL);
if
(img_convert_ctx
== NULL) {
LOGE(
"could
not initialize conversion context\n"
);
return
;
}
sws_scale(img_convert_ctx,
(
const
uint8_t*
const
*)pFrame->data,
pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
fill_bitmap(&info,
pixels, pFrameRGB);
i
= 1;
}
}
av_free_packet(&packet);
}
AndroidBitmap_unlockPixels(env,
bitmap);
}
相关推荐
ffmpeg库:ffmpeg-n5.1-latest-win64-gpl-shared-5.1
使用FFmpeg合并MP4视频 ffmpeg -i 1.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 1.ts ffmpeg -i 2.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 2.ts ffmpeg -i "concat:1.ts|2.ts" -acodec ...
可以使用的ffmpeg-4.2.2-win64-static.zip
资源分类:Python库 所属语言:Python 使用前提:需要解压 资源全名:imageio_ffmpeg-0.4.1-py3-none-win32.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了目前领先的音/视频编码库libavcodec。 FFmpeg是在 Linux 下开发出来的,但它可以在包括 Windows 在内的大多数操作系统中...
ffmpeg-3.1.2-1.2-android-x86.jar是javaCV-FFmpeg在安卓x86平台的依赖包
Android-ffmpeg-android-java.zip,使用HTTPS://GithuB.COM/Wrngs/FFMPEG-Android编译的FFMPEG二进制的Android Java库,安卓系统是谷歌在2008年设计和制造的。操作系统主要写在爪哇,C和C 的核心组件。它是在linux内核...
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了目前领先的音/视频编码库libavcodec。 FFmpeg是在 Linux 下开发出来的,但它可以在包括 Windows 在内的大多数操作系统中...
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了目前领先的音/视频编码库libavcodec。 FFmpeg是在 Linux 下开发出来的,但它可以在包括 Windows 在内的大多数操作系统中...
FFMPEG-AAC-264-Android-32-64,安卓、ffmpeg、fdk、aac、arm、32/64、x86、32/64、mips、android7.0。.zip
【Android FFMPEG 开发】Android 中执行 FFMPEG 指令 ( 集成 mobile-ffmpeg 框架 | 完整代码示例 ) https://hanshuliang.blog.csdn.net/article/details/123731092 博客源码 一、配置远程 Maven 仓库 二、配置...
为安卓平台编译的 ffmpeg库,支持anroid-api-21,有功能开发需求者也可以联系本人, 有其他平台编译库需求者可联系我
以前从ffmpeg官网下的,现在官网的下载跟以前版本不一样了,这两个跟现有的教程用起来比较接近,找了好久也没有从官网下载成功,分享出来方便和我有一样需求的朋友
赠送jar包:ffmpeg-4.3.2-1.5.5.jar; 赠送原API文档:ffmpeg-4.3.2-1.5.5-javadoc.jar; 赠送源代码:ffmpeg-4.3.2-1.5.5-sources.jar; 赠送Maven依赖信息文件:ffmpeg-4.3.2-1.5.5.pom; 包含翻译后的API文档:...
Download ffmpeg 4.4 Mac 64-bit 22MB April 9, 2021
ffmpeg-3.2-win32-dev.zip
ffmpeg-3.1.2-1.2-android-arm.jar是javaCV-FFmpeg安卓端arm平台的依赖包
FFmpeg sdk 3.2 ,音视频解码器,支持众多格式。内有文档。开发方便。
ffmpeg-master-latest-win64-gpl.zip