you never do any read packets and decode after each av_seek_frame???

"seek" only moves the read pointer to the place you want, you must
redo a whole processes of "av_read_frame", "avcodec_decode_video2",
"swscale..." to get a new picture

On Feb 24, 3:15 am, cervello <[email protected]> wrote:
> I have an array that keeps which frames are the keyframe and I want to
> create a video with these keyframes but first off all I try to save
> these keyframes in a directory in sdcard called "keyframes".
> I use a video that I have 217 keyframe and  I think I understand using
> of av_seek_frame() wrong .
> Because my code always save the last frame 217 times with different
> names like frame1,frame2...frame217.
> Can someone help me? Thank you.
>
> void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
> log_message("saving frame.");
>
>   FILE *pFile;
>   char szFilename[32];
>   int  y;
>   // Open file
>   sprintf(szFilename, "/sdcard/keyframes/frame%d.ppm", iFrame+1);
>   pFile=fopen(szFilename, "wb");
>   if(pFile==NULL)
>     return;
>
>   // Write header
>   fprintf(pFile, "P6\n%d %d\n255\n", width, height);
>
>   // Write pixel data
>   for(y=0; y<height; y++)
>     fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
>
>   // Close file
>   fclose(pFile);
>
> }
>
> jint Java_com_test_Test_takePics(JNIEnv* env, jobject javaThis)  {
>
>    const char path[256] = "/sdcard/keyframes/";
>    if (mkdir (path) != 0) printf("Fail Retry");
>
>     log_message("Fonka girdim!\n");
>
>     AVFormatContext *pFormatCtx;
>     int             i, videoStream, j;
>     AVCodecContext  *pCodecCtx;
>     AVCodec         *pCodec;
>     AVFrame         *pFrame;
>     AVFrame         *pFrameRGB;
>     AVPacket        packet;
>     int             frameFinished;
>     int             numBytes;
>     uint8_t         *buffer;
>     unsigned char r, g, b;
>     int framecount;
>
>     char* filename = "/sdcard/do-beer-not-drugs.3gp";
>     // Register all formats and codecs
>     av_register_all();
>
>     // Open video file
>     if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0)
>         return -1; // Couldn't open file
>
>     // Retrieve stream information
>     if(av_find_stream_info(pFormatCtx)<0)
>         return -1; // Couldn't find stream information
>
>     // Dump information about file onto standard error
>     dump_format(pFormatCtx, 0, filename, 0);
>
>         framecount = pFormatCtx->streams[0]->nb_frames;
>         hist = malloc(framecount*sizeof(int*));
>
>             for (j = 0; j < framecount; ++j) {
>                         hist[j] = malloc(sizeof(int)*64); // this is because 
> we use 64-bin
> histogram
>                 }
>             for (i = 0; i < framecount; i++) {
>                 for (j = 0; j < 64; j++) {
>                                 hist[i][j] = 0;
>                         }
>
>             }
>
>     // Find the first video stream
>     videoStream=-1;
>     for(i=0; i<pFormatCtx->nb_streams; i++)
>         if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
>
>         {
>             videoStream=i;
>             break;
>         }
>     if(videoStream==-1)
>         return -1; // Didn't find a video stream
>
>     // Get a pointer to the codec context for the video stream
>     pCodecCtx=pFormatCtx->streams[videoStream]->codec;
>
>     // Find the decoder for the video stream
>     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
>     if(pCodec==NULL)
>         return -1; // Codec not found
>
>     // Open codec
>     if(avcodec_open(pCodecCtx, pCodec)<0)
>         return -1; // Could not open codec
>
>     // Hack to correct wrong frame rates that seem to be generated by
> some codecs
>     if(pCodecCtx->time_base.num>1000 && pCodecCtx->time_base.den==1)
>                 pCodecCtx->time_base.den=1000;
>
>     // Allocate video frame
>     pFrame=avcodec_alloc_frame();
>
>     // Allocate an AVFrame structure
>     pFrameRGB=avcodec_alloc_frame();
>     if(pFrameRGB==NULL)
>         return -1;
>
>     // Determine required buffer size and allocate buffer
>     numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
>         pCodecCtx->height);
>
>     buffer=malloc(numBytes);
>
>     // Assign appropriate parts of buffer to image planes in pFrameRGB
>     avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
>         pCodecCtx->width, pCodecCtx->height);
>
>     // Read frames and save first five frames to disk
>     i=0;
>     while(av_read_frame(pFormatCtx, &packet)>=0)
>     {
>         // Is this a packet from the video stream?
>         if(packet.stream_index==videoStream)
>         {
>             // Decode video frame
>             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
>                 &packet);
>
>             // Did we get a video frame?
>             if(frameFinished)
>             {
>
>                 static struct SwsContext *img_convert_ctx;
>
>                                 // Convert the image into YUV format that SDL 
> uses
>                                 if(img_convert_ctx == NULL) {
>                                         int w = pCodecCtx->width;
>                                         int h = pCodecCtx->height;
>
>                                         img_convert_ctx = sws_getContext(w, h,
>                                                                         
> pCodecCtx->pix_fmt,
>                                                                         w, h, 
> PIX_FMT_RGB24, SWS_BICUBIC,
>                                                                         NULL, 
> NULL, NULL);
>                                         if(img_convert_ctx == NULL) {
>                                                 fprintf(stderr, "Cannot 
> initialize the conversion context!\n");
>                                                 exit(1);
>                                         }
>                                 }
>                                 int ret = sws_scale(img_convert_ctx, 
> pFrame->data, pFrame->linesize, 0,
>
>                                                   pCodecCtx->height, 
> pFrameRGB->data, pFrameRGB->linesize);
>
>                                         for (j = 0; j < 
> 3*pCodecCtx->height*pCodecCtx->width -3; j++) {
>                                                                               
>                                   r = (unsigned char) pFrameRGB->data[0][j];
>                                                                               
>                                   g = (unsigned char) pFrameRGB->data[0][j
> +1];
>                                                                               
>                                   b = (unsigned char) pFrameRGB->data[0][j
> +2];
>
>                                                                               
>                                   r = (unsigned char) ((r >> 2) & 0x30);
>                                                                               
>                                   g = (unsigned char) ((g >> 4) & 0x0C);
>                                                                               
>                                   b = (unsigned char) ((b >> 6) & 0x03);
>
>                                                                               
>                                   unsigned char h = (unsigned char)(r|g|b);
>                                                                               
>                                   hist[i][h]++;
>                                         }
>                                 i++;
>             }
>         }
>
>         // Free the packet that was allocated by av_read_frame
>         av_free_packet(&packet);
>     }
>
>         framecount = i;
>         int keyframelength=select_keyFrames(framecount);
>
> for(i=1;i<keyframelength+1;i++){
>         int64_t timeStamp = (int64_t)((pFormatCtx->duration) /
> framecount)*keyFrames[i]/100;
>         av_seek_frame(pFormatCtx,0,timeStamp,AVSEEK_FLAG_ANY);
>         SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
>
> }
>
>     free(keyFrames);
>     // Free the RGB image
>     free(buffer);
>     av_free(pFrameRGB);
>
>     // Free the YUV frame
>     av_free(pFrame);
>
>     // Close the codec
>     avcodec_close(pCodecCtx);
>
>     // Close the video file
>     av_close_input_file(pFormatCtx);
>
>     return 0;
>
>
>
>
>
>
>
> }

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to