// tutorial01.c // Code based on a tutorial by Martin Bohme (boehme@inb.uni-luebeckREMOVETHIS.de) // Tested on Gentoo, CVS version 5/01/07 compiled with GCC 4.1.1 // A small sample program that shows how to use libavformat and libavcodec to // read video from a file. // // Use // // gcc -O3 -g -Wall -o dumpframe dumpframe.c -I/usr/local/include/ -L/usr/local/lib/ -lavformat -lavcodec -lz // // to build (assuming libavformat and libavcodec are correctly installed // your system). // // Run using // // tutorial01 myvideofile.mpg // // to write the first five frames from "myvideofile.mpg" to disk in PPM // format. #include #include #include #include #include #include #include #include static int frame_start = 0; static int frame_number = 0xffff; static int frame_saved = 0; static int frame_current = 0; static int frame_step = 1; static int frame_single = 0; /* write each frame to single files */ static char *src_fn = NULL; static char *dst_fn = NULL; static int srcFd = 0; static int outFd = 0; static int is_vp8 = 0; static int dump_frame(int pos, int size) { char fn[1024]; if ((frame_start > frame_current) || (frame_saved >= frame_number)) { //printf("==Dumped Frame #%d: Skiped and Not Happend==\n", frame_current); return 0; } if (frame_single) /* dump each frame into a single file */ sprintf(fn, "%s.%d", dst_fn, frame_saved); else sprintf(fn, "%s", dst_fn); if (outFd == 0) { outFd = open(fn, O_TRUNC|O_RDWR|O_CREAT, S_IROTH); if (outFd <= 0) { printf("Open file %s error (%s)\n", fn, strerror(errno)); return 0; } } if (is_vp8) { /* include the IVF header */ if (frame_current == 0) { pos = pos - 32; size = size + 32 + 12; } else { //pos = pos - 12; size = size + 12; } } if (outFd > 0 && srcFd > 0 && pos >=0 && size > 0) { char *p = malloc(size+4096); lseek(srcFd, pos, SEEK_SET); read(srcFd, p, size); write(outFd, p, size); if (frame_single) { close(outFd); outFd = 0; } free(p); printf("=====Dumped Frame #%d to File %s (start:%d, size:%d)=====\n", frame_current, fn, pos, size); } else printf("=====Fail to dumped Frame #%d to File %s for Some Reason=====\n", frame_current, fn); frame_saved++; frame_start += frame_step; /* pointer to next frame location*/ return 0; } static int process_frame(AVCodecContext *pCodecCtx, AVFrame *pFrame, AVPacket *packet) { int ret, frameFinished; avcodec_get_frame_defaults(pFrame); /// Decode video frame //avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size); ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, packet); if (ret < 0) return ret; #define FFMIN(a, b) ((a) > (b) ? (b) : (a)) ret = FFMIN(ret, packet->size);/* guard against bogus return values */ packet->data += ret; packet->size -= ret; // Did we get a video frame? if (frameFinished == 0) return 0; int pos = -1, size = -1; if (av_frame_get_pkt_pos (pFrame) != -1) { pos = (int)av_frame_get_pkt_pos(pFrame); } else { printf("pkt_pos:N/A\n"); } if (av_frame_get_pkt_size(pFrame) != -1) { size = av_frame_get_pkt_size(pFrame); } else { printf("pkt_size:N/A"); } printf("=====Frame #%d (pkt_pos=%d, pkt_size=%d)====\n", frame_current, pos, size); dump_frame(pos, size); frame_current++; return frameFinished; } static void help() { printf("dumpframe -s -n -step -single -v