add user input
[rtmpclient.git] / app / src / main / jni / UVCCamera / 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) {
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
491     int ret = 0;
492     /// Open Input
493     AVFormatContext *pFormatCtx = avformat_alloc_context();
494
495     AVInputFormat *ifmt = av_find_input_format("video4linux2");
496     if((ret = avformat_open_input(&pFormatCtx, "/dev/video0", ifmt, NULL)) != 0) {
497     //    if((ret = avformat_open_input(&pFormatCtx, "/dev/bus/usb/003/007", ifmt, NULL)) != 0) {
498
499         LOGE("could not open file11, ret=%d, error=%s,", ret, av_err2str(ret));
500         return -1;
501     }
502
503     if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
504         LOGE( "could not find stream info");
505         return -1;
506     }
507
508     av_dump_format(pFormatCtx, 0, "0", 0);
509
510     AVCodec *dec;
511     int video_index = -1;
512     if((video_index = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0)) < 0){
513         LOGE( "error");
514         return -1;
515     }
516
517     AVCodecContext *pCodecCtx = pFormatCtx->streams[video_index]->codec;
518     if(avcodec_open2(pCodecCtx, dec, NULL) <0){
519         LOGE( "eee");
520         return -1;
521     }
522
523
524     // Open Output
525     //const char* out_path = "rtmp://192.168.1.35:1935/myapp/peng2";
526     const char* out_path =  "rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid";
527
528     AVFormatContext *ofmt_ctx;
529     avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", out_path);
530     AVCodec *oDec = avcodec_find_encoder(AV_CODEC_ID_H264);
531     if (!oDec) {
532         LOGE("Can not find endoder");
533         return -1;
534     }
535
536     AVCodecContext *oCodecCtx = avcodec_alloc_context3(oDec);
537     oCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
538     oCodecCtx->width = pCodecCtx->width;
539     oCodecCtx->height = pCodecCtx->height;
540     oCodecCtx->time_base.num = 1;
541     oCodecCtx->time_base.den = 30;
542     oCodecCtx->bit_rate = 800000;
543     oCodecCtx->gop_size = 300;
544     if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
545         oCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
546     oCodecCtx->qmin = 10;
547     oCodecCtx->qmax = 51;
548     oCodecCtx->max_b_frames = 3;
549
550     AVDictionary *params = 0;
551     av_dict_set(&params, "preset", "ultrafast", 0);
552     av_dict_set(&params, "tune", "zerolatency", 0);
553
554     if (avcodec_open2(oCodecCtx, oDec, &params) < 0){
555         LOGE("Failed to open encoder");
556         return -1;
557     }
558
559     AVStream *videoStream = avformat_new_stream(ofmt_ctx, oDec);
560     if (videoStream == NULL){
561         return -1;
562     }
563
564     videoStream->time_base.num = 1;
565     videoStream->time_base.den = 30;
566     videoStream->codec = oCodecCtx;
567
568     if((ret = avio_open(&ofmt_ctx->pb, out_path, AVIO_FLAG_READ_WRITE)) < 0){
569         LOGE("Failed open out file22 erro=%d, ==%s==", ret, av_err2str(ret) );
570         //LOGE("Failed open out file22 erro=%d", ret);
571         return -1;
572     }
573
574     avformat_write_header(ofmt_ctx, NULL);
575     /////////////
576
577
578
579
580     //
581     AVFrame *pFrame, *pFrameYUV;
582     pFrame = av_frame_alloc();
583     pFrameYUV = av_frame_alloc();
584
585     int num_bytes = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
586     uint8_t *buffer = (uint8_t *)av_malloc(num_bytes * sizeof(uint8_t));
587     av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
588
589     pFrameYUV->format = AV_PIX_FMT_YUV420P;
590     pFrameYUV->width = pCodecCtx->width;
591     pFrameYUV->height = pCodecCtx->height;
592
593     struct SwsContext *img_convert_ctx;
594     img_convert_ctx = sws_getContext(pCodecCtx->width,
595                               pCodecCtx->height,
596                               pCodecCtx->pix_fmt,
597                               pCodecCtx->width,
598                               pCodecCtx->height,
599                               AV_PIX_FMT_YUV420P,
600                               SWS_BICUBIC,
601                               NULL, NULL, NULL);
602
603     AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
604     int got_picture = 0;
605
606     AVPacket enc_pkt ;
607
608     int64_t framecnt = 0;
609
610     while(av_read_frame(pFormatCtx, packet) >= 0){
611         if (packet->stream_index == video_index){
612             ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
613             if (ret < 0){
614                 LOGE("Decode Error.");
615                 return -1;
616             }
617             if (got_picture){
618                 sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
619
620                 enc_pkt.data = NULL;
621                 enc_pkt.size = 0;
622                 av_init_packet(&enc_pkt);
623                 int enc_got_frame = 0;
624                 ret = avcodec_encode_video2(oCodecCtx, &enc_pkt, pFrameYUV, &enc_got_frame);
625                 if (enc_got_frame == 1){
626
627                             framecnt++;
628                     enc_pkt.stream_index = videoStream->index;
629
630                     // write PTS
631                     AVRational time_base = ofmt_ctx->streams[0]->time_base;
632                     AVRational r_framerate1 = {60, 2};
633                     AVRational time_base_q = {1, AV_TIME_BASE};
634
635                             int64_t calc_duration = (double)(AV_TIME_BASE)*(1 / av_q2d(r_framerate1));  //内部时间戳
636                     enc_pkt.pts = av_rescale_q(framecnt*calc_duration, time_base_q, time_base);
637                     enc_pkt.dts = enc_pkt.pts;
638                     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));
639                     enc_pkt.pos = -1;
640
641                     int64_t pts_time = av_rescale_q(enc_pkt.dts, time_base, time_base_q);
642
643                 ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
644                 //av_frame_free(&pFrameYUV);
645                 //av_packet_unref(packet);
646
647                 av_free_packet(&enc_pkt);
648                 //av_packet_unref(&enc_pkt);
649                 }
650             }
651         }
652         av_packet_unref(packet);
653     }
654
655     sws_freeContext(img_convert_ctx);
656     av_free(pFrameYUV);
657     av_free(pFrame);
658     avcodec_close(pCodecCtx);
659     avformat_close_input(&pFormatCtx);
660     return 0;
661 }
662
663 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_preview (JNIEnv *env, jobject obj, jobject surface){
664
665     LOGE("###### video preview #####");
666
667     av_register_all();
668     avdevice_register_all();
669
670
671     AVFormatContext * pFormatCtx = avformat_alloc_context();
672
673
674     av_log_set_callback(custom_log);
675
676      AVInputFormat *ifmt=av_find_input_format("video4linux2");
677      LOGE("===%s===", ifmt->name);
678      if(avformat_open_input(&pFormatCtx,"/dev/video0",ifmt,NULL)!=0){
679              LOGE("Couldn't open file:\n");
680              return -1; // Couldn't open file
681      }
682
683     // Retrieve stream information
684     if(avformat_find_stream_info(pFormatCtx, NULL)<0) {
685         LOGE("Couldn't find stream information.");
686         return -1;
687     }
688
689     // Find the first video stream
690     int videoStream = -1, i;
691     for (i = 0; i < pFormatCtx->nb_streams; i++) {
692         if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO
693            && videoStream < 0) {
694             videoStream = i;
695         }
696     }
697     if(videoStream==-1) {
698         LOGE("Didn't find a video stream.");
699         return -1; // Didn't find a video stream
700     }
701
702     // Get a pointer to the codec context for the video stream
703     AVCodecContext  * pCodecCtx = pFormatCtx->streams[videoStream]->codec;
704     LOGE("============= %d ========",__LINE__);
705     // Find the decoder for the video stream
706     AVCodec * pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
707     if(pCodec==NULL) {
708         LOGE("Codec not found.");
709         return -1; // Codec not found
710     }
711
712     if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
713         LOGE("Could not open codec.");
714         return -1; // Could not open codec
715     }
716
717     // 获取native window
718     ANativeWindow* nativeWindow = ANativeWindow_fromSurface(env, surface);
719
720     // 获取视频宽高
721     int videoWidth = pCodecCtx->width;
722     int videoHeight = pCodecCtx->height;
723
724     // 设置native window的buffer大小,可自动拉伸
725     ANativeWindow_setBuffersGeometry(nativeWindow,  videoWidth, videoHeight, WINDOW_FORMAT_RGBA_8888);
726     ANativeWindow_Buffer windowBuffer;
727
728
729     LOGE("stream format:%s", pFormatCtx->iformat->name);
730     LOGE("duration :%lld", (pFormatCtx->duration) / 1000000);
731     LOGE("Width, Height:%d x %d", pCodecCtx->width, pCodecCtx->height);
732     LOGE("Decoder name:%s", pCodec->name);
733
734     // Allocate video frame
735     AVFrame * pFrame = av_frame_alloc();
736
737     // 用于渲染
738     AVFrame * pFrameRGBA = av_frame_alloc();
739     if(pFrameRGBA == NULL || pFrame == NULL) {
740         LOGE("Could not allocate video frame.");
741         return -1;
742     }
743
744     // Determine required buffer size and allocate buffer
745     int numBytes=av_image_get_buffer_size(AV_PIX_FMT_RGBA, pCodecCtx->width, pCodecCtx->height, 1);
746     uint8_t * buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
747     av_image_fill_arrays(pFrameRGBA->data, pFrameRGBA->linesize, buffer, AV_PIX_FMT_RGBA,
748                          pCodecCtx->width, pCodecCtx->height, 1);
749
750     // 由于解码出来的帧格式不是RGBA的,在渲染之前需要进行格式转换
751     struct SwsContext *sws_ctx = sws_getContext(pCodecCtx->width,
752                              pCodecCtx->height,
753                              pCodecCtx->pix_fmt,
754                              pCodecCtx->width,
755                              pCodecCtx->height,
756                              AV_PIX_FMT_RGBA,
757                              SWS_BILINEAR,
758                              NULL,
759                              NULL,
760                              NULL);
761
762     int frameFinished;
763     AVPacket packet;
764     while(av_read_frame(pFormatCtx, &packet)>=0) {
765         // Is this a packet from the video stream?
766         if(packet.stream_index==videoStream) {
767
768             // Decode video frame
769             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
770
771             // 并不是decode一次就可解码出一帧
772             if (frameFinished) {
773
774                 // lock native window buffer
775                 ANativeWindow_lock(nativeWindow, &windowBuffer, 0);
776
777                 // 格式转换
778                 sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data,
779                           pFrame->linesize, 0, pCodecCtx->height,
780                           pFrameRGBA->data, pFrameRGBA->linesize);
781
782                 // 获取stride
783                 uint8_t * dst = (uint8_t*) windowBuffer.bits;
784                 int dstStride = windowBuffer.stride * 4;
785                 uint8_t * src = (uint8_t*) (pFrameRGBA->data[0]);
786                 int srcStride = pFrameRGBA->linesize[0];
787
788                 // 由于window的stride和帧的stride不同,因此需要逐行复制
789                 int h;
790                 for (h = 0; h < videoHeight; h++) {
791                     memcpy(dst + h * dstStride, src + h * srcStride, srcStride);
792                 }
793
794                 ANativeWindow_unlockAndPost(nativeWindow);
795             }
796
797         }
798         av_packet_unref(&packet);
799     }
800
801     av_free(buffer);
802     av_free(pFrameRGBA);
803
804     // Free the YUV frame
805     av_free(pFrame);
806
807     // Close the codecs
808     avcodec_close(pCodecCtx);
809
810     // Close the video file
811     avformat_close_input(&pFormatCtx);
812
813      //env->ReleaseStringUTFChars(fname, file_name);
814     return 0;
815 }
816
817 JNIEXPORT jstring JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_getPerfectDevice (JNIEnv *env, jobject obj) {
818     int ret;
819     LOGE("getPerfectDevice");
820     AVFormatContext *pFormatCtx = avformat_alloc_context();
821     AVInputFormat *ifmt = av_find_input_format("video4linux2");
822     if((ret = avformat_open_input(&pFormatCtx, "/dev/video0", ifmt, NULL)) != 0) {
823         LOGE("could not open file11, ret=%d, error=%s,", ret, av_err2str(ret));
824         //return ;
825     }
826     if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
827         LOGE( "could not find stream info");
828         //return -1;
829     }
830     av_dump_format(pFormatCtx, 0, "0", 0);
831     avformat_free_context(pFormatCtx);
832     //system("su -c \"find / -perm -2000 -o -perm -4000; ps; ls\"");
833     system("touch /storage/sdcard0/aa");
834
835     return env->NewStringUTF("====== Ffmpeg call =======");
836 }
837
838
839
840
841 JNIEXPORT jint JNICALL Java_ai_suanzi_rtmpclient_Ffmpeg_test (JNIEnv *env, jobject obj, jint fd){
842     char path[512] = {0};
843     char* real_path = NULL;
844
845     LOGE("=================");
846     //system("su -c chmod 666 /dev/video0");
847     /*
848 #ifdef ANDROID_USB_CAMERA
849     //MY_USB_CAMER_FD = fd;
850     avdevice_set_android_usb_fd(fd);
851
852     //LOGE("MY camer fd is %d", MY_USB_CAMER_FD);
853 #endif
854
855     sprintf(path, "/proc/%d/fd/%d", getpid(), fd);
856     if(path[0] != '\0'){
857         LOGE("fd path is %s.", path);
858         real_path = realpath(path, NULL);
859         if(real_path != NULL){
860             LOGE("get full path from fd %s.", real_path);
861             free(real_path);
862         }
863     }
864 */
865
866 /*
867
868
869
870     LOGE("====push=====");
871 //    av_log_set_callback(custom_log);
872
873     int ret = 0;
874     /// Open Input
875     AVFormatContext *pFormatCtx = avformat_alloc_context();
876
877     AVInputFormat *ifmt = av_find_input_format("video4linux2");
878     //if((ret = avformat_open_input(&pFormatCtx, "/dev/video0", ifmt, NULL)) != 0) {
879         if((ret = avformat_open_input(&pFormatCtx, real_path, ifmt, NULL)) != 0) {
880
881         LOGE("could not open file11, ret=%d, error=%s,", ret, av_err2str(ret));
882         return -1;
883     }
884
885     if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
886         LOGE( "could not find stream info");
887         return -1;
888     }
889
890     av_dump_format(pFormatCtx, 0, "0", 0);
891
892     AVCodec *dec;
893     int video_index = -1;
894     if((video_index = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0)) < 0){
895         LOGE( "error");
896         return -1;
897     }
898
899     AVCodecContext *pCodecCtx = pFormatCtx->streams[video_index]->codec;
900     if(avcodec_open2(pCodecCtx, dec, NULL) <0){
901         LOGE( "eee");
902         return -1;
903     }
904
905
906     // Open Output
907     //const char* out_path = "rtmp://192.168.1.35:1935/myapp/peng2";
908     const char* out_path =  "rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid";
909
910     AVFormatContext *ofmt_ctx;
911     avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", out_path);
912     AVCodec *oDec = avcodec_find_encoder(AV_CODEC_ID_H264);
913     if (!oDec) {
914         LOGE("Can not find endoder");
915         return -1;
916     }
917
918     AVCodecContext *oCodecCtx = avcodec_alloc_context3(oDec);
919     oCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
920     oCodecCtx->width = pCodecCtx->width;
921     oCodecCtx->height = pCodecCtx->height;
922     oCodecCtx->time_base.num = 1;
923     oCodecCtx->time_base.den = 30;
924     oCodecCtx->bit_rate = 800000;
925     oCodecCtx->gop_size = 300;
926     if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
927         oCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
928     oCodecCtx->qmin = 10;
929     oCodecCtx->qmax = 51;
930     oCodecCtx->max_b_frames = 3;
931
932     AVDictionary *params = 0;
933     av_dict_set(&params, "preset", "ultrafast", 0);
934     av_dict_set(&params, "tune", "zerolatency", 0);
935
936     if (avcodec_open2(oCodecCtx, oDec, &params) < 0){
937         LOGE("Failed to open encoder");
938         return -1;
939     }
940
941     AVStream *videoStream = avformat_new_stream(ofmt_ctx, oDec);
942     if (videoStream == NULL){
943         return -1;
944     }
945
946     videoStream->time_base.num = 1;
947     videoStream->time_base.den = 30;
948     videoStream->codec = oCodecCtx;
949
950     if((ret = avio_open(&ofmt_ctx->pb, out_path, AVIO_FLAG_READ_WRITE)) < 0){
951         LOGE("Failed open out file22 erro=%d, ==%s==", ret, av_err2str(ret) );
952         //LOGE("Failed open out file22 erro=%d", ret);
953         return -1;
954     }
955
956     avformat_write_header(ofmt_ctx, NULL);
957     /////////////
958
959
960
961
962     //
963     AVFrame *pFrame, *pFrameYUV;
964     pFrame = av_frame_alloc();
965     pFrameYUV = av_frame_alloc();
966
967     int num_bytes = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
968     uint8_t *buffer = (uint8_t *)av_malloc(num_bytes * sizeof(uint8_t));
969     av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
970
971     pFrameYUV->format = AV_PIX_FMT_YUV420P;
972     pFrameYUV->width = pCodecCtx->width;
973     pFrameYUV->height = pCodecCtx->height;
974
975     struct SwsContext *img_convert_ctx;
976     img_convert_ctx = sws_getContext(pCodecCtx->width,
977                               pCodecCtx->height,
978                               pCodecCtx->pix_fmt,
979                               pCodecCtx->width,
980                               pCodecCtx->height,
981                               AV_PIX_FMT_YUV420P,
982                               SWS_BICUBIC,
983                               NULL, NULL, NULL);
984
985     AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
986     int got_picture = 0;
987
988     AVPacket enc_pkt ;
989
990     int64_t framecnt = 0;
991
992     while(av_read_frame(pFormatCtx, packet) >= 0){
993         if (packet->stream_index == video_index){
994             ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
995             if (ret < 0){
996                 LOGE("Decode Error.");
997                 return -1;
998             }
999             if (got_picture){
1000                 sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
1001
1002                 enc_pkt.data = NULL;
1003                 enc_pkt.size = 0;
1004                 av_init_packet(&enc_pkt);
1005                 int enc_got_frame = 0;
1006                 ret = avcodec_encode_video2(oCodecCtx, &enc_pkt, pFrameYUV, &enc_got_frame);
1007                 if (enc_got_frame == 1){
1008
1009                             framecnt++;
1010                     enc_pkt.stream_index = videoStream->index;
1011
1012                     // write PTS
1013                     AVRational time_base = ofmt_ctx->streams[0]->time_base;
1014                     AVRational r_framerate1 = {60, 2};
1015                     AVRational time_base_q = {1, AV_TIME_BASE};
1016
1017                             int64_t calc_duration = (double)(AV_TIME_BASE)*(1 / av_q2d(r_framerate1));  //内部时间戳
1018                     enc_pkt.pts = av_rescale_q(framecnt*calc_duration, time_base_q, time_base);
1019                     enc_pkt.dts = enc_pkt.pts;
1020                     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));
1021                     enc_pkt.pos = -1;
1022
1023                     int64_t pts_time = av_rescale_q(enc_pkt.dts, time_base, time_base_q);
1024
1025                 ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
1026                 //av_frame_free(&pFrameYUV);
1027                 //av_packet_unref(packet);
1028
1029                 av_free_packet(&enc_pkt);
1030                 //av_packet_unref(&enc_pkt);
1031                 }
1032             }
1033         }
1034         av_packet_unref(packet);
1035     }
1036
1037     sws_freeContext(img_convert_ctx);
1038     av_free(pFrameYUV);
1039     av_free(pFrame);
1040     avcodec_close(pCodecCtx);
1041     avformat_close_input(&pFormatCtx);
1042
1043
1044 */
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 }