android4.0 USB Camera实例(六)ffmpeg mpeg编码

前面本来说是做h264编码的 研究了两天发现ffmpeg里的h264编码似乎是要信赖第三方库x264 还是怎么简单怎么来吧所以就整了个mpeg编码 ffmpeg移植前面我有一篇ffmpeg解码里已经给了 具体链接在这http://blog.csdn.net/hclydao/article/details/18546757

怎么使用那里面也已经说了 这里主要是通过ffmpeg将yuv422格式转换成rgb 然后就是yuv422转成mpeg格式 接前面几篇 获取到yuv422数据后 为了能显示出来 所以先转换成rgb565的数据 接口函数如下

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2. * yuv to rgb 
  3. */  
  4. JNIEXPORT jint JNICALL Java_com_hclydao_webcam_Ffmpeg_yuvtorgb(JNIEnv * env, jclass obj,const jbyteArray yuvdata, jbyteArray rgbdata,const jint dwidth,const jint dheight)  
  5. {  
  6.     jbyte *ydata = (jbyte*)(*env)->GetByteArrayElements(env, yuvdata, 0);  
  7.     jbyte *rdata = (jbyte*)(*env)->GetByteArrayElements(env, rgbdata, 0);  
  8.     AVFrame * rpicture=NULL;  
  9.     AVFrame * ypicture=NULL;  
  10.     struct SwsContext *swsctx = NULL;  
  11.     rpicture=avcodec_alloc_frame();  
  12.     ypicture=avcodec_alloc_frame();  
  13.     avpicture_fill((AVPicture *) rpicture, (uint8_t *)rdata, PIX_FMT_RGB565,dwidth,dheight);  
  14.     avpicture_fill((AVPicture *) ypicture, (uint8_t *)ydata, AV_PIX_FMT_YUYV422,mwidth,mheight);  
  15.     swsctx = sws_getContext(mwidth,mheight, AV_PIX_FMT_YUYV422, dwidth, dheight,PIX_FMT_RGB565, SWS_BICUBIC, NULL, NULL, NULL);  
  16.     sws_scale(swsctx,(const uint8_t* const*)ypicture->data,ypicture->linesize,0,mheight,rpicture->data,rpicture->linesize);  
  17.     sws_freeContext(swsctx);  
  18.     av_free(rpicture);  
  19.     av_free(ypicture);  
  20.     (*env)->ReleaseByteArrayElements(env, yuvdata, ydata, 0);  
  21.     (*env)->ReleaseByteArrayElements(env, rgbdata, rdata, 0);  
  22.     return 0;  
  23. }  

然后就是mpeg编码了 网上说ffmpeg只能将yuv420p的编码 所以要先将yuv422转成yuv420p后在进行编码 相关接口函数如下

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. AVCodecContext *pCodecCtx= NULL;  
  2. AVPacket avpkt;  
  3. FILE * video_file;  
  4. unsigned char *outbuf=NULL;  
  5. unsigned char *yuv420buf=NULL;  
  6. static int outsize=0;  
  7. /* 
  8. * encording init 
  9. */  
  10. JNIEXPORT jint JNICALL Java_com_hclydao_webcam_Ffmpeg_videoinit(JNIEnv * env, jclass obj,jbyteArray filename)  
  11. {  
  12.     LOGI("%s\n",__func__);  
  13.     AVCodec * pCodec=NULL;  
  14.     avcodec_register_all();  
  15.     pCodec=avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO);  
  16.     if(pCodec == NULL) {  
  17.         LOGE("++++++++++++codec not found\n");  
  18.         return -1;  
  19.     }   
  20.     pCodecCtx=avcodec_alloc_context3(pCodec);  
  21.     if (pCodecCtx == NULL) {  
  22.         LOGE("++++++Could not allocate video codec context\n");  
  23.         return -1;  
  24.     }  
  25.     /* put sample parameters */  
  26.     pCodecCtx->bit_rate = 400000;  
  27.     /* resolution must be a multiple of two */  
  28.     pCodecCtx->width = mwidth;  
  29.     pCodecCtx->height = mheight;  
  30.     /* frames per second */  
  31.     pCodecCtx->time_base= (AVRational){1,25};  
  32.     pCodecCtx->gop_size = 10/* emit one intra frame every ten frames */  
  33.     pCodecCtx->max_b_frames=1;  
  34.     pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;//AV_PIX_FMT_YUYV422;  
  35.     /* open it */  
  36.     if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {  
  37.         LOGE("+++++++Could not open codec\n");  
  38.         return -1;  
  39.     }  
  40.     outsize = mwidth * mheight*2;  
  41.     outbuf = malloc(outsize*sizeof(char));  
  42.     yuv420buf = malloc(outsize*sizeof(char));  
  43.     jbyte *filedir = (jbyte*)(*env)->GetByteArrayElements(env, filename, 0);  
  44.     if ((video_file = fopen(filedir, "wb")) == NULL) {  
  45.         LOGE("++++++++++++open %s failed\n",filedir);  
  46.         return -1;  
  47.     }  
  48.     (*env)->ReleaseByteArrayElements(env, filename, filedir, 0);  
  49.     return 1;  
  50. }  
  51.   
  52. JNIEXPORT jint JNICALL Java_com_hclydao_webcam_Ffmpeg_videostart(JNIEnv * env, jclass obj,jbyteArray yuvdata)  
  53. {  
  54.     int frameFinished=0,size=0;  
  55.     jbyte *ydata = (jbyte*)(*env)->GetByteArrayElements(env, yuvdata, 0);  
  56.     AVFrame * yuv420pframe=NULL;  
  57.     AVFrame * yuv422frame=NULL;  
  58.     struct SwsContext *swsctx = NULL;  
  59.     yuv420pframe=avcodec_alloc_frame();  
  60.     yuv422frame=avcodec_alloc_frame();  
  61.     avpicture_fill((AVPicture *) yuv420pframe, (uint8_t *)yuv420buf, AV_PIX_FMT_YUV420P,mwidth,mheight);  
  62.     avpicture_fill((AVPicture *) yuv422frame, (uint8_t *)ydata, AV_PIX_FMT_YUYV422,mwidth,mheight);  
  63.     swsctx = sws_getContext(mwidth,mheight, AV_PIX_FMT_YUYV422, mwidth, mheight,AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);  
  64.     sws_scale(swsctx,(const uint8_t* const*)yuv422frame->data,yuv422frame->linesize,0,mheight,yuv420pframe->data,yuv420pframe->linesize);  
  65.     av_init_packet(&avpkt);  
  66.     size = avcodec_encode_video2(pCodecCtx, &avpkt, yuv420pframe, &frameFinished);  
  67.     if (size < 0) {  
  68.         LOGE("+++++Error encoding frame\n");  
  69.         return -1;  
  70.     }  
  71.     if(frameFinished)  
  72.         fwrite(avpkt.data,avpkt.size,1,video_file);  
  73.     av_free_packet(&avpkt);  
  74.     sws_freeContext(swsctx);  
  75.     av_free(yuv420pframe);  
  76.     av_free(yuv422frame);  
  77.     (*env)->ReleaseByteArrayElements(env, yuvdata, ydata, 0);  
  78. }  
  79.   
  80. JNIEXPORT jint JNICALL Java_com_hclydao_webcam_Ffmpeg_videoclose(JNIEnv * env, jclass obj)  
  81. {  
  82.     fclose(video_file);  
  83.     avcodec_close(pCodecCtx);  
  84.     av_free(pCodecCtx);  
  85.     free(outbuf);  
  86. }  
最后录下来的视频是可以用播放的 总感觉代码好像哪里写的不对 bug总是有的 过程和原理搞清楚了其它就容易了

下面是我录的 至此摄像头这块暂时就这样了

这测试我又重新新建了一个工程

整个工程下载链接 请去我的资源里找吧 我上传了没显示出来 那个有20几M的就是的了 

这个bug很多 没怎么认真去写 如果原理和过程有问题的希望大家指出


============================================
作者:hclydao
http://blog.csdn.net/hclydao
版权没有,但是转载请保留此段声明

============================================


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值