Browse Source

Basic VPX decoding for plMoviePlayer

Adam Johnson 12 years ago committed by Florian Meißner
parent
commit
2caade5fff
  1. 1
      CMakeLists.txt
  2. 4
      Sources/Plasma/Apps/plClient/CMakeLists.txt
  3. 16
      Sources/Plasma/FeatureLib/pfMoviePlayer/CMakeLists.txt
  4. 361
      Sources/Plasma/FeatureLib/pfMoviePlayer/plMoviePlayer.cpp
  5. 31
      Sources/Plasma/FeatureLib/pfMoviePlayer/plMoviePlayer.h
  6. 97
      Sources/Plasma/FeatureLib/pfMoviePlayer/plPlanarImage.cpp
  7. 53
      Sources/Plasma/FeatureLib/pfMoviePlayer/plPlanarImage.h
  8. 9371
      Sources/Plasma/FeatureLib/pfMoviePlayer/webm/mkvparser.cpp
  9. 1044
      Sources/Plasma/FeatureLib/pfMoviePlayer/webm/mkvparser.hpp
  10. 128
      Sources/Plasma/FeatureLib/pfMoviePlayer/webm/mkvreader.cpp
  11. 39
      Sources/Plasma/FeatureLib/pfMoviePlayer/webm/mkvreader.hpp
  12. 18
      cmake/FindVPX.cmake

1
CMakeLists.txt

@ -41,6 +41,7 @@ find_package(PNG REQUIRED)
find_package(Ogg REQUIRED) #TODO: Not required if we aren't building the client
find_package(Vorbis REQUIRED) #TODO: Not required if we aren't building the client
find_package(Speex REQUIRED) #TODO: Not required if we aren't building the client
find_package(VPX)
find_package(CURL REQUIRED)
find_package(Freetype)

4
Sources/Plasma/Apps/plClient/CMakeLists.txt

@ -166,6 +166,10 @@ if(USE_VLD)
target_link_libraries(plClient ${VLD_LIBRARY})
endif()
if (VPX_AVAILABLE)
target_link_libraries(plClient ${VPX_LIBRARY})
endif (VPX_AVAILABLE)
if (WIN32)
target_link_libraries(plClient rpcrt4)
target_link_libraries(plClient version)

16
Sources/Plasma/FeatureLib/pfMoviePlayer/CMakeLists.txt

@ -3,15 +3,29 @@ include_directories(../../NucleusLib)
include_directories(../../NucleusLib/inc)
include_directories(../../PubUtilLib)
if (VPX_AVAILABLE)
include_directories(${VPX_INCLUDE_DIR})
endif (VPX_AVAILABLE)
set(pfMoviePlayer_SOURCES
plMoviePlayer.cpp
plPlanarImage.cpp
)
set(pfMoviePlayer_HEADERS
plMoviePlayer.h
plPlanarImage.h
)
set(pfMoviePlayer_WEBM
webm/mkvparser.cpp
webm/mkvparser.hpp
webm/mkvreader.cpp
webm/mkvreader.hpp
)
add_library(pfMoviePlayer STATIC ${pfMoviePlayer_SOURCES} ${pfMoviePlayer_HEADERS})
add_library(pfMoviePlayer STATIC ${pfMoviePlayer_SOURCES} ${pfMoviePlayer_HEADERS} ${pfMoviePlayer_WEBM})
source_group("Source Files" FILES ${pfMoviePlayer_SOURCES})
source_group("Header Files" FILES ${pfMoviePlayer_HEADERS})
source_group("WebM" FILES ${pfMoviePlayer_WEBM})

361
Sources/Plasma/FeatureLib/pfMoviePlayer/plMoviePlayer.cpp

@ -41,22 +41,379 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
*==LICENSE==*/
#include "plMoviePlayer.h"
#include <tuple>
#ifdef VPX_AVAILABLE
# define VPX_CODEC_DISABLE_COMPAT 1
# include <vpx/vpx_decoder.h>
# include <vpx/vp8dx.h>
# define iface (vpx_codec_vp8_dx())
#endif
#include "plGImage/plMipmap.h"
#include "pnKeyedObject/plUoid.h"
#include "plPipeline/hsGDeviceRef.h"
#include "plPipeline/plPlates.h"
#include "plPlanarImage.h"
#include "hsResMgr.h"
#include "hsTimer.h"
#include "webm/mkvreader.hpp"
#include "webm/mkvparser.hpp"
#define SAFE_OP(x, err) \
{ \
int64_t ret = 0; \
ret = x; \
if (ret == -1) \
{ \
hsAssert(false, "failed to " err); \
return false; \
} \
}
// =====================================================
class VPX
{
VPX() { }
public:
vpx_codec_ctx_t codec;
~VPX() {
if (vpx_codec_destroy(&codec))
hsAssert(false, vpx_codec_error_detail(&codec));
}
static VPX* Create()
{
VPX* instance = new VPX;
if(vpx_codec_dec_init(&instance->codec, iface, nullptr, 0))
{
hsAssert(false, vpx_codec_error_detail(&instance->codec));
return nullptr;
}
return instance;
}
vpx_image_t* Decode(uint8_t* buf, uint32_t size)
{
if (vpx_codec_decode(&codec, buf, size, nullptr, 0) != VPX_CODEC_OK)
{
const char* detail = vpx_codec_error_detail(&codec);
hsAssert(false, detail ? detail : "unspecified decode error");
return nullptr;
}
vpx_codec_iter_t iter = nullptr;
// ASSUMPTION: only one image per frame
// if this proves false, move decoder function into IProcessVideoFrame
return vpx_codec_get_frame(&codec, &iter);
}
};
// =====================================================
class TrackMgr
{
const mkvparser::BlockEntry* blk_entry;
bool valid;
bool PeekNextBlockEntry(const std::unique_ptr<mkvparser::Segment>& segment)
{
// Assume that if blk_entry == nullptr, we need to start from the beginning
const mkvparser::Cluster* cluster;
if (blk_entry)
cluster = blk_entry->GetCluster();
else
cluster = segment->GetFirst();
while (true)
{
if (cluster->EOS())
{
cluster = segment->GetNext(cluster);
blk_entry = nullptr;
if (!cluster)
return false;
}
if (blk_entry)
{
SAFE_OP(cluster->GetNext(blk_entry, blk_entry), "get next block");
}
else
{
SAFE_OP(cluster->GetFirst(blk_entry), "get first block");
}
if (blk_entry)
{
if (blk_entry->EOS())
continue;
if (blk_entry->GetBlock()->GetTrackNumber() == number)
return true;
}
}
return false; // if this happens, boom.
}
public:
uint32_t number;
TrackMgr(uint32_t num) : blk_entry(nullptr), valid(true), number(num) { }
bool GetFrames(plMoviePlayer* p, int64_t movieTime, std::vector<blkbuf_t>& frames)
{
if (!valid)
return false;
const mkvparser::BlockEntry* prev = blk_entry;
while ((valid = PeekNextBlockEntry(p->fSegment)))
{
const mkvparser::Block* blk = blk_entry->GetBlock();
if (blk->GetTime(blk_entry->GetCluster()) <= movieTime)
{
frames.reserve(frames.size() + blk->GetFrameCount());
for (int32_t i = 0; i < blk->GetFrameCount(); ++i)
{
const mkvparser::Block::Frame data = blk->GetFrame(i);
uint8_t* buf = new uint8_t[data.len];
data.Read(p->fReader, buf);
frames.push_back(std::make_tuple(std::unique_ptr<uint8_t>(buf), static_cast<int32_t>(data.len)));
}
} else
{
blk_entry = prev;
return true;
}
prev = blk_entry;
}
return true;
}
#if 0
bool Advance(plMoviePlayer* p, int64_t movieTime=0)
{
if (!valid)
return false;
// This keeps us from getting behind due to freezes
// Assumption: Audio will not skip ahead in time. FIXME?
while ((valid = PeekNextBlockEntry(p->fSegment)))
{
const mkvparser::Block* blk = blk_entry->GetBlock();
if (blk->GetTime(blk_entry->GetCluster()) < movieTime)
continue;
else
return true;
}
return false; // ran out of blocks
}
int32_t GetBlockData(plMoviePlayer* p, std::vector<blkbuf_t>& frames) const
{
const mkvparser::Block* block = blk_entry->GetBlock();
// Return the frames
frames.reserve(block->GetFrameCount());
for (int32_t i = 0; i < block->GetFrameCount(); ++i)
{
const mkvparser::Block::Frame frame = block->GetFrame(i);
std::shared_ptr<uint8_t> data(new uint8_t[frame.len]);
frame.Read(p->fReader, data.get());
frames.push_back(std::make_tuple(data, frame.len));
}
return block->GetFrameCount();
}
#endif 0
};
// =====================================================
plMoviePlayer::plMoviePlayer() :
fTimeScale(0),
fStartTime(0)
fPlate(nullptr),
fTexture(nullptr),
fReader(nullptr),
fTimeScale(0),
fStartTime(0)
{
fScale.Set(1.0f, 1.0f);
}
plMoviePlayer::~plMoviePlayer()
{
if (fPlate)
// The plPlate owns the Mipmap Texture, so it destroys it for us
plPlateManager::Instance().DestroyPlate(fPlate);
#ifdef VPX_AVAILABLE
if (fReader)
fReader->Close();
#endif
}
int64_t plMoviePlayer::GetMovieTime() const
{
return ((int64_t) hsTimer::GetSeconds() * fTimeScale) - fStartTime;
}
bool plMoviePlayer::IOpenMovie()
{
#ifdef VPX_AVAILABLE
if (!plFileInfo(fMoviePath).Exists())
{
hsAssert(false, "Tried to play a movie that doesn't exist");
return false;
}
// open the movie with libwebm
fReader = new mkvparser::MkvReader;
SAFE_OP(fReader->Open(fMoviePath.AsString().c_str()), "open movie");
// opens the segment
// it contains everything you ever want to know about the movie
long long pos = 0;
mkvparser::EBMLHeader ebmlHeader;
ebmlHeader.Parse(fReader, pos);
mkvparser::Segment* seg;
SAFE_OP(mkvparser::Segment::CreateInstance(fReader, pos, seg), "get segment info");
SAFE_OP(seg->Load(), "load segment from webm");
fSegment.reset(seg);
// Just in case someone gives us a weird file, find out the timecode offset
fTimeScale = fSegment->GetInfo()->GetTimeCodeScale();
// TODO: Figure out video and audio based on current language
// For now... just take the first one.
const mkvparser::Tracks* tracks = fSegment->GetTracks();
for (uint32_t i = 0; i < tracks->GetTracksCount(); ++i)
{
const mkvparser::Track* track = tracks->GetTrackByIndex(i);
if (!track)
continue;
switch (track->GetType())
{
case mkvparser::Track::kAudio:
{
if (!fAudioTrack)
fAudioTrack.reset(new TrackMgr(track->GetNumber()));
break;
}
case mkvparser::Track::kVideo:
{
if (!fVideoTrack)
fVideoTrack.reset(new TrackMgr(track->GetNumber()));
break;
}
}
}
return true;
#else
return false;
#endif
}
bool plMoviePlayer::IProcessVideoFrame(const std::vector<blkbuf_t>& frames)
{
vpx_image_t* img = nullptr;
// We have to decode all the frames, but we only want to display the most recent one to the user.
for (auto it = frames.begin(); it != frames.end(); ++it)
{
const std::unique_ptr<uint8_t>& buf = std::get<0>(*it);
int32_t size = std::get<1>(*it);
img = fVpx->Decode(buf.get(), static_cast<uint32_t>(size));
}
if (img)
{
// According to VideoLAN[1], I420 is the most common image format in videos. I am inclined to believe this as our
// attemps to convert the common Uru videos use I420 image data. So, as a shortcut, we will only implement that format.
// If for some reason we need other formats, please, be my guest!
// [1] = http://wiki.videolan.org/YUV#YUV_4:2:0_.28I420.2FJ420.2FYV12.29
switch (img->fmt)
{
case VPX_IMG_FMT_I420:
plPlanarImage::Yuv420ToRgba(img->d_w, img->d_h, img->stride, img->planes, reinterpret_cast<uint8_t*>(fTexture->GetImage()));
break;
DEFAULT_FATAL("image format");
}
// Flush new data to the device
if (fTexture->GetDeviceRef())
fTexture->GetDeviceRef()->SetDirty(true);
return true;
}
return false;
}
bool plMoviePlayer::Start()
{
#ifdef VPX_AVAILABLE
if (!IOpenMovie())
return false;
hsAssert(fVideoTrack, "nil video track -- expect bad things to happen!");
// Initialize VP8
if (VPX* vpx = VPX::Create())
fVpx.reset(vpx);
else
return false;
// Need to figure out scaling based on pipe size.
plPlateManager& plateMgr = plPlateManager::Instance();
const mkvparser::VideoTrack* video = static_cast<const mkvparser::VideoTrack*>(fSegment->GetTracks()->GetTrackByNumber(fVideoTrack->number));
float width = (static_cast<float>(video->GetWidth()) / static_cast<float>(plateMgr.GetPipeWidth())) * fScale.fX;
float height = (static_cast<float>(video->GetHeight()) / static_cast<float>(plateMgr.GetPipeHeight())) * fScale.fY;
plateMgr.CreatePlate(&fPlate, fPosition.fX, fPosition.fY, width, height);
fPlate->SetVisible(true);
fTexture = fPlate->CreateMaterial(static_cast<uint32_t>(video->GetWidth()), static_cast<uint32_t>(video->GetHeight()), nullptr);
return true;
#else
return false;
#endif // VPX_AVAILABLE
}
bool plMoviePlayer::NextFrame()
{
#ifdef VPX_AVAILABLE
// Get our current timecode
int64_t movieTime = 0;
if (fStartTime == 0)
fStartTime = static_cast<int64_t>((hsTimer::GetSeconds() * fTimeScale));
else
movieTime = GetMovieTime();
std::vector<blkbuf_t> audio;
std::vector<blkbuf_t> video;
{
uint8_t tracksWithData = 0;
if (fAudioTrack)
{
if (fAudioTrack->GetFrames(this, movieTime, audio))
tracksWithData++;
}
if (fVideoTrack)
{
if (fVideoTrack->GetFrames(this, movieTime, video))
tracksWithData++;
}
if (tracksWithData == 0)
return false;
}
// Show our mess
IProcessVideoFrame(video);
return true;
#else
return false;
#endif // VPX_AVAILABLE
}
bool plMoviePlayer::Stop()
{
for (int i = 0; i < fCallbacks.GetCount(); i++)

31
Sources/Plasma/FeatureLib/pfMoviePlayer/plMoviePlayer.h

@ -49,25 +49,48 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "hsColorRGBA.h"
#include "plMessage/plMovieMsg.h"
#include <memory>
#include <vector>
#include <tuple>
namespace mkvparser
{
class BlockEntry;
class MkvReader;
class Segment;
}
typedef std::tuple<std::unique_ptr<uint8_t>, int32_t> blkbuf_t;
class plMoviePlayer
{
protected:
friend class TrackMgr;
class plPlate* fPlate;
class plMipmap* fTexture;
mkvparser::MkvReader* fReader;
std::unique_ptr<mkvparser::Segment> fSegment;
std::unique_ptr<class TrackMgr> fAudioTrack, fVideoTrack; // TODO: vector of tracks?
std::unique_ptr<class VPX> fVpx;
int64_t fTimeScale, fStartTime;
hsPoint2 fPosition, fScale;
plFileName fMoviePath;
int64_t GetMovieTime() const;
bool IOpenMovie() { return false; };
bool IOpenMovie();
bool IProcessVideoFrame(const std::vector<blkbuf_t>& frames);
public:
plMoviePlayer();
~plMoviePlayer() {}
~plMoviePlayer();
bool Start() { return false; }
bool Start();
bool Pause(bool on) { return false; }
bool Stop();
bool NextFrame() { return Stop(); }
bool NextFrame();
void AddCallback(plMessage* msg) { hsRefCnt_SafeRef(msg); fCallbacks.Append(msg); }
uint32_t GetNumCallbacks() const { return 0; }

97
Sources/Plasma/FeatureLib/pfMoviePlayer/plPlanarImage.cpp

@ -0,0 +1,97 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "plPlanarImage.h"
///////////////////////////////////////////////////////////////////////////////
static uint8_t Clip(int32_t val) {
if (val < 0) {
return 0;
} else if (val > 255) {
return 255;
}
return static_cast<uint8_t>(val);
}
#define YG 74 /* static_cast<int8>(1.164 * 64 + 0.5) */
#define UB 127 /* min(63,static_cast<int8>(2.018 * 64)) */
#define UG -25 /* static_cast<int8>(-0.391 * 64 - 0.5) */
#define UR 0
#define VB 0
#define VG -52 /* static_cast<int8>(-0.813 * 64 - 0.5) */
#define VR 102 /* static_cast<int8>(1.596 * 64 + 0.5) */
// Bias
#define BB UB * 128 + VB * 128
#define BG UG * 128 + VG * 128
#define BR UR * 128 + VR * 128
void plPlanarImage::Yuv420ToRgba(uint32_t w, uint32_t h, const int32_t* stride, uint8_t** planes, uint8_t* const dest)
{
const uint8_t* y_src = planes[0];
const uint8_t* u_src = planes[1];
const uint8_t* v_src = planes[2];
for (uint32_t i = 0; i < h; ++i)
{
for (uint32_t j = 0; j < w; ++j)
{
size_t y_idx = stride[0] * i + j;
size_t u_idx = stride[1] * (i/2) + (j/2);
size_t v_idx = stride[2] * (i/2) + (j/2);
size_t dest_idx = w * i + j;
int32_t y = static_cast<int32_t>(y_src[y_idx]);
int32_t u = static_cast<int32_t>(u_src[u_idx]);
int32_t v = static_cast<int32_t>(v_src[v_idx]);
int32_t y1 = (y - 16) * YG;
dest[dest_idx*4+0] = Clip(((u * UB + v * VB) - (BB) + y1) >> 6);
dest[dest_idx*4+1] = Clip(((u * UG + v * VG) - (BG) + y1) >> 6);
dest[dest_idx*4+2] = Clip(((u * UR + v * VR) - (BR) + y1) >> 6);
dest[dest_idx*4+3] = 0xff;
}
}
}

53
Sources/Plasma/FeatureLib/pfMoviePlayer/plPlanarImage.h

@ -0,0 +1,53 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _plPlanarImage_inc
#define _plPlanarImage_inc
#include "HeadSpin.h"
namespace plPlanarImage
{
void Yuv420ToRgba(uint32_t w, uint32_t h, const int32_t* stride, uint8_t** planes, uint8_t* const dest);
};
#endif // _plPlanarImage_inc

9371
Sources/Plasma/FeatureLib/pfMoviePlayer/webm/mkvparser.cpp

File diff suppressed because it is too large Load Diff

1044
Sources/Plasma/FeatureLib/pfMoviePlayer/webm/mkvparser.hpp

File diff suppressed because it is too large Load Diff

128
Sources/Plasma/FeatureLib/pfMoviePlayer/webm/mkvreader.cpp

@ -0,0 +1,128 @@
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#include "mkvreader.hpp"
#include <cassert>
namespace mkvparser
{
MkvReader::MkvReader() :
m_file(NULL)
{
}
MkvReader::~MkvReader()
{
Close();
}
int MkvReader::Open(const char* fileName)
{
if (fileName == NULL)
return -1;
if (m_file)
return -1;
#ifdef WIN32
const errno_t e = fopen_s(&m_file, fileName, "rb");
if (e)
return -1; //error
#else
m_file = fopen(fileName, "rb");
if (m_file == NULL)
return -1;
#endif
#ifdef WIN32
int status = _fseeki64(m_file, 0L, SEEK_END);
if (status)
return -1; //error
m_length = _ftelli64(m_file);
#else
fseek(m_file, 0L, SEEK_END);
m_length = ftell(m_file);
#endif
assert(m_length >= 0);
#ifdef WIN32
status = _fseeki64(m_file, 0L, SEEK_SET);
if (status)
return -1; //error
#else
fseek(m_file, 0L, SEEK_SET);
#endif
return 0;
}
void MkvReader::Close()
{
if (m_file != NULL)
{
fclose(m_file);
m_file = NULL;
}
}
int MkvReader::Length(long long* total, long long* available)
{
if (m_file == NULL)
return -1;
if (total)
*total = m_length;
if (available)
*available = m_length;
return 0;
}
int MkvReader::Read(long long offset, long len, unsigned char* buffer)
{
if (m_file == NULL)
return -1;
if (offset < 0)
return -1;
if (len < 0)
return -1;
if (len == 0)
return 0;
if (offset >= m_length)
return -1;
#ifdef WIN32
const int status = _fseeki64(m_file, offset, SEEK_SET);
if (status)
return -1; //error
#else
fseek(m_file, offset, SEEK_SET);
#endif
const size_t size = fread(buffer, 1, len, m_file);
if (size < size_t(len))
return -1; //error
return 0; //success
}
} //end namespace mkvparser

39
Sources/Plasma/FeatureLib/pfMoviePlayer/webm/mkvreader.hpp

@ -0,0 +1,39 @@
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#ifndef MKVREADER_HPP
#define MKVREADER_HPP
#include "mkvparser.hpp"
#include <cstdio>
namespace mkvparser
{
class MkvReader : public IMkvReader
{
MkvReader(const MkvReader&);
MkvReader& operator=(const MkvReader&);
public:
MkvReader();
virtual ~MkvReader();
int Open(const char*);
void Close();
bool IsOpen() const;
virtual int Read(long long position, long length, unsigned char* buffer);
virtual int Length(long long* total, long long* available);
private:
long long m_length;
FILE* m_file;
};
} //end namespace mkvparser
#endif //MKVREADER_HPP

18
cmake/FindVPX.cmake

@ -0,0 +1,18 @@
if(VPX_INCLUDE_DIR AND VPX_LIBRARY)
set(VPX_FIND_QUIETLY TRUE)
endif()
find_path(VPX_INCLUDE_DIR vpx/vp8.h
/usr/local/include
/usr/include
)
find_library(VPX_LIBRARY NAMES vpxmt vpx
PATHS /usr/local/lib /usr/lib
)
# If everything has been found, we have movie support!
if (VPX_INCLUDE_DIR AND VPX_LIBRARY)
set(VPX_AVAILABLE TRUE)
add_definitions(-DVPX_AVAILABLE)
endif()
Loading…
Cancel
Save