Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6112 was 6112, checked in by stefalie, 18 years ago

branches\avi_play: OpenGL still has problems to display our texture, way too slow

File size: 8.3 KB
RevLine 
[5937]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 */
[5939]34MediaContainer::MediaContainer(const char* filename)
[5937]35{
[5975]36  /* set the class id for the base object */
37  this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer");
38
[5962]39  /* register all formats and codecs */
40  av_register_all();
[5937]41
[6013]42  current_frame = 0;
[6003]43
[5975]44  if (filename != NULL)
[5962]45    this->loadMedia(filename);
46
[5937]47}
48
49/**
50 * Default destructor
51 */
52MediaContainer::~MediaContainer()
53{
[6068]54  // Free the RGB image
55  delete [] buffer;
56  av_free(RGB_frame);
[5937]57
[6013]58  /* Free the frame */
[6003]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
[5937]67}
68
[6068]69GLuint MediaContainer::getFrame(int frame_number)
[5937]70{
71
72}
73
74GLuint MediaContainer::getNextFrame()
75{
[6068]76  /* get next frame */
77  if(av_read_frame(format_context, &packet) >= 0)
78  {
79    //this->printPacketInformation();
[5937]80
[6068]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);
[6003]87
[6068]88      // Did we get a video frame?
89      if(frame_finished)
90      {
91        current_frame++;
92        PRINTF(1)("current_frame: %i\n", current_frame);
[6003]93
[6112]94                    // Convert the image from its native format to RGB
[6068]95        img_convert((AVPicture*)RGB_frame, PIX_FMT_RGB24, (AVPicture*)frame, codec_context->pix_fmt,
[6112]96                                        codec_context->width, codec_context->height);
[6094]97
98        picture = (AVPicture*)RGB_frame;
[6112]99
100
101        data = 0;
102        data = new uint8_t[codec_context->width*codec_context->height*3*sizeof(uint8_t)];
103        for(int i = 0; i < codec_context->height; i++)
104          memcpy(&data[i*codec_context->width*3],
105                 picture->data[0]+i * picture->linesize[0],codec_context->width*sizeof(uint8_t)*3);
106
107
[6094]108        glGenTextures(1, &texture);
109        glBindTexture(GL_TEXTURE_2D, texture);
[6112]110        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
111        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[6094]112        // if it is the first frame create texture
[6112]113        //if(current_frame == 1)
114        //{
115          // build the texture
116        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, codec_context->width, codec_context->height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
117        //}
[6094]118        // if its not the first use glTexSubImage2D <-- faster then creating always a new texture
[6112]119        //else
120        //  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, codec_context->width, codec_context->height, GL_RGB, GL_UNSIGNED_BYTE, data);
[5937]121
[6057]122
[6094]123        glBindTexture(GL_TEXTURE_2D, 0);
124        //////////////////////////////////////////////
125        /////////////////////////////////////////////
[6057]126
[6094]127        // save frame
128        //this->saveCurrentFrame();
[6057]129
[6068]130        return texture;
131      }
132    }
133    // Free the packet that was allocated by av_read_frame
134    av_free_packet(&packet);
135  }
136  else
137    return NULL;
138}
[6057]139
[6068]140void MediaContainer::saveCurrentFrame()
141{
142  FILE *file;
143  char filename[32];
144  int  y;
[6057]145
[6068]146  // Open file
147  sprintf(filename, "frame%i.ppm", current_frame);
148  file = fopen(filename, "wb");
149  if(file == NULL)
[6112]150        return;
[6057]151
[6068]152  // Write header
153  fprintf(file, "P6\n%d %d\n255\n", codec_context->width, codec_context->height);
154  // Write pixel data
155  for(y = 0; y < codec_context->height; y++)
156    fwrite(picture->data[0]+y * picture->linesize[0], 1, codec_context->width*3, file);
157  // Close file
158  fclose(file);
159
160  PRINTF(1)("created file: %s\n", filename);
[6003]161}
162
[5975]163void MediaContainer::loadMedia(const char* filename)
[5937]164{
[5975]165  /* Open video file */
166  if (av_open_input_file(&format_context, filename, NULL, 0, NULL) !=0 )
167    PRINTF(1)("Could not open %s\n", filename);
[5937]168
[6013]169  /* Retrieve stream information */
[6003]170  if (av_find_stream_info(format_context) < 0)
[6112]171    PRINTF(1)("Could not find stream information in %s\n", filename);
[6003]172
173  // Dump information about file onto standard error
174  //dump_format(pFormatCtx, 0, argv[1], false);
175
176  /* Find the first video stream and take it */
177  video_stream = -1;
178  for(int i = 0; i < format_context->nb_streams; i++)
[6013]179  {
180    // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
[6112]181    // if(format_context->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO)
[6013]182    if(format_context->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
[6003]183    {
[6013]184      video_stream = i;
[6003]185      break;
186    }
[6013]187  }
[6112]188
[6013]189  if(video_stream == -1)
190    PRINTF(1)("Could not find a video stream in %s\n", filename);
[6003]191
[6013]192  /* Get a pointer to the codec context for the video stream */
193  // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)
194  // codec_context = &format_context->streams[video_stream]->codec;
[6003]195  codec_context = format_context->streams[video_stream]->codec;
196
[6013]197  /* Find the decoder for the video stream */
[6003]198  codec = avcodec_find_decoder(codec_context->codec_id);
199  if (codec == NULL)
[6013]200    PRINTF(1)("Could not find codec\n");
[6003]201
[6013]202  /* Open codec */
[6003]203  if (avcodec_open(codec_context, codec) < 0)
[6068]204    PRINTF(1)("Could not open codec\n");
[6003]205
[6068]206  // Allocate video frame
207  frame = avcodec_alloc_frame();
[6112]208        RGB_frame = avcodec_alloc_frame();
[6068]209
210  // Determine required buffer size and allocate buffer
211  num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);
212  buffer=new uint8_t[num_bytes];
213
214  // Assign appropriate parts of buffer to image planes in pFrameRGB
[6112]215  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
[6068]216
[5937]217}
218
219int MediaContainer::getHeight()
220{
[6068]221  return codec_context->height;
[5937]222}
223
224int MediaContainer::getWidth()
225{
[6068]226  return codec_context->width;
[5937]227}
228
[6094]229int MediaContainer::getCurrentFrame()
230{
231  return this->current_frame;
232}
233
[5937]234int MediaContainer::getFrameRate()
235{
236
237}
238
239void MediaContainer::getStream(/* stream */)
240{
241
242}
[6057]243
[6068]244void MediaContainer::printMediaInformation()
[6057]245{
[6068]246  PRINTF(1)("========================\n");
247  PRINTF(1)("========================\n");
248  PRINTF(1)("=    MEDIACONTAINER    =\n");
249  PRINTF(1)("========================\n");
250  PRINTF(1)("========================\n");
251  PRINTF(1)("=    AVFormatContext   =\n");
252  PRINTF(1)("========================\n");
253  PRINTF(1)("filename: %s\n", format_context->filename);
254  PRINTF(1)("nb_streams: %i\n", format_context->nb_streams);
255  PRINTF(1)("duration: %fs\n", format_context->duration/1000000.);
256  PRINTF(1)("file_size: %ikb\n", format_context->file_size/1024);
257  PRINTF(1)("bit_rate: %ikb/s\n", format_context->bit_rate/1000);
258  PRINTF(1)("nb_frames: %i\n", format_context->streams[video_stream]->nb_frames);
259  PRINTF(1)("r_frame_rate: %i\n", format_context->streams[video_stream]->r_frame_rate.num);
260  PRINTF(1)("========================\n");
261  PRINTF(1)("=    AVCodecContext    =\n");
262  PRINTF(1)("========================\n");
263  PRINTF(1)("width: %i\n", codec_context->width);
264  PRINTF(1)("height: %i\n", codec_context->height);
265  PRINTF(1)("========================\n");
266  PRINTF(1)("=       AVCodec        =\n");
267  PRINTF(1)("========================\n");
268  PRINTF(1)("codec name: %s\n", codec->name);
269  PRINTF(1)("========================\n");
270  PRINTF(1)("========================\n");
[6057]271}
272
[6068]273void MediaContainer::printPacketInformation()
[6057]274{
[6068]275  PRINTF(1)("========================\n");
276  PRINTF(1)("========================\n");
277  PRINTF(1)("=       AVPacket       =\n");
278  PRINTF(1)("========================\n");
279  PRINTF(1)("pts: %i\n", packet.pts);
280  PRINTF(1)("dts: %i\n", packet.dts);
281  PRINTF(1)("size: %i\n", packet.size);
282  PRINTF(1)("stream_index: %i\n", packet.stream_index);
283  PRINTF(1)("duration: %i\n", packet.duration);
284  PRINTF(1)("pos: %i\n", packet.pos);
285  PRINTF(1)("========================\n");
286  PRINTF(1)("========================\n");
[6057]287}
Note: See TracBrowser for help on using the repository browser.