android - 使用 ffmpeg (sws_scale) 将图像编码为视频

标签 android video encoding ffmpeg scale

我正在尝试使用 ffmpeg 库将图像编码为视频。
我有这些全局参数:

//Global params
AVCodec         *codec;
AVCodecContext  *codecCtx;
uint8_t         *output_buffer;
int             output_buffer_size;

我将编码分为3种方法:
初始化编码器:
jint Java_com_camera_simpledoublewebcams2_CameraPreview_initencoder(JNIEnv* env,jobject thiz){
avcodec_register_all();
avcodec_init();
av_register_all();

int fps = 30;

/* find the H263 video encoder */
codec = avcodec_find_encoder(CODEC_ID_H263);
if (!codec) {
    LOGI("avcodec_find_encoder() run fail.");
    return -5;
}

//allocate context
codecCtx = avcodec_alloc_context();

/* put sample parameters */
codecCtx->bit_rate = 400000;
/* resolution must be a multiple of two */
codecCtx->width = 176;
codecCtx->height = 144;
/* frames per second */
codecCtx->time_base = (AVRational){1,fps};
codecCtx->pix_fmt = PIX_FMT_YUV420P;
codecCtx->codec_id = CODEC_ID_H263;
codecCtx->codec_type = AVMEDIA_TYPE_VIDEO;

/* open it */
if (avcodec_open(codecCtx, codec) < 0) {
    LOGI("avcodec_open() run fail.");
    return -10;
}

//init buffer
output_buffer_size = 500000;
output_buffer = malloc(output_buffer_size);

return 0;

}

编码图像:
jint Java_com_camera_simpledoublewebcams2_CameraPreview_encodejpeg(JNIEnv* env,jobject thiz,jchar* cImage, jint imageSize){
int             out_size;
AVFrame         *picture;
AVFrame         *outpic;
uint8_t         *outbuffer;

//allocate frame    
picture = avcodec_alloc_frame();    
outpic = avcodec_alloc_frame();

int nbytes = avpicture_get_size(PIX_FMT_YUV420P, codecCtx->width, codecCtx->height);
outbuffer = (uint8_t*)av_malloc(nbytes);
outpic->pts = 0;

//fill picture with image
avpicture_fill((AVPicture*)picture, (uint8_t*)cImage, PIX_FMT_RGBA, codecCtx->width, codecCtx->height);
//fill outpic with empty image
avpicture_fill((AVPicture*)outpic, outbuffer, PIX_FMT_YUV420P, codecCtx->width, codecCtx->height);

//rescale the image 
struct SwsContext* fooContext = sws_getContext(codecCtx->width, codecCtx->height, 
                                                       PIX_FMT_RGBA, 
                                                       codecCtx->width, codecCtx->height, 
                                                       PIX_FMT_YUV420P, 
                                                       SWS_FAST_BILINEAR, NULL, NULL, NULL);
sws_scale(fooContext, picture->data, picture->linesize, 0, codecCtx->height, outpic->data, outpic->linesize);   

//encode the image
out_size = avcodec_encode_video(codecCtx, output_buffer, output_buffer_size, outpic);
out_size += avcodec_encode_video(codecCtx, output_buffer, output_buffer_size, outpic);

//release pictures
av_free(outbuffer);
av_free(picture);
av_free(outpic);

return out_size;

}

并关闭编码器:
void Java_com_camera_simpledoublewebcams2_CameraPreview_closeencoder(JNIEnv* env,jobject thiz){
free(output_buffer);
avcodec_close(codecCtx);
av_free(codecCtx);

}

当我发送第一张图像时,我会从编码器中得到一个结果。当我尝试发送另一个图像时,程序崩溃了。
我尝试调用 init 一次,然后调用图像,然后关闭 - 不起作用。
我尝试为每个图像调用初始化和关闭 - 没有用。

有什么建议么?

谢谢!

编辑:经过进一步研究,我发现问题出在 sws_scale方法。
仍然不知道是什么导致了这个问题......

最佳答案

out_size = avcodec_encode_video(codecCtx, output_buffer,output_buffer_size, outpic);

out_size += avcodec_encode_video(codecCtx, output_buffer, output_buffer_size,outpic);


为什么要编码两次?
也许错误是由于双重编码造成的。尝试删除第二个编码。

关于android - 使用 ffmpeg (sws_scale) 将图像编码为视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11329116/

相关文章:

javascript - 服务器端从html页面(不是jsp)输出编码以防止XSS

android - --prod 标志导致在 Android 7 的 Ionic 3 应用程序中不显示键盘

android - ListView 替代颜色

html - 摆脱 html 视频标签的水平溢出

javascript - 更改 JavaScript 字符串编码

MySQL 数据库显示 Lik 'רולר חו×'

java - 我尝试纠正这个问题,但我做不到

android - 如何正确集成 Listener Bindings 和 Lambda 表达式

python - 如何合并两个视频?

video - 无需下载整个文件即可获取媒体持续时间