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

Last change on this file since 4703 was 4703, checked in by Sam Hocevar, 10 years ago

Ensure dumpmovie outputs YUVA pictures.

  • Property svn:keywords set to Id
File size: 3.9 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 4703 2010-11-03 21:31:31Z 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;
41
42    if(argc < 2)
43        return EXIT_FAILURE;
44
45    /* Ensure our linear YUV values do not get gamma-corrected */
46    pipi_set_gamma(1.0);
47
48    parser = strrchr(argv[1], '/');
49    strcpy(fmtstr, parser ? parser + 1 : argv[1]);
50    parser = strrchr(fmtstr, '.');
51    if(parser)
52        *parser = '\0';
53    strcat(fmtstr, "-%06i.png");
54
55    av_register_all();
56    if(av_open_input_file(&fmt, argv[1], NULL, 0, NULL) != 0)
57        return EXIT_FAILURE;
58    if(av_find_stream_info(fmt) < 0 )
59        return EXIT_FAILURE;
60
61    stream = -1;
62    for(i = 0; stream == -1 && i < (int)fmt->nb_streams; i++)
63        if(fmt->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
64            stream = i;
65    if(stream == -1)
66        return EXIT_FAILURE;
67    ctx = fmt->streams[stream]->codec;
68
69    codec = avcodec_find_decoder(ctx->codec_id);
70    if(codec == NULL)
71        return EXIT_FAILURE;
72    if(avcodec_open(ctx, codec) < 0)
73        return EXIT_FAILURE;
74
75    frame = avcodec_alloc_frame();
76
77    for(;;)
78    {
79        int finished, ret, x, y;
80
81        ret = av_read_frame(fmt, &packet);
82
83        if(ret < 0)
84            break;
85
86        if(packet.stream_index != stream)
87        {
88            av_free_packet(&packet);
89            continue;
90        }
91
92        avcodec_decode_video(ctx, frame, &finished, packet.data, packet.size);
93        if(!finished)
94        {
95            av_free_packet(&packet);
96            continue;
97        }
98
99        if(!sws)
100        {
101            sws = sws_getContext(ctx->width, ctx->height, ctx->pix_fmt,
102                                 ctx->width, ctx->height, PIX_FMT_YUV444P,
103                                 SWS_FAST_BILINEAR, NULL, NULL, NULL);
104            pitch[0] = ctx->width;
105            pitch[1] = ctx->width;
106            pitch[2] = ctx->width;
107            pitch[3] = 0;
108            dst[0] = malloc(ctx->width * ctx->height * 3);
109            dst[1] = dst[0] + ctx->width * ctx->height;
110            dst[2] = dst[1] + ctx->width * ctx->height;
111            dst[3] = NULL;
112            image = pipi_new(ctx->width, ctx->height);
113        }
114
115        sws_scale(sws, (uint8_t const **)frame->data, frame->linesize, 0,
116                  ctx->height, dst, pitch);
117
118        p = pipi_get_pixels(image, PIPI_PIXELS_RGBA_U8);
119        data = (uint8_t *)p->pixels;
120
121        for (y = 0; y < ctx->height; y++)
122        {
123            int off = y * ctx->width;
124
125            for (x = 0; x < ctx->width; x++, off++)
126            {
127                /* Reorder components to store YUVA */
128                data[4 * off] = dst[0][off];
129                data[4 * off + 1] = dst[2][off];
130                data[4 * off + 2] = dst[1][off];
131                data[4 * off + 3] = 0xff;
132            }
133        }
134
135        {
136            char buf[1024];
137            sprintf(buf, fmtstr, k++);
138            printf("saving in %s\n", buf);
139            pipi_save(image, buf);
140        }
141
142        av_free_packet(&packet);
143    }
144
145    return EXIT_SUCCESS;
146}
147
Note: See TracBrowser for help on using the repository browser.