|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /*
- * 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;
- }
-
|