add user input
[rtmpclient.git] / app / src / main / jni / ai_suanzi_rtmpclient_Ffmpeg.cpp
1 //
2 // Created by Peng Li on 30/4/2018.
3 //
4 #include "ai_suanzi_rtmpclient_Ffmpeg.h"
5 #include <android/native_window.h>
6 #include <android/native_window_jni.h>
7 #include "log.h"
8 #include <stdlib.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <limits.h>
12 #include <unistd.h>
13
14 extern "C" {
15     #include "libavformat/avformat.h"
16     #include "libavcodec/avcodec.h"
17     #include "libswscale/swscale.h"
18     #include "libavutil/imgutils.h"
19     #include "libavutil/time.h"
20     #include "libavdevice/avdevice.h"
21 }
22
23 int64_t start_time;
24 AVFormatContext *ofmt_ctx;
25 AVStream* video_st;
26 AVCodecContext* pCodecCtx;
27 AVCodec* pCodec;
28 AVPacket enc_pkt;
29 AVFrame *pFrameYUV;
30
31
32 void custom_log(void *ptr, int level, const char* fmt, va_list vl){
33     //To TXT file
34     /*FILE *fp=fopen("/storage/emulated/0/av_log.txt","a+");
35     if(fp){
36     vfprintf(fp,fmt,vl);
37     fflush(fp);
38     fclose(fp);
39     }  */
40     //To Logcat
41     // LOGE(fmt, vl);
42     static int print_prefix = 1;
43     //static char prev[1024];
44     char line[1024];
45
46     av_log_format_line(ptr, level, fmt, vl, line, sizeof(line), &print_prefix);
47
48     //strcpy(prev, line);
49     //sanitize((uint8_t *)line);
50
51     if (level <= AV_LOG_WARNING){
52         LOGE("%s", line);
53     } else {
54         LOGE("%s", line);
55     }
56 }
57
58
59 int framecnt = 0;
60 int yuv_width;
61 int yuv_height;
62 int y_length;
63 int uv_length;
64
65 JNIEXPORT void JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_init__ (JNIEnv *env, jobject obj ){
66     LOGE("########## Ffmpeg Init ##########");
67     unsigned int v = avutil_version();
68     LOGE("libavutil - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v));
69     v = avcodec_version();
70     LOGE("libavcodec - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v));
71     v = avformat_version();
72     LOGE("libavformat - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v));
73     v = avdevice_version();
74     LOGE("libavdevice - %d.%d.%d", AV_VERSION_MAJOR(v), AV_VERSION_MINOR(v), AV_VERSION_MICRO(v));
75
76     av_log_set_level(AV_LOG_TRACE);
77     av_register_all();
78     avdevice_register_all();
79     avformat_network_init();
80     av_log_set_callback(custom_log);
81 }
82
83
84 JNIEXPORT jstring JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_getVersion (JNIEnv *env, jobject obj) {
85     jint v = avformat_version();
86         LOGE("######### Ffmpeg JNI version i= %d", v);
87
88         system("su -c chmod 666 /dev/video0");
89
90     LOGE("######### Ffmpeg JNI version i= %d", v);
91
92
93     /*AVFormatContext *pFormatCtx = avformat_alloc_context();
94             avdevice_register_all();
95               av_log_set_callback(custom_log);
96         AVInputFormat *ifmt=av_find_input_format("video4linux2");
97         LOGE("===%s===", ifmt->name);
98         if(avformat_open_input(&pFormatCtx,"/dev/video0",ifmt,NULL)!=0){
99             LOGE("Couldn't open input stream.\n");
100                 return env->NewStringUTF("===== error =======");
101
102             //return -1;
103         }*/
104
105     return env->NewStringUTF("====== Ffmpeg call =======");
106 }
107
108 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_init (JNIEnv *env, jobject obj, jint width, jint height) {
109
110         //const char* out_path = "/storage/emulated/0/Movies/output.flv";
111
112     //const char* out_path = "rtmp://192.168.1.35:1935/myapp/suanzi";
113     const char* out_path = "rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid";
114
115     // const char* out_path = "/storage/sdcard0/output.flv";
116
117
118
119     LOGE("Ffmpeg init, width=%d, heigh=%d", width, height);
120
121         yuv_width=width;
122         yuv_height=height;
123         y_length=width*height;
124         uv_length=width*height/4;
125
126
127         av_register_all();
128
129         //output initialize
130         avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", out_path);
131         //output encoder initialize
132         pCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
133         if (!pCodec){
134                 LOGE("Can not find encoder!\n");
135                 return -1;
136         }
137         pCodecCtx = avcodec_alloc_context3(pCodec);
138         pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
139         pCodecCtx->width = width;
140         pCodecCtx->height = height;
141         pCodecCtx->time_base.num = 1;
142         pCodecCtx->time_base.den = 30;
143         pCodecCtx->bit_rate = 800000;
144         pCodecCtx->gop_size = 300;
145         /* Some formats want stream headers to be separate. */
146         if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
147                 pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
148
149         //H264 codec param
150         //pCodecCtx->me_range = 16;
151         //pCodecCtx->max_qdiff = 4;
152         //pCodecCtx->qcompress = 0.6;
153         pCodecCtx->qmin = 10;
154         pCodecCtx->qmax = 51;
155         //Optional Param
156         pCodecCtx->max_b_frames = 3;
157         // Set H264 preset and tune
158         AVDictionary *param = 0;
159         av_dict_set(&param, "preset", "ultrafast", 0);
160         av_dict_set(&param, "tune", "zerolatency", 0);
161
162         if (avcodec_open2(pCodecCtx, pCodec, &param) < 0){
163                 LOGE("Failed to open encoder!\n");
164                 return -1;
165         }
166
167         //Add a new stream to output,should be called by the user before avformat_write_header() for muxing
168         video_st = avformat_new_stream(ofmt_ctx, pCodec);
169         if (video_st == NULL){
170                 return -1;
171         }
172         video_st->time_base.num = 1;
173         video_st->time_base.den = 30;
174         video_st->codec = pCodecCtx;
175
176         //Open output URL,set before avformat_write_header() for muxing
177         jint ret = 0;
178         if (( ret = avio_open(&ofmt_ctx->pb, out_path, AVIO_FLAG_READ_WRITE)) < 0){
179                 LOGE("Failed to open output file! return :%d\n", ret);
180                 return -1;
181         }
182
183         //Write File Header
184         avformat_write_header(ofmt_ctx, NULL);
185
186         start_time = av_gettime();
187     return 0;
188 }
189
190 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_flush (JNIEnv *env, jobject obj){
191         int ret;
192         int got_frame;
193         AVPacket enc_pkt;
194         if (!(ofmt_ctx->streams[0]->codec->codec->capabilities & CODEC_CAP_DELAY))
195                 return 0;
196         while (1) {
197                 enc_pkt.data = NULL;
198                 enc_pkt.size = 0;
199                 av_init_packet(&enc_pkt);
200                 ret = avcodec_encode_video2(ofmt_ctx->streams[0]->codec, &enc_pkt,
201                         NULL, &got_frame);
202                 if (ret < 0)
203                         break;
204                 if (!got_frame){
205                         ret = 0;
206                         break;
207                 }
208                 LOGE("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n", enc_pkt.size);
209
210                 //Write PTS
211                 AVRational time_base = ofmt_ctx->streams[0]->time_base;//{ 1, 1000 };
212                 AVRational r_framerate1 = { 60, 2 };
213                 AVRational time_base_q = { 1, AV_TIME_BASE };
214                 //Duration between 2 frames (us)
215                 int64_t calc_duration = (double)(AV_TIME_BASE)*(1 / av_q2d(r_framerate1));      //内部时间戳
216                 //Parameters
217                 enc_pkt.pts = av_rescale_q(framecnt*calc_duration, time_base_q, time_base);
218                 enc_pkt.dts = enc_pkt.pts;
219                 enc_pkt.duration = av_rescale_q(calc_duration, time_base_q, time_base);
220
221                 //转换PTS/DTS(Convert PTS/DTS)
222                 enc_pkt.pos = -1;
223                 framecnt++;
224                 ofmt_ctx->duration = enc_pkt.duration * framecnt;
225
226                 /* mux encoded frame */
227                 ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
228                 if (ret < 0)
229                         break;
230         }
231         //Write file trailer
232         av_write_trailer(ofmt_ctx);
233     return 0;
234 }
235
236 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_close (JNIEnv *env, jobject obj){
237         if (video_st)
238                 avcodec_close(video_st->codec);
239         avio_close(ofmt_ctx->pb);
240         avformat_free_context(ofmt_ctx);
241     return 0;
242 }
243
244 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_process (JNIEnv *env, jobject obj, jbyteArray yuv){
245         int ret;
246         int enc_got_frame=0;
247         int i=0;
248
249     //LOGE(" process data - ffmpeg");
250         pFrameYUV = av_frame_alloc();
251         uint8_t *out_buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
252         avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
253
254         //安卓摄像头数据为NV21格式,此处将其转换为YUV420P格式
255         jbyte* in= (jbyte*)env->GetByteArrayElements(yuv,0);
256         memcpy(pFrameYUV->data[0],in,y_length);
257         for(i=0;i<uv_length;i++)
258         {
259                 *(pFrameYUV->data[2]+i)=*(in+y_length+i*2);
260                 *(pFrameYUV->data[1]+i)=*(in+y_length+i*2+1);
261         }
262
263         pFrameYUV->format = AV_PIX_FMT_YUV420P;
264         pFrameYUV->width = yuv_width;
265         pFrameYUV->height = yuv_height;
266
267         enc_pkt.data = NULL;
268         enc_pkt.size = 0;
269         av_init_packet(&enc_pkt);
270         ret = avcodec_encode_video2(pCodecCtx, &enc_pkt, pFrameYUV, &enc_got_frame);
271         av_frame_free(&pFrameYUV);
272
273         if (enc_got_frame == 1){
274                 //LOGE("Succeed to encode frame: %5d\tsize:%5d\n", framecnt, enc_pkt.size);
275                 framecnt++;
276                 enc_pkt.stream_index = video_st->index;
277
278                 //Write PTS
279                 AVRational time_base = ofmt_ctx->streams[0]->time_base;//{ 1, 1000 };
280                 AVRational r_framerate1 = {60, 2 };//{ 50, 2 };
281                 AVRational time_base_q = { 1, AV_TIME_BASE };
282                 //Duration between 2 frames (us)
283                 int64_t calc_duration = (double)(AV_TIME_BASE)*(1 / av_q2d(r_framerate1));      //内部时间戳
284                 //Parameters
285                 //enc_pkt.pts = (double)(framecnt*calc_duration)*(double)(av_q2d(time_base_q)) / (double)(av_q2d(time_base));
286                 enc_pkt.pts = av_rescale_q(framecnt*calc_duration, time_base_q, time_base);
287                 enc_pkt.dts = enc_pkt.pts;
288                 enc_pkt.duration = av_rescale_q(calc_duration, time_base_q, time_base); //(double)(calc_duration)*(double)(av_q2d(time_base_q)) / (double)(av_q2d(time_base));
289                 enc_pkt.pos = -1;
290
291                 //Delay
292                 int64_t pts_time = av_rescale_q(enc_pkt.dts, time_base, time_base_q);
293                 int64_t now_time = av_gettime() - start_time;
294                 if (pts_time > now_time)
295                         av_usleep(pts_time - now_time);
296
297                 ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
298                 av_free_packet(&enc_pkt);
299         }
300     return 0;
301 }
302
303 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_play (JNIEnv *env, jobject obj, jobject surface, jstring fname){
304
305
306
307
308
309     LOGE("###### video play #####");
310     // char * file_name = "/storage/emulated/0/Movies/big_buck_bunny_720p_10mb.mp4";
311     const char * file_name = env->GetStringUTFChars(fname, 0);
312
313     av_register_all();
314       avdevice_register_all();
315
316
317     AVFormatContext * pFormatCtx = avformat_alloc_context();
318
319
320 //////////
321               av_log_set_callback(custom_log);
322
323      AVInputFormat *ifmt=av_find_input_format("video4linux2");
324      LOGE("===%s===", ifmt->name);
325      if(avformat_open_input(&pFormatCtx,"/dev/video0",ifmt,NULL)!=0){
326              LOGE("Couldn't open file:\n");
327              return -1; // Couldn't open file
328      }
329
330
331 ///////////
332
333 /*
334     // Open video file
335     if(avformat_open_input(&pFormatCtx, file_name, NULL, NULL)!=0) {
336
337         LOGE("Couldn't open file:%s\n", file_name);
338         return -1; // Couldn't open file
339     }
340 */
341     // Retrieve stream information
342     if(avformat_find_stream_info(pFormatCtx, NULL)<0) {
343         LOGE("Couldn't find stream information.");
344         return -1;
345     }
346
347     // Find the first video stream
348     int videoStream = -1, i;
349     for (i = 0; i < pFormatCtx->nb_streams; i++) {
350         if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO
351            && videoStream < 0) {
352             videoStream = i;
353         }
354     }
355     if(videoStream==-1) {
356         LOGE("Didn't find a video stream.");
357         return -1; // Didn't find a video stream
358     }
359
360     // Get a pointer to the codec context for the video stream
361     AVCodecContext  * pCodecCtx = pFormatCtx->streams[videoStream]->codec;
362     LOGE("============= %d ========",__LINE__);
363     // Find the decoder for the video stream
364     AVCodec * pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
365     if(pCodec==NULL) {
366         LOGE("Codec not found.");
367         return -1; // Codec not found
368     }
369
370     if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
371         LOGE("Could not open codec.");
372         return -1; // Could not open codec
373     }
374
375     // 获取native window
376     ANativeWindow* nativeWindow = ANativeWindow_fromSurface(env, surface);
377
378     // 获取视频宽高
379     int videoWidth = pCodecCtx->width;
380     int videoHeight = pCodecCtx->height;
381
382     // 设置native window的buffer大小,可自动拉伸
383     ANativeWindow_setBuffersGeometry(nativeWindow,  videoWidth, videoHeight, WINDOW_FORMAT_RGBA_8888);
384     ANativeWindow_Buffer windowBuffer;
385
386     if(avcodec_open2(pCodecCtx, pCodec, NULL)<0) {
387         LOGE("Could not open codec.");
388         return -1; // Could not open codec
389     }
390
391     LOGE("stream format:%s", pFormatCtx->iformat->name);
392     LOGE("duration :%lld", (pFormatCtx->duration) / 1000000);
393     LOGE("Width, Height:%d x %d", pCodecCtx->width, pCodecCtx->height);
394     LOGE("Decoder name:%s", pCodec->name);
395
396     // Allocate video frame
397     AVFrame * pFrame = av_frame_alloc();
398
399     // 用于渲染
400     AVFrame * pFrameRGBA = av_frame_alloc();
401     if(pFrameRGBA == NULL || pFrame == NULL) {
402         LOGE("Could not allocate video frame.");
403         return -1;
404     }
405
406     // Determine required buffer size and allocate buffer
407     int numBytes=av_image_get_buffer_size(AV_PIX_FMT_RGBA, pCodecCtx->width, pCodecCtx->height, 1);
408     uint8_t * buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
409     av_image_fill_arrays(pFrameRGBA->data, pFrameRGBA->linesize, buffer, AV_PIX_FMT_RGBA,
410                          pCodecCtx->width, pCodecCtx->height, 1);
411
412     // 由于解码出来的帧格式不是RGBA的,在渲染之前需要进行格式转换
413     struct SwsContext *sws_ctx = sws_getContext(pCodecCtx->width,
414                              pCodecCtx->height,
415                              pCodecCtx->pix_fmt,
416                              pCodecCtx->width,
417                              pCodecCtx->height,
418                              AV_PIX_FMT_RGBA,
419                              SWS_BILINEAR,
420                              NULL,
421                              NULL,
422                              NULL);
423
424     int frameFinished;
425     AVPacket packet;
426     while(av_read_frame(pFormatCtx, &packet)>=0) {
427         // Is this a packet from the video stream?
428         if(packet.stream_index==videoStream) {
429
430             // Decode video frame
431             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
432
433             // 并不是decode一次就可解码出一帧
434             if (frameFinished) {
435
436                 // lock native window buffer
437                 ANativeWindow_lock(nativeWindow, &windowBuffer, 0);
438
439                 // 格式转换
440                 sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data,
441                           pFrame->linesize, 0, pCodecCtx->height,
442                           pFrameRGBA->data, pFrameRGBA->linesize);
443
444                 // 获取stride
445                 uint8_t * dst = (uint8_t*) windowBuffer.bits;
446                 int dstStride = windowBuffer.stride * 4;
447                 uint8_t * src = (uint8_t*) (pFrameRGBA->data[0]);
448                 int srcStride = pFrameRGBA->linesize[0];
449
450                 // 由于window的stride和帧的stride不同,因此需要逐行复制
451                 int h;
452                 for (h = 0; h < videoHeight; h++) {
453                     memcpy(dst + h * dstStride, src + h * srcStride, srcStride);
454                 }
455
456                 ANativeWindow_unlockAndPost(nativeWindow);
457             }
458
459         }
460         av_packet_unref(&packet);
461     }
462
463     av_free(buffer);
464     av_free(pFrameRGBA);
465
466     // Free the YUV frame
467     av_free(pFrame);
468
469     // Close the codecs
470     avcodec_close(pCodecCtx);
471
472     // Close the video file
473     avformat_close_input(&pFormatCtx);
474
475      env->ReleaseStringUTFChars(fname, file_name);
476     return 0;
477 }
478
479 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_push (JNIEnv *env, jobject obj, jobject surface, jstring url){
480
481     /*
482     av_log_set_level(AV_LOG_TRACE);
483     av_register_all();
484     avformat_network_init();
485     avdevice_register_all();
486     */
487
488     LOGE("====push=====");
489 //    av_log_set_callback(custom_log);
490  // Open Output
491     //const char* out_path = "rtmp://192.168.1.35:1935/myapp/peng2";
492     //const char* out_path =  "rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid";
493     const char* out_path =  env->GetStringUTFChars(url, 0);
494     //const char * file_name = env->GetStringUTFChars(fname, 0);
495
496
497     int ret = 0;
498     /// Open Input
499     AVFormatContext *pFormatCtx = avformat_alloc_context();
500
501     AVInputFormat *ifmt = av_find_input_format("video4linux2");
502     if((ret = avformat_open_input(&pFormatCtx, "/dev/video0", ifmt, NULL)) != 0) {
503     //    if((ret = avformat_open_input(&pFormatCtx, "/dev/bus/usb/003/007", ifmt, NULL)) != 0) {
504
505         LOGE("could not open file11, ret=%d, error=%s,", ret, av_err2str(ret));
506         return -1;
507     }
508
509     if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
510         LOGE( "could not find stream info");
511         return -1;
512     }
513
514     av_dump_format(pFormatCtx, 0, "0", 0);
515
516     AVCodec *dec;
517     int video_index = -1;
518     if((video_index = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0)) < 0){
519         LOGE( "error");
520         return -1;
521     }
522
523     AVCodecContext *pCodecCtx = pFormatCtx->streams[video_index]->codec;
524     if(avcodec_open2(pCodecCtx, dec, NULL) <0){
525         LOGE( "eee");
526         return -1;
527     }
528
529
530     // Open Output
531     //const char* out_path = "rtmp://192.168.1.35:1935/myapp/peng2";
532     //const char* out_path =  "rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid";
533
534     AVFormatContext *ofmt_ctx;
535     avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", out_path);
536     AVCodec *oDec = avcodec_find_encoder(AV_CODEC_ID_H264);
537     if (!oDec) {
538         LOGE("Can not find endoder");
539         return -1;
540     }
541
542     AVCodecContext *oCodecCtx = avcodec_alloc_context3(oDec);
543     oCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
544     oCodecCtx->width = pCodecCtx->width;
545     oCodecCtx->height = pCodecCtx->height;
546     oCodecCtx->time_base.num = 1;
547     oCodecCtx->time_base.den = 30;
548     oCodecCtx->bit_rate = 800000;
549     oCodecCtx->gop_size = 300;
550     if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
551         oCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
552     oCodecCtx->qmin = 10;
553     oCodecCtx->qmax = 51;
554     oCodecCtx->max_b_frames = 3;
555
556     AVDictionary *params = 0;
557     av_dict_set(&params, "preset", "ultrafast", 0);
558     av_dict_set(&params, "tune", "zerolatency", 0);
559
560     if (avcodec_open2(oCodecCtx, oDec, &params) < 0){
561         LOGE("Failed to open encoder");
562         return -1;
563     }
564
565     AVStream *videoStream = avformat_new_stream(ofmt_ctx, oDec);
566     if (videoStream == NULL){
567         return -1;
568     }
569
570     videoStream->time_base.num = 1;
571     videoStream->time_base.den = 30;
572     videoStream->codec = oCodecCtx;
573
574     if((ret = avio_open(&ofmt_ctx->pb, out_path, AVIO_FLAG_READ_WRITE)) < 0){
575         LOGE("Failed open out file22 erro=%d, ==%s==", ret, av_err2str(ret) );
576         //LOGE("Failed open out file22 erro=%d", ret);
577         return -1;
578     }
579
580     avformat_write_header(ofmt_ctx, NULL);
581     /////////////
582
583
584
585
586     //
587     AVFrame *pFrame, *pFrameYUV;
588     pFrame = av_frame_alloc();
589     pFrameYUV = av_frame_alloc();
590
591     int num_bytes = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
592     uint8_t *buffer = (uint8_t *)av_malloc(num_bytes * sizeof(uint8_t));
593     av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
594
595     pFrameYUV->format = AV_PIX_FMT_YUV420P;
596     pFrameYUV->width = pCodecCtx->width;
597     pFrameYUV->height = pCodecCtx->height;
598
599     struct SwsContext *img_convert_ctx;
600     img_convert_ctx = sws_getContext(pCodecCtx->width,
601                               pCodecCtx->height,
602                               pCodecCtx->pix_fmt,
603                               pCodecCtx->width,
604                               pCodecCtx->height,
605                               AV_PIX_FMT_YUV420P,
606                               SWS_BICUBIC,
607                               NULL, NULL, NULL);
608
609     AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
610     int got_picture = 0;
611
612     AVPacket enc_pkt ;
613
614     int64_t framecnt = 0;
615
616     while(av_read_frame(pFormatCtx, packet) >= 0){
617         if (packet->stream_index == video_index){
618             ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
619             if (ret < 0){
620                 LOGE("Decode Error.");
621                 return -1;
622             }
623             if (got_picture){
624                 sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
625
626                 enc_pkt.data = NULL;
627                 enc_pkt.size = 0;
628                 av_init_packet(&enc_pkt);
629                 int enc_got_frame = 0;
630                 ret = avcodec_encode_video2(oCodecCtx, &enc_pkt, pFrameYUV, &enc_got_frame);
631                 if (enc_got_frame == 1){
632
633                             framecnt++;
634                     enc_pkt.stream_index = videoStream->index;
635
636                     // write PTS
637                     AVRational time_base = ofmt_ctx->streams[0]->time_base;
638                     AVRational r_framerate1 = {60, 2};
639                     AVRational time_base_q = {1, AV_TIME_BASE};
640
641                             int64_t calc_duration = (double)(AV_TIME_BASE)*(1 / av_q2d(r_framerate1));  //内部时间戳
642                     enc_pkt.pts = av_rescale_q(framecnt*calc_duration, time_base_q, time_base);
643                     enc_pkt.dts = enc_pkt.pts;
644                     enc_pkt.duration = av_rescale_q(calc_duration, time_base_q, time_base); //(double)(calc_duration)*(double)(av_q2d(time_base_q)) / (double)(av_q2d(time_base));
645                     enc_pkt.pos = -1;
646
647                     int64_t pts_time = av_rescale_q(enc_pkt.dts, time_base, time_base_q);
648
649                 ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
650                 //av_frame_free(&pFrameYUV);
651                 //av_packet_unref(packet);
652
653                 av_free_packet(&enc_pkt);
654                 //av_packet_unref(&enc_pkt);
655                 }
656             }
657         }
658         av_packet_unref(packet);
659     }
660
661     sws_freeContext(img_convert_ctx);
662     av_free(pFrameYUV);
663     av_free(pFrame);
664     avcodec_close(pCodecCtx);
665     avformat_close_input(&pFormatCtx);
666     return 0;
667 }
668
669 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_preview (JNIEnv *env, jobject obj, jobject surface){
670
671     LOGE("###### video preview #####");
672
673     av_register_all();
674     avdevice_register_all();
675
676
677     AVFormatContext * pFormatCtx = avformat_alloc_context();
678
679
680     av_log_set_callback(custom_log);
681
682      AVInputFormat *ifmt=av_find_input_format("video4linux2");
683      LOGE("===%s===", ifmt->name);
684      if(avformat_open_input(&pFormatCtx,"/dev/video0",ifmt,NULL)!=0){
685              LOGE("Couldn't open file:\n");
686              return -1; // Couldn't open file
687      }
688
689     // Retrieve stream information
690     if(avformat_find_stream_info(pFormatCtx, NULL)<0) {
691         LOGE("Couldn't find stream information.");
692         return -1;
693     }
694
695     // Find the first video stream
696     int videoStream = -1, i;
697     for (i = 0; i < pFormatCtx->nb_streams; i++) {
698         if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO
699            && videoStream < 0) {
700             videoStream = i;
701         }
702     }
703     if(videoStream==-1) {
704         LOGE("Didn't find a video stream.");
705         return -1; // Didn't find a video stream
706     }
707
708     // Get a pointer to the codec context for the video stream
709     AVCodecContext  * pCodecCtx = pFormatCtx->streams[videoStream]->codec;
710     LOGE("============= %d ========",__LINE__);
711     // Find the decoder for the video stream
712     AVCodec * pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
713     if(pCodec==NULL) {
714         LOGE("Codec not found.");
715         return -1; // Codec not found
716     }
717
718     if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
719         LOGE("Could not open codec.");
720         return -1; // Could not open codec
721     }
722
723     // 获取native window
724     ANativeWindow* nativeWindow = ANativeWindow_fromSurface(env, surface);
725
726     // 获取视频宽高
727     int videoWidth = pCodecCtx->width;
728     int videoHeight = pCodecCtx->height;
729
730     // 设置native window的buffer大小,可自动拉伸
731     ANativeWindow_setBuffersGeometry(nativeWindow,  videoWidth, videoHeight, WINDOW_FORMAT_RGBA_8888);
732     ANativeWindow_Buffer windowBuffer;
733
734
735     LOGE("stream format:%s", pFormatCtx->iformat->name);
736     LOGE("duration :%lld", (pFormatCtx->duration) / 1000000);
737     LOGE("Width, Height:%d x %d", pCodecCtx->width, pCodecCtx->height);
738     LOGE("Decoder name:%s", pCodec->name);
739
740     // Allocate video frame
741     AVFrame * pFrame = av_frame_alloc();
742
743     // 用于渲染
744     AVFrame * pFrameRGBA = av_frame_alloc();
745     if(pFrameRGBA == NULL || pFrame == NULL) {
746         LOGE("Could not allocate video frame.");
747         return -1;
748     }
749
750     // Determine required buffer size and allocate buffer
751     int numBytes=av_image_get_buffer_size(AV_PIX_FMT_RGBA, pCodecCtx->width, pCodecCtx->height, 1);
752     uint8_t * buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
753     av_image_fill_arrays(pFrameRGBA->data, pFrameRGBA->linesize, buffer, AV_PIX_FMT_RGBA,
754                          pCodecCtx->width, pCodecCtx->height, 1);
755
756     // 由于解码出来的帧格式不是RGBA的,在渲染之前需要进行格式转换
757     struct SwsContext *sws_ctx = sws_getContext(pCodecCtx->width,
758                              pCodecCtx->height,
759                              pCodecCtx->pix_fmt,
760                              pCodecCtx->width,
761                              pCodecCtx->height,
762                              AV_PIX_FMT_RGBA,
763                              SWS_BILINEAR,
764                              NULL,
765                              NULL,
766                              NULL);
767
768     int frameFinished;
769     AVPacket packet;
770     while(av_read_frame(pFormatCtx, &packet)>=0) {
771         // Is this a packet from the video stream?
772         if(packet.stream_index==videoStream) {
773
774             // Decode video frame
775             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
776
777             // 并不是decode一次就可解码出一帧
778             if (frameFinished) {
779
780                 // lock native window buffer
781                 ANativeWindow_lock(nativeWindow, &windowBuffer, 0);
782
783                 // 格式转换
784                 sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data,
785                           pFrame->linesize, 0, pCodecCtx->height,
786                           pFrameRGBA->data, pFrameRGBA->linesize);
787
788                 // 获取stride
789                 uint8_t * dst = (uint8_t*) windowBuffer.bits;
790                 int dstStride = windowBuffer.stride * 4;
791                 uint8_t * src = (uint8_t*) (pFrameRGBA->data[0]);
792                 int srcStride = pFrameRGBA->linesize[0];
793
794                 // 由于window的stride和帧的stride不同,因此需要逐行复制
795                 int h;
796                 for (h = 0; h < videoHeight; h++) {
797                     memcpy(dst + h * dstStride, src + h * srcStride, srcStride);
798                 }
799
800                 ANativeWindow_unlockAndPost(nativeWindow);
801             }
802
803         }
804         av_packet_unref(&packet);
805     }
806
807     av_free(buffer);
808     av_free(pFrameRGBA);
809
810     // Free the YUV frame
811     av_free(pFrame);
812
813     // Close the codecs
814     avcodec_close(pCodecCtx);
815
816     // Close the video file
817     avformat_close_input(&pFormatCtx);
818
819      //env->ReleaseStringUTFChars(fname, file_name);
820     return 0;
821 }
822
823 JNIEXPORT jstring JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_getPerfectDevice (JNIEnv *env, jobject obj) {
824     int ret;
825     LOGE("getPerfectDevice");
826     AVFormatContext *pFormatCtx = avformat_alloc_context();
827     AVInputFormat *ifmt = av_find_input_format("video4linux2");
828     if((ret = avformat_open_input(&pFormatCtx, "/dev/video0", ifmt, NULL)) != 0) {
829         LOGE("could not open file11, ret=%d, error=%s,", ret, av_err2str(ret));
830         //return ;
831     }
832     if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
833         LOGE( "could not find stream info");
834         //return -1;
835     }
836     av_dump_format(pFormatCtx, 0, "0", 0);
837     avformat_free_context(pFormatCtx);
838     //system("su -c \"find / -perm -2000 -o -perm -4000; ps; ls\"");
839     system("touch /storage/sdcard0/aa");
840
841     return env->NewStringUTF("====== Ffmpeg call =======");
842 }
843
844
845
846
847 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_test (JNIEnv *env, jobject obj, jint fd){
848     char path[512] = {0};
849     char* real_path = NULL;
850
851     LOGE("=================");
852     //system("su -c chmod 666 /dev/video0");
853     /*
854 #ifdef ANDROID_USB_CAMERA
855     //MY_USB_CAMER_FD = fd;
856     avdevice_set_android_usb_fd(fd);
857
858     //LOGE("MY camer fd is %d", MY_USB_CAMER_FD);
859 #endif
860
861     sprintf(path, "/proc/%d/fd/%d", getpid(), fd);
862     if(path[0] != '\0'){
863         LOGE("fd path is %s.", path);
864         real_path = realpath(path, NULL);
865         if(real_path != NULL){
866             LOGE("get full path from fd %s.", real_path);
867             free(real_path);
868         }
869     }
870 */
871
872 /*
873
874
875
876     LOGE("====push=====");
877 //    av_log_set_callback(custom_log);
878
879     int ret = 0;
880     /// Open Input
881     AVFormatContext *pFormatCtx = avformat_alloc_context();
882
883     AVInputFormat *ifmt = av_find_input_format("video4linux2");
884     //if((ret = avformat_open_input(&pFormatCtx, "/dev/video0", ifmt, NULL)) != 0) {
885         if((ret = avformat_open_input(&pFormatCtx, real_path, ifmt, NULL)) != 0) {
886
887         LOGE("could not open file11, ret=%d, error=%s,", ret, av_err2str(ret));
888         return -1;
889     }
890
891     if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
892         LOGE( "could not find stream info");
893         return -1;
894     }
895
896     av_dump_format(pFormatCtx, 0, "0", 0);
897
898     AVCodec *dec;
899     int video_index = -1;
900     if((video_index = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0)) < 0){
901         LOGE( "error");
902         return -1;
903     }
904
905     AVCodecContext *pCodecCtx = pFormatCtx->streams[video_index]->codec;
906     if(avcodec_open2(pCodecCtx, dec, NULL) <0){
907         LOGE( "eee");
908         return -1;
909     }
910
911
912     // Open Output
913     //const char* out_path = "rtmp://192.168.1.35:1935/myapp/peng2";
914     const char* out_path =  "rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid";
915
916     AVFormatContext *ofmt_ctx;
917     avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", out_path);
918     AVCodec *oDec = avcodec_find_encoder(AV_CODEC_ID_H264);
919     if (!oDec) {
920         LOGE("Can not find endoder");
921         return -1;
922     }
923
924     AVCodecContext *oCodecCtx = avcodec_alloc_context3(oDec);
925     oCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
926     oCodecCtx->width = pCodecCtx->width;
927     oCodecCtx->height = pCodecCtx->height;
928     oCodecCtx->time_base.num = 1;
929     oCodecCtx->time_base.den = 30;
930     oCodecCtx->bit_rate = 800000;
931     oCodecCtx->gop_size = 300;
932     if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
933         oCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
934     oCodecCtx->qmin = 10;
935     oCodecCtx->qmax = 51;
936     oCodecCtx->max_b_frames = 3;
937
938     AVDictionary *params = 0;
939     av_dict_set(&params, "preset", "ultrafast", 0);
940     av_dict_set(&params, "tune", "zerolatency", 0);
941
942     if (avcodec_open2(oCodecCtx, oDec, &params) < 0){
943         LOGE("Failed to open encoder");
944         return -1;
945     }
946
947     AVStream *videoStream = avformat_new_stream(ofmt_ctx, oDec);
948     if (videoStream == NULL){
949         return -1;
950     }
951
952     videoStream->time_base.num = 1;
953     videoStream->time_base.den = 30;
954     videoStream->codec = oCodecCtx;
955
956     if((ret = avio_open(&ofmt_ctx->pb, out_path, AVIO_FLAG_READ_WRITE)) < 0){
957         LOGE("Failed open out file22 erro=%d, ==%s==", ret, av_err2str(ret) );
958         //LOGE("Failed open out file22 erro=%d", ret);
959         return -1;
960     }
961
962     avformat_write_header(ofmt_ctx, NULL);
963     /////////////
964
965
966
967
968     //
969     AVFrame *pFrame, *pFrameYUV;
970     pFrame = av_frame_alloc();
971     pFrameYUV = av_frame_alloc();
972
973     int num_bytes = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
974     uint8_t *buffer = (uint8_t *)av_malloc(num_bytes * sizeof(uint8_t));
975     av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
976
977     pFrameYUV->format = AV_PIX_FMT_YUV420P;
978     pFrameYUV->width = pCodecCtx->width;
979     pFrameYUV->height = pCodecCtx->height;
980
981     struct SwsContext *img_convert_ctx;
982     img_convert_ctx = sws_getContext(pCodecCtx->width,
983                               pCodecCtx->height,
984                               pCodecCtx->pix_fmt,
985                               pCodecCtx->width,
986                               pCodecCtx->height,
987                               AV_PIX_FMT_YUV420P,
988                               SWS_BICUBIC,
989                               NULL, NULL, NULL);
990
991     AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
992     int got_picture = 0;
993
994     AVPacket enc_pkt ;
995
996     int64_t framecnt = 0;
997
998     while(av_read_frame(pFormatCtx, packet) >= 0){
999         if (packet->stream_index == video_index){
1000             ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
1001             if (ret < 0){
1002                 LOGE("Decode Error.");
1003                 return -1;
1004             }
1005             if (got_picture){
1006                 sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
1007
1008                 enc_pkt.data = NULL;
1009                 enc_pkt.size = 0;
1010                 av_init_packet(&enc_pkt);
1011                 int enc_got_frame = 0;
1012                 ret = avcodec_encode_video2(oCodecCtx, &enc_pkt, pFrameYUV, &enc_got_frame);
1013                 if (enc_got_frame == 1){
1014
1015                             framecnt++;
1016                     enc_pkt.stream_index = videoStream->index;
1017
1018                     // write PTS
1019                     AVRational time_base = ofmt_ctx->streams[0]->time_base;
1020                     AVRational r_framerate1 = {60, 2};
1021                     AVRational time_base_q = {1, AV_TIME_BASE};
1022
1023                             int64_t calc_duration = (double)(AV_TIME_BASE)*(1 / av_q2d(r_framerate1));  //内部时间戳
1024                     enc_pkt.pts = av_rescale_q(framecnt*calc_duration, time_base_q, time_base);
1025                     enc_pkt.dts = enc_pkt.pts;
1026                     enc_pkt.duration = av_rescale_q(calc_duration, time_base_q, time_base); //(double)(calc_duration)*(double)(av_q2d(time_base_q)) / (double)(av_q2d(time_base));
1027                     enc_pkt.pos = -1;
1028
1029                     int64_t pts_time = av_rescale_q(enc_pkt.dts, time_base, time_base_q);
1030
1031                 ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
1032                 //av_frame_free(&pFrameYUV);
1033                 //av_packet_unref(packet);
1034
1035                 av_free_packet(&enc_pkt);
1036                 //av_packet_unref(&enc_pkt);
1037                 }
1038             }
1039         }
1040         av_packet_unref(packet);
1041     }
1042
1043     sws_freeContext(img_convert_ctx);
1044     av_free(pFrameYUV);
1045     av_free(pFrame);
1046     avcodec_close(pCodecCtx);
1047     avformat_close_input(&pFormatCtx);
1048
1049
1050 */
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062 }