Ticket #6373: the_program.txt

File the_program.txt, 4.7 KB (added by nthrev, 7 months ago)
Line 
1//#pragma comment( lib, "MyLib.lib" )  // the icludes of my project
2
3#include <libavcodec/avcodec.h>
4#include <libavformat/avformat.h>
5
6#include <my_libswscale/swscale.h>
7
8#include <stdio.h>
9
10// compatibility with newer API
11#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
12#define av_frame_alloc avcodec_alloc_frame
13#define av_frame_free avcodec_free_frame
14#endif
15
16
17void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
18        FILE *pFile;
19        char szFilename[32];
20        int  y;
21
22        // Open file
23        sprintf(szFilename, "frame%d.ppm", iFrame);
24        pFile = fopen(szFilename, "wb");
25        if (pFile == NULL)
26                return;
27
28        // Write header
29        fprintf(pFile, "P6\n%d %d\n255\n", width, height);
30
31        // Write pixel data
32        for (y = 0; y<height; y++)
33                fwrite(pFrame->data[0] + y*pFrame->linesize[0], 1, width * 3, pFile);
34
35        // Close file
36        fclose(pFile);
37}
38
39int main(int argc, char *argv[]) {
40        // Initalizing these to NULL prevents segfaults!
41        AVFormatContext   *pFormatCtx = NULL;
42        int               i, videoStream;
43        AVCodecContext    *pCodecCtxOrig = NULL;
44        AVCodecContext    *pCodecCtx = NULL;
45        AVCodec           *pCodec = NULL;
46        AVFrame           *pFrame = NULL;
47        AVFrame           *pFrameRGB = NULL;
48        AVPacket          packet;
49        int               frameFinished;
50        int               numBytes;
51        uint8_t           *buffer = NULL;
52        struct SwsContext *sws_ctx = NULL;
53
54        if (argc < 2) {
55                printf("Please provide a movie file\n");
56                return -1;
57        }
58        // Register all formats and codecs
59        av_register_all();
60
61        // Open video file
62        if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0)
63                return -1; // Couldn't open file
64
65                                   // Retrieve stream information
66        if (avformat_find_stream_info(pFormatCtx, NULL)<0)
67                return -1; // Couldn't find stream information
68
69                                   // Dump information about file onto standard error
70        av_dump_format(pFormatCtx, 0, argv[1], 0);
71
72        // Find the first video stream
73        videoStream = -1;
74        for (i = 0; i<pFormatCtx->nb_streams; i++)
75                if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
76                        videoStream = i;
77                        break;
78                }
79        if (videoStream == -1)
80                return -1; // Didn't find a video stream
81
82                                   // Get a pointer to the codec context for the video stream
83        pCodecCtxOrig = pFormatCtx->streams[videoStream]->codec;
84        // Find the decoder for the video stream
85        pCodec = avcodec_find_decoder(pCodecCtxOrig->codec_id);
86        if (pCodec == NULL) {
87                fprintf(stderr, "Unsupported codec!\n");
88                return -1; // Codec not found
89        }
90        // Copy context
91        pCodecCtx = avcodec_alloc_context3(pCodec);
92        if (avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) {
93                fprintf(stderr, "Couldn't copy codec context");
94                return -1; // Error copying codec context
95        }
96
97        // Open codec
98        if (avcodec_open2(pCodecCtx, pCodec, NULL)<0)
99                return -1; // Could not open codec
100
101                                   // Allocate video frame
102        pFrame = av_frame_alloc();
103
104        // Allocate an AVFrame structure
105        pFrameRGB = av_frame_alloc();
106        if (pFrameRGB == NULL)
107                return -1;
108
109        // Determine required buffer size and allocate buffer
110        numBytes = avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width,
111                pCodecCtx->height);
112        buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
113
114        // Assign appropriate parts of buffer to image planes in pFrameRGB
115        // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
116        // of AVPicture
117        avpicture_fill((AVPicture *)pFrameRGB, buffer, AV_PIX_FMT_RGB24,
118                pCodecCtx->width, pCodecCtx->height);
119
120        // initialize SWS context for software scaling
121        sws_ctx = sws_getContext(pCodecCtx->width,
122                pCodecCtx->height,
123                pCodecCtx->pix_fmt,
124                pCodecCtx->width,
125                pCodecCtx->height,
126                AV_PIX_FMT_RGB24,
127                SWS_BILINEAR,
128                NULL,
129                NULL,
130                NULL
131        );
132
133        // Read frames and save first five frames to disk
134        i = 0;
135        while (av_read_frame(pFormatCtx, &packet) >= 0) {
136                // Is this a packet from the video stream?
137                if (packet.stream_index == videoStream) {
138                        // Decode video frame
139                        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
140
141                        // Did we get a video frame?
142                        if (frameFinished) {
143                                // Convert the image from its native format to RGB
144                                sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data,
145                                        pFrame->linesize, 0, pCodecCtx->height,
146                                        pFrameRGB->data, pFrameRGB->linesize);
147
148                                // Save the frame to disk
149                                if (++i <= 5)
150                                        SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height,
151                                                i);
152                        }
153                }
154
155                // Free the packet that was allocated by av_read_frame
156                av_free_packet(&packet);
157        }
158
159        // Free the RGB image
160        av_free(buffer);
161        av_frame_free(&pFrameRGB);
162
163        // Free the YUV frame
164        av_frame_free(&pFrame);
165
166        // Close the codecs
167        avcodec_close(pCodecCtx);
168        avcodec_close(pCodecCtxOrig);
169
170        // Close the video file
171        avformat_close_input(&pFormatCtx);
172
173        return 0;
174}