Mercurial > hg > easaier-soundaccess
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 } |