Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FFmpeg sample code for creating a video file from still images JNI Android

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

like image 583
MobDev Avatar asked Oct 18 '11 14:10

MobDev


2 Answers

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.

like image 157
ciphor Avatar answered Oct 03 '22 00:10

ciphor


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

like image 44
N.Droid Avatar answered Oct 03 '22 02:10

N.Droid