forked from mia/Aegisub
Mostly convert yuv4mpeg.cpp -- a little bit of parsing is left which I will take care of shortly.
Originally committed to SVN as r5341.
This commit is contained in:
parent
3522c0b4bd
commit
106b331cb0
3 changed files with 44 additions and 43 deletions
|
@ -24,9 +24,6 @@ endif
|
||||||
|
|
||||||
|
|
||||||
SRC = \
|
SRC = \
|
||||||
common/audio_manager.cpp \
|
|
||||||
common/video_frame.cpp \
|
|
||||||
common/video_manager.cpp \
|
|
||||||
audio/downmix.cpp \
|
audio/downmix.cpp \
|
||||||
audio/convert.cpp \
|
audio/convert.cpp \
|
||||||
audio/dummy_audio.cpp \
|
audio/dummy_audio.cpp \
|
||||||
|
@ -34,6 +31,10 @@ SRC = \
|
||||||
cache/audio_ram.cpp \
|
cache/audio_ram.cpp \
|
||||||
cache/audio_hd.cpp \
|
cache/audio_hd.cpp \
|
||||||
cache/video_cache.cpp \
|
cache/video_cache.cpp \
|
||||||
|
common/audio_manager.cpp \
|
||||||
|
common/video_frame.cpp \
|
||||||
|
common/video_manager.cpp \
|
||||||
|
video/yuv4mpeg.cpp \
|
||||||
$(SRC_OPT)
|
$(SRC_OPT)
|
||||||
|
|
||||||
HEADERS = \
|
HEADERS = \
|
||||||
|
|
|
@ -37,10 +37,9 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <libaegisub/log.h>
|
#include <libaegisub/log.h>
|
||||||
|
#include <libaegisub/util.h>
|
||||||
|
|
||||||
#include "compat.h"
|
#include "yuv4mpeg.h"
|
||||||
#include "utils.h"
|
|
||||||
#include "video_provider_yuv4mpeg.h"
|
|
||||||
|
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ namespace media {
|
||||||
|
|
||||||
/// @brief Constructor
|
/// @brief Constructor
|
||||||
/// @param filename The filename to open
|
/// @param filename The filename to open
|
||||||
YUV4MPEGVideoProvider::YUV4MPEGVideoProvider(wxString fname)
|
YUV4MPEGVideoProvider::YUV4MPEGVideoProvider(std::string filename)
|
||||||
: sf(NULL)
|
: sf(NULL)
|
||||||
, inited(false)
|
, inited(false)
|
||||||
, w (0)
|
, w (0)
|
||||||
|
@ -69,15 +68,14 @@ YUV4MPEGVideoProvider::YUV4MPEGVideoProvider(wxString fname)
|
||||||
fps_rat.den = 1;
|
fps_rat.den = 1;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
wxString filename = wxFileName(fname).GetShortPath();
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
sf = _wfopen(filename.wc_str(), L"rb");
|
sf = _wfopen(filename.c_str(), L"rb");
|
||||||
#else
|
#else
|
||||||
sf = fopen(filename.utf8_str(), "rb");
|
sf = fopen(filename.c_str(), "rb");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sf == NULL) throw agi::FileNotFoundError(STD_STR(fname));
|
if (sf == NULL) throw agi::FileNotFoundError(filename);
|
||||||
|
|
||||||
CheckFileFormat();
|
CheckFileFormat();
|
||||||
|
|
||||||
|
@ -145,15 +143,15 @@ void YUV4MPEGVideoProvider::CheckFileFormat() {
|
||||||
/// @param startpos The byte offset at where to start reading
|
/// @param startpos The byte offset at where to start reading
|
||||||
/// @param reset_pos If true, the function will reset the file position to what it was before the function call before returning
|
/// @param reset_pos If true, the function will reset the file position to what it was before the function call before returning
|
||||||
/// @return A list of parameters
|
/// @return A list of parameters
|
||||||
std::vector<wxString> YUV4MPEGVideoProvider::ReadHeader(int64_t startpos, bool reset_pos) {
|
std::vector<std::string> YUV4MPEGVideoProvider::ReadHeader(int64_t startpos, bool reset_pos) {
|
||||||
int64_t oldpos = ftello(sf);
|
int64_t oldpos = ftello(sf);
|
||||||
std::vector<wxString> tags;
|
std::vector<std::string> tags;
|
||||||
wxString curtag;
|
std::string curtag;
|
||||||
int bytesread = 0;
|
int bytesread = 0;
|
||||||
int buf;
|
int buf;
|
||||||
|
|
||||||
if (fseeko(sf, startpos, SEEK_SET))
|
if (fseeko(sf, startpos, SEEK_SET))
|
||||||
throw VideoOpenError(STD_STR(wxString::Format(L"YUV4MPEG video provider: ReadHeader: failed seeking to position %d", startpos)));
|
throw VideoOpenError("YUV4MPEG video provider: ReadHeader: failed seeking to position %d"); //XXX:, startpos)));
|
||||||
|
|
||||||
// read header until terminating newline (0x0A) is found
|
// read header until terminating newline (0x0A) is found
|
||||||
while ((buf = fgetc(sf)) != 0x0A) {
|
while ((buf = fgetc(sf)) != 0x0A) {
|
||||||
|
@ -175,16 +173,16 @@ std::vector<wxString> YUV4MPEGVideoProvider::ReadHeader(int64_t startpos, bool r
|
||||||
// found a new tag
|
// found a new tag
|
||||||
if (buf == 0x20) {
|
if (buf == 0x20) {
|
||||||
tags.push_back(curtag);
|
tags.push_back(curtag);
|
||||||
curtag.Clear();
|
curtag.clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
curtag.Append(static_cast<wxChar>(buf));
|
curtag.append((const char*)buf);
|
||||||
}
|
}
|
||||||
// if only one tag with no trailing space was found (possible in the
|
// if only one tag with no trailing space was found (possible in the
|
||||||
// FRAME header case), make sure we get it
|
// FRAME header case), make sure we get it
|
||||||
if (!curtag.IsEmpty()) {
|
if (!curtag.empty()) {
|
||||||
tags.push_back(curtag);
|
tags.push_back(curtag);
|
||||||
curtag.Clear();
|
curtag.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reset_pos)
|
if (reset_pos)
|
||||||
|
@ -193,12 +191,14 @@ std::vector<wxString> YUV4MPEGVideoProvider::ReadHeader(int64_t startpos, bool r
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Parses a list of parameters and sets reader state accordingly
|
/// @brief Parses a list of parameters and sets reader state accordingly
|
||||||
/// @param tags The list of parameters to parse
|
/// @param tags The list of parameters to parse
|
||||||
void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector<wxString>& tags) {
|
void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector<std::string>& tags) {
|
||||||
if (tags.size() <= 1)
|
if (tags.size() <= 1)
|
||||||
throw VideoOpenError("ParseFileHeader: contentless header");
|
throw VideoOpenError("ParseFileHeader: contentless header");
|
||||||
if (tags.front().Cmp("YUV4MPEG2"))
|
if (tags.front() == "YUV4MPEG2")
|
||||||
throw VideoOpenError("ParseFileHeader: malformed header (bad magic)");
|
throw VideoOpenError("ParseFileHeader: malformed header (bad magic)");
|
||||||
|
|
||||||
// temporary stuff
|
// temporary stuff
|
||||||
|
@ -210,11 +210,12 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector<wxString>& tags) {
|
||||||
Y4M_PixelFormat t_pixfmt = Y4M_PIXFMT_NONE;
|
Y4M_PixelFormat t_pixfmt = Y4M_PIXFMT_NONE;
|
||||||
|
|
||||||
for (unsigned i = 1; i < tags.size(); i++) {
|
for (unsigned i = 1; i < tags.size(); i++) {
|
||||||
wxString tag;
|
std::string tag;
|
||||||
long tmp_long1 = 0;
|
long tmp_long1 = 0;
|
||||||
long tmp_long2 = 0;
|
long tmp_long2 = 0;
|
||||||
|
|
||||||
if (tags[i].StartsWith("W", &tag)) {
|
if (tags.find("W") == 0) {
|
||||||
|
tags.erase(0,1);
|
||||||
if (!tag.ToLong(&tmp_long1))
|
if (!tag.ToLong(&tmp_long1))
|
||||||
throw VideoOpenError("ParseFileHeader: invalid width");
|
throw VideoOpenError("ParseFileHeader: invalid width");
|
||||||
t_w = (int)tmp_long1;
|
t_w = (int)tmp_long1;
|
||||||
|
@ -233,7 +234,7 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector<wxString>& tags) {
|
||||||
else if (tags[i].StartsWith("C", &tag)) {
|
else if (tags[i].StartsWith("C", &tag)) {
|
||||||
// technically this should probably be case sensitive,
|
// technically this should probably be case sensitive,
|
||||||
// but being liberal in what you accept doesn't hurt
|
// but being liberal in what you accept doesn't hurt
|
||||||
tag.MakeLower();
|
agi::util::str_lower(tag);
|
||||||
if (tag == "420") t_pixfmt = Y4M_PIXFMT_420JPEG; // is this really correct?
|
if (tag == "420") t_pixfmt = Y4M_PIXFMT_420JPEG; // is this really correct?
|
||||||
else if (tag == "420jpeg") t_pixfmt = Y4M_PIXFMT_420JPEG;
|
else if (tag == "420jpeg") t_pixfmt = Y4M_PIXFMT_420JPEG;
|
||||||
else if (tag == "420mpeg2") t_pixfmt = Y4M_PIXFMT_420MPEG2;
|
else if (tag == "420mpeg2") t_pixfmt = Y4M_PIXFMT_420MPEG2;
|
||||||
|
@ -247,7 +248,7 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector<wxString>& tags) {
|
||||||
throw VideoOpenError("ParseFileHeader: invalid or unknown colorspace");
|
throw VideoOpenError("ParseFileHeader: invalid or unknown colorspace");
|
||||||
}
|
}
|
||||||
else if (tags[i].StartsWith("I", &tag)) {
|
else if (tags[i].StartsWith("I", &tag)) {
|
||||||
tag.MakeLower();
|
agi::util::str_lower(tag);
|
||||||
if (tag == "p") t_imode = Y4M_ILACE_PROGRESSIVE;
|
if (tag == "p") t_imode = Y4M_ILACE_PROGRESSIVE;
|
||||||
else if (tag == "t") t_imode = Y4M_ILACE_TFF;
|
else if (tag == "t") t_imode = Y4M_ILACE_TFF;
|
||||||
else if (tag == "b") t_imode = Y4M_ILACE_BFF;
|
else if (tag == "b") t_imode = Y4M_ILACE_BFF;
|
||||||
|
@ -292,8 +293,8 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector<wxString>& tags) {
|
||||||
/// @param tags The list of parameters to parse
|
/// @param tags The list of parameters to parse
|
||||||
/// @return The flags set, as a binary mask
|
/// @return The flags set, as a binary mask
|
||||||
/// This function is currently unimplemented (it will always return Y4M_FFLAG_NONE).
|
/// This function is currently unimplemented (it will always return Y4M_FFLAG_NONE).
|
||||||
YUV4MPEGVideoProvider::Y4M_FrameFlags YUV4MPEGVideoProvider::ParseFrameHeader(const std::vector<wxString>& tags) {
|
YUV4MPEGVideoProvider::Y4M_FrameFlags YUV4MPEGVideoProvider::ParseFrameHeader(const std::vector<std::string>& tags) {
|
||||||
if (tags.front().Cmp(_("FRAME")))
|
if (tags.front() == "FRAME")
|
||||||
throw VideoOpenError("ParseFrameHeader: malformed frame header (bad magic)");
|
throw VideoOpenError("ParseFrameHeader: malformed frame header (bad magic)");
|
||||||
|
|
||||||
/// @todo implement parsing of frame flags
|
/// @todo implement parsing of frame flags
|
||||||
|
@ -315,18 +316,18 @@ int YUV4MPEGVideoProvider::IndexFile() {
|
||||||
while (true) {
|
while (true) {
|
||||||
curpos = ftello(sf); // update position
|
curpos = ftello(sf); // update position
|
||||||
// continue reading headers until no more are found
|
// continue reading headers until no more are found
|
||||||
std::vector<wxString> tags = ReadHeader(curpos, false);
|
std::vector<std::string> tags = ReadHeader(curpos, false);
|
||||||
curpos = ftello(sf);
|
curpos = ftello(sf);
|
||||||
|
|
||||||
if (tags.empty())
|
if (tags.empty())
|
||||||
break; // no more headers
|
break; // no more headers
|
||||||
|
|
||||||
Y4M_FrameFlags flags = Y4M_FFLAG_NOTSET;
|
Y4M_FrameFlags flags = Y4M_FFLAG_NOTSET;
|
||||||
if (!tags.front().Cmp("YUV4MPEG2")) {
|
if (tags.front() != "YUV4MPEG2") {
|
||||||
ParseFileHeader(tags);
|
ParseFileHeader(tags);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (!tags.front().Cmp("FRAME"))
|
else if (tags.front() != "FRAME")
|
||||||
flags = ParseFrameHeader(tags);
|
flags = ParseFrameHeader(tags);
|
||||||
|
|
||||||
if (flags == Y4M_FFLAG_NONE) {
|
if (flags == Y4M_FFLAG_NONE) {
|
||||||
|
@ -334,7 +335,7 @@ int YUV4MPEGVideoProvider::IndexFile() {
|
||||||
seek_table.push_back(curpos);
|
seek_table.push_back(curpos);
|
||||||
// seek to next frame header start position
|
// seek to next frame header start position
|
||||||
if (fseeko(sf, frame_sz, SEEK_CUR))
|
if (fseeko(sf, frame_sz, SEEK_CUR))
|
||||||
throw VideoOpenError(STD_STR(wxString::Format("IndexFile: failed seeking to position %d", curpos + frame_sz)));
|
throw VideoOpenError("IndexFile: failed seeking to position %d"); //XXX: , curpos + frame_sz)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/// @todo implement rff flags etc
|
/// @todo implement rff flags etc
|
||||||
|
@ -345,7 +346,7 @@ int YUV4MPEGVideoProvider::IndexFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://bob.allegronetwork.com/prog/tricks.html#clamp
|
// http://bob.allegronetwork.com/prog/tricks.html#clamp
|
||||||
static FORCEINLINE int clamp(int x) {
|
static inline int clamp(int x) {
|
||||||
x &= (~x) >> 31;
|
x &= (~x) >> 31;
|
||||||
x -= 255;
|
x -= 255;
|
||||||
x &= x >> 31;
|
x &= x >> 31;
|
||||||
|
@ -357,7 +358,7 @@ static FORCEINLINE int clamp(int x) {
|
||||||
/// @param n The frame number to return
|
/// @param n The frame number to return
|
||||||
/// @return The video frame
|
/// @return The video frame
|
||||||
const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n) {
|
const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n) {
|
||||||
cur_fn = mid(0, n, num_frames - 1);
|
cur_fn = agi::util::mid(0, n, num_frames - 1);
|
||||||
|
|
||||||
int uv_width = w / 2;
|
int uv_width = w / 2;
|
||||||
switch (pixfmt) {
|
switch (pixfmt) {
|
||||||
|
|
|
@ -34,16 +34,15 @@
|
||||||
/// @ingroup video_input
|
/// @ingroup video_input
|
||||||
///
|
///
|
||||||
|
|
||||||
#include "include/aegisub/video_provider.h"
|
|
||||||
#ifndef AGI_PRE
|
#ifndef MAGI_PRE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <wx/filename.h>
|
|
||||||
#include <wx/log.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "libmedia/video.h"
|
||||||
|
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
/// the maximum allowed header length, in bytes
|
/// the maximum allowed header length, in bytes
|
||||||
|
@ -134,13 +133,13 @@ class YUV4MPEGVideoProvider : public VideoProvider {
|
||||||
std::vector<int64_t> seek_table;
|
std::vector<int64_t> seek_table;
|
||||||
|
|
||||||
void CheckFileFormat();
|
void CheckFileFormat();
|
||||||
void ParseFileHeader(const std::vector<wxString>& tags);
|
void ParseFileHeader(const std::vector<std::string>& tags);
|
||||||
Y4M_FrameFlags ParseFrameHeader(const std::vector<wxString>& tags);
|
Y4M_FrameFlags ParseFrameHeader(const std::vector<std::string>& tags);
|
||||||
std::vector<wxString> ReadHeader(int64_t startpos, bool reset_pos=false);
|
std::vector<std::string> ReadHeader(int64_t startpos, bool reset_pos=false);
|
||||||
int IndexFile();
|
int IndexFile();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
YUV4MPEGVideoProvider(wxString filename);
|
YUV4MPEGVideoProvider(std::string filename);
|
||||||
~YUV4MPEGVideoProvider();
|
~YUV4MPEGVideoProvider();
|
||||||
|
|
||||||
const AegiVideoFrame GetFrame(int n);
|
const AegiVideoFrame GetFrame(int n);
|
||||||
|
@ -151,7 +150,7 @@ public:
|
||||||
int GetHeight() const { return h; }
|
int GetHeight() const { return h; }
|
||||||
agi::vfr::Framerate GetFPS() const { return fps; }
|
agi::vfr::Framerate GetFPS() const { return fps; }
|
||||||
std::vector<int> GetKeyFrames() const { return std::vector<int>(); };
|
std::vector<int> GetKeyFrames() const { return std::vector<int>(); };
|
||||||
wxString GetDecoderName() const { return L"YU4MPEG"; };
|
std::string GetDecoderName() const { return "YU4MPEG"; };
|
||||||
bool WantsCaching() const { return true; };
|
bool WantsCaching() const { return true; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue