Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

branches/avi_play: MediaContainer::getFPS() works

File size: 8.6 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  fps = 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        PRINTF(1)("frame_number: %i\n", codec_context->frame_number);
92
93        // Convert the image from its native format to RGB
94        img_convert((AVPicture*)RGB_frame, PIX_FMT_RGB24, (AVPicture*)frame, codec_context->pix_fmt,
95                                        codec_context->width, codec_context->height);
96
97        picture = (AVPicture*)RGB_frame;
98
99
100        data = 0;
101        data = new uint8_t[codec_context->width*codec_context->height*3*sizeof(uint8_t)];
102        for(int i = 0; i < codec_context->height; i++)
103          memcpy(&data[i*codec_context->width*3],
104                 picture->data[0]+i * picture->linesize[0],codec_context->width*sizeof(uint8_t)*3);
105
106
107        glGenTextures(1, &texture);
108        glBindTexture(GL_TEXTURE_2D, texture);
109        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
110        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
111        // if it is the first frame create texture
112        //if(current_frame == 1)
113        //{
114          // build the texture
115        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, codec_context->width, codec_context->height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
116        //}
117        // if its not the first use glTexSubImage2D <-- faster then creating always a new texture
118        //else
119        //  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, codec_context->width, codec_context->height, GL_RGB, GL_UNSIGNED_BYTE, data);
120
121
122        glBindTexture(GL_TEXTURE_2D, 0);
123        //////////////////////////////////////////////
124        /////////////////////////////////////////////
125
126        // save frame
127        //this->saveCurrentFrame();
128
129        return texture;
130      }
131    }
132    // Free the packet that was allocated by av_read_frame
133    av_free_packet(&packet);
134  }
135  else
136    return NULL;
137}
138
139void MediaContainer::saveCurrentFrame()
140{
141  FILE *file;
142  char filename[32];
143  int  y;
144
145  // Open file
146  sprintf(filename, "frame%i.ppm", codec_context->frame_number);
147  file = fopen(filename, "wb");
148  if(file == NULL)
149        return;
150
151  // Write header
152  fprintf(file, "P6\n%d %d\n255\n", codec_context->width, codec_context->height);
153  // Write pixel data
154  for(y = 0; y < codec_context->height; y++)
155    fwrite(picture->data[0]+y * picture->linesize[0], 1, codec_context->width*3, file);
156  // Close file
157  fclose(file);
158
159  PRINTF(1)("created file: %s\n", filename);
160}
161
162void MediaContainer::loadMedia(const char* filename)
163{
164  /* Open video file */
165  if (av_open_input_file(&format_context, filename, NULL, 0, NULL) !=0 )
166    PRINTF(1)("Could not open %s\n", filename);
167
168  /* Retrieve stream information */
169  if (av_find_stream_info(format_context) < 0)
170    PRINTF(1)("Could not find stream information in %s\n", filename);
171
172  // Dump information about file onto standard error
173  //dump_format(pFormatCtx, 0, argv[1], false);
174
175  /* Find the first video stream and take it */
176  video_stream = -1;
177  for(int i = 0; i < format_context->nb_streams; i++)
178  {
179    // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
180    // if(format_context->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO)
181    if(format_context->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
182    {
183      video_stream = i;
184      break;
185    }
186  }
187
188  if(video_stream == -1)
189    PRINTF(1)("Could not find a video stream in %s\n", filename);
190
191  /* Get a pointer to the codec context for the video stream */
192  // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
193  // codec_context = &format_context->streams[video_stream]->codec;
194  codec_context = format_context->streams[video_stream]->codec;
195
196  /* Find the decoder for the video stream */
197  codec = avcodec_find_decoder(codec_context->codec_id);
198  if (codec == NULL)
199    PRINTF(1)("Could not find codec\n");
200
201  /* Open codec */
202  if (avcodec_open(codec_context, codec) < 0)
203    PRINTF(1)("Could not open codec\n");
204
205  // Allocate video frame
206  frame = avcodec_alloc_frame();
207        RGB_frame = avcodec_alloc_frame();
208
209  // Determine required buffer size and allocate buffer
210  num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);
211  buffer=new uint8_t[num_bytes];
212
213  // Assign appropriate parts of buffer to image planes in pFrameRGB
214  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
215
216  // Calculate fps
217  fps = av_q2d(format_context->streams[video_stream]->r_frame_rate);
218}
219
220int MediaContainer::getHeight()
221{
222  return codec_context->height;
223}
224
225int MediaContainer::getWidth()
226{
227  return codec_context->width;
228}
229
230int MediaContainer::getFrameNumber()
231{
232  return codec_context->frame_number;
233}
234
235double MediaContainer::getFPS()
236{
237  return this->fps;
238}
239
240void MediaContainer::printMediaInformation()
241{
242  PRINTF(1)("========================\n");
243  PRINTF(1)("========================\n");
244  PRINTF(1)("=    MEDIACONTAINER    =\n");
245  PRINTF(1)("========================\n");
246  PRINTF(1)("========================\n");
247  PRINTF(1)("=    AVFormatContext   =\n");
248  PRINTF(1)("========================\n");
249  PRINTF(1)("filename: %s\n", format_context->filename);
250  PRINTF(1)("nb_streams: %i\n", format_context->nb_streams);
251  PRINTF(1)("duration: %fs\n", format_context->duration/1000000.);
252  PRINTF(1)("file_size: %ikb\n", format_context->file_size/1024);
253  PRINTF(1)("bit_rate: %ikb/s\n", format_context->bit_rate/1000);
254  PRINTF(1)("nb_frames: %i\n", format_context->streams[video_stream]->nb_frames);
255  PRINTF(1)("r_frame_rate: %i\n", format_context->streams[video_stream]->r_frame_rate.num);
256  PRINTF(1)("FPS: %f\n", av_q2d(format_context->streams[video_stream]->r_frame_rate));
257  PRINTF(1)("========================\n");
258  PRINTF(1)("=    AVCodecContext    =\n");
259  PRINTF(1)("========================\n");
260  PRINTF(1)("width: %i\n", codec_context->width);
261  PRINTF(1)("height: %i\n", codec_context->height);
262  PRINTF(1)("time_base.den: %i\n", codec_context->time_base.den);
263  PRINTF(1)("time_base.num: %i\n", codec_context->time_base.num);
264  PRINTF(1)("========================\n");
265  PRINTF(1)("=       AVCodec        =\n");
266  PRINTF(1)("========================\n");
267  PRINTF(1)("codec name: %s\n", codec->name);
268  PRINTF(1)("========================\n");
269  PRINTF(1)("========================\n");
270}
271
272void MediaContainer::printPacketInformation()
273{
274  PRINTF(1)("========================\n");
275  PRINTF(1)("========================\n");
276  PRINTF(1)("=       AVPacket       =\n");
277  PRINTF(1)("========================\n");
278  PRINTF(1)("pts: %i\n", packet.pts);
279  PRINTF(1)("dts: %i\n", packet.dts);
280  PRINTF(1)("size: %i\n", packet.size);
281  PRINTF(1)("stream_index: %i\n", packet.stream_index);
282  PRINTF(1)("duration: %i\n", packet.duration);
283  PRINTF(1)("pos: %i\n", packet.pos);
284  PRINTF(1)("========================\n");
285  PRINTF(1)("========================\n");
286}
287
288
289//pts = av_q2d(is->video_st->time_base)*pkt->dts;
290//pkt = packet
291//avstrream = viedo_st
292//pts = double
Note: See TracBrowser for help on using the repository browser.