ivand_qmul@125: /******************************************************************************* ivand_qmul@125: * * ivand_qmul@125: * SDL_ffmpeg is a library for basic multimedia functionality. * ivand_qmul@125: * SDL_ffmpeg is based on ffmpeg. * ivand_qmul@125: * * ivand_qmul@125: * Copyright (C) 2007 Arjan Houben * ivand_qmul@125: * * ivand_qmul@125: * SDL_ffmpeg is free software: you can redistribute it and/or modify * ivand_qmul@125: * it under the terms of the GNU Lesser General Public License as published * ivand_qmul@125: * by the Free Software Foundation, either version 3 of the License, or any * ivand_qmul@125: * later version. * ivand_qmul@125: * * ivand_qmul@125: * This program is distributed in the hope that it will be useful, * ivand_qmul@125: * but WITHOUT ANY WARRANTY; without even the implied warranty of * ivand_qmul@125: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ivand_qmul@125: * GNU Lesser General Public License for more details. * ivand_qmul@125: * * ivand_qmul@125: * You should have received a copy of the GNU Lesser General Public License * ivand_qmul@125: * along with this program. If not, see . * ivand_qmul@125: * * ivand_qmul@125: *******************************************************************************/ ivand_qmul@125: ivand_qmul@125: #ifndef SDL_FFMPEG_INCLUDED ivand_qmul@125: #define SDL_FFMPEG_INCLUDED ivand_qmul@125: #ifdef __cplusplus ivand_qmul@125: extern "C" { ivand_qmul@125: #endif ivand_qmul@125: #ifdef WIN32 ivand_qmul@125: #ifdef SDL_FFMPEG_LIBRARY ivand_qmul@125: #define __STDC_LIMIT_MACROS ivand_qmul@125: #define __STDC_CONSTANT_MACROS ivand_qmul@125: #include "avformat.h" ivand_qmul@125: #include "swscale.h" ivand_qmul@125: #endif ivand_qmul@125: #include "SDL_thread.h" ivand_qmul@125: #include "SDL.h" ivand_qmul@125: ivand_qmul@125: #endif ivand_qmul@125: ivand_qmul@125: #ifdef __unix__ ivand_qmul@125: #include "SDL/SDL_thread.h" ivand_qmul@125: #include "SDL/SDL.h" ivand_qmul@125: #ifdef SDL_FFMPEG_LIBRARY ivand_qmul@125: #include "ffmpeg/avformat.h" ivand_qmul@125: #endif ivand_qmul@125: #endif ivand_qmul@125: ivand_qmul@125: #ifdef __cplusplus ivand_qmul@125: } ivand_qmul@125: #endif ivand_qmul@125: #define SWS_BICUBIC 4 ivand_qmul@150: const int SDL_FFMPEG_MAX_BUFFERED_FRAMES = 25; ivand_qmul@125: const int SDL_FFMPEG_MAX_BUFFERED_SAMPLES = 512*512; ivand_qmul@125: static int sws_flags = SWS_BICUBIC; ivand_qmul@125: // we pack our decoded images into bufferImage structs ivand_qmul@125: typedef struct bufferImage { ivand_qmul@125: // pointer to image data ivand_qmul@125: SDL_Surface *img; ivand_qmul@125: // timestamp of current image ivand_qmul@125: int64_t timestamp; ivand_qmul@125: } bufferImage; ivand_qmul@125: ivand_qmul@125: // this is the basic stream for SDL_ffmpeg ivand_qmul@125: typedef struct SDL_ffmpegStream { ivand_qmul@125: ivand_qmul@125: // pointer to ffmpeg data, internal use only! ivand_qmul@125: // points to AVCodecContext ivand_qmul@125: int pixFmt; ivand_qmul@125: void *_ffmpeg; ivand_qmul@125: ivand_qmul@125: // semaphore for current stream ivand_qmul@125: SDL_sem *sem; ivand_qmul@125: ivand_qmul@125: // audio/video buffers ivand_qmul@125: bufferImage **imageBuffer; ivand_qmul@125: int8_t *audio; ivand_qmul@129: int writeImage; ivand_qmul@129: int readImage; ivand_qmul@125: // userinfo ivand_qmul@125: double frameRate[2]; ivand_qmul@125: char language[4]; ivand_qmul@125: int sampleRate; ivand_qmul@125: int channels; ivand_qmul@125: char codecName[32]; ivand_qmul@125: double timeBase; ivand_qmul@125: uint16_t width; ivand_qmul@125: uint16_t height; ivand_qmul@125: ivand_qmul@125: // extra data for audio ivand_qmul@125: int32_t size; ivand_qmul@125: int id; ivand_qmul@125: int64_t lastTimeStamp; ivand_qmul@125: int64_t pts, hardPts; ivand_qmul@125: int64_t totalBytes; ivand_qmul@125: ivand_qmul@125: } SDL_ffmpegStream; ivand_qmul@125: ivand_qmul@125: typedef struct SDL_ffmpegFile { ivand_qmul@125: ivand_qmul@125: // pointer to ffmpeg data, internal use only! ivand_qmul@125: // points to AVFormatContext ivand_qmul@125: void *_ffmpeg; ivand_qmul@125: ivand_qmul@125: // our streams ivand_qmul@125: SDL_ffmpegStream **vs; ivand_qmul@125: SDL_ffmpegStream **as; ivand_qmul@125: ivand_qmul@125: // data used for syncing/searching ivand_qmul@125: int64_t offset, videoOffset, startTime; ivand_qmul@125: int pause; ivand_qmul@125: ivand_qmul@125: // streams and data about threads ivand_qmul@125: int VStreams, AStreams, videoStream, audioStream, threadActive, videoThreadActive; ivand_qmul@125: SDL_Thread *threadID, *videoThread; ivand_qmul@125: SDL_sem *decode; ivand_qmul@125: int skipAudio; ivand_qmul@125: int skipVideo; ivand_qmul@125: int delay; ivand_qmul@129: int64_t timer; ivand_qmul@129: int64_t countFreq; ivand_qmul@129: int timebase; ivand_qmul@125: int64_t audioTime; ivand_qmul@125: } SDL_ffmpegFile; ivand_qmul@125: ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegStartDecoding(SDL_ffmpegFile* file); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegStopDecoding(SDL_ffmpegFile* file); ivand_qmul@125: ivand_qmul@125: SDL_Surface* SDL_ffmpegGetVideo(SDL_ffmpegFile* file); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegReleaseVideo(SDL_ffmpegFile *file, SDL_Surface *bmp); ivand_qmul@125: ivand_qmul@125: SDL_ffmpegStream* SDL_ffmpegGetAudioStream(SDL_ffmpegFile *file, int audioID); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegSelectAudioStream(SDL_ffmpegFile* file, int audioID); ivand_qmul@125: ivand_qmul@125: SDL_ffmpegStream* SDL_ffmpegGetVideoStream(SDL_ffmpegFile *file, int audioID); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegSelectVideoStream(SDL_ffmpegFile* file, int videoID); ivand_qmul@125: ivand_qmul@125: SDL_ffmpegFile* SDL_ffmpegCreateFile(); ivand_qmul@125: ivand_qmul@125: void SDL_ffmpegFree(SDL_ffmpegFile* file); ivand_qmul@125: ivand_qmul@125: SDL_ffmpegFile* SDL_ffmpegOpen(const char* filename); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegDecodeThread(void* data); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegSeek(SDL_ffmpegFile* file, int64_t timestamp); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegSeekRelative(SDL_ffmpegFile* file, int64_t timestamp); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegFlush(SDL_ffmpegFile *file); ivand_qmul@125: ivand_qmul@125: int8_t* SDL_ffmpegGetAudio(SDL_ffmpegFile *file, int *len); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegReleaseAudio(SDL_ffmpegFile *file, int len); ivand_qmul@125: ivand_qmul@125: int64_t SDL_ffmpegGetPosition(SDL_ffmpegFile *file); ivand_qmul@125: ivand_qmul@125: SDL_AudioSpec* SDL_ffmpegGetAudioSpec(SDL_ffmpegFile *file, int samples, void *callback); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegGetVideoSize(SDL_ffmpegFile *file, int *w, int *h); ivand_qmul@125: ivand_qmul@125: int64_t SDL_ffmpegGetDuration(SDL_ffmpegFile *file); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegValidAudio(SDL_ffmpegFile *file); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegValidVideo(SDL_ffmpegFile *file); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegPause(SDL_ffmpegFile *file, int state); ivand_qmul@125: ivand_qmul@125: int SDL_ffmpegGetState(SDL_ffmpegFile *file); ivand_qmul@125: ivand_qmul@125: #endif // SDL_FFMPEG_INCLUDED