Ticket #1772: vidapi.c

File vidapi.c, 18.3 KB (added by neelima, 14 years ago)
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 }