Changeset 6339 in orxonox.OLD for branches/avi_play/src/lib/graphics/importer
- Timestamp:
- Dec 30, 2005, 1:51:41 AM (19 years ago)
- Location:
- branches/avi_play/src/lib/graphics/importer
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/avi_play/src/lib/graphics/importer/media_container.cc
r6333 r6339 34 34 MediaContainer::MediaContainer(const char* filename) 35 35 { 36 this->init(); 36 // set the class id for the base object 37 this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer"); 38 39 fps = 0; 37 40 38 41 if (filename != NULL) … … 42 45 MediaContainer::MediaContainer() 43 46 { 44 this->init(); 47 // set the class id for the base object 48 this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer"); 49 50 fps = 0; 45 51 } 46 52 … … 50 56 MediaContainer::~MediaContainer() 51 57 { 52 // delete all textures. 53 while(!this->texture_list.empty()) 54 { 55 if (glIsTexture(this->texture_list.back())) 56 glDeleteTextures(1, &this->texture_list.back()); 57 this->texture_list.pop_back(); 58 } 59 glDeleteTextures(1, &texture); 58 if (glIsTexture(texture)) 59 glDeleteTextures(1, &texture); 60 60 SDL_FreeSurface(surface); 61 61 … … 64 64 av_free(RGB_frame); 65 65 66 / * Free the frame */66 // Free the frame 67 67 av_free(frame); 68 68 69 / * Close the codec */69 // Close the codec 70 70 avcodec_close(codec_context); 71 71 72 / * Close the video file */72 // Close the video file 73 73 av_close_input_file(format_context); 74 75 } 76 77 void MediaContainer::init() 78 { 79 /* set the class id for the base object */ 80 this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer"); 81 82 /* register all formats and codecs */ 74 } 75 76 void MediaContainer::loadMedia(const char* filename) 77 { 78 // register all formats and codecs 83 79 av_register_all(); 84 80 85 fps = 0; 86 frame_num = 0; 87 } 88 89 void MediaContainer::gotoFrame(int frame_number) 90 { 91 // seek doesnt work for the first two frames 92 // you will get ugly fragments 93 if(frame_number < 2) 81 // Open video file 82 if (av_open_input_file(&format_context, filename, NULL, 0, NULL) !=0 ) 83 PRINTF(1)("Could not open %s\n", filename); 84 85 // Retrieve stream information 86 if (av_find_stream_info(format_context) < 0) 87 PRINTF(1)("Could not find stream information in %s\n", filename); 88 89 // Find the first video stream and take it 90 video_stream = -1; 91 for(int i = 0; i < format_context->nb_streams; i++) 94 92 { 95 // go to the begin of the video 96 av_seek_frame(format_context, video_stream, 0, AVSEEK_FLAG_BACKWARD); 97 frame_num = 0; 93 // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis) 94 // if(format_context->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO) 95 if(format_context->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) 96 { 97 video_stream = i; 98 break; 99 } 98 100 } 99 else 100 { 101 // seeks to the nearest keyframe 102 // NOTE: there is only about every 5s a keyframe! 103 av_seek_frame(format_context, video_stream, frame_number, AVSEEK_FLAG_BACKWARD); 104 105 // go from the keyframe to the exact position 106 codec_context->hurry_up = 1; 107 do { 108 av_read_frame(format_context, &packet); 109 if(packet.pts >= frame_number-1) 110 break; 111 int frame_finished; 112 avcodec_decode_video(codec_context, frame, &frame_finished, packet.data, packet.size); 113 av_free_packet(&packet); 114 } while(1); 115 codec_context->hurry_up = 0; 116 117 frame_num = frame_number; 118 } 119 } 101 102 if(video_stream == -1) 103 PRINTF(1)("Could not find a video stream in %s\n", filename); 104 105 // Get a pointer to the codec context for the video stream 106 // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis) 107 // codec_context = &format_context->streams[video_stream]->codec; 108 codec_context = format_context->streams[video_stream]->codec; 109 110 // Find the decoder for the video stream 111 codec = avcodec_find_decoder(codec_context->codec_id); 112 if (codec == NULL) 113 PRINTF(1)("Could not find codec\n"); 114 115 // Open codec 116 if (avcodec_open(codec_context, codec) < 0) 117 PRINTF(1)("Could not open codec\n"); 118 119 // Allocate video frame 120 frame = avcodec_alloc_frame(); 121 RGB_frame = avcodec_alloc_frame(); 122 123 // Determine required buffer size and allocate buffer 124 num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height); 125 buffer=new uint8_t[num_bytes]; 126 127 // Assign appropriate parts of buffer to image planes in pFrameRGB 128 avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height); 129 130 // Calculate fps 131 fps = av_q2d(format_context->streams[video_stream]->r_frame_rate); 132 133 // read the frames and save them in a sequence as textures 134 this->loadFrames(); 135 } 136 137 double MediaContainer::getFPS() 138 { 139 return this->fps; 140 } 141 142 void MediaContainer::loadFrames() 143 { 144 // go to the begin of the video 145 av_seek_frame(format_context, video_stream, 0, AVSEEK_FLAG_BACKWARD); 146 147 // get all the frames and save them in the sequence 148 while(this->addFrame(this->getNextFrame()) != NULL); 149 } 150 120 151 121 152 GLuint MediaContainer::getNextFrame() 122 153 { 123 / * get next frame */154 // get next frame 124 155 if(av_read_frame(format_context, &packet) >= 0) 125 156 { 126 //this->printPacketInformation(); 127 128 /* Is this a packet from the video stream? */ 157 // Is this a packet from the video stream? 129 158 if(packet.stream_index == video_stream) 130 159 { … … 140 169 if(frame_finished) 141 170 { 142 frame_num++;143 //PRINTF(1)("frame_number: %i\n", this->getFrameNumber());144 171 // Conversion from YUV to RGB 145 172 // Most codecs return images in YUV 420 format … … 149 176 codec_context->pix_fmt, codec_context->width, codec_context->height); 150 177 151 picture = (AVPicture*)RGB_frame;152 153 154 178 data = 0; 155 179 data = new uint8_t[codec_context->width*codec_context->height*3*sizeof(uint8_t)]; 156 180 for(int i = 0; i < codec_context->height; i++) 157 memcpy(&data[i*codec_context->width*3], picture->data[0]+i * 158 picture->linesize[0],codec_context->width*sizeof(uint8_t)*3); 181 memcpy(&data[i*codec_context->width*3], 182 ((AVPicture*)RGB_frame)->data[0]+i * 183 ((AVPicture*)RGB_frame)->linesize[0], 184 codec_context->width*sizeof(uint8_t)*3); 159 185 160 186 surface = SDL_CreateRGBSurfaceFrom(data, codec_context->width, 161 187 codec_context->height,24, 162 188 codec_context->width*sizeof(uint8_t)*3, 163 #if SDL_BYTEORDER == SDL_LIL_ENDIAN / * OpenGL RGBA masks */189 #if SDL_BYTEORDER == SDL_LIL_ENDIAN // OpenGL RGBA masks 164 190 0x000000FF, 165 191 0x0000FF00, … … 174 200 ); 175 201 176 if(frame_num == 1) 177 { 178 /* Create an OpenGL texture from the surface */ 179 glGenTextures(1, &texture); 180 glBindTexture(GL_TEXTURE_2D, texture); 181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 183 // create the texture 184 glTexImage2D(GL_TEXTURE_2D, 185 0, 186 GL_RGB, 187 surface->w, surface->h, 188 0, 189 GL_RGB, 190 GL_UNSIGNED_BYTE, 191 surface->pixels); 192 // build the MipMaps 193 gluBuild2DMipmaps(GL_TEXTURE_2D, 194 GL_RGB, 195 surface->w, 196 surface->h, 197 GL_RGB, 198 GL_UNSIGNED_BYTE, 199 surface->pixels); 200 glBindTexture(GL_TEXTURE_2D, 0); 201 } 202 else 203 { 204 /* Create an OpenGL texture from the surface */ 205 glGenTextures(1, &texture); 206 glBindTexture(GL_TEXTURE_2D, texture); 207 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 208 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 209 // update the texture 210 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surface->w, surface->h, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels); 211 212 // build the MipMaps 213 gluBuild2DMipmaps(GL_TEXTURE_2D, 214 GL_RGB, 215 surface->w, 216 surface->h, 217 GL_RGB, 218 GL_UNSIGNED_BYTE, 219 surface->pixels); 220 glBindTexture(GL_TEXTURE_2D, 0); 221 } 222 202 // Create an OpenGL texture from the surface 203 glGenTextures(1, &texture); 204 glBindTexture(GL_TEXTURE_2D, texture); 205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 206 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 207 // create the texture 208 glTexImage2D(GL_TEXTURE_2D, 209 0, 210 GL_RGB, 211 surface->w, surface->h, 212 0, 213 GL_RGB, 214 GL_UNSIGNED_BYTE, 215 surface->pixels); 216 // build the MipMaps 217 gluBuild2DMipmaps(GL_TEXTURE_2D, 218 GL_RGB, 219 surface->w, 220 surface->h, 221 GL_RGB, 222 GL_UNSIGNED_BYTE, 223 surface->pixels); 224 glBindTexture(GL_TEXTURE_2D, 0); 225 223 226 return texture; 227 } 228 else 229 { 230 av_free_packet(&packet); 231 this->getNextFrame(); 224 232 } 225 233 } … … 233 241 return NULL; 234 242 } 235 236 GLuint MediaContainer::skipFrame(int num_frames)237 {238 frame_num += num_frames;239 240 while(num_frames != 0)241 {242 if(av_read_frame(format_context, &packet) < 0)243 break;244 if(packet.stream_index == video_stream)245 {246 int frame_finished;247 // We have to decode the frame to not get ugly fragments248 avcodec_decode_video(codec_context, frame, &frame_finished,249 packet.data, packet.size);250 251 // Did we get a video frame?252 if(frame_finished)253 num_frames--;254 }255 av_free_packet(&packet);256 }257 258 return this->getNextFrame();259 }260 261 vector<GLuint> MediaContainer::getFrameList()262 {263 264 while((texture = this->getNextFrame()) != NULL)265 texture_list.push_back(texture);266 267 return texture_list;268 }269 270 void MediaContainer::saveCurrentFrame()271 {272 FILE *file;273 char filename[32];274 int y;275 276 // Open file277 sprintf(filename, "frame%i.ppm", frame_num);278 file = fopen(filename, "wb");279 if(file == NULL)280 return;281 282 // Write header283 fprintf(file, "P6\n%d %d\n255\n", codec_context->width, codec_context->height);284 // Write pixel data285 for(y = 0; y < codec_context->height; y++)286 fwrite(picture->data[0]+y * picture->linesize[0], 1, codec_context->width*3, file);287 // Close file288 fclose(file);289 290 PRINTF(1)("created file: %s\n", filename);291 }292 293 void MediaContainer::loadMedia(const char* filename)294 {295 /* Open video file */296 if (av_open_input_file(&format_context, filename, NULL, 0, NULL) !=0 )297 PRINTF(1)("Could not open %s\n", filename);298 299 /* Retrieve stream information */300 if (av_find_stream_info(format_context) < 0)301 PRINTF(1)("Could not find stream information in %s\n", filename);302 303 // Dump information about file onto standard error304 //dump_format(pFormatCtx, 0, argv[1], false);305 306 /* Find the first video stream and take it */307 video_stream = -1;308 for(int i = 0; i < format_context->nb_streams; i++)309 {310 // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)311 // if(format_context->streams[i]->codec.codec_type == CODEC_TYPE_VIDEO)312 if(format_context->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)313 {314 video_stream = i;315 break;316 }317 }318 319 if(video_stream == -1)320 PRINTF(1)("Could not find a video stream in %s\n", filename);321 322 /* Get a pointer to the codec context for the video stream */323 // NOTE: different code for the 0.4.9-pre1 release of ffmpeg (tardis)324 // codec_context = &format_context->streams[video_stream]->codec;325 codec_context = format_context->streams[video_stream]->codec;326 327 /* Find the decoder for the video stream */328 codec = avcodec_find_decoder(codec_context->codec_id);329 if (codec == NULL)330 PRINTF(1)("Could not find codec\n");331 332 /* Open codec */333 if (avcodec_open(codec_context, codec) < 0)334 PRINTF(1)("Could not open codec\n");335 336 // Allocate video frame337 frame = avcodec_alloc_frame();338 RGB_frame = avcodec_alloc_frame();339 340 // Determine required buffer size and allocate buffer341 num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);342 buffer=new uint8_t[num_bytes];343 344 // Assign appropriate parts of buffer to image planes in pFrameRGB345 avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);346 347 // Calculate fps348 fps = av_q2d(format_context->streams[video_stream]->r_frame_rate);349 350 // duration351 duration = format_context->duration / 1000000LL;352 353 frame_num = 0;354 }355 356 int MediaContainer::getHeight()357 {358 return codec_context->height;359 }360 361 int MediaContainer::getWidth()362 {363 return codec_context->width;364 }365 366 int MediaContainer::getFrameNumber()367 {368 return frame_num;369 }370 371 double MediaContainer::getFPS()372 {373 return this->fps;374 }375 376 void MediaContainer::printMediaInformation()377 {378 PRINTF(1)("========================\n");379 PRINTF(1)("========================\n");380 PRINTF(1)("= MEDIACONTAINER =\n");381 PRINTF(1)("========================\n");382 PRINTF(1)("========================\n");383 PRINTF(1)("= AVFormatContext =\n");384 PRINTF(1)("========================\n");385 PRINTF(1)("filename: %s\n", format_context->filename);386 PRINTF(1)("nb_streams: %i\n", format_context->nb_streams);387 PRINTF(1)("duration: (%02d:%02d:%02d)\n", duration/3600, (duration%3600)/60, duration%60);388 PRINTF(1)("file_size: %ikb\n", format_context->file_size/1024);389 PRINTF(1)("bit_rate: %ikb/s\n", format_context->bit_rate/1000);390 PRINTF(1)("nb_frames: %i\n", format_context->streams[video_stream]->nb_frames);391 PRINTF(1)("r_frame_rate: %i\n", format_context->streams[video_stream]->r_frame_rate.num);392 PRINTF(1)("fps: %0.2f\n", av_q2d(format_context->streams[video_stream]->r_frame_rate));393 PRINTF(1)("========================\n");394 PRINTF(1)("= AVCodecContext =\n");395 PRINTF(1)("========================\n");396 PRINTF(1)("width: %i\n", codec_context->width);397 PRINTF(1)("height: %i\n", codec_context->height);398 PRINTF(1)("time_base.den: %i\n", codec_context->time_base.den);399 PRINTF(1)("time_base.num: %i\n", codec_context->time_base.num);400 PRINTF(1)("========================\n");401 PRINTF(1)("= AVCodec =\n");402 PRINTF(1)("========================\n");403 PRINTF(1)("codec name: %s\n", codec->name);404 PRINTF(1)("========================\n");405 PRINTF(1)("========================\n");406 }407 408 void MediaContainer::printPacketInformation()409 {410 PRINTF(1)("========================\n");411 PRINTF(1)("========================\n");412 PRINTF(1)("= AVPacket =\n");413 PRINTF(1)("========================\n");414 PRINTF(1)("pts: %i\n", packet.pts);415 PRINTF(1)("dts: %i\n", packet.dts);416 PRINTF(1)("size: %i\n", packet.size);417 PRINTF(1)("stream_index: %i\n", packet.stream_index);418 PRINTF(1)("duration: %i\n", packet.duration);419 PRINTF(1)("pos: %i\n", packet.pos);420 PRINTF(1)("========================\n");421 PRINTF(1)("========================\n");422 } -
branches/avi_play/src/lib/graphics/importer/media_container.h
r6330 r6339 9 9 10 10 #include <SDL.h> 11 #include <vector>12 11 13 12 #ifdef HAVE_AVFORMAT_H … … 19 18 /* include base_object.h since all classes are derived from this one */ 20 19 #include "base_object.h" 20 #include "texture_sequence.h" 21 21 22 22 #include "glincl.h" 23 23 24 /* using namespace std is default, this needs to be here */ 25 using namespace std; 26 27 class MediaContainer : public BaseObject 24 class MediaContainer : public TextureSequence 28 25 { 29 26 30 27 private: 31 32 double fps;33 SDL_Surface* surface;34 GLuint texture;35 uint8_t* data;36 28 37 29 AVFormatContext* format_context; … … 41 33 AVPacket packet; 42 34 AVFrame* RGB_frame; 43 AVPicture* picture;44 35 36 SDL_Surface* surface; 37 GLuint texture; 38 uint8_t* data; 39 uint8_t* buffer; 45 40 int num_bytes; 46 uint8_t* buffer;47 41 int video_stream; 48 int duration; 49 int frame_num; 50 51 vector<GLuint> texture_list; 42 double fps; 52 43 53 44 public: … … 57 48 ~MediaContainer(); 58 49 59 void init();60 void gotoFrame(int frame_number);61 GLuint getNextFrame();62 GLuint skipFrame(int num_frames);63 vector<GLuint> getFrameList();64 50 void loadMedia(const char* filename); 51 void loadFrames(); 65 52 66 int getHeight();67 int getWidth();68 int getFrameNumber();69 53 double getFPS(); 70 54 71 void saveCurrentFrame(); 72 73 void printMediaInformation(); 74 void printPacketInformation(); 55 private: 56 57 GLuint getNextFrame(); 75 58 76 59 }; -
branches/avi_play/src/lib/graphics/importer/movie_player.cc
r6330 r6339 18 18 /* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_MEDIA module 19 19 For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput 20 */ 20 *//* 21 21 #define DEBUG_MODULE_MEDIA 22 22 23 23 24 / * include your own header */24 // include your own header 25 25 #include "movie_player.h" 26 26 27 / * header for debug output */27 // header for debug output 28 28 #include "debug.h" 29 29 30 30 31 / **32 *Default constructor33 */31 // 32 // Default constructor 33 // 34 34 MoviePlayer::MoviePlayer(const char* filename) 35 35 { … … 46 46 } 47 47 48 /**49 * Default destructor50 */51 48 MoviePlayer::~MoviePlayer() 52 49 { … … 165 162 return this->status; 166 163 } 164 */ -
branches/avi_play/src/lib/graphics/importer/movie_player.h
r6330 r6339 4 4 5 5 */ 6 6 /* 7 7 #ifndef _MOVIE_PLAYER 8 8 #define _MOVIE_PLAYER … … 17 17 #include "primitive_model.h" 18 18 19 / * include base_object.h since all classes are derived from this one */19 // include base_object.h since all classes are derived from this one 20 20 #include "base_object.h" 21 21 22 / * The state of the MoviePlayer */22 // The state of the MoviePlayer 23 23 typedef enum MP_STATUS { 24 24 PLAY, … … 71 71 72 72 73 #endif /* _MOVIE_PLAYER */ 73 #endif // _MOVIE_PLAYER 74 */ -
branches/avi_play/src/lib/graphics/importer/texture_sequence.cc
r6317 r6339 153 153 } 154 154 155 bool TextureSequence::addFrameList(std::vector<GLuint> textures)156 {157 // add the textures to the list158 for(int i = 0; i < textures.size(); i++)159 this->addFrame(textures[i]);160 }161 162 155 /** 163 156 * @brief adds a new Frame at the end of the Sequence. … … 177 170 * @param frameNumber the n-th frame 178 171 */ 179 void TextureSequence::gotoFrame(unsigned int frameNumber)172 /*void TextureSequence::gotoFrame(unsigned int frameNumber) 180 173 { 181 174 if (this->textures.size() > frameNumber) 182 175 this->setTexture(this->textures[frameNumber]); 183 176 } 177 */ -
branches/avi_play/src/lib/graphics/importer/texture_sequence.h
r6317 r6339 30 30 bool addFrame(SDL_Surface* surface); 31 31 bool addFrame(GLuint texture); 32 bool addFrameList(std::vector<GLuint> textures);33 32 34 33 virtual bool rebuild(); … … 37 36 inline unsigned int getFrameCount() const { return this->textures.size(); }; 38 37 39 void gotoFrame(unsigned int frameNumber);38 //void gotoFrame(unsigned int frameNumber); 40 39 /** @returns The textureID of the Frame @param frameNumber the n-th frame this texture-series. */ 41 40 inline GLuint getFrameTexture(unsigned int frameNumber) const { return (this->textures.size()>frameNumber)?this->textures[frameNumber]:0; };
Note: See TracChangeset
for help on using the changeset viewer.