diff options
-rw-r--r-- | src/Makefile | 5 | ||||
-rw-r--r-- | src/advtime.c | 212 |
2 files changed, 50 insertions, 167 deletions
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 <stdio.h> #include <stdlib.h> -#include <string.h> - -#ifdef HAVE_AV_CONFIG_H -#undef HAVE_AV_CONFIG_H -#endif - -#include <libavcodec/avcodec.h> -#include <libavutil/audioconvert.h> -#include <libavutil/common.h> -#include <libavutil/imgutils.h> -#include <libavutil/mathematics.h> -#include <libavutil/samplefmt.h> - -#define INBUF_SIZE 4096 -#define AUDIO_INBUF_SIZE 20480 -#define AUDIO_REFILL_THRESH 4096 +#include <stdint.h> -/* - * 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;i<ysize;i++) - fwrite(buf + i * wrap,1,xsize,f); - fclose(f); + FILE *f; + int i; + + f = fopen(filename, "w"); + fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255); + for(i=0; i < ysize; i++) + fwrite(buf + i * wrap, 1, xsize, f); + fclose(f); } -static void video_decode_example(const char *outfilename, const char *filename) +int64_t +frame_average(struct video_frame *frame) { - AVCodec *codec; - AVCodecContext *c= NULL; - int frame, got_picture, len; - FILE *f; - AVFrame *picture; - uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; - char buf[1024]; - AVPacket avpkt; - - av_init_packet(&avpkt); - - /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ - memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); - - printf("Video decoding\n"); - - /* find the mpeg1 video decoder */ - codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - c = avcodec_alloc_context3(codec); - picture= avcodec_alloc_frame(); - - if(codec->capabilities&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); } |