17

How i modify the following FFMPEG sample code for creating a video file from still images that i am having in my android phone. I am using JNI for invoking ffmpeg.

JNIEXPORT void JNICALL videoEncodeExample((JNIEnv *pEnv, jobject pObj, jstring filename)

    {
     AVCodec *codec;
     AVCodecContext *c= NULL;
     int i, out_size, size, x, y, outbuf_size;
     FILE *f;
     AVFrame *picture;
     uint8_t *outbuf, *picture_buf;

     printf("Video encoding\n");

     /* find the mpeg1 video encoder */
     codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
     if (!codec) {
         fprintf(stderr, "codec not found\n");
         exit(1);
     }

     c= avcodec_alloc_context();
     picture= avcodec_alloc_frame();

     /* put sample parameters */
     c->bit_rate = 400000;
     /* resolution must be a multiple of two */
     c->width = 352;
     c->height = 288;
     /* frames per second */
     c->time_base= (AVRational){1,25};
     c->gop_size = 10; /* emit one intra frame every ten frames */
     c->max_b_frames=1;
     c->pix_fmt = PIX_FMT_YUV420P;

     /* open it */
     if (avcodec_open(c, codec) < 0) {
         fprintf(stderr, "could not open codec\n");
         exit(1);
     }

     f = fopen(filename, "wb");
     if (!f) {
         fprintf(stderr, "could not open %s\n", filename);
         exit(1);
     }

     /* alloc image and output buffer */
     outbuf_size = 100000;
     outbuf = malloc(outbuf_size);
     size = c->width * c->height;
     picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */

     picture->data[0] = picture_buf;
     picture->data[1] = picture->data[0] + size;
     picture->data[2] = picture->data[1] + size / 4;
     picture->linesize[0] = c->width;
     picture->linesize[1] = c->width / 2;
     picture->linesize[2] = c->width / 2;

     /* encode 1 second of video */
     for(i=0;i<25;i++) {
         fflush(stdout);
         /* prepare a dummy image */
         /* Y */
         for(y=0;y<c->height;y++) {
             for(x=0;x<c->width;x++) {
                 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
             }
         }

         /* Cb and Cr */
         for(y=0;y<c->height/2;y++) {
             for(x=0;x<c->width/2;x++) {
                 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
                 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
             }
         }

         /* encode the image */
         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
         printf("encoding frame %3d (size=%5d)\n", i, out_size);
         fwrite(outbuf, 1, out_size, f);
     }

     /* get the delayed frames */
     for(; out_size; i++) {
         fflush(stdout);

         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
         printf("write frame %3d (size=%5d)\n", i, out_size);
         fwrite(outbuf, 1, out_size, f);
     }

     /* add sequence end code to have a real mpeg file */
     outbuf[0] = 0x00;
     outbuf[1] = 0x00;
     outbuf[2] = 0x01;
     outbuf[3] = 0xb7;
     fwrite(outbuf, 1, 4, f);
     fclose(f);
     free(picture_buf);
     free(outbuf);

     avcodec_close(c);
     av_free(c);
     av_free(picture);
     printf("\n");
    }

Thanks and Regards Anish

Francesco Laurita
  • 23,434
  • 8
  • 55
  • 63
MobDev
  • 1,489
  • 1
  • 17
  • 26
  • 1
    Hello @anish Have you found the solution for your problem..If you got please tell me how you solved it..Cause I am stuck into the same and need to get solution urgently...Please do me the favour..Thanks :) – MKJParekh Nov 26 '11 at 12:32
  • 7
    You would have better luck and more responses if you had a more specific question. You've pasted 100 lines of code but you make no mention of what you've tried or what specific area isn't working as planned. Until then, the only answer I can give is *modify the code very carefully until it does what you expect* – Error 454 Jan 20 '12 at 17:42
  • You might want to check out http://stackoverflow.com/questions/4705830/ffmpeg-encoding-in-c which looks like a similar question, but possibly with the piece you're dealing with already fixed. – mikebabcock Jan 25 '12 at 06:24
  • In what form are the still images in your Android app? Are they bitmaps? byte buffers? Either way, you can pass the data to the JNI code for ffmpeg to encode. Your question is incomplete without this information. – BitBank Jan 26 '12 at 18:17
  • this code I believe is just for one image how can I modify it to use multiple bitmaps ?? I tried copying ffmpeg executables and lib to /system/bin and /system/lib dosn't work it shows segmentattion fault – Aashish Bhatnagar May 05 '12 at 05:37
  • hai anish,did u get the answer for this? – rams Nov 07 '12 at 08:58
  • Hi anish, have you got things worked? if yes, would you please share your outout? – Ravi K. Sharma May 13 '13 at 11:34

2 Answers2

1

In your sample code, the encoded image is dummy. So, I think what you should do is to replace the dummy image to the actual images in your android device, and remember to convert its format to YUV420.

ciphor
  • 8,018
  • 11
  • 53
  • 70
1

In your Code you are using image format as PIX_FMT_YUV420P. You need to convert your images to YUV420P as Android is using raw picture format YUV420SP (PIX_FMT_NV21) you still need to scale your images using libswscale library provided in ffmpeg. may be on of my answer will help you. check it. Converting YUV420SP to YUV420P

Community
  • 1
  • 1
Nishant Rajput
  • 2,053
  • 16
  • 28