From 9dbb1110bedd35664f17c84e6459b6b597b14f70 Mon Sep 17 00:00:00 2001 From: Jan Klemkow Date: Wed, 14 Nov 2012 13:34:55 +0100 Subject: Add average frame calculation. --- src/Makefile | 5 +- src/advtime.c | 212 +++++++++++++--------------------------------------------- 2 files changed, 50 insertions(+), 167 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 0cd8c91..b5a6901 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,11 +1,10 @@ CFLAGS=-std=c99 -Wall -Wstrict-prototypes -Wmissing-prototypes -Wno-unused-parameter -LibAV=`pkg-config --cflags --libs libavcodec` LIBAV_DECODE_FLAGS=`pkg-config --libs --cflags libavformat libavcodec libavutil libswscale` all: advtime decode_frame frame_to_pgm -advtime: advtime.c - gcc ${LibAV} advtime.c -o $@ +advtime: advtime.c video_decode.c + gcc $(CFLAGS) $(LIBAV_DECODE_FLAGS) advtime.c video_decode.c -o $@ decode_frame: decode_frame.c gcc $(CFLAGS) $(LIBAV_DECODE_FLAGS) decode_frame.c -o $@ diff --git a/src/advtime.c b/src/advtime.c index e4efb34..07be68c 100644 --- a/src/advtime.c +++ b/src/advtime.c @@ -1,182 +1,66 @@ -/** - * @file - * libavcodec API use example. - * - * @example libavcodec/api-example.c - * Note that this library only handles codecs (mpeg, mpeg4, etc...), - * not file formats (avi, vob, etc...). See library 'libavformat' for the - * format handling - */ - #include #include -#include - -#ifdef HAVE_AV_CONFIG_H -#undef HAVE_AV_CONFIG_H -#endif - -#include -#include -#include -#include -#include -#include - -#define INBUF_SIZE 4096 -#define AUDIO_INBUF_SIZE 20480 -#define AUDIO_REFILL_THRESH 4096 +#include -/* - * Video decoding example - */ +#include "video_decode.h" -static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, - char *filename) +static void +pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, char *filename) { - FILE *f; - int i; - - f=fopen(filename,"w"); - fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255); - for(i=0;icapabilities&CODEC_CAP_TRUNCATED) - c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */ - - /* For some codecs, such as msmpeg4 and mpeg4, width and height - MUST be initialized there because this information is not - available in the bitstream. */ - - /* open it */ - if (avcodec_open2(c, codec, NULL) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - /* the codec gives us the frame size, in samples */ - - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "could not open %s\n", filename); - exit(1); - } - - frame = 0; - for(;;) { - avpkt.size = fread(inbuf, 1, INBUF_SIZE, f); - if (avpkt.size == 0) - break; - - /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) - and this is the only method to use them because you cannot - know the compressed data size before analysing it. - - BUT some other codecs (msmpeg4, mpeg4) are inherently frame - based, so you must call them with all the data for one - frame exactly. You must also initialize 'width' and - 'height' before initializing them. */ - - /* NOTE2: some codecs allow the raw parameters (frame size, - sample rate) to be changed at any frame. We handle this, so - you should also take care of it */ - - /* here, we use a stream based decoder (mpeg1video), so we - feed decoder and see if it could decode a frame */ - avpkt.data = inbuf; - while (avpkt.size > 0) { - len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); - if (len < 0) { - fprintf(stderr, "Error while decoding frame %d\n", frame); - exit(1); - } - if (got_picture) { - printf("saving frame %3d\n", frame); - fflush(stdout); - - /* the picture is allocated by the decoder. no need to - free it */ - snprintf(buf, sizeof(buf), outfilename, frame); - pgm_save(picture->data[0], picture->linesize[0], - c->width, c->height, buf); - frame++; - } - avpkt.size -= len; - avpkt.data += len; - } - } - - /* some codecs, such as MPEG, transmit the I and P frame with a - latency of one frame. You must do the following to have a - chance to get the last frame of the video */ - avpkt.data = NULL; - avpkt.size = 0; - len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); - if (got_picture) { - printf("saving last frame %3d\n", frame); - fflush(stdout); - - /* the picture is allocated by the decoder. no need to - free it */ - snprintf(buf, sizeof(buf), outfilename, frame); - pgm_save(picture->data[0], picture->linesize[0], - c->width, c->height, buf); - frame++; - } - - fclose(f); - - avcodec_close(c); - av_free(c); -// avcodec_free_frame(&picture); - printf("\n"); + int64_t average = 0; + uint8_t *row = frame->data; + uint8_t *col = NULL; + + for (int y = 0; y < frame->height; ++y) { + col = row; + for (int x = 0; x < frame->width; ++x) { + average += *col; + col++; + } + row += frame->stride; + } + + return average / (frame->width * frame->height); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { + struct video_decode *vd; + struct video_frame *frame; + int ret; + int64_t timestamp = 0; + if (argc < 2) return 1; - /* register all the codecs */ - avcodec_register_all(); + if (argc == 3 && strtol(argv[2], NULL, 10) > 0) + timestamp = strtol(argv[2], NULL, 10); + + ret = video_decode_init(&vd, argv[1], timestamp); + if (ret < 0) + return -ret; -// FILE *fh = fopen(argv[1], "rb"); -// if (fh == NULL) -// return 1; + while (video_decode_get_frame(vd, &frame) == 0) { + printf("%d\n", frame_average(frame)); + video_decode_free_frame(&frame); + } - video_decode_example("out", argv[1]); +// pgm_save(frame->data, frame->stride, frame->width, frame->height, +// argv[2]); -// fclose(sh); - return 0; + video_decode_uninit(&vd); } -- cgit