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