Ticket #1786: vidapi.c

File vidapi.c, 18.3 KB (added by neelima, 4 years ago)

This file is for video encoding

Line 
1
2#include <android/log.h>
3#ifdef HAVE_AV_CONFIG_H
4#undef HAVE_AV_CONFIG_H
5#endif
6
7#include "clib/stdio.h"
8#include "clib/stdlib.h"
9#include "clib/stdlib.h"
10#include "clib/string.h"
11#include "libavcodec/avcodec.h"
12#include "libavutil/mathematics.h"
13#include "libswscale/swscale.h"
14#include "libavformat/avformat.h"
15#include "libavfilter/avfilter.h"
16#include "libavdevice/avdevice.h"
17#include "libavutil/avstring.h"
18#include "libavutil/pixdesc.h"
19#include "libavutil/eval.h"
20#define INBUF_SIZE 4096
21#define AUDIO_INBUF_SIZE 20480
22#define AUDIO_REFILL_THRESH 4096
23#define  LOG_TAG    "FFMPEGSample"
24#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
25#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
26
27/* definition of data structures */
28typedef struct {
29  int            x,y;
30  unsigned char *data;
31  char          *name;
32} PPMImage;
33typedef PPMImage *img;
34
35typedef struct {
36     unsigned char red,green,blue;
37} PPMPixel;
38
39/*
40typedef struct {
41     unsigned char red,green,blue;
42} JPGPixel;
43
44
45typedef struct {
46     int x, y;
47     JPGPixel *data;
48     char          *name;
49} JPGImage;
50typedef JPGImage *img;
51
52*/
53#define CREATOR "RPFELGUEIRAS"
54#define RGB_COMPONENT_COLOR 255
55
56/*
57static JPGImage *getJPG(char *filename)
58{
59
60char buff[16];
61JPGImage *img;
62FILE *fp;
63int c, rgb_comp_color;
64//open PPM file for reading
65LOGI("try to open file '%s'\n", filename);
66    fp = fopen(filename, "rb");
67        if (!fp) {
68                 LOGI("Unable to open file '%s'\n", filename);
69
70                 exit(1);
71        }
72        fclose(fp);
73        img = (JPGImage*)malloc(sizeof(JPGImage));
74     return img;
75}
76     /*
77        LOGI("Buffer size");
78        if (!fgets(buff, sizeof(buff), fp)) {
79                                  perror(filename);
80                                  exit(1);
81        }
82
83
84        LOGI("Allocating memory");
85        img = (JPGImage*)malloc(sizeof(JPGImage));
86        //check for comments
87            c = getc(fp);
88            while (c == '#') {
89            while (getc(fp) != '\n') ;
90                 c = getc(fp);
91            }
92           /* LOGI("ungetc(c, fp)");
93            ungetc(c, fp);
94            //read image size information
95            if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) {
96                LOGI( "Invalid image size (error loading '%s')\n", filename);
97                 exit(1);
98            }
99            LOGI("read image size information");
100            //read rgb component
101            if (fscanf(fp, "%d", &rgb_comp_color) != 1) {
102                LOGI( "Invalid rgb component (error loading '%s')\n", filename);
103                 exit(1);
104            }
105            LOGI("check rgb component depth");
106            //check rgb component depth
107         if (rgb_comp_color!= RGB_COMPONENT_COLOR) {
108                LOGI("'%s' does not have 8-bits components\n", filename);
109                 exit(1);
110            }
111         LOGI("memory allocation for pixel data");
112            while (fgetc(fp) != '\n') ;
113            //memory allocation for pixel data
114            img->data = (JPGPixel*)malloc(img->x * img->y * sizeof(JPGPixel));
115
116            if (!img) {
117                LOGI( "Unable to allocate memory\n");
118                 exit(1);
119            }
120            LOGI("read pixel data from file");
121         //read pixel data from file
122            if (fread(img->data, 3 * img->x, img->y, fp) != img->y) {
123                LOGI( "Error loading image '%s'\n", filename);
124                 exit(1);
125            }
126*/
127        //  fclose(fp);
128    //  return img;
129//}
130
131
132static PPMImage *getPPM(const char *filename)
133{
134    LOGI("At getPPM:");
135         char buff[16];
136         PPMImage *img;
137         FILE *fp;
138         int c, rgb_comp_color;
139         //open PPM file for reading
140         fp = fopen(filename, "rb");
141         if (!fp) {
142              LOGI("Unable to open file '%s'\n", filename);
143              exit(1);
144         }
145           //   fclose(fp);
146         //     return img;
147
148         LOGI("Reading Image format");
149         //read image format
150         if (!fgets(buff, sizeof(buff), fp)) {
151              perror(filename);
152              exit(1);
153         }
154
155    //check the image format
156    if (buff[0] != 'P' || buff[1] != '6') {
157        LOGI("Invalid image format (must be 'P6')\n");
158         exit(1);
159    }
160
161     LOGI("Before Memory location");
162    //alloc memory form image
163    img = (PPMImage*)malloc(sizeof(PPMImage));
164    if (!img) {
165        LOGI("Unable to allocate memory\n");
166         exit(1);
167    }
168
169    //check for comments
170    c = getc(fp);
171    while (c == '#') {
172    while (getc(fp) != '\n') ;
173         c = getc(fp);
174    }
175
176    ungetc(c, fp);
177    //read image size information
178    if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) {
179        LOGI( "Invalid image size (error loading '%s')\n", filename);
180         exit(1);
181    }
182
183    //read rgb component
184    if (fscanf(fp, "%d", &rgb_comp_color) != 1) {
185        LOGI( "Invalid rgb component (error loading '%s')\n", filename);
186         exit(1);
187    }
188
189    //check rgb component depth
190   if (rgb_comp_color!= RGB_COMPONENT_COLOR) {
191        LOGI("'%s' does not have 8-bits components\n", filename);
192         exit(1);
193    }
194
195    while (fgetc(fp) != '\n') ;
196    //memory allocation for pixel data
197    img->data = (PPMPixel*)malloc(img->x * img->y * sizeof(PPMPixel));
198
199    if (!img) {
200        LOGI( "Unable to allocate memory\n");
201         exit(1);
202    }
203
204    //read pixel data from file
205    if (fread(img->data, 3 * img->x, img->y, fp) != img->y) {
206        LOGI( "Error loading image '%s'\n", filename);
207         exit(1);
208    }
209
210    fclose(fp);
211    return img;
212}
213
214
215/*
216//load PPM image
217
218static PPMImage *getPPM(const char *filename)
219{
220    char buff[32];
221    PPMImage *result;
222    FILE *fp;
223    int maxval;
224
225    fp = fopen(filename, "rb");
226    LOGI("Sucess fully opend file `%s'\n",filename);
227    if (!fp)
228    {
229LOGI("Unable to open file `%s'\n", filename);
230        exit(1);
231    }
232
233    if (!fgets(buff, sizeof(buff), fp))
234    {
235        perror(filename);
236        exit(1);
237    }
238
239    if (buff[0] == 'P' || buff[1] == '6')
240    {
241        LOGI("Buffer value one value '%d'\n",buff[1]);
242        LOGI("Buffer value zero value '%d'\n",buff[0]);
243        LOGI("Invalid image format (must be `P6')\n");
244        exit(1);
245    }
246
247    result = (PPMImage *) malloc(sizeof(PPMImage));
248    if (!result)
249    {
250        LOGI("Unable to allocate memory\n");
251        exit(1);
252    }
253
254    if (fscanf(fp, "%d %d", &result->x, &result->y) != 2)
255    {
256        LOGI( "Error loading image `%s'\n", filename);
257        exit(1);
258    }
259
260    if (fscanf(fp, "%d", &maxval) != 1)
261    {
262        LOGI( "Error loading image `%s'\n", filename);
263        exit(1);
264    }
265
266    while (fgetc(fp) != '\n')
267        ;
268
269    result->data = (char *) malloc(3 * result->x * result->y);
270    if (!result)
271    {
272        LOGI("Unable to allocate memory\n");
273        exit(1);
274    }
275
276    if (fread(result->data, 3 * result->x, result->y, fp) != result->y)
277    {
278        LOGI( "Error loading image `%s'\n", filename);
279        exit(1);
280    }
281
282    fclose(fp);
283
284    return result;
285}
286*/
287/*
288  * Audio encoding example
289  */
290 static void audio_encode_example(const char *filename)
291 {
292     AVCodec *codec;
293     AVCodecContext *c= NULL;
294     int frame_size, i, j, out_size, outbuf_size;
295     FILE *f;
296     short *samples;
297     float t, tincr;
298     uint8_t *outbuf;
299
300     printf("Audio encoding\n");
301
302     /* find the MP2 encoder */
303     codec = avcodec_find_encoder(CODEC_ID_MP2);
304
305     if (!codec) {
306         fprintf(stderr, "codec not found\n");
307         exit(1);
308     }
309
310     c= avcodec_alloc_context();
311
312     /* put sample parameters */
313     c->bit_rate =64000;
314     c->sample_rate = 44100;
315     c->channels = 2;
316
317     /* open it */
318     if (avcodec_open(c, codec) < 0) {
319         fprintf(stderr, "could not open codec\n");
320         exit(1);
321     }
322
323     /* the codec gives us the frame size, in samples */
324     frame_size = c->frame_size;
325     samples = malloc(frame_size * 2 * c->channels);
326     outbuf_size = 10000;
327     outbuf = malloc(outbuf_size);
328
329     f = fopen(filename, "wb");
330     if (!f) {
331         fprintf(stderr, "could not open %s\n", filename);
332         exit(1);
333     }
334
335     /* encode a single tone sound */
336     t = 0;
337     tincr = 2 * M_PI * 4.0 / c->sample_rate;
338     for(i=0;i<0;i++) {
339         for(j=0;j<frame_size;j++) {
340                  samples[2*j] = (int)(sin(t) * 10000);
341             samples[2*j+1] = samples[2*j];
342             t += tincr;
343         }
344         /* encode the samples */
345         out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
346        fwrite(outbuf, 1, out_size, f);
347    }
348     fclose(f);
349    free(outbuf);
350    free(samples);
351    avcodec_close(c);
352    av_free(c);
353}
354
355 /*
356 * Audio decoding.  */
357static void audio_decode_example(const char *outfilename, const char *filename)
358 {
359         AVCodec *codec;
360     AVCodecContext *c= NULL;
361     int out_size, len;
362     FILE *f, *outfile;
363     uint8_t *outbuf;
364     uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
365     AVPacket avpkt;
366     av_init_packet(&avpkt);
367     printf("Audio decoding\n");
368
369     /* find the mpeg audio decoder */
370    codec = avcodec_find_decoder(CODEC_ID_MP2);
371     if (!codec) {
372         fprintf(stderr, "codec not found\n");
373         exit(1);
374     }
375
376     c= avcodec_alloc_context();
377
378     /* open it */
379     if (avcodec_open(c, codec) < 0) {
380         fprintf(stderr, "could not open codec\n");
381exit(1);
382     }
383
384     outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
385
386     f = fopen(filename, "rb");
387     if (!f) {
388         fprintf(stderr, "could not open %s\n", filename);
389         exit(1);
390     }
391     outfile = fopen(outfilename, "wb");
392     if (!outfile) {
393         av_free(c);
394         exit(1);
395     }
396
397     /* decode until eof */
398     avpkt.data = inbuf;
399     avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
400
401     while (avpkt.size > 0) {
402         out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
403         len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
404         if (len < 0) {
405             fprintf(stderr, "Error while decoding\n");
406             exit(1);
407         }
408         if (out_size > 0) {
409            /* if a frame has been decoded, output it */
410             fwrite(outbuf, 1, out_size, outfile);
411         }
412         avpkt.size -= len;
413         avpkt.data += len;
414         if (avpkt.size < AUDIO_REFILL_THRESH) {
415             /* Refill the input buffer, to avoid trying to decode
416              * incomplete frames. Instead of this, one could also use
417             * a parser, or use a proper container format through
418              * libavformat. */
419            memmove(inbuf, avpkt.data, avpkt.size);
420             avpkt.data = inbuf;
421             len = fread(avpkt.data + avpkt.size, 1,
422                         AUDIO_INBUF_SIZE - avpkt.size, f);
423             if (len > 0)
424                 avpkt.size += len;
425         }
426     }
427     fclose(outfile);
428     fclose(f);
429     free(outbuf);
430     avcodec_close(c);
431     av_free(c);
432 }
433    int encodeVideo()
434{
435         LOGI("encode video called");
436     char *flname, *err, *info;
437     AVCodec *codec;
438     AVCodecContext *c= NULL;
439     int i,out_size, size, x, y,z, outbuf_size;
440     int frameCount=800;
441     FILE *f;
442     AVFrame *picture,*yuvFrame;
443     uint8_t *outbuf, *picture_buf;
444      //JPGImage *img;
445     PPMImage *img;
446     const char *destfilename = "/sdcard/ppmscreencastone.3gp";
447     int             numBytes;
448     uint8_t         *buffer;
449     LOGI("Video encoding\n");
450     // find the H263 video encoder
451     codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
452    // codec = avcodec_find_encoder(CODEC_ID_H263);
453     LOGI("After Codec\n");
454     if (!codec) {
455         sprintf(err, "codec not found\n");
456         LOGI("Codec not found\n");
457     }
458     LOGI("After Codec\n");
459     c= avcodec_alloc_context();
460     picture= avcodec_alloc_frame();
461     LOGI("picture \n");
462     yuvFrame= avcodec_alloc_frame();
463     LOGI("yuvFrame\n");
464     // get first ppm context. it is because I need width and height values.
465    // img = getJPG("/sdcard/saved_images/Image10.jpg");
466     img = getPPM("/sdcard/first.ppm");
467     if(img==NULL){
468           LOGI("image get from sdcard faild\n");
469     }
470     LOGI("image get from sdcard\n");
471     c->bit_rate = 400000;
472     // resolution must be a multiple of two
473     c->width = img->x;
474     c->height = img->y;
475     free(img);
476     // frames per second
477     LOGI("frames per second\n");
478     c->time_base= (AVRational){1,25};
479     c->gop_size = 10; // emit one intra frame every ten frames
480     //c->max_b_frames=100;
481     c->pix_fmt = PIX_FMT_YUV420P;
482     // open it
483     if (avcodec_open(c, codec) < 0){
484                 LOGI("codec couldn't open");
485    return -1;
486     }
487     //destfilename = (*env)->GetStringUTFChars(env, dst, 0);
488     f = fopen(destfilename, "wb");
489     LOGI(destfilename);
490     if (!f) {
491         sprintf(err, "could not open %s", destfilename);
492         LOGI(err);
493     }
494     LOGI("after destination file opening");
495     // alloc image and output buffer
496     outbuf_size = 1000000;
497     outbuf = malloc(outbuf_size);
498     size = c->width * c->height;
499     picture_buf = malloc(size * 3); // size for RGB
500     picture->data[0] = picture_buf;
501     picture->data[1] = picture->data[0] + size;
502     picture->data[2] = picture->data[1] + size / 4;
503     picture->linesize[0] = c->width;
504     picture->linesize[1] = c->width / 2;
505     picture->linesize[2] = c->width / 2;
506     numBytes=avpicture_get_size(PIX_FMT_YUV420P, c->width,
507              c->height);
508     buffer=malloc(numBytes);
509          // Assign appropriate parts of buffer to image planes in FrameYUV
510     avpicture_fill((AVPicture *)yuvFrame, buffer, PIX_FMT_YUV420P,
511              c->width, c->height);
512     // encode the video
513
514    /* int num = 123;
515
516         char buf[25];
517         strcpy(buf, "venu");
518         LOGI("%s\n", buf);
519         char bufone[25];
520         sprintf(bufone, "%d", num);
521        // print our string
522         LOGI("%s\n", buf);
523         LOGI("%s\n",strcat(buf,bufone));
524*/
525     LOGI("before for loop");
526     for(z=1;z<frameCount;z++) {
527    /*    LOGI("After for loop");
528          char lnm[6];
529          strcpy(lnm, ".jpg");
530          LOGI("%s\n",lnm);
531          char fnm[20];
532          char filename[50];
533          strcpy(filename, "/sdcard/saved_images/Image");
534          LOGI("%s\n",filename);
535          sprintf(fnm, "%d", z);
536          LOGI("%s\n",fnm);
537          strcat(filename,fnm);
538          LOGI("%s\n",filename);
539          strcat(filename,lnm);
540          LOGI("At Last point%s\n",filename);
541                  // read the ppm file
542                */
543        //       img = getJPG("/sdcard/saved_images/Image10.jpg");
544
545           img = getPPM("/sdcard/first.ppm");
546          LOGI("After get ppm");
547                  picture->data[0] = img->data;
548                  // convert the rgb frame into yuv frame
549                  LOGI("before conversion");
550                  rgb2yuv(picture,yuvFrame,c);
551                  LOGI("translation completed.");
552                  // encode the image
553                  LOGI("outsize conversion");
554                  out_size = avcodec_encode_video(c, outbuf, outbuf_size, yuvFrame);
555                  LOGI("After conversion '%d'",out_size);
556                  fprintf(info,"encoding frame %3d (size=%5d)\n", z, out_size);
557                  fwrite(outbuf, 1, z, f);
558                  LOGI("After fwrite");
559                  free(img);
560                  LOGI("After free");
561          }
562    /* int count = 1;
563    do{
564        LOGI("With in the do loop...loop",count);
565        //sprintf(flname, "/sdcard/saved_images/Image%d.jpg", count);
566        flname = "/sdcard/saved_images/Image1.jpg";
567        LOGI(flname);
568         count = count +1;
569         fflush(stdout);
570             img = getJPG(flname);
571                 LOGI("Picture data '%d' is....",img->data);
572                 picture->data[0] = img->data;
573                 // convert the rgb frame into yuv frame
574                // rgb2yuv(picture,yuvFrame,c);
575                 LOGI("translation completed.");
576                 // encode the image
577                 out_size = avcodec_encode_video(c, outbuf, outbuf_size, yuvFrame);
578                 LOGI("after out_size value");
579                 LOGI("Out size value '%d'",out_size);
580                // sprintf(info,"encoding frame %3d (size=%5d)\n", z, out_size);
581                 LOGI("Out_buf value '%d'",outbuf);
582                 LOGI("encoding frame %3d (size=%5d)\n", z);
583                 LOGI("encoding frame %3d (size=%5d)\n", out_size);
584                 fwrite(outbuf, 1, out_size, f);
585                 LOGI("after fwrite completed.");
586                 free(img);
587                 LOGI("after free completed.");
588                 flname = "/sdcard/saved_images/Image'%d'+1.jpg";
589    }while(count<699);*/
590     /* get the delayed frames */
591    /* for(; out_size; i++) {
592         fflush(stdout);
593                 LOGI("in get delayed frames for loop.");
594         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
595         LOGI("in get delayed frames for loop after out_size.");
596      //   printf("write frame %3d (size=%5d)\n", i, out_size);
597         LOGI("write frame %3d (size=%5d)\n", i);
598         fwrite(outbuf, 1, z, f);
599         LOGI("after  fwrite(outbuf, 1, out_size, f) completed.");
600      }*/
601
602      /* add sequence end code to have a real mpeg file */
603     LOGI("Adding sequance..");
604     outbuf[0] = 0x00;
605     outbuf[1] = 0x00;
606     outbuf[2] = 0x01;
607     outbuf[3] = 0xb7;
608     fwrite(outbuf, 1, 4, f);
609     LOGI("Adding sequance.. After fwrite");
610     fclose(f);
611     LOGI("close the file");
612     free(picture_buf);
613     free(outbuf);
614     avcodec_close(c);
615     av_free(c);
616     av_free(picture);
617     LOGI("Free the PIC");
618     printf("\n");
619      }
620
621int rgb2yuv(AVFrame *frameRGB, AVFrame *frameYUV, AVCodecContext *c)
622{
623        LOGI("rgb2yuv starts.......");
624        char *err;
625        static struct SwsContext *img_convert_ctx;
626        LOGI("conversion starts");
627        // Convert the image into YUV format from RGB format
628        if(img_convert_ctx == NULL) {
629                int w = c->width;
630                int h = c->height;
631                LOGI("Before img_convert_ctx..");
632                img_convert_ctx = sws_getContext(w, h, PIX_FMT_RGB24,w, h, c->pix_fmt, SWS_BICUBIC,NULL, NULL, NULL);
633                img_convert_ctx = sws_getContext(c->width, c->height, c->pix_fmt, c->width, c->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
634                LOGI("After img_convert_ctx..");
635                if(img_convert_ctx == NULL) {
636                        sprintf(err, "Cannot initialize the conversion context!\n");
637                        LOGI(err);
638                        return -1;
639                }
640        }
641        LOGI("Before sws_scale..");
642        int ret = sws_scale(img_convert_ctx,(const uint8_t* const*)frameRGB->data, frameRGB->linesize , 0,c->height,frameYUV->data, frameYUV->linesize );
643        LOGI("rgb returns....ret value");
644            return  ret;
645}
646 int Java_com_google_video_AndroidVideoRecordingActivity_record()
647 {
648         LOGI("avcodec_init called");
649     avcodec_init();
650     LOGI("avcodec_register_all called");
651     avcodec_register_all();
652     LOGI("video_encode_example called");
653     encodeVideo();
654     return 0;
655 }