Browse Source

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
master
sam 14 years ago
parent
commit
449823bd99
2 changed files with 153 additions and 1 deletions
  1. +7
    -1
      examples/Makefile.am
  2. +146
    -0
      examples/dumpmovie.c

+ 7
- 1
examples/Makefile.am View File

@@ -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)


+ 146
- 0
examples/dumpmovie.c View File

@@ -0,0 +1,146 @@
/*
* dumpmovie dump a movie into YUV PNG files
* Copyright (c) 2010 Sam Hocevar <sam@hocevar.net>
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>

#include <pipi.h>

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;
}


Loading…
Cancel
Save