|
[原创 ]如何在Android平台实现H.264视频数据压制与传送
发表于 2014-10-28 16:17:59
浏览:56352
|
回复:24
打印
只看该作者
[复制链接]
楼主
本帖最后由 error结构体 于 2014-10-28 16:51 编辑
本帖子主要展示如何在Android平台实现对摄像头数据采集,再通过JNI调用ffmpeg库压制成H.264格式的视频数据,再通过简单UDP协议外发到WIN平台的简易例程,没有实现RTSP和考虑的效率,。实现步骤如下:
1、Android 摄像部分代码实现摄像数据采集。上传代码部分没有实现设定采集YUV数据的宽高。
- @Override
- public void onPreviewFrame(byte[] arg0, Camera arg1) {
- // TODO Auto-generated method stub
- if(arg0 != null)
- {
- int len = arg0.length;
- Log.i("xinw","len:"+String.valueOf(len));
- encodeprocess(arg0);
-
- }
- }
-
- public boolean getIsPreviewCallback()
- {
- return ispreviewcallback;
- }
- public void setIsPreviewCallback(boolean flag)
- {
- ispreviewcallback = flag;
- }
复制代码 android端界面效果如下:
2、定义JNI接口,实现对FFMPEG库的调用。JAVA部分:
- static{
- System.loadLibrary("postproc-53");
- System.loadLibrary("avutil-54");
- System.loadLibrary("avcodec-56");
- System.loadLibrary("swresample-1");
- System.loadLibrary("avformat-56");
- System.loadLibrary("swscale-3");
- System.loadLibrary("avfilter-5");
- System.loadLibrary("avdevice-56");
- System.loadLibrary("x264");
- System.loadLibrary("ffmpeg_codec");
- }
- public native int encodeinit(String inputStr);
- public native int encodeprocess(byte[] yuv420spArr);
复制代码
PS:另外如何编译FFMPEG库和X264看我上一篇发的帖子:http://developer.t-firefly.com/thread-201-1-1.html
JNI的C语言的实现:
- //static void video_encode_example(int i)
- JNIEXPORT jint JNICALL Java_com_tchip_remotepushvideo_CameraPreview_encodeprocess(JNIEnv *env, jobject obj,jbyteArray yuvspArr)
- {
- jbyte *tmpHandle = (*env)->GetByteArrayElements(env,yuvspArr,NULL);
- av_init_packet(&pkt);
- pkt.data = NULL; // packet data will be allocated by the encoder
- pkt.size = 0;
- LOGD("ffmpeg cxx");
- /* prepare a dummy image */
- /* Y */
- for (y = 0; y < c->height; y++) {
- for (x = 0; x < c->width; x++) {
- frame->data[0][y * frame->linesize[0] + x] = tmpHandle[x + y*1024];
- }
- }
- /* Cb and Cr */
- for (y = 0; y < c->height/2; y++) {
- for (x = 0; x < c->width/2; x++) {
- frame->data[1][y * frame->linesize[1] + x] = tmpHandle[1024*768 + 512*y + 2*x + 1];
- frame->data[2][y * frame->linesize[2] + x] = tmpHandle[1024*768 + 512*y + 2*x];
-
- }
- }
- //以上代码作用是将YUV420SP转为YUV420P caixx
- frame->pts = i++;
- /* encode the image */
- ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
- if (ret < 0) {
- //fprintf(stderr, "Error encoding frame\n");
- //exit(1);
- }
- if (got_output) {
- //printf("Write frame %3d (size=%5d)\n", i, pkt.size);
- //printf("count:%d\n",g_h264q.size());
- //fwrite(pkt.data, 1, pkt.size, f);
- sendto(g_socket,pkt.data, pkt.size, 0, (struct sockaddr *)&g_addr, sizeof(g_addr));
- av_free_packet(&pkt);
- }
- }
复制代码
3、PC端实现对接收H.264数据的解码。效果如下:
其中代码部分主要是基于对ffmpeg中sample, decoding_encoding.c的改造。
PS:代码中的IP地址和数据数组宽高为了调试方便,都是绝对值,若要正常使用,请更改相关参数。
tcPlayersingle.rar
(11.21 MB, 下载次数: 269)
x264.tar.gz
(1.07 MB, 下载次数: 121)
ffmpeg.tar.gz
(8.84 MB, 下载次数: 128)
ffmpeg_codec.tar.gz
(201.91 KB, 下载次数: 96)
remotepushvideo.tar.gz
(71.45 KB, 下载次数: 99)
|
|