Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/avi_play/src/lib/graphics/importer/media_container.cc @ 6068

Last change on this file since 6068 was 6068, checked in by hdavid, 18 years ago

branches\avi_play: MediaContainer::getNextFrame() grabs a frame and saves it as a ppm image, would not try it with large video files ;)

File size: 7.0 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: David Hasenfratz, Stephan Lienhard
13   co-programmer:
14*/
15
16
17
18/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_MEDIA module
19   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
20*/
21#define DEBUG_MODULE_MEDIA
22
23
24/* include your own header */
25#include "media_container.h"
26
27/* header for debug output */
28#include "debug.h"
29
30
31/**
32 * Default constructor
33 */
34MediaContainer::MediaContainer(const char* filename)
35{
36  /* set the class id for the base object */
37  this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer");
38
39  /* register all formats and codecs */
40  av_register_all();
41
42  current_frame = 0;
43
44  if (filename != NULL)
45    this->loadMedia(filename);
46
47}
48
49/**
50 * Default destructor
51 */
52MediaContainer::~MediaContainer()
53{
54  // Free the RGB image
55  delete [] buffer;
56  av_free(RGB_frame);
57
58  /* Free the frame */
59  av_free(frame);
60
61  /* Close the codec */
62  avcodec_close(codec_context);
63
64  /* Close the video file */
65  av_close_input_file(format_context);
66
67}
68
69GLuint MediaContainer::getFrame(int frame_number)
70{
71
72}
73
74GLuint MediaContainer::getNextFrame()
75{
76  /* get next frame */
77  if(av_read_frame(format_context, &packet) >= 0)
78  {
79    //this->printPacketInformation();
80
81    /* Is this a packet from the video stream? */
82    if(packet.stream_index == video_stream)
83    {
84      int frame_finished;
85      // Decode video frame
86      avcodec_decode_video(codec_context, frame, &frame_finished, packet.data, packet.size);
87
88      // Did we get a video frame?
89      if(frame_finished)
90      {
91        current_frame++;
92        PRINTF(1)("current_frame: %i\n", current_frame);
93
94        // Convert the image from its native format to RGB
95        img_convert((AVPicture*)RGB_frame, PIX_FMT_RGB24, (AVPicture*)frame, codec_context->pix_fmt,
96                                        codec_context->width, codec_context->height);
97                       
98        // save frame
99        this->saveCurrentFrame();
100
101
102        /* RGB_picture -> texture */
103
104
105        return texture;
106      }
107    }
108    // Free the packet that was allocated by av_read_frame
109    av_free_packet(&packet);
110  }
111  else
112    return NULL;
113}
114
115void MediaContainer::saveCurrentFrame()
116{
117  FILE *file;
118  char filename[32];
119  int  y;
120
121  picture = (AVPicture*)RGB_frame;
122
123  // Open file
124  sprintf(filename, "frame%i.ppm", current_frame);
125  file = fopen(filename, "wb");
126  if(file == NULL)
127        return;
128
129  // Write header
130  fprintf(file, "P6\n%d %d\n255\n", codec_context->width, codec_context->height);
131  // Write pixel data
132  for(y = 0; y < codec_context->height; y++)
133    fwrite(picture->data[0]+y * picture->linesize[0], 1, codec_context->width*3, file);
134  // Close file
135  fclose(file);
136
137  PRINTF(1)("created file: %s\n", filename);
138}
139
140void MediaContainer::loadMedia(const char* filename)
141{
142  /* Open video file */
143  if (av_open_input_file(&format_context, filename, NULL, 0, NULL) !=0 )
144    PRINTF(1)("Could not open %s\n", filename);
145
146  /* Retrieve stream information */
147  if (av_find_stream_info(format_context) < 0)
148    PRINTF(1)("Could not find stream information in %s\n", filename); 
149
150  // Dump information about file onto standard error
151  //dump_format(pFormatCtx, 0, argv[1], false);
152
153  /* Find the first video stream and take it */
154  video_stream = -1;
155  for(int i = 0; i < format_context->nb_streams; i++)
156  {
157    // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
158    // if(format_context->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO)             
159    if(format_context->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
160    {
161      video_stream = i;
162      break;
163    }
164  }
165 
166  if(video_stream == -1)
167    PRINTF(1)("Could not find a video stream in %s\n", filename);
168
169  /* Get a pointer to the codec context for the video stream */
170  // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
171  // codec_context = &format_context->streams[video_stream]->codec;
172  codec_context = format_context->streams[video_stream]->codec;
173
174  /* Find the decoder for the video stream */
175  codec = avcodec_find_decoder(codec_context->codec_id);
176  if (codec == NULL)
177    PRINTF(1)("Could not find codec\n");
178
179  /* Open codec */
180  if (avcodec_open(codec_context, codec) < 0)
181    PRINTF(1)("Could not open codec\n");
182
183  // Allocate video frame
184  frame = avcodec_alloc_frame();
185  RGB_frame = avcodec_alloc_frame();
186
187  // Determine required buffer size and allocate buffer
188  num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);
189  buffer=new uint8_t[num_bytes];
190
191  // Assign appropriate parts of buffer to image planes in pFrameRGB
192  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);   
193
194}
195
196int MediaContainer::getHeight()
197{
198  return codec_context->height;
199}
200
201int MediaContainer::getWidth()
202{
203  return codec_context->width;
204}
205
206int MediaContainer::getFrameRate()
207{
208
209}
210
211void MediaContainer::getStream(/* stream */)
212{
213
214}
215
216void MediaContainer::printMediaInformation()
217{
218  PRINTF(1)("========================\n");
219  PRINTF(1)("========================\n");
220  PRINTF(1)("=    MEDIACONTAINER    =\n");
221  PRINTF(1)("========================\n");
222  PRINTF(1)("========================\n");
223  PRINTF(1)("=    AVFormatContext   =\n");
224  PRINTF(1)("========================\n");
225  PRINTF(1)("filename: %s\n", format_context->filename);
226  PRINTF(1)("nb_streams: %i\n", format_context->nb_streams);
227  PRINTF(1)("duration: %fs\n", format_context->duration/1000000.);
228  PRINTF(1)("file_size: %ikb\n", format_context->file_size/1024);
229  PRINTF(1)("bit_rate: %ikb/s\n", format_context->bit_rate/1000);
230  PRINTF(1)("nb_frames: %i\n", format_context->streams[video_stream]->nb_frames);
231  PRINTF(1)("r_frame_rate: %i\n", format_context->streams[video_stream]->r_frame_rate.num);
232  PRINTF(1)("========================\n");
233  PRINTF(1)("=    AVCodecContext    =\n");
234  PRINTF(1)("========================\n");
235  PRINTF(1)("width: %i\n", codec_context->width);
236  PRINTF(1)("height: %i\n", codec_context->height);
237  PRINTF(1)("========================\n");
238  PRINTF(1)("=       AVCodec        =\n");
239  PRINTF(1)("========================\n");
240  PRINTF(1)("codec name: %s\n", codec->name);
241  PRINTF(1)("========================\n");
242  PRINTF(1)("========================\n");
243}
244
245void MediaContainer::printPacketInformation()
246{
247  PRINTF(1)("========================\n");
248  PRINTF(1)("========================\n");
249  PRINTF(1)("=       AVPacket       =\n");
250  PRINTF(1)("========================\n");
251  PRINTF(1)("pts: %i\n", packet.pts);
252  PRINTF(1)("dts: %i\n", packet.dts);
253  PRINTF(1)("size: %i\n", packet.size);
254  PRINTF(1)("stream_index: %i\n", packet.stream_index);
255  PRINTF(1)("duration: %i\n", packet.duration);
256  PRINTF(1)("pos: %i\n", packet.pos);
257  PRINTF(1)("========================\n");
258  PRINTF(1)("========================\n");
259}
Note: See TracBrowser for help on using the repository browser.