
Recherche avancée
Médias (91)
-
Spitfire Parade - Crisis
15 mai 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
Wired NextMusic
14 mai 2011, par
Mis à jour : Février 2012
Langue : English
Type : Video
-
Video d’abeille en portrait
14 mai 2011, par
Mis à jour : Février 2012
Langue : français
Type : Video
-
Sintel MP4 Surround 5.1 Full
13 mai 2011, par
Mis à jour : Février 2012
Langue : English
Type : Video
-
Carte de Schillerkiez
13 mai 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Texte
-
Publier une image simplement
13 avril 2011, par ,
Mis à jour : Février 2012
Langue : français
Type : Video
Autres articles (40)
-
Support audio et vidéo HTML5
10 avril 2011MediaSPIP utilise les balises HTML5 video et audio pour la lecture de documents multimedia en profitant des dernières innovations du W3C supportées par les navigateurs modernes.
Pour les navigateurs plus anciens, le lecteur flash Flowplayer est utilisé.
Le lecteur HTML5 utilisé a été spécifiquement créé pour MediaSPIP : il est complètement modifiable graphiquement pour correspondre à un thème choisi.
Ces technologies permettent de distribuer vidéo et son à la fois sur des ordinateurs conventionnels (...) -
HTML5 audio and video support
13 avril 2011, parMediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
For older browsers the Flowplayer flash fallback is used.
MediaSPIP allows for media playback on major mobile platforms with the above (...) -
De l’upload à la vidéo finale [version standalone]
31 janvier 2010, parLe chemin d’un document audio ou vidéo dans SPIPMotion est divisé en trois étapes distinctes.
Upload et récupération d’informations de la vidéo source
Dans un premier temps, il est nécessaire de créer un article SPIP et de lui joindre le document vidéo "source".
Au moment où ce document est joint à l’article, deux actions supplémentaires au comportement normal sont exécutées : La récupération des informations techniques des flux audio et video du fichier ; La génération d’une vignette : extraction d’une (...)
Sur d’autres sites (8956)
-
Ffmpeg lose streams while using -map 0
27 mars 2016, par NgoralI had a strange issue using ffmpeg on Ubuntu 14.04.
I run a commandffmpeg -i output2.avi -c:v h264 -minrate 2000k -maxrate 5000k -bufsize 2000k -profile:v high -level:v 4 -coder 1 -s 640x360 -bf 0 -pix_fmt yuv420p -r 25 -g 25 -c:a aac -ar 48k -b:a 321k -map 0 -y outpu.mp4
It provides such a usual output in console (already with -loglevel verbose) :
ffmpeg version N-79004-g2e6636a Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04)
configuration: --prefix=/home/ngoral/ffmpeg_build --pkg-config-flags=--static --extra-cflags=-I/home/ngoral/ffmpeg_build/include --extra-ldflags=-L/home/ngoral/ffmpeg_build/lib --bindir=/home/ngoral/bin --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-nonfree
libavutil 55. 19.100 / 55. 19.100
libavcodec 57. 28.101 / 57. 28.101
libavformat 57. 28.101 / 57. 28.101
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 39.102 / 6. 39.102
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
[avi @ 0x2707800] parser not found for codec dvvideo, packets or times may be invalid.
Last message repeated 1 times
Input #0, avi, from 'output2.avi':
Metadata:
encoder : Lavf57.28.101
Duration: 00:00:20.04, start: 0.000000, bitrate: 28911 kb/s
Stream #0:0: Video: dvvideo, 1 reference frame (dvsd / 0x64737664), yuv420p, 720x576 [SAR 16:15 DAR 4:3], 28684 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc
Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 192 kb/s
Stream #0:2: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 64 kb/s
Stream #0:3: Audio: aac ([255][0][0][0] / 0x00FF), 48000 Hz, stereo, fltp, 117 kb/s
Matched encoder 'libx264' for codec 'h264'.
[graph 0 input from stream 0:0 @ 0x2784f60] w:720 h:576 pixfmt:yuv420p tb:1/25 fr:25/1 sar:16/15 sws_param:flags=2
[scaler for output stream 0:0 @ 0x2749d20] w:640 h:360 flags:'bicubic' interl:0
[scaler for output stream 0:0 @ 0x2749d20] w:720 h:576 fmt:yuv420p sar:16/15 -> w:640 h:360 fmt:yuv420p sar:3/4 flags:0x4
[graph 1 input from stream 0:1 @ 0x27a4fc0] tb:1/48000 samplefmt:s16p samplerate:48000 chlayout:0x3
[audio format for output stream 0:1 @ 0x27a5380] auto-inserting filter 'auto-inserted resampler 0' between the filter 'Parsed_anull_0' and the filter 'audio format for output stream 0:1'
[auto-inserted resampler 0 @ 0x27a7ae0] ch:2 chl:stereo fmt:s16p r:48000Hz -> ch:2 chl:stereo fmt:fltp r:48000Hz
[graph 2 input from stream 0:2 @ 0x27a6620] tb:1/48000 samplefmt:s16p samplerate:48000 chlayout:0x3
[audio format for output stream 0:2 @ 0x27a6440] auto-inserting filter 'auto-inserted resampler 0' between the filter 'Parsed_anull_0' and the filter 'audio format for output stream 0:2'
[auto-inserted resampler 0 @ 0x27b6be0] ch:2 chl:stereo fmt:s16p r:48000Hz -> ch:2 chl:stereo fmt:fltp r:48000Hz
[graph 3 input from stream 0:3 @ 0x27b6560] tb:1/48000 samplefmt:fltp samplerate:48000 chlayout:0x3
[libx264 @ 0x27889a0] using SAR=3/4
[libx264 @ 0x27889a0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x27889a0] profile High, level 4.0
[libx264 @ 0x27889a0] 264 - core 148 r2643 5c65704 - H.264/MPEG-4 AVC codec - Copyleft 2003-2015 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=2 keyint=25 keyint_min=2 scenecut=40 intra_refresh=0 rc_lookahead=25 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 vbv_maxrate=5000 vbv_bufsize=2000 crf_max=0.0 nal_hrd=none filler=0 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'outpu.mp4':
Metadata:
encoder : Lavf57.28.101
Stream #0:0: Video: h264 (libx264), -1 reference frame ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 3:4 DAR 4:3], q=-1--1, max. 5000 kb/s, 25 fps, 12800 tbn, 25 tbc
Metadata:
encoder : Lavc57.28.101 libx264
Side data:
cpb: bitrate max/min/avg: 5000000/0/0 buffer size: 2000000 vbv_delay: -1
Stream #0:1: Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 321 kb/s
Metadata:
encoder : Lavc57.28.101 aac
Stream #0:2: Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 321 kb/s
Metadata:
encoder : Lavc57.28.101 aac
Stream #0:3: Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 321 kb/s
Metadata:
encoder : Lavc57.28.101 aac
Stream mapping:
Stream #0:0 -> #0:0 (dvvideo (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (mp3 (native) -> aac (native))
Stream #0:2 -> #0:2 (mp3 (native) -> aac (native))
Stream #0:3 -> #0:3 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
*** 3 dup!
No more output streams to write to, finishing.e=00:00:19.84 bitrate= 359.9kbits/s dup=3 drop=0 speed=1.15x
frame= 501 fps= 29 q=-1.0 Lsize= 1792kB time=00:00:20.05 bitrate= 732.2kbits/s dup=3 drop=0 speed=1.14x
video:440kB audio:1331kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.155376%
Input file #0 (output2.avi):
Input stream #0:0 (video): 498 packets read (71712000 bytes); 498 frames decoded;
Input stream #0:1 (audio): 834 packets read (480384 bytes); 834 frames decoded (960768 samples);
Input stream #0:2 (audio): 835 packets read (160320 bytes); 835 frames decoded (961920 samples);
Input stream #0:3 (audio): 0 packets read (0 bytes); 0 frames decoded (0 samples);
Total: 2167 packets (72352704 bytes) demuxed
Output file #0 (outpu.mp4):
Output stream #0:0 (video): 501 frames encoded; 501 packets muxed (451055 bytes);
Output stream #0:1 (audio): 939 frames encoded (960768 samples); 940 packets muxed (724261 bytes);
Output stream #0:2 (audio): 940 frames encoded (961920 samples); 941 packets muxed (639072 bytes);
Output stream #0:3 (audio): 0 frames encoded (0 samples); 0 packets muxed (0 bytes);
Total: 2382 packets (1814388 bytes) muxed
[libx264 @ 0x27889a0] frame I:21 Avg QP:15.30 size: 8718
[libx264 @ 0x27889a0] frame P:480 Avg QP:24.52 size: 557
[libx264 @ 0x27889a0] mb I I16..4: 20.4% 55.5% 24.1%
[libx264 @ 0x27889a0] mb P I16..4: 0.0% 0.1% 0.0% P16..4: 7.6% 3.7% 1.7% 0.0% 0.0% skip:86.8%
[libx264 @ 0x27889a0] 8x8 transform intra:56.3% inter:50.3%
[libx264 @ 0x27889a0] coded y,uvDC,uvAC intra: 42.0% 39.5% 27.5% inter: 2.6% 1.4% 0.0%
[libx264 @ 0x27889a0] i16 v,h,dc,p: 36% 52% 3% 10%
[libx264 @ 0x27889a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 56% 20% 14% 2% 1% 1% 2% 2% 2%
[libx264 @ 0x27889a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 42% 26% 7% 4% 3% 4% 5% 5% 4%
[libx264 @ 0x27889a0] i8c dc,h,v,p: 66% 13% 17% 4%
[libx264 @ 0x27889a0] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x27889a0] ref P L0: 68.1% 11.5% 13.9% 6.5%
[libx264 @ 0x27889a0] kb/s:179.78
[aac @ 0x2747da0] Qavg: 62719.090
[aac @ 0x2748b20] Qavg: 64509.496
[aac @ 0x27498a0] Qavg: -nanit seems like it outputs all 3 audiostreams, but then i do
ffmpeg -loglevel verbose -i outpu.mp4
And get only 2 audiostreams :
ffmpeg version N-79004-g2e6636a Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04)
configuration: --prefix=/home/ngoral/ffmpeg_build --pkg-config-flags=--static --extra-cflags=-I/home/ngoral/ffmpeg_build/include --extra-ldflags=-L/home/ngoral/ffmpeg_build/lib --bindir=/home/ngoral/bin --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-nonfree
libavutil 55. 19.100 / 55. 19.100
libavcodec 57. 28.101 / 57. 28.101
libavformat 57. 28.101 / 57. 28.101
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 39.102 / 6. 39.102
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'outpu.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.28.101
Duration: 00:00:20.06, start: 0.021333, bitrate: 731 kb/s
Stream #0:0(und): Video: h264 (High), 3 reference frames (avc1 / 0x31637661), yuv420p, 640x360 (640x368) [SAR 3:4 DAR 4:3], 180 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 289 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream #0:2(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 254 kb/s
Metadata:
handler_name : SoundHandlerWhat’s wrong with it ?
It works fine on my Win machine, on virtual machine with Ubuntu on it, but as ran on real Ubuntu it behaves like this. Do you have any ideas ?
Thanks ! -
ffmpeg - scaling and stacking 2 videos ?
25 mai 2016, par Gambit2007I have 2 inputs and i want to scale, crop and put them on top of each other at the same time. My command should look something like this :
ffmpeg -i input1 -i input2 -filter_complex crop=10000:5000:1000:0,scale=3840:1536 vstack output.mp4
I know i need to use chaining (?) but i tried to look it up online and couldn’t really get it to work.
So what would be the correct syntax the scale and crop both inputs and then put them vertically on top of each other while using ’-filter_complex’ only once ?
Thanks !
-
Decoding and playing audio with ffmpeg and XAudio2 - frequency raito wrong
12 juillet 2016, par Brent de CarteretI’m using ffmpeg to decode audio and output it using the XAudio2 API, it works and plays synced with the video output using the pts. But it’s high pitched (i.e. sounds like chipmunks).
Setting breakpoints I can see it has sets the correct sample rate from the audio codec in CreateSourceVoice. I’m stumped.
Any help would be much appreciated.
#include "DVDAudioDevice.h"
HANDLE m_hBufferEndEvent;
CDVDAudio::CDVDAudio()
{
m_pXAudio2 = NULL;
m_pMasteringVoice = NULL;
m_pSourceVoice = NULL;
m_pWfx = NULL;
m_VoiceCallback = NULL;
m_hBufferEndEvent = CreateEvent(NULL, false, false, "Buffer end event");
}
CDVDAudio::~CDVDAudio()
{
m_pXAudio2 = NULL;
m_pMasteringVoice = NULL;
m_pSourceVoice = NULL;
m_pWfx = NULL;
m_VoiceCallback = NULL;
CloseHandle(m_hBufferEndEvent);
m_hBufferEndEvent = NULL;
}
bool CDVDAudio::Create(int iChannels, int iBitrate, int iBitsPerSample, bool bPasstrough)
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
HRESULT hr = XAudio2Create( &m_pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR);
if (SUCCEEDED(hr))
{
m_pXAudio2->CreateMasteringVoice( &m_pMasteringVoice );
}
// Create source voice
WAVEFORMATEXTENSIBLE wfx;
memset(&wfx, 0, sizeof(WAVEFORMATEXTENSIBLE));
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
wfx.Format.nSamplesPerSec = iBitrate;//pFFMpegData->pAudioCodecCtx->sample_rate;//48000 by default
wfx.Format.nChannels = iChannels;//pFFMpegData->pAudioCodecCtx->channels;
wfx.Format.wBitsPerSample = 16;
wfx.Format.nBlockAlign = wfx.Format.nChannels*16/8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample;
if(wfx.Format.nChannels == 1)
{
wfx.dwChannelMask = SPEAKER_MONO;
}
else if(wfx.Format.nChannels == 2)
{
wfx.dwChannelMask = SPEAKER_STEREO;
}
else if(wfx.Format.nChannels == 5)
{
wfx.dwChannelMask = SPEAKER_5POINT1;
}
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
unsigned int flags = 0;//XAUDIO2_VOICE_NOSRC;// | XAUDIO2_VOICE_NOPITCH;
//Source voice
m_VoiceCallback = new StreamingVoiceCallback(this);
hr = m_pXAudio2->CreateSourceVoice(&m_pSourceVoice,(WAVEFORMATEX*)&wfx, 0 , 1.0f, m_VoiceCallback);
if(!SUCCEEDED(hr))
return false;
// Start sound
hr = m_pSourceVoice->Start(0);
if(!SUCCEEDED(hr))
return false;
return true;
}
DWORD CDVDAudio::AddPackets(unsigned char* data, DWORD len)
{
memset(&m_SoundBuffer,0,sizeof(XAUDIO2_BUFFER));
m_SoundBuffer.AudioBytes = len;
m_SoundBuffer.pAudioData = data;
m_SoundBuffer.pContext = NULL;//(VOID*)data;
XAUDIO2_VOICE_STATE state;
while(m_pSourceVoice->GetState( &state ), state.BuffersQueued > 60)
{
WaitForSingleObject( m_hBufferEndEvent, INFINITE );
}
m_pSourceVoice->SubmitSourceBuffer( &m_SoundBuffer );
return 0;
}
void CDVDAudio::Destroy()
{
m_pMasteringVoice->DestroyVoice();
m_pXAudio2->Release();
m_pSourceVoice->DestroyVoice();
delete m_VoiceCallback;
m_VoiceCallback = NULL;
}#include "DVDAudioCodecFFmpeg.h"
#include "Log.h"
CDVDAudioCodecFFmpeg::CDVDAudioCodecFFmpeg() : CDVDAudioCodec()
{
m_iBufferSize = 0;
m_pCodecContext = NULL;
m_bOpenedCodec = false;
}
CDVDAudioCodecFFmpeg::~CDVDAudioCodecFFmpeg()
{
Dispose();
}
bool CDVDAudioCodecFFmpeg::Open(AVCodecID codecID, int iChannels, int iSampleRate)
{
AVCodec* pCodec;
m_bOpenedCodec = false;
av_register_all();
pCodec = avcodec_find_decoder(codecID);
m_pCodecContext = avcodec_alloc_context3(pCodec);//avcodec_alloc_context();
avcodec_get_context_defaults3(m_pCodecContext, pCodec);
if (!pCodec)
{
CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Open() Unable to find codec");
return false;
}
m_pCodecContext->debug_mv = 0;
m_pCodecContext->debug = 0;
m_pCodecContext->workaround_bugs = 1;
if (pCodec->capabilities & CODEC_CAP_TRUNCATED)
m_pCodecContext->flags |= CODEC_FLAG_TRUNCATED;
m_pCodecContext->channels = iChannels;
m_pCodecContext->sample_rate = iSampleRate;
//m_pCodecContext->bits_per_sample = 24;
/* //FIXME BRENT
if( ExtraData && ExtraSize > 0 )
{
m_pCodecContext->extradata_size = ExtraSize;
m_pCodecContext->extradata = m_dllAvCodec.av_mallocz(ExtraSize + FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(m_pCodecContext->extradata, ExtraData, ExtraSize);
}
*/
// set acceleration
//m_pCodecContext->dsp_mask = FF_MM_FORCE | FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE; //BRENT
if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0)
{
CLog::Log(LOGERROR, "CDVDAudioCodecFFmpeg::Open() Unable to open codec");
Dispose();
return false;
}
m_bOpenedCodec = true;
return true;
}
void CDVDAudioCodecFFmpeg::Dispose()
{
if (m_pCodecContext)
{
if (m_bOpenedCodec) avcodec_close(m_pCodecContext);
m_bOpenedCodec = false;
av_free(m_pCodecContext);
m_pCodecContext = NULL;
}
m_iBufferSize = 0;
}
int CDVDAudioCodecFFmpeg::Decode(BYTE* pData, int iSize)
{
int iBytesUsed;
if (!m_pCodecContext) return -1;
//Copy into a FFMpeg AVPAcket again
AVPacket packet;
av_init_packet(&packet);
packet.data=pData;
packet.size=iSize;
int iOutputSize = AVCODEC_MAX_AUDIO_FRAME_SIZE; //BRENT
iBytesUsed = avcodec_decode_audio3(m_pCodecContext, (int16_t *)m_buffer, &iOutputSize/*m_iBufferSize*/, &packet);
m_iBufferSize = iOutputSize;//BRENT
return iBytesUsed;
}
int CDVDAudioCodecFFmpeg::GetData(BYTE** dst)
{
*dst = m_buffer;
return m_iBufferSize;
}
void CDVDAudioCodecFFmpeg::Reset()
{
if (m_pCodecContext) avcodec_flush_buffers(m_pCodecContext);
}
int CDVDAudioCodecFFmpeg::GetChannels()
{
if (m_pCodecContext) return m_pCodecContext->channels;
return 0;
}
int CDVDAudioCodecFFmpeg::GetSampleRate()
{
if (m_pCodecContext) return m_pCodecContext->sample_rate;
return 0;
}
int CDVDAudioCodecFFmpeg::GetBitsPerSample()
{
if (m_pCodecContext) return 16;
return 0;
}#include "DVDPlayerAudio.h"
#include "DVDDemuxUtils.h"
#include "Log.h"
#include
#include "DVDAudioCodecFFmpeg.h" //FIXME Move to a codec factory!!
CDVDPlayerAudio::CDVDPlayerAudio(CDVDClock* pClock) : CThread()
{
m_pClock = pClock;
m_pAudioCodec = NULL;
m_bInitializedOutputDevice = false;
m_iSourceChannels = 0;
m_audioClock = 0;
// m_currentPTSItem.pts = DVD_NOPTS_VALUE;
// m_currentPTSItem.timestamp = 0;
SetSpeed(DVD_PLAYSPEED_NORMAL);
InitializeCriticalSection(&m_critCodecSection);
m_messageQueue.SetMaxDataSize(10 * 16 * 1024);
// g_dvdPerformanceCounter.EnableAudioQueue(&m_packetQueue);
}
CDVDPlayerAudio::~CDVDPlayerAudio()
{
// g_dvdPerformanceCounter.DisableAudioQueue();
// close the stream, and don't wait for the audio to be finished
CloseStream(true);
DeleteCriticalSection(&m_critCodecSection);
}
bool CDVDPlayerAudio::OpenStream( CDemuxStreamAudio *pDemuxStream )
{
// should alway's be NULL!!!!, it will probably crash anyway when deleting m_pAudioCodec here.
if (m_pAudioCodec)
{
CLog::Log(LOGFATAL, "CDVDPlayerAudio::OpenStream() m_pAudioCodec != NULL");
return false;
}
AVCodecID codecID = pDemuxStream->codec;
CLog::Log(LOGNOTICE, "Finding audio codec for: %i", codecID);
//m_pAudioCodec = CDVDFactoryCodec::CreateAudioCodec( pDemuxStream );
m_pAudioCodec = new CDVDAudioCodecFFmpeg; //FIXME BRENT Codec Factory needed!
if (!m_pAudioCodec->Open(pDemuxStream->codec, pDemuxStream->iChannels, pDemuxStream->iSampleRate))
{
m_pAudioCodec->Dispose();
delete m_pAudioCodec;
m_pAudioCodec = NULL;
return false;
}
if( !m_pAudioCodec )
{
CLog::Log(LOGERROR, "Unsupported audio codec");
return false;
}
m_codec = pDemuxStream->codec;
m_iSourceChannels = pDemuxStream->iChannels;
m_messageQueue.Init();
CLog::Log(LOGNOTICE, "Creating audio thread");
Create();
return true;
}
void CDVDPlayerAudio::CloseStream(bool bWaitForBuffers)
{
// wait until buffers are empty
if (bWaitForBuffers) m_messageQueue.WaitUntilEmpty();
// send abort message to the audio queue
m_messageQueue.Abort();
CLog::Log(LOGNOTICE, "waiting for audio thread to exit");
// shut down the adio_decode thread and wait for it
StopThread(); // will set this->m_bStop to true
this->WaitForThreadExit(INFINITE);
// uninit queue
m_messageQueue.End();
CLog::Log(LOGNOTICE, "Deleting audio codec");
if (m_pAudioCodec)
{
m_pAudioCodec->Dispose();
delete m_pAudioCodec;
m_pAudioCodec = NULL;
}
// flush any remaining pts values
//FlushPTSQueue(); //FIXME BRENT
}
void CDVDPlayerAudio::OnStartup()
{
CThread::SetName("CDVDPlayerAudio");
pAudioPacket = NULL;
m_audioClock = 0;
audio_pkt_data = NULL;
audio_pkt_size = 0;
// g_dvdPerformanceCounter.EnableAudioDecodePerformance(ThreadHandle());
}
void CDVDPlayerAudio::Process()
{
CLog::Log(LOGNOTICE, "running thread: CDVDPlayerAudio::Process()");
int result;
// silence data
BYTE silence[1024];
memset(silence, 0, 1024);
DVDAudioFrame audioframe;
__int64 iClockDiff=0;
while (!m_bStop)
{
//Don't let anybody mess with our global variables
EnterCriticalSection(&m_critCodecSection);
result = DecodeFrame(audioframe, m_speed != DVD_PLAYSPEED_NORMAL); // blocks if no audio is available, but leaves critical section before doing so
LeaveCriticalSection(&m_critCodecSection);
if( result & DECODE_FLAG_ERROR )
{
CLog::Log(LOGERROR, "CDVDPlayerAudio::Process - Decode Error. Skipping audio frame");
continue;
}
if( result & DECODE_FLAG_ABORT )
{
CLog::Log(LOGDEBUG, "CDVDPlayerAudio::Process - Abort recieved, exiting thread");
break;
}
if( result & DECODE_FLAG_DROP ) //FIXME BRENT
{
/* //frame should be dropped. Don't let audio move ahead of the current time thou
//we need to be able to start playing at any time
//when playing backwords, we try to keep as small buffers as possible
// set the time at this delay
AddPTSQueue(audioframe.pts, m_dvdAudio.GetDelay());
*/
if (m_speed > 0)
{
__int64 timestamp = m_pClock->GetAbsoluteClock() + (audioframe.duration * DVD_PLAYSPEED_NORMAL) / m_speed;
while( !m_bStop && timestamp > m_pClock->GetAbsoluteClock() ) Sleep(1);
}
continue;
}
if( audioframe.size > 0 )
{
// we have succesfully decoded an audio frame, openup the audio device if not already done
if (!m_bInitializedOutputDevice)
{
m_bInitializedOutputDevice = InitializeOutputDevice();
}
//Add any packets play
m_dvdAudio.AddPackets(audioframe.data, audioframe.size);
// store the delay for this pts value so we can calculate the current playing
//AddPTSQueue(audioframe.pts, m_dvdAudio.GetDelay() - audioframe.duration);//BRENT
}
// if we where asked to resync on this packet, do so here
if( result & DECODE_FLAG_RESYNC )
{
CLog::Log(LOGDEBUG, "CDVDPlayerAudio::Process - Resync recieved.");
//while (!m_bStop && (unsigned int)m_dvdAudio.GetDelay() > audioframe.duration ) Sleep(5); //BRENT
m_pClock->Discontinuity(CLOCK_DISC_NORMAL, audioframe.pts);
}
#ifdef USEOLDSYNC
//Clock should be calculated after packets have been added as m_audioClock points to the
//time after they have been played
const __int64 iCurrDiff = (m_audioClock - m_dvdAudio.GetDelay()) - m_pClock->GetClock();
const __int64 iAvDiff = (iClockDiff + iCurrDiff)/2;
//Check for discontinuity in the stream, use a moving average to
//eliminate highfreq fluctuations of large packet sizes
if( ABS(iAvDiff) > 5000 ) // sync clock if average diff is bigger than 5 msec
{
//Wait untill only the new audio frame wich triggered the discontinuity is left
//then set disc state
while (!m_bStop && (unsigned int)m_dvdAudio.GetBytesInBuffer() > audioframe.size ) Sleep(5);
m_pClock->Discontinuity(CLOCK_DISC_NORMAL, m_audioClock - m_dvdAudio.GetDelay());
CLog::("CDVDPlayer:: Detected Audio Discontinuity, syncing clock. diff was: %I64d, %I64d, av: %I64d", iClockDiff, iCurrDiff, iAvDiff);
iClockDiff = 0;
}
else
{
//Do gradual adjustments (not working yet)
//m_pClock->AdjustSpeedToMatch(iClock + iAvDiff);
iClockDiff = iCurrDiff;
}
#endif
}
}
void CDVDPlayerAudio::OnExit()
{
//g_dvdPerformanceCounter.DisableAudioDecodePerformance();
// destroy audio device
CLog::Log(LOGNOTICE, "Closing audio device");
m_dvdAudio.Destroy();
m_bInitializedOutputDevice = false;
CLog::Log(LOGNOTICE, "thread end: CDVDPlayerAudio::OnExit()");
}
// decode one audio frame and returns its uncompressed size
int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe, bool bDropPacket)
{
CDVDDemux::DemuxPacket* pPacket = pAudioPacket;
int n=48000*2*16/8, len;
//Store amount left at this point, and what last pts was
unsigned __int64 first_pkt_pts = 0;
int first_pkt_size = 0;
int first_pkt_used = 0;
int result = 0;
// make sure the sent frame is clean
memset(&audioframe, 0, sizeof(DVDAudioFrame));
if (pPacket)
{
first_pkt_pts = pPacket->pts;
first_pkt_size = pPacket->iSize;
first_pkt_used = first_pkt_size - audio_pkt_size;
}
for (;;)
{
/* NOTE: the audio packet can contain several frames */
while (audio_pkt_size > 0)
{
len = m_pAudioCodec->Decode(audio_pkt_data, audio_pkt_size);
if (len < 0)
{
/* if error, we skip the frame */
audio_pkt_size=0;
m_pAudioCodec->Reset();
break;
}
// fix for fucked up decoders //FIXME BRENT
if( len > audio_pkt_size )
{
CLog::Log(LOGERROR, "CDVDPlayerAudio:DecodeFrame - Codec tried to consume more data than available. Potential memory corruption");
audio_pkt_size=0;
m_pAudioCodec->Reset();
assert(0);
}
// get decoded data and the size of it
audioframe.size = m_pAudioCodec->GetData(&audioframe.data);
audio_pkt_data += len;
audio_pkt_size -= len;
if (audioframe.size <= 0) continue;
audioframe.pts = m_audioClock;
// compute duration.
n = m_pAudioCodec->GetChannels() * m_pAudioCodec->GetBitsPerSample() / 8 * m_pAudioCodec->GetSampleRate();
if (n > 0)
{
// safety check, if channels == 0, n will result in 0, and that will result in a nice devide exception
audioframe.duration = (unsigned int)(((__int64)audioframe.size * DVD_TIME_BASE) / n);
// increase audioclock to after the packet
m_audioClock += audioframe.duration;
}
//If we are asked to drop this packet, return a size of zero. then it won't be played
//we currently still decode the audio.. this is needed since we still need to know it's
//duration to make sure clock is updated correctly.
if( bDropPacket )
{
result |= DECODE_FLAG_DROP;
}
return result;
}
// free the current packet
if (pPacket)
{
CDVDDemuxUtils::FreeDemuxPacket(pPacket); //BRENT FIXME
pPacket = NULL;
pAudioPacket = NULL;
}
if (m_messageQueue.RecievedAbortRequest()) return DECODE_FLAG_ABORT;
// read next packet and return -1 on error
LeaveCriticalSection(&m_critCodecSection); //Leave here as this might stall a while
CDVDMsg* pMsg;
MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, INFINITE);
EnterCriticalSection(&m_critCodecSection);
if (MSGQ_IS_ERROR(ret) || ret == MSGQ_ABORT) return DECODE_FLAG_ABORT;
if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET))
{
CDVDMsgDemuxerPacket* pMsgDemuxerPacket = (CDVDMsgDemuxerPacket*)pMsg;
pPacket = pMsgDemuxerPacket->GetPacket();
pMsgDemuxerPacket->m_pPacket = NULL; // XXX, test
pAudioPacket = pPacket;
audio_pkt_data = pPacket->pData;
audio_pkt_size = pPacket->iSize;
}
else
{
// other data is not used here, free if
// msg itself will still be available
pMsg->Release();
}
// if update the audio clock with the pts
if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET) || pMsg->IsType(CDVDMsg::GENERAL_RESYNC))
{
if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC))
{
//player asked us to sync on this package
CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg;
result |= DECODE_FLAG_RESYNC;
m_audioClock = pMsgGeneralResync->GetPts();
}
else if (pPacket->pts != DVD_NOPTS_VALUE) // CDVDMsg::DEMUXER_PACKET, pPacket is already set above
{
if (first_pkt_size == 0)
{
//first package
m_audioClock = pPacket->pts;
}
else if (first_pkt_pts > pPacket->pts)
{
//okey first packet in this continous stream, make sure we use the time here
m_audioClock = pPacket->pts;
}
else if((unsigned __int64)m_audioClock < pPacket->pts || (unsigned __int64)m_audioClock > pPacket->pts)
{
//crap, moved outsided correct pts
//Use pts from current packet, untill we find a better value for it.
//Should be ok after a couple of frames, as soon as it starts clean on a packet
m_audioClock = pPacket->pts;
}
else if(first_pkt_size == first_pkt_used)
{
//Nice starting up freshly on the start of a packet, use pts from it
m_audioClock = pPacket->pts;
}
}
}
pMsg->Release();
}
}
void CDVDPlayerAudio::SetSpeed(int speed)
{
m_speed = speed;
//if (m_speed == DVD_PLAYSPEED_PAUSE) m_dvdAudio.Pause(); //BRENT FIXME
//else m_dvdAudio.Resume();
}
bool CDVDPlayerAudio::InitializeOutputDevice()
{
int iChannels = m_pAudioCodec->GetChannels();
int iSampleRate = m_pAudioCodec->GetSampleRate();
int iBitsPerSample = m_pAudioCodec->GetBitsPerSample();
//bool bPasstrough = m_pAudioCodec->NeedPasstrough(); //BRENT
if (iChannels == 0 || iSampleRate == 0 || iBitsPerSample == 0)
{
CLog::Log(LOGERROR, "Unable to create audio device, (iChannels == 0 || iSampleRate == 0 || iBitsPerSample == 0)");
return false;
}
CLog::Log(LOGNOTICE, "Creating audio device with codec id: %i, channels: %i, sample rate: %i", m_codec, iChannels, iSampleRate);
if (m_dvdAudio.Create(iChannels, iSampleRate, iBitsPerSample, /*bPasstrough*/0)) // always 16 bit with ffmpeg ? //BRENT Passthrough needed?
{
return true;
}
CLog::Log(LOGERROR, "Failed Creating audio device with codec id: %i, channels: %i, sample rate: %i", m_codec, iChannels, iSampleRate);
return false;
}