首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

LAV Filter 源代码分析 三: LAV Video (1)

2013-10-28 
LAV Filter 源代码分析 3: LAV Video (1)LAV Video 是使用很广泛的DirectShow Filter。它封装了FFMPEG中的l

LAV Filter 源代码分析 3: LAV Video (1)

LAV Video 是使用很广泛的DirectShow Filter。它封装了FFMPEG中的libavcodec,支持十分广泛的视频格式的解码。在这里对其源代码进行详细的分析。

LAV Video 工程代码的结构如下图所示

LAV Filter 源代码分析 三: LAV Video (1)

直接看LAV Video最主要的类CLAVVideo吧,它的定义位于LAVVideo.h中。

LAVVideo.h

//包含了对进程的各种操作DWORD CDecodeThread::ThreadProc(){  HRESULT hr;  DWORD cmd;  BOOL bEOS = FALSE;  BOOL bReinit = FALSE;  SetThreadName(-1, "LAVVideo Decode Thread");  HANDLE hWaitEvents[2] = { GetRequestHandle(), m_evInput };  //不停转圈,永不休止  while(1) {    if (!bEOS && !bReinit) {      // Wait for either an input sample, or an request      WaitForMultipleObjects(2, hWaitEvents, FALSE, INFINITE);    }//根据操作命令的不同    if (CheckRequest(&cmd)) {      switch (cmd) {  //创建解码器      case CMD_CREATE_DECODER:        {          CAutoLock lock(&m_ThreadCritSec);  //创建          hr = CreateDecoderInternal(m_ThreadCallContext.pmt, m_ThreadCallContext.codec);          Reply(hr);          m_ThreadCallContext.pmt = NULL;        }        break;      case CMD_CLOSE_DECODER:        {//关闭          ClearQueues();          SAFE_DELETE(m_pDecoder);          Reply(S_OK);        }        break;      case CMD_FLUSH:        {//清楚          ClearQueues();          m_pDecoder->Flush();          Reply(S_OK);        }        break;      case CMD_EOS:        {          bEOS = TRUE;          m_evEOSDone.Reset();          Reply(S_OK);        }        break;      case CMD_EXIT:        {//退出          Reply(S_OK);          return 0;        }        break;      case CMD_INIT_ALLOCATOR:        {          CAutoLock lock(&m_ThreadCritSec);          hr = m_pDecoder->InitAllocator(m_ThreadCallContext.allocator);          Reply(hr);          m_ThreadCallContext.allocator = NULL;        }        break;      case CMD_POST_CONNECT:        {          CAutoLock lock(&m_ThreadCritSec);          hr = PostConnectInternal(m_ThreadCallContext.pin);          Reply(hr);          m_ThreadCallContext.pin = NULL;        }        break;      case CMD_REINIT:        {//重启          CMediaType &mt = m_pLAVVideo->GetInputMediaType();          CreateDecoderInternal(&mt, m_Codec);          m_TempSample[1] = m_NextSample;          m_NextSample = m_FailedSample;          m_FailedSample = NULL;          bReinit = TRUE;          m_evEOSDone.Reset();          Reply(S_OK);          m_bDecoderNeedsReInit = FALSE;        }        break;      default:        ASSERT(0);      }    }    if (m_bDecoderNeedsReInit) {      m_evInput.Reset();      continue;    }    if (bReinit && !m_NextSample) {      if (m_TempSample[0]) {        m_NextSample = m_TempSample[0];        m_TempSample[0] = NULL;      } else if (m_TempSample[1]) {        m_NextSample = m_TempSample[1];        m_TempSample[1] = NULL;      } else {        bReinit = FALSE;        m_evEOSDone.Set();        m_evSample.Set();        continue;      }    }//获得一份数据    IMediaSample *pSample = GetSample();    if (!pSample) {      // Process the EOS now that the sample queue is empty      if (bEOS) {        bEOS = FALSE;        m_pDecoder->EndOfStream();        m_evEOSDone.Set();        m_evSample.Set();      }      continue;    }//解码    DecodeInternal(pSample);    // Release the sample//释放    SafeRelease(&pSample);    // Indicates we're done decoding this sample    m_evDecodeDone.Set();    // Set the Sample Event to unblock any waiting threads    m_evSample.Set();  }  return 0;}

先分析到这里了,至于ILAVDecoder接口方面的东西下篇文章再写。






热点排行