From 449823bd9971a99c9fe02706b9b1c4e629974019 Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 19 Oct 2010 16:33:04 +0000 Subject: [PATCH] Add a simple dumpmovie program to extract YUV images from a movie. git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@4698 92316355-f0b4-4df1-b90c-862c8a59935f --- examples/Makefile.am | 8 ++- examples/dumpmovie.c | 146 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 examples/dumpmovie.c diff --git a/examples/Makefile.am b/examples/Makefile.am index 870030b..81bff12 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -3,7 +3,7 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/pipi -I../pipi noinst_PROGRAMS = edd img2rubik sharpen floodfill line bezier histogram \ - colorstring makemovie $(storyboard) $(img2twit) + colorstring makemovie $(dumpmovie) $(storyboard) $(img2twit) edd_SOURCES = edd.c edd_LDADD = ../pipi/libpipi.la @@ -33,9 +33,15 @@ makemovie_SOURCES = makemovie.c makemovie_LDADD = ../pipi/libpipi.la if USE_FFMPEG +dumpmovie = dumpmovie storyboard = storyboard endif +dumpmovie_SOURCES = dumpmovie.c +dumpmovie_LDADD = ../pipi/libpipi.la +dumpmovie_CFLAGS = $(LIBAVFORMAT_CFLAGS) $(LIBAVCODEC_CFLAGS) $(LIBSWSCALE_CFLAGS) +dumpmovie_LDFLAGS = $(LIBAVFORMAT_LIBS) $(LIBAVCODEC_LIBS) $(LIBSWSCALE_LIBS) + storyboard_SOURCES = storyboard.c storyboard_LDADD = ../pipi/libpipi.la storyboard_CFLAGS = $(LIBAVFORMAT_CFLAGS) $(LIBAVCODEC_CFLAGS) $(LIBSWSCALE_CFLAGS) diff --git a/examples/dumpmovie.c b/examples/dumpmovie.c new file mode 100644 index 0000000..7821afc --- /dev/null +++ b/examples/dumpmovie.c @@ -0,0 +1,146 @@ +/* + * dumpmovie dump a movie into YUV PNG files + * Copyright (c) 2010 Sam Hocevar + * All Rights Reserved + * + * $Id$ + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + char fmtstr[1024]; + AVPacket packet; + AVFormatContext *fmt; + AVCodecContext *ctx; + AVCodec *codec; + AVFrame *frame; + struct SwsContext *sws = NULL; + pipi_image_t *image = NULL; + pipi_pixels_t *p; + uint8_t *dst[4], *data = NULL; + char *parser; + int stream, pitch[4], i, k = 0; + + if(argc < 2) + return EXIT_FAILURE; + + /* Ensure our linear YUV values do not get gamma-corrected */ + pipi_set_gamma(1.0); + + parser = strrchr(argv[1], '/'); + strcpy(fmtstr, parser ? parser + 1 : argv[1]); + parser = strrchr(fmtstr, '.'); + if(parser) + *parser = '\0'; + strcat(fmtstr, "-%06i.png"); + + av_register_all(); + if(av_open_input_file(&fmt, argv[1], NULL, 0, NULL) != 0) + return EXIT_FAILURE; + if(av_find_stream_info(fmt) < 0 ) + return EXIT_FAILURE; + + stream = -1; + for(i = 0; stream == -1 && i < (int)fmt->nb_streams; i++) + if(fmt->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) + stream = i; + if(stream == -1) + return EXIT_FAILURE; + ctx = fmt->streams[stream]->codec; + + codec = avcodec_find_decoder(ctx->codec_id); + if(codec == NULL) + return EXIT_FAILURE; + if(avcodec_open(ctx, codec) < 0) + return EXIT_FAILURE; + + frame = avcodec_alloc_frame(); + + for(;;) + { + int finished, ret, x, y; + + ret = av_read_frame(fmt, &packet); + + if(ret < 0) + break; + + if(packet.stream_index != stream) + { + av_free_packet(&packet); + continue; + } + + avcodec_decode_video(ctx, frame, &finished, packet.data, packet.size); + if(!finished) + { + av_free_packet(&packet); + continue; + } + + if(!sws) + { + sws = sws_getContext(ctx->width, ctx->height, ctx->pix_fmt, + ctx->width, ctx->height, PIX_FMT_YUV444P, + SWS_FAST_BILINEAR, NULL, NULL, NULL); + pitch[0] = ctx->width; + pitch[1] = ctx->width; + pitch[2] = ctx->width; + pitch[3] = 0; + dst[0] = malloc(ctx->width * ctx->height * 3); + dst[1] = dst[0] + ctx->width * ctx->height; + dst[2] = dst[1] + ctx->width * ctx->height; + dst[3] = NULL; + image = pipi_new(ctx->width, ctx->height); + } + + sws_scale(sws, (uint8_t const **)frame->data, frame->linesize, 0, + ctx->height, dst, pitch); + + p = pipi_get_pixels(image, PIPI_PIXELS_RGBA_U8); + data = (uint8_t *)p->pixels; + + for (y = 0; y < ctx->height; y++) + { + int off = y * ctx->width; + + for (x = 0; x < ctx->width; x++, off++) + { + data[4 * off] = dst[0][off]; + data[4 * off + 1] = dst[1][off]; + data[4 * off + 2] = dst[2][off]; + data[4 * off + 3] = 0xff; + } + } + + { + char buf[1024]; + sprintf(buf, fmtstr, k++); + printf("saving in %s\n", buf); + pipi_save(image, buf); + } + + av_free_packet(&packet); + } + + return EXIT_SUCCESS; +} +