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

时间:2012-07-04 12:28:11

标签: 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一次然后是图像,然后关闭 - 没有用。 我尝试为每个图像调用init和close - 没有用。

有什么建议吗?

谢谢!

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

1 个答案:

答案 0 :(得分:1)

  

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

     

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

为什么要编码两次?

错误可能是由于双重编码造成的。尝试删除第二个编码。