
Recherche avancée
Médias (91)
-
Richard Stallman et le logiciel libre
19 octobre 2011, par
Mis à jour : Mai 2013
Langue : français
Type : Texte
-
Stereo master soundtrack
17 octobre 2011, par
Mis à jour : Octobre 2011
Langue : English
Type : Audio
-
Elephants Dream - Cover of the soundtrack
17 octobre 2011, par
Mis à jour : Octobre 2011
Langue : English
Type : Image
-
#7 Ambience
16 octobre 2011, par
Mis à jour : Juin 2015
Langue : English
Type : Audio
-
#6 Teaser Music
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#5 End Title
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
Autres articles (76)
-
MediaSPIP v0.2
21 juin 2013, parMediaSPIP 0.2 est la première version de MediaSPIP stable.
Sa date de sortie officielle est le 21 juin 2013 et est annoncée ici.
Le fichier zip ici présent contient uniquement les sources de MediaSPIP en version standalone.
Comme pour la version précédente, il est nécessaire d’installer manuellement l’ensemble des dépendances logicielles sur le serveur.
Si vous souhaitez utiliser cette archive pour une installation en mode ferme, il vous faudra également procéder à d’autres modifications (...) -
XMP PHP
13 mai 2011, parDixit Wikipedia, XMP signifie :
Extensible Metadata Platform ou XMP est un format de métadonnées basé sur XML utilisé dans les applications PDF, de photographie et de graphisme. Il a été lancé par Adobe Systems en avril 2001 en étant intégré à la version 5.0 d’Adobe Acrobat.
Étant basé sur XML, il gère un ensemble de tags dynamiques pour l’utilisation dans le cadre du Web sémantique.
XMP permet d’enregistrer sous forme d’un document XML des informations relatives à un fichier : titre, auteur, historique (...) -
Use, discuss, criticize
13 avril 2011, parTalk to people directly involved in MediaSPIP’s development, or to people around you who could use MediaSPIP to share, enhance or develop their creative projects.
The bigger the community, the more MediaSPIP’s potential will be explored and the faster the software will evolve.
A discussion list is available for all exchanges between users.
Sur d’autres sites (11554)
-
ffmpeg concat doesn't keep video speed/framerate ?
28 août 2016, par NickI have a bunch of small webm clips in directory vidchunks. These clips were generated using javascript MediaRecorder API.
MediaRecorder code :
var mRecorder;
var chunks = [];
navigator.mediaDevices.getUserMedia({
audio: false,
video: {
width: 1280,
height: 760,
mozMediaSource: "screen",
mediaSource: "screen"
}
}).then(function(stream) {
mRecorder = new MediaRecorder(stream,{mimeType:"video/webm"});
mRecorder.ondataavailable = function(event) {
var blob = event.data;
chunks.push(blob);
var vidchunk = new Blob(chunks);
// save to directory vid chunk.
};
mRecorder.start(5000);
}).catch(function(error) {
console.log(error.message);
});Then, once I have a bunch of these 5 second clips, I merge them :
ffmpeg -safe 0 \
-f concat -i <(for f in `ls vidchunks/* | sort -V`; do echo file $f; done) \
-c:v copy -r 30 -vsync drop test.webmWhen I play back these chunks individually, they play correctly. All 5 seconds of video are rendered smoothly.
However, once I merge, some 5 second chunks are condensed to like 1 second. So the total video, which should be 50 seconds for 10 chunks, turns out to be like 38 seconds because three of the chunks got condensed to 1 second.
Any ideas on how to fix this ?
EDIT : I’ve tried :
- without "-r 30 -vsync drop"
- without "-c:v copy"
No changes...
EDIT2 (some ffprobe outputs) :
ffprobe 1472343170-1.webm
ffprobe version 2.8.6-1ubuntu2 Copyright (c) 2007-2016 the FFmpeg developers
built with gcc 5.3.1 (Ubuntu 5.3.1-11ubuntu1) 20160311
configuration: --prefix=/usr --extra-version=1ubuntu2 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv
libavutil 54. 31.100 / 54. 31.100
libavcodec 56. 60.100 / 56. 60.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 40.101 / 5. 40.101
libavresample 2. 1. 0 / 2. 1. 0
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
Input #0, matroska,webm, from '1472343170-1.webm':
Metadata:
encoder : Chrome
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0(eng): Video: vp8, yuv420p, 1280x760, SAR 1:1 DAR 32:19, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)ffprobe 1472343245-16.webm
ffprobe version 2.8.6-1ubuntu2 Copyright (c) 2007-2016 the FFmpeg developers
built with gcc 5.3.1 (Ubuntu 5.3.1-11ubuntu1) 20160311
configuration: --prefix=/usr --extra-version=1ubuntu2 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv
libavutil 54. 31.100 / 54. 31.100
libavcodec 56. 60.100 / 56. 60.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 40.101 / 5. 40.101
libavresample 2. 1. 0 / 2. 1. 0
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
Input #0, matroska,webm, from '1472343245-16.webm':
Metadata:
encoder : Chrome
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0(eng): Video: vp8, yuv420p, 1280x760, SAR 1:1 DAR 32:19, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)ffprobe 1472343350-37.webm
ffprobe version 2.8.6-1ubuntu2 Copyright (c) 2007-2016 the FFmpeg developers
built with gcc 5.3.1 (Ubuntu 5.3.1-11ubuntu1) 20160311
configuration: --prefix=/usr --extra-version=1ubuntu2 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv
libavutil 54. 31.100 / 54. 31.100
libavcodec 56. 60.100 / 56. 60.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 40.101 / 5. 40.101
libavresample 2. 1. 0 / 2. 1. 0
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
Input #0, matroska,webm, from '1472343350-37.webm':
Metadata:
encoder : Chrome
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0(eng): Video: vp8, yuv420p, 1280x760, SAR 1:1 DAR 32:19, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)I also noticed that the merged video plays normal when the mouse is moving around on the screen, but when the mouse is not moving, it moves 5x faster.
I know this because I have a timer on the screen that I’m recording, and I can see that the timer speeds up significantly when mouse isn’t moving but when mouse is moving, the timer moves at normal speed.
EDIT3 :
The DTS/PTS looks like resets after each file is merged :DTS -9223363446915256, next:6866667 st:0 invalid dropping
PTS -9223363446915256, next:6866667 invalid dropping st:0
DTS -9223363446915222, next:6900000 st:0 invalid dropping
PTS -9223363446915222, next:6900000 invalid dropping st:0
DTS -9223363446915188, next:6933333 st:0 invalid dropping
PTS -9223363446915188, next:6933333 invalid dropping st:0
[concat @ 0x1cde3e0] DTS -9223363446920184 < 5006 out of order
DTS -9223363446920184, next:5033333 st:0 invalid dropping
PTS -9223363446920184, next:5033333 invalid dropping st:0
DTS -9223363446920056, next:5066667 st:0 invalid dropping
PTS -9223363446920056, next:5066667 invalid dropping st:0
DTS -9223363446919956, next:5100000 st:0 invalid dropping
PTS -9223363446919956, next:5100000 invalid dropping st:0EDIT4 : Tried ffmpeg -i "$f" -y -c copy -fflags +genpts "$f" and then merge again.
Works a lot better, but now other files are getting skipped.
Here’s ffprobe from a file that’s skipped :
Metadata:
encoder : Lavf56.40.101
Duration: 00:00:01.17, start: 0.000000, bitrate: 428 kb/s
Stream #0:0(eng): Video: vp8, yuv420p, 1280x760, SAR 1:1 DAR 32:19, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
[webm @ 0x1c01940] Codec for stream 0 does not use global headers but container format requires global headers
Output #0, webm, to '1472343225-12.webm':
Metadata:
encoder : Lavf56.40.101
Stream #0:0(eng): Video: vp8, yuv420p, 1280x760 [SAR 1:1 DAR 32:19], q=2-31, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
Stream mapping:
Stream #0:0 -> #0:0 (copy)Here’s ffprobe from a file not skipped :
Input #0, matroska,webm, from '1472343215-10.webm':
Metadata:
encoder : Lavf56.40.101
Duration: 00:00:05.03, start: 0.000000, bitrate: 80 kb/s
Stream #0:0(eng): Video: vp8, yuv420p, 1280x760, SAR 1:1 DAR 32:19, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
[webm @ 0x1349940] Codec for stream 0 does not use global headers but container format requires global headers
Output #0, webm, to '1472343215-10.webm':
Metadata:
encoder : Lavf56.40.101
Stream #0:0(eng): Video: vp8, yuv420p, 1280x760 [SAR 1:1 DAR 32:19], q=2-31, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
Stream mapping:
Stream #0:0 -> #0:0 (copy) -
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;
} -
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 !