comparison sv/videoio/SDL_ffmpeg.cpp @ 129:587ad94d6ac2

(none)
author ivand_qmul
date Thu, 08 Nov 2007 13:29:48 +0000
parents 66af7c1b10d9
children b3df8b8185db
comparison
equal deleted inserted replaced
128:247ea6460ec2 129:587ad94d6ac2
27 #endif 27 #endif
28 #ifdef WIN32 28 #ifdef WIN32
29 #include "SDL_ffmpeg.h" 29 #include "SDL_ffmpeg.h"
30 #include <SDL.h> 30 #include <SDL.h>
31 #include <SDL_thread.h> 31 #include <SDL_thread.h>
32 #include <stdio.h>
33 #include <Windows.h>
32 #endif 34 #endif
33 35
34 #ifdef __unix__ 36 #ifdef __unix__
35 #include <SDL/SDL.h> 37 #include <SDL/SDL.h>
36 #include <SDL/SDL_thread.h> 38 #include <SDL/SDL_thread.h>
37 #endif 39 #endif
38 #ifdef __cplusplus 40 #ifdef __cplusplus
39 } 41 }
40 #endif 42 #endif
41 #include "../../sv/main/MainWindow.h" 43 #include "../../sv/main/MainWindow.h"
44 #include <time.h>
42 45
43 //const int SDL_FFMPEG_MAX_BUFFERED_FRAMES = 25; 46 //const int SDL_FFMPEG_MAX_BUFFERED_FRAMES = 25;
44 //const int SDL_FFMPEG_MAX_BUFFERED_SAMPLES = 512 * 512; 47 //const int SDL_FFMPEG_MAX_BUFFERED_SAMPLES = 512 * 512;
45 48 extern float hopfactor;
46 int FFMPEG_init_was_called = 0; 49 int FFMPEG_init_was_called = 0;
47 50 FILE *pFile, *tFile;
51 int64_t Time,Time1;
52 int64_t realt=0;
53
48 SDL_ffmpegFile* SDL_ffmpegCreateFile() { 54 SDL_ffmpegFile* SDL_ffmpegCreateFile() {
49 55
50 // create SDL_ffmpegFile pointer 56 // create SDL_ffmpegFile pointer
51 SDL_ffmpegFile *file = (SDL_ffmpegFile*)malloc( sizeof(SDL_ffmpegFile) ); 57 SDL_ffmpegFile *file = (SDL_ffmpegFile*)malloc( sizeof(SDL_ffmpegFile) );
52 if(!file) return 0; 58 if(!file) return 0;
53 file->_ffmpeg=av_alloc_format_context();//(AVFormatContext*)malloc(sizeof(AVFormatContext)); 59 file->_ffmpeg=av_alloc_format_context();//(AVFormatContext*)malloc(sizeof(AVFormatContext));
54 // create a semaphore for every file 60 // create a semaphore for every file
55 file->decode = SDL_CreateSemaphore(1); 61 file->decode = SDL_CreateSemaphore(1);
56 62
63 Time=0;
64 Time1=0;
65 fopen_s (&pFile,"myfile.txt","w");
66 fopen_s (&tFile,"Timestampfile.txt","w");
57 // allocate room for VStreams 67 // allocate room for VStreams
58 file->vs = (SDL_ffmpegStream**)malloc( sizeof(SDL_ffmpegStream*) * MAX_STREAMS ); 68 file->vs = (SDL_ffmpegStream**)malloc( sizeof(SDL_ffmpegStream*) * MAX_STREAMS );
59 if(!file->vs) { 69 if(!file->vs) {
60 free( file ); 70 free( file );
61 return 0; 71 return 0;
174 memcpy(stream->codecName, ((AVFormatContext*)file->_ffmpeg)->streams[i]->codec->codec_name, 32); 184 memcpy(stream->codecName, ((AVFormatContext*)file->_ffmpeg)->streams[i]->codec->codec_name, 32);
175 185
176 stream->audio = 0; 186 stream->audio = 0;
177 stream->size = 0; 187 stream->size = 0;
178 stream->imageBuffer = (bufferImage**)calloc( SDL_FFMPEG_MAX_BUFFERED_FRAMES, sizeof(bufferImage*) ); 188 stream->imageBuffer = (bufferImage**)calloc( SDL_FFMPEG_MAX_BUFFERED_FRAMES, sizeof(bufferImage*) );
179 189 stream->writeImage = 0;
190 stream->readImage = 0;
180 file->vs[file->VStreams] = stream; 191 file->vs[file->VStreams] = stream;
181 file->VStreams++; 192 file->VStreams++;
182 193
183 // create semaphore for thread-safe use 194 // create semaphore for thread-safe use
184 stream->sem = SDL_CreateSemaphore(1); 195 stream->sem = SDL_CreateSemaphore(1);
248 if( !SDL_ffmpegValidVideo(file) || file->pause || file->skipVideo) return 0; 259 if( !SDL_ffmpegValidVideo(file) || file->pause || file->skipVideo) return 0;
249 260
250 SDL_SemWait(file->vs[file->videoStream]->sem); 261 SDL_SemWait(file->vs[file->videoStream]->sem);
251 262
252 bufferImage *option = 0; 263 bufferImage *option = 0;
253 int i; 264 //int i;
254 265 float ratio;
255 for(i=0; i<SDL_FFMPEG_MAX_BUFFERED_FRAMES; i++) { 266 int64_t pos,pos1, pos2, timestamp;
256 267 //for(i=0; i<SDL_FFMPEG_MAX_BUFFERED_FRAMES; i++) {
268 pos=MWinsA->Get_CurAudioTime();
269
270 fprintf (pFile, "p: \t %u\t", pos);
271 //if (MWinsA->Get_HardwareBufferTime()==0)
272 // pos1=0;
273 //else {
274 // pos1=MWinsA->Get_HardwareBufferTime();
275 // //fprintf (tFile, "%u\t", pos1);
276 // int64_t timeTemp;
277 // QueryPerformanceCounter((LARGE_INTEGER *)(&timeTemp));
278 //
279 // pos1=(timeTemp-pos1)/(file->countFreq*hopfactor);
280 // fprintf (pFile, "%u\t", pos1);
281 //}
282 //pos2=pos+pos1;
283 fprintf (pFile, "%u\n", pos);
284
257 // if this entry does not exist, continue 285 // if this entry does not exist, continue
258 if(!file->vs[file->videoStream]->imageBuffer[i]) continue; 286 while(((file->vs[file->videoStream]->writeImage - file->vs[file->videoStream]->readImage)>0)&&(file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]->timestamp <= pos + ((AVFormatContext*)file->_ffmpeg)->start_time/1000))//&& (file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]->timestamp >= pos - file->timebase+ ((AVFormatContext*)file->_ffmpeg)->start_time/1000))
259 287 {
260 288 //pos=MWinsA->Get_CurAudioTime();
261 int64_t pos=MWinsA->Get_CurAudioTime(); 289 //timestamp=file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]->timestamp;
262 // do we have an image that should have been shown? 290 //fprintf (tFile, "try: %d %d\n", (pos+ ((AVFormatContext*)file->_ffmpeg)->start_time/1000), timestamp);
263 if(file->vs[file->videoStream]->imageBuffer[i]->timestamp <= pos + ((AVFormatContext*)file->_ffmpeg)->start_time/1000) { 291 // do we have an image that should have been shown?
264 292 //if(file->vs[file->videoStream]->imageBuffer[mod(file->vs[file->videoStream]->readImage,SDL_FFMPEG_MAX_BUFFERED_FRAMES)]->timestamp <= pos + (file->vs[file->videoStream]->timeBase)/4+((AVFormatContext*)file->_ffmpeg)->start_time/1000) {
265 // if this is the first option we find, we simply save it 293
266 if(!option) { 294 // if this is the first option we find, we simply save it
267 295 if(!option) {
268 option = file->vs[file->videoStream]->imageBuffer[i]; 296
269 297 option = file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES];
270 // set to 0 so we know this position in the buffer is available again 298
271 file->vs[file->videoStream]->imageBuffer[i] = 0; 299 // set to 0 so we know this position in the buffer is available again
272 300 file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES] = 0;
273 } else { 301 file->vs[file->videoStream]->readImage++;
274 302
275 // we found a newer possible timestamp, we delete the older one 303 } else {
276 if( option->timestamp < file->vs[file->videoStream]->imageBuffer[i]->timestamp) { 304
277 305 // we found a newer possible timestamp, we delete the older one
278 // this image is too old, we discard it 306 if( option->timestamp < file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]->timestamp) {
279 SDL_FreeSurface( option->img ); 307
280 308 // this image is too old, we discard it
281 // free old option 309 SDL_FreeSurface( option->img );
282 free( option ); 310
283 311 // free old option
284 // new pointer to position in container 312 free( option );
285 option = file->vs[file->videoStream]->imageBuffer[i]; 313
286 314 // new pointer to position in container
287 // set to 0 so we know this position in the buffer is available again 315 option = file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES];
288 file->vs[file->videoStream]->imageBuffer[i] = 0; 316
289 } 317 // set to 0 so we know this position in the buffer is available again
290 } 318 file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES] = 0;
291 } 319 file->vs[file->videoStream]->readImage++;
292 } 320 }
293 321 else {
322 file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]=0;
323 file->vs[file->videoStream]->readImage++;
324 }
325 }
326
327
328 pos=MWinsA->Get_CurAudioTime();
329 fprintf (pFile, "e:\t%u\t", pos);
330 //if (MWinsA->Get_HardwareBufferTime()==0)
331 // pos1=0;
332 //else {
333 // pos1=MWinsA->Get_HardwareBufferTime();
334 // //fprintf (tFile, "%u\t", pos1);
335 // int64_t timeTemp;
336 // QueryPerformanceCounter((LARGE_INTEGER *)(&timeTemp));
337
338 // pos1=(timeTemp-pos1)/(file->countFreq*hopfactor);
339 // fprintf (pFile, "%u\t", pos1);
340 //}
341 //fprintf (pFile, "%u\n", pos2);
342 //pos2=pos+pos1;
343 //if (pos<pos2) pos=pos2;
344 }
345 //}
346 //}
347 int x=file->vs[file->videoStream]->writeImage - file->vs[file->videoStream]->readImage;
294 // if we did not found an option, we exit 348 // if we did not found an option, we exit
295 if(!option) { 349 if(!option) {
296 // release the lock 350 // release the lock
351 /*timestamp=0;
352 int64_t tt=av_gettime()/1000-file->timer;
353 file->timer=av_gettime()/1000;
354 realt+=tt;
355 fprintf (tFile, "%u\t", realt);
356 fprintf (tFile, "%u\t", tt);
357 fprintf (tFile, "%u\t", pos);
358 fprintf (tFile, "%u\n", timestamp);*/
297 SDL_SemPost(file->vs[file->videoStream]->sem); 359 SDL_SemPost(file->vs[file->videoStream]->sem);
298 return 0; 360 return 0;
299 } 361 }
300 362 int64_t tt;
363 QueryPerformanceCounter((LARGE_INTEGER *)(&tt));
364 tt=tt/(file->countFreq)-file->timer;
365
366 QueryPerformanceCounter((LARGE_INTEGER *)(&file->timer));
367 file->timer=file->timer/(file->countFreq);
368 realt+=tt;
369 fprintf (tFile, "%u\t", x);
370 fprintf (tFile, "%u\t", realt);
371 fprintf (tFile, "%u\t", tt);
372 timestamp=(pos-option->timestamp+((AVFormatContext*)file->_ffmpeg)->start_time/1000)/hopfactor;
373 fprintf (tFile, "%u\t", pos);//+ (file->vs[file->videoStream]->timeBase)/4+((AVFormatContext*)file->_ffmpeg)->start_time/1000);
374 fprintf (tFile, "%d\n", timestamp);
301 // we did found an option, so we return the imagedata 375 // we did found an option, so we return the imagedata
302 return option->img; 376 return option->img;
303 } 377 }
304 378
305 int SDL_ffmpegReleaseVideo(SDL_ffmpegFile *file, SDL_Surface *bmp) { 379 int SDL_ffmpegReleaseVideo(SDL_ffmpegFile *file, SDL_Surface *bmp) {
510 584
511 // If it's a video packet from our video stream... 585 // If it's a video packet from our video stream...
512 if( SDL_ffmpegValidVideo(file) && pack.stream_index == file->vs[file->videoStream]->id && !file->skipVideo) { 586 if( SDL_ffmpegValidVideo(file) && pack.stream_index == file->vs[file->videoStream]->id && !file->skipVideo) {
513 587
514 got_frame = 0; 588 got_frame = 0;
515 589 //Time1=av_gettime();
516 // Decode the packet 590 // Decode the packet
517 avcodec_decode_video((AVCodecContext *)(file->vs[file->videoStream]->_ffmpeg), inFrame, &got_frame, pack.data, pack.size); 591 avcodec_decode_video((AVCodecContext *)(file->vs[file->videoStream]->_ffmpeg), inFrame, &got_frame, pack.data, pack.size);
518 592
519 if(got_frame) { 593 if(got_frame) {
520 594
564 24, 0x0000FF, 0x00FF00, 0xFF0000, 0); 638 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);
565 639
566 // copy image data to image room 640 // copy image data to image room
567 memcpy(buf->img->pixels, inFrameRGB->data[0], 641 memcpy(buf->img->pixels, inFrameRGB->data[0],
568 file->vs[file->videoStream]->width * file->vs[file->videoStream]->height * 3); 642 file->vs[file->videoStream]->width * file->vs[file->videoStream]->height * 3);
569 643 file->timebase=buf->timestamp-file->vs[file->videoStream]->lastTimeStamp;
570 // we write the lastTimestamp we got 644 // we write the lastTimestamp we got
571 file->vs[file->videoStream]->lastTimeStamp = buf->timestamp; 645 file->vs[file->videoStream]->lastTimeStamp = buf->timestamp;
572 646
573 int i; 647 //int i;
574 int again = 1; 648 int again = 1;
575 649 //Time=av_gettime()-Time1;
650
651 //fprintf (pFile, "%d \n",Time);
576 // keep trying to fit in buffer, until the data was actually placed in the buffer 652 // keep trying to fit in buffer, until the data was actually placed in the buffer
577 while(again && file->threadActive) { 653 while(again && file->threadActive) {
578 654
579 // we enter the video semaphore 655 // we enter the video semaphore
580 SDL_SemWait(file->vs[file->videoStream]->sem); 656 SDL_SemWait(file->vs[file->videoStream]->sem);
581 657
582 // loop through all positions in buffer until an empty 658 // loop through all positions in buffer until an empty
583 // space was found 659 // space was found
584 for(i=0; i<SDL_FFMPEG_MAX_BUFFERED_FRAMES; i++) { 660 //for(i=0; i<SDL_FFMPEG_MAX_BUFFERED_FRAMES; i++) {
585 // if this place in the buffer is empty we write our new frame 661 // if this place in the buffer is empty we write our new frame
586 if(file->vs[file->videoStream]->imageBuffer[i] == 0) { 662 if((file->vs[file->videoStream]->writeImage - file->vs[file->videoStream]->readImage) < SDL_FFMPEG_MAX_BUFFERED_FRAMES) {
587 file->vs[file->videoStream]->imageBuffer[i] = buf; 663 file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->writeImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES] = buf;
664 file->vs[file->videoStream]->writeImage++;
588 // we placed our image in the buffer, moving on 665 // we placed our image in the buffer, moving on
589 again = 0; 666 again = 0;
590 break; 667
591 } 668 }
592 } 669 //}
593 670
594 // we leave the video semaphore 671 // we leave the video semaphore
595 SDL_SemPost(file->vs[file->videoStream]->sem); 672 SDL_SemPost(file->vs[file->videoStream]->sem);
596 673
597 // frames aren't being release every ms, so we can take some 674 // frames aren't being release every ms, so we can take some
598 // time before we try and fit our new image again 675 // time before we try and fit our new image again
599 if(again) SDL_Delay(5); 676 if(again)
677 {
678 SDL_SemPost(file->decode);
679 SDL_Delay(3);
680 SDL_SemWait(file->decode);
681 }
600 } 682 }
601 // } 683 // }
602 //else { 684 //else {
603 // // if our decoded frame was too old, we don't bother putting 685 // // if our decoded frame was too old, we don't bother putting
604 // // it in our buffer 686 // // it in our buffer
728 free( file->vs[file->videoStream]->imageBuffer[i] ); 810 free( file->vs[file->videoStream]->imageBuffer[i] );
729 811
730 // set position in buffer to 0, so we know it is empty 812 // set position in buffer to 0, so we know it is empty
731 file->vs[file->videoStream]->imageBuffer[i] = 0; 813 file->vs[file->videoStream]->imageBuffer[i] = 0;
732 } 814 }
733 815 file->vs[file->videoStream]->writeImage=0;
816 file->vs[file->videoStream]->readImage=0;
734 SDL_SemPost(file->vs[file->videoStream]->sem); 817 SDL_SemPost(file->vs[file->videoStream]->sem);
735 } 818 }
736 819
737 return 0; 820 return 0;
738 } 821 }