source: libpipi/trunk/examples/dumpmovie.c @ 4704

Last change on this file since 4704 was 4704, checked in by Sam Hocevar, 13 years ago

YUV support in dumpmovie and makemovie.

  • Property svn:keywords set to Id
File size: 4.4 KB
Line 
1/*
2 *  dumpmovie     dump a movie into YUV PNG files
3 *  Copyright (c) 2010 Sam Hocevar <sam@hocevar.net>
4 *                All Rights Reserved
5 *
6 *  $Id: dumpmovie.c 4704 2010-11-03 21:31:38Z sam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15#include "config.h"
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include <libavcodec/avcodec.h>
22#include <libavformat/avformat.h>
23#include <libswscale/swscale.h>
24
25#include <pipi.h>
26
27int main(int argc, char *argv[])
28{
29    char fmtstr[1024];
30    AVPacket packet;
31    AVFormatContext *fmt;
32    AVCodecContext *ctx;
33    AVCodec *codec;
34    AVFrame *frame;
35    struct SwsContext *sws = NULL;
36    pipi_image_t *image = NULL;
37    pipi_pixels_t *p;
38    uint8_t *dst[4], *data = NULL;
39    char *parser;
40    int stream, pitch[4], i, k = 0, nframes = -1;
41    double skip_seconds = 0.0;
42
43    if (argc < 2)
44        return EXIT_FAILURE;
45
46    if (argc > 2)
47        skip_seconds = atof(argv[2]);
48    if (argc > 3)
49        nframes = atoi(argv[3]);
50
51    /* Ensure our linear YUV values do not get gamma-corrected */
52    pipi_set_gamma(1.0);
53
54    parser = strrchr(argv[1], '/');
55    strcpy(fmtstr, parser ? parser + 1 : argv[1]);
56    parser = strrchr(fmtstr, '.');
57    if(parser)
58        *parser = '\0';
59    strcat(fmtstr, "-%06i.png");
60
61    av_register_all();
62    if(av_open_input_file(&fmt, argv[1], NULL, 0, NULL) != 0)
63        return EXIT_FAILURE;
64    if(av_find_stream_info(fmt) < 0 )
65        return EXIT_FAILURE;
66
67    stream = -1;
68    for(i = 0; stream == -1 && i < (int)fmt->nb_streams; i++)
69        if(fmt->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
70            stream = i;
71    if(stream == -1)
72        return EXIT_FAILURE;
73    ctx = fmt->streams[stream]->codec;
74
75    codec = avcodec_find_decoder(ctx->codec_id);
76    if(codec == NULL)
77        return EXIT_FAILURE;
78    if(avcodec_open(ctx, codec) < 0)
79        return EXIT_FAILURE;
80
81    skip_seconds /= av_q2d(fmt->streams[stream]->time_base);
82    av_seek_frame(fmt, stream, (int)(skip_seconds + 0.5), SEEK_SET);
83    //avformat_seek_file(fmt, stream, skip_bytes, skip_bytes,
84    //                   skip_bytes, AVSEEK_FLAG_BYTE);
85
86    frame = avcodec_alloc_frame();
87
88    for (k = 0; k < nframes || nframes == -1; /* k incremented below */)
89    {
90        int finished, ret, x, y;
91
92        ret = av_read_frame(fmt, &packet);
93
94        if(ret < 0)
95            break;
96
97        if(packet.stream_index != stream)
98        {
99            av_free_packet(&packet);
100            continue;
101        }
102
103        avcodec_decode_video(ctx, frame, &finished, packet.data, packet.size);
104        if(!finished)
105        {
106            av_free_packet(&packet);
107            continue;
108        }
109
110        if(!sws)
111        {
112            sws = sws_getContext(ctx->width, ctx->height, ctx->pix_fmt,
113                                 ctx->width, ctx->height, PIX_FMT_YUV444P,
114                                 SWS_FAST_BILINEAR, NULL, NULL, NULL);
115            pitch[0] = ctx->width;
116            pitch[1] = ctx->width;
117            pitch[2] = ctx->width;
118            pitch[3] = 0;
119            dst[0] = malloc(ctx->width * ctx->height * 3);
120            dst[1] = dst[0] + ctx->width * ctx->height;
121            dst[2] = dst[1] + ctx->width * ctx->height;
122            dst[3] = NULL;
123            image = pipi_new(ctx->width, ctx->height);
124        }
125
126        {
127            char buf[1024];
128            sprintf(buf, fmtstr, k);
129            printf("saving in %s\n", buf);
130
131            sws_scale(sws, (uint8_t const **)frame->data, frame->linesize, 0,
132                      ctx->height, dst, pitch);
133
134            p = pipi_get_pixels(image, PIPI_PIXELS_RGBA_U8);
135            data = (uint8_t *)p->pixels;
136
137            for (y = 0; y < ctx->height; y++)
138            {
139                int off = y * ctx->width;
140
141                for (x = 0; x < ctx->width; x++, off++)
142                {
143                    /* Reorder components to store YUVA */
144                    data[4 * off] = dst[0][off];
145                    data[4 * off + 1] = dst[2][off];
146                    data[4 * off + 2] = dst[1][off];
147                    data[4 * off + 3] = 0xff;
148                }
149            }
150
151            pipi_save(image, buf);
152        }
153
154        av_free_packet(&packet);
155
156        k++;
157    }
158
159    return EXIT_SUCCESS;
160}
161
Note: See TracBrowser for help on using the repository browser.