You can subscribe to this list here.
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(25) |
Jul
(288) |
Aug
(119) |
Sep
(31) |
Oct
(59) |
Nov
(458) |
Dec
(359) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2010 |
Jan
(268) |
Feb
(26) |
Mar
(36) |
Apr
(48) |
May
(119) |
Jun
(37) |
Jul
(173) |
Aug
(429) |
Sep
(137) |
Oct
(156) |
Nov
(59) |
Dec
(45) |
| 2011 |
Jan
(398) |
Feb
(257) |
Mar
(49) |
Apr
(5) |
May
(34) |
Jun
(11) |
Jul
(38) |
Aug
(12) |
Sep
(1) |
Oct
(49) |
Nov
(5) |
Dec
(10) |
| 2012 |
Jan
(21) |
Feb
(32) |
Mar
(20) |
Apr
(1) |
May
(2) |
Jun
|
Jul
(173) |
Aug
|
Sep
(25) |
Oct
(6) |
Nov
(44) |
Dec
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:51:14
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Fri Jul 6 12:48:40 2012 +0300
Fix PangoCairo deprecation warning.
---
game/opengl_text.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/opengl_text.cc b/game/opengl_text.cc
index f403aeb..bb618af 100644
--- a/game/opengl_text.cc
+++ b/game/opengl_text.cc
@@ -37,7 +37,7 @@ OpenGLText::OpenGLText(TThemeTxtOpenGL& _text, double m) {
// compute text extents
{
- PangoContext* ctx = pango_cairo_font_map_create_context ((PangoCairoFontMap*)pango_cairo_font_map_get_default());
+ PangoContext* ctx = pango_font_map_create_context(pango_cairo_font_map_get_default());
PangoLayout* layout = pango_layout_new(ctx);
pango_layout_set_alignment(layout, alignment);
pango_layout_set_font_description (layout, desc);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:51:10
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Fri Jul 6 12:41:39 2012 +0300
Use premultiplied alpha
- OpenGL blending mode changed
- PNG loading with Cairo (internally converts from non-premultiplied)
- Color setting now needs to multiply R/G/B components by alpha (fixed a few cases, others remain broken)
---
game/guitargraph.cc | 4 +---
game/image.hh | 18 +++++++++++++++++-
game/notegraph.cc | 2 --
game/screen_songs.cc | 12 ++++++------
game/video_driver.cc | 4 ++--
5 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index 4339b4a..5279fbd 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -1015,9 +1015,7 @@ void GuitarGraph::draw(double time) {
if (m_neckglowColor.w > 0.0) {
// Neck glow drawing
using namespace glmath;
- double a = m_neckglowColor.w;
- vec4 color((1.0 / a) * vec3(m_neckglowColor), a); // Convert into non-premultiplied
- ColorTrans c(glmath::mat4::diagonal(color));
+ ColorTrans c(glmath::mat4::diagonal(m_neckglowColor));
m_neckglow.dimensions.screenBottom(0.0).middle().fixedWidth(neckWidth());
m_neckglow.draw();
}
diff --git a/game/image.hh b/game/image.hh
index 61dbb14..ed3ff8c 100644
--- a/game/image.hh
+++ b/game/image.hh
@@ -125,6 +125,22 @@ static inline void loadSVG(Bitmap& bitmap, std::string const& filename) {
}
static inline void loadPNG(Bitmap& bitmap, std::string const& filename) {
+ // Raster with Cairo
+ boost::shared_ptr<cairo_surface_t> surface(
+ cairo_image_surface_create_from_png(filename.c_str()),
+ cairo_surface_destroy);
+ cairo_surface_flush(surface.get());
+ unsigned char* buf = cairo_image_surface_get_data(surface.get());
+ // Prepare the pixel buffer
+ bitmap.resize(
+ cairo_image_surface_get_width(surface.get()),
+ cairo_image_surface_get_height(surface.get()));
+ bitmap.fmt = pix::INT_ARGB;
+ std::copy(buf, buf + bitmap.buf.size(), bitmap.buf.begin());
+}
+
+/*
+static inline void loadPNG(Bitmap& bitmap, std::string const& filename) {
std::ifstream file(filename.c_str(), std::ios::binary);
png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!pngPtr) throw std::runtime_error("png_create_read_struct failed");
@@ -140,7 +156,7 @@ static inline void loadPNG(Bitmap& bitmap, std::string const& filename) {
std::vector<png_bytep> rows;
loadPNG_internal(pngPtr, infoPtr, file, bitmap, rows);
}
-
+*/
struct my_jpeg_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
diff --git a/game/notegraph.cc b/game/notegraph.cc
index 6340d6c..ec9deb3 100644
--- a/game/notegraph.cc
+++ b/game/notegraph.cc
@@ -196,7 +196,6 @@ namespace {
void NoteGraph::drawWaves(Database const& database) {
if (m_vocal.notes.empty()) return; // Cannot draw without notes
UseTexture tblock(m_wave);
- //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
for (std::list<Player>::const_iterator p = database.cur.begin(); p != database.cur.end(); ++p) {
if (p->m_vocal.name != m_vocal.name)
continue;
@@ -250,6 +249,5 @@ void NoteGraph::drawWaves(Database const& database) {
}
strip(va);
}
- //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index 9dacfcf..afe23a1 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -280,7 +280,7 @@ void ScreenSongs::drawCovers() {
s.draw();
// Draw the reflection
Transform transMirror(scale(vec3(1.0f, -1.0f, 1.0f)));
- ColorTrans c2(Color(1.0f, 1.0f, 1.0f, 0.4f));
+ ColorTrans c2(Color(0.4f, 0.4f, 0.4f, 0.4f));
s.draw();
}
}
@@ -336,7 +336,7 @@ void ScreenSongs::drawInstruments(Dimensions const& dim, float alpha) const {
float a = alpha * (have_vocals ? 1.00 : 0.25);
float m = !(typeFilter & 8);
glutil::VertexArray va;
- glmath::vec4 c(m * 1.0f, 1.0f, m * (is_karaoke ? 0.25f : 1.0f), a);
+ glmath::vec4 c(m * a, a, m * (is_karaoke ? 0.25f : 1.0f) * a, a);
x = dim.x1()+0.00*(dim.x2()-dim.x1());
va.Color(c).TexCoord(getIconTex(1), 0.0f).Vertex(x, dim.y1());
va.Color(c).TexCoord(getIconTex(1), 1.0f).Vertex(x, dim.y2());
@@ -352,7 +352,7 @@ void ScreenSongs::drawInstruments(Dimensions const& dim, float alpha) const {
if (guitarCount == 0) { guitarCount = 1; a *= 0.25f; }
for (int i = guitarCount-1; i >= 0; i--) {
glutil::VertexArray va;
- glmath::vec4 c(m * 1.0f, 1.0f, m * 1.0f, a);
+ glmath::vec4 c(m * a, a, m * a, a);
x = dim.x1()+(xincr+i*0.04)*(dim.x2()-dim.x1());
va.Color(c).TexCoord(getIconTex(2), 0.0f).Vertex(x, dim.y1());
va.Color(c).TexCoord(getIconTex(2), 1.0f).Vertex(x, dim.y2());
@@ -367,7 +367,7 @@ void ScreenSongs::drawInstruments(Dimensions const& dim, float alpha) const {
float a = alpha * (have_bass ? 1.00f : 0.25f);
float m = !(typeFilter & 4);
glutil::VertexArray va;
- glmath::vec4 c(m * 1.0f, 1.0f, m * 1.0f, a);
+ glmath::vec4 c(m * a, a, m * a, a);
x = dim.x1()+2*xincr*(dim.x2()-dim.x1());
va.Color(c).TexCoord(getIconTex(3), 0.0f).Vertex(x, dim.y1());
va.Color(c).TexCoord(getIconTex(3), 1.0f).Vertex(x, dim.y2());
@@ -381,7 +381,7 @@ void ScreenSongs::drawInstruments(Dimensions const& dim, float alpha) const {
float a = alpha * (have_drums ? 1.00f : 0.25f);
float m = !(typeFilter & 2);
glutil::VertexArray va;
- glmath::vec4 c(m * 1.0f, 1.0f, m * 1.0f, a);
+ glmath::vec4 c(m * a, a, m * a, a);
x = dim.x1()+3*xincr*(dim.x2()-dim.x1());
va.Color(c).TexCoord(getIconTex(4), 0.0f).Vertex(x, dim.y1());
va.Color(c).TexCoord(getIconTex(4), 1.0f).Vertex(x, dim.y2());
@@ -409,7 +409,7 @@ void ScreenSongs::drawInstruments(Dimensions const& dim, float alpha) const {
float a = alpha * (have_dance ? 1.00f : 0.25f);
float m = !(typeFilter & 1);
glutil::VertexArray va;
- glmath::vec4 c(m * 1.0f, 1.0f, m * 1.0f, a);
+ glmath::vec4 c(m * a, a, m * a, a);
x = dim.x1()+4*xincr*(dim.x2()-dim.x1());
va.Color(c).TexCoord(getIconTex(6), 0.0f).Vertex(x, dim.y1());
va.Color(c).TexCoord(getIconTex(6), 1.0f).Vertex(x, dim.y2());
diff --git a/game/video_driver.cc b/game/video_driver.cc
index c1ed465..51f02b6 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -196,7 +196,7 @@ void Window::render(boost::function<void (void)> drawFunc) {
// Over/under only available in fullscreen
if (stereo && type == 2 && !m_fullscreen) stereo = false;
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
updateStereo(stereo ? getSeparation() : 0.0);
glerror.check("setup");
// Can we do direct to framebuffer rendering (no FBO)?
@@ -259,7 +259,7 @@ void Window::view(unsigned num) {
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:51:07
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Fri Jul 6 05:03:06 2012 +0300
Reimplement SVG loading
- Use Cairo surfaces instead of GDKPixbuf (avoids rsvg depracation warnings)
- Do not reopen the same SVG multiple times (the old code was hackish)
- PNG caching simplified, no longer throws anything
- Cairo used for writing PNGs (Cairo internally converts into non-premultiplied alpha)
- Cairo surfaces use premultiplied alpha (affects SVG loading)
- BUG: our rendering system assumes non-premultiplied alpha (SVGs display incorrectly)
---
game/cache.hh | 36 +++++++------------------------
game/image.hh | 65 +++++++++++++++++++-------------------------------------
2 files changed, 30 insertions(+), 71 deletions(-)
diff --git a/game/cache.hh b/game/cache.hh
index 9121a54..2427432 100644
--- a/game/cache.hh
+++ b/game/cache.hh
@@ -8,38 +8,18 @@
namespace cache {
- /** Cache is for some reason invalid. (i.e. too old or not non existent) **/
- class invalid_cache_error : public std::runtime_error {
- /* This exception should always be caught so that the user never
- * ever sees it. We shouldn't bother them with caching issues.
- */
- public:
- invalid_cache_error() : std::runtime_error("Invalid Cache. This error should never be seen.") {}
- };
-
-
/** Builds the full path and file name for the SVG cache resource **/
fs::path constructSVGCacheFileName(fs::path const& svgfilename, double factor);
- /** Given a path to an SVG the caching policy is returned **/
- inline bool cachableSVGResource(fs::path const& /*svgfilename*/ ) {
- // FIXME: Currently all is cached, so should this be removed?
- return true;
- }
-
/** Load an SVG from the cache, if loading fails invalid_cache_error is thrown **/
- template <typename T> void loadSVG(T& target, fs::path const& source_filename, double factor) {
- if(!cachableSVGResource(source_filename)) throw invalid_cache_error();
-
+ template <typename T> bool loadSVG(T& target, fs::path const& source_filename, double factor) {
fs::path const cache_filename = cache::constructSVGCacheFileName(source_filename, factor);
- if(!fs::exists(cache_filename)) throw invalid_cache_error();
-
- // SVG file is newer, so the cache is now invalid
- if(fs::last_write_time(source_filename) > fs::last_write_time(cache_filename))
- throw invalid_cache_error();
-
- try {
- loadPNG(target, cache_filename.string());
- } catch( ... ) { throw invalid_cache_error(); }
+ // Verify that a cached file exists and that it is more recent than the original SVG
+ if (!fs::exists(cache_filename)) return false;
+ if (fs::last_write_time(source_filename) > fs::last_write_time(cache_filename)) return false;
+ // Try to load the cached file
+ try { loadPNG(target, cache_filename.string()); } catch( ... ) { return false; }
+ return true;
}
}
+
diff --git a/game/image.hh b/game/image.hh
index f36d231..61dbb14 100644
--- a/game/image.hh
+++ b/game/image.hh
@@ -53,6 +53,7 @@ namespace {
bpp = 4;
break;
default:
+ // Note: INT_ARGB uses premultiplied alpha and cannot be supported by libpng
throw std::logic_error("Unsupported pixel format in writePNG_internal");
}
png_write_info(pngPtr, infoPtr);
@@ -94,55 +95,33 @@ namespace {
static inline void loadSVG(Bitmap& bitmap, std::string const& filename) {
double factor = config["graphic/svg_lod"].f();
-
- /* always */ try {
- cache::loadSVG(bitmap, filename, factor);
- return;
- } catch ( ... ) { /* no-op. Failing to read the cache only means more work here */ }
-
- struct RSVGInit {
- RSVGInit() { rsvg_init(); }
- ~RSVGInit() { rsvg_term(); }
- } rsvgInit;
+ // Try to load a cached PNG instead
+ if (cache::loadSVG(bitmap, filename, factor)) return;
+ // Open the SVG file in librsvg
+ g_type_init();
GError* pError = NULL;
- // Find SVG dimensions (in pixels)
- RsvgHandle* svgHandle = rsvg_handle_new_from_file(filename.c_str(), &pError);
+ boost::shared_ptr<RsvgHandle> svgHandle(rsvg_handle_new_from_file(filename.c_str(), &pError), g_object_unref);
if (pError) {
g_error_free(pError);
throw std::runtime_error("Unable to load " + filename);
}
+ // Get SVG dimensions
RsvgDimensionData svgDimension;
- rsvg_handle_get_dimensions (svgHandle, &svgDimension);
- rsvg_handle_free(svgHandle);
- unsigned int w = nextPow2(svgDimension.width*factor);
- unsigned int h = nextPow2(svgDimension.height*factor);
- // Load and raster the SVG
- GdkPixbuf* pb = rsvg_pixbuf_from_file_at_size(filename.c_str(), w, h, &pError);
- if (pError) {
- g_error_free(pError);
- throw std::runtime_error("Unable to load " + filename);
- }
- bitmap.resize(w, h);
- std::memcpy(&bitmap.buf[0], gdk_pixbuf_get_pixels(pb), bitmap.buf.size());
- bitmap.ar = float(svgDimension.width)/svgDimension.height;
- gdk_pixbuf_unref(pb);
-
- // write the cache iff the resource is cachable
- if(cache::cachableSVGResource(filename)) {
- fs::path const cache_filename = cache::constructSVGCacheFileName(filename, factor);
-
- // need to reload the svg to have the correct aspect ratio
- w = svgDimension.width * factor;
- h = svgDimension.height * factor;
- pb = rsvg_pixbuf_from_file_at_size(filename.c_str(), w, h, &pError);
- if (pError) {
- g_error_free(pError);
- throw std::runtime_error("Unable to load " + filename);
- }
- fs::create_directories(cache_filename.parent_path());
- writePNG(cache_filename.string(), w, h, pix::CHAR_RGBA, false, gdk_pixbuf_get_pixels(pb));
- gdk_pixbuf_unref(pb);
- }
+ rsvg_handle_get_dimensions(svgHandle.get(), &svgDimension);
+ // Prepare the pixel buffer
+ bitmap.resize(svgDimension.width*factor, svgDimension.height*factor);
+ bitmap.fmt = pix::INT_ARGB;
+ // Raster with Cairo
+ boost::shared_ptr<cairo_surface_t> surface(
+ cairo_image_surface_create_for_data(&bitmap.buf[0], CAIRO_FORMAT_ARGB32, bitmap.width, bitmap.height, bitmap.width * 4),
+ cairo_surface_destroy);
+ boost::shared_ptr<cairo_t> dc(cairo_create(surface.get()), cairo_destroy);
+ cairo_scale(dc.get(), factor, factor);
+ rsvg_handle_render_cairo(svgHandle.get(), dc.get());
+ // Write to cache so that it can be loaded faster the next time
+ fs::path const cache_filename = cache::constructSVGCacheFileName(filename, factor);
+ fs::create_directories(cache_filename.parent_path());
+ cairo_surface_write_to_png(surface.get(), cache_filename.string().c_str());
}
static inline void loadPNG(Bitmap& bitmap, std::string const& filename) {
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:51:04
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Fri Jul 6 04:50:10 2012 +0300
Fix reading of key from stdin in gh_fsb_decrypt (not tested, probably never used, but fixes a compiler warning).
---
tools/gh_fsb/fsbext.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/tools/gh_fsb/fsbext.c b/tools/gh_fsb/fsbext.c
index 1d46227..ee561d8 100644
--- a/tools/gh_fsb/fsbext.c
+++ b/tools/gh_fsb/fsbext.c
@@ -1644,9 +1644,7 @@ FILE *try_fsbdec(FILE *fd) {
" type ? for viewing the hex dump of the first %d bytes of the file because\n"
" it's possible to see part of the plain-text password in the encrypted file!\n"
" ", HEXSIZE);
- fflush(stdin);
- // TODO: test return value
- fgets(key, sizeof(key), stdin);
+ if (!fgets(key, sizeof(key), stdin)) exit(1);
delimit(key);
if(strcmp(key, "?")) break;
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:51:01
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Fri Jul 6 04:42:56 2012 +0300
Removed the ss_ipu_decode tool because it appears to be unfinished and completely abandoned.
---
tools/CMakeLists.txt | 3 +-
tools/ipu_decode.cpp | 163 --------------------------------------------------
2 files changed, 1 insertions(+), 165 deletions(-)
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 1d2bbfd..f4467c0 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -72,9 +72,8 @@ endif (Boost_FOUND)
add_subdirectory(gh_fsb)
add_executable(gh_xen_decrypt gh_xen_decrypt.cpp)
add_executable(ss_adpcm_decode adpcm_decode.cpp pak.cpp)
-add_executable(ss_ipu_decode ipu_decode.cpp)
add_executable(ss_ipu_conv ipu_conv.cpp ipuconvmain.cpp pak.cpp)
-set(targets ${targets} gh_xen_decrypt ss_adpcm_decode ss_ipu_decode ss_ipu_conv)
+set(targets ${targets} gh_xen_decrypt ss_adpcm_decode ss_ipu_conv)
# add install target:
install(TARGETS ${targets} DESTINATION bin)
diff --git a/tools/ipu_decode.cpp b/tools/ipu_decode.cpp
deleted file mode 100644
index e241130..0000000
--- a/tools/ipu_decode.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-#include <fstream>
-#include <iostream>
-#include <stdexcept>
-#include <vector>
-
-#define FLAG_IDP 3
-#define FLAG_DTD 4
-#define FLAG_AS 16
-#define FLAG_IVF 32
-#define FLAG_QST 64
-#define FLAG_MPEG_TYPE 128
-
-#define FPS 25
-
-struct IPUHeader {
- unsigned int file_size;
- unsigned short width;
- unsigned short height;
- unsigned int frames;
-};
-
-struct IPUFrame {
- unsigned int id;
- char mpeg1;
- char qst;
- char ivf;
- char as;
- char dtd;
- char idp;
-};
-
-int intSwitch( int in ) {
- int result=0;
- result |= (0x000000ff&in)<<24;
- result |= (0x0000ff00&in)<<8;
- result |= (0x00ff0000&in)>>8;
- result |= (0xff000000&in)>>24;
- return result;
-}
-
-void writeMpegHeader( std::ofstream &mpegfile, char mpeg1, short width, short height ) {
- unsigned int header;
- header = 0xB3010000;
- mpegfile.write((char*)&header,sizeof(int));
- header = intSwitch(width * (1 << 20) + height * (1 << 8) + (1 << 4) + 3);
- mpegfile.write((char*)&header,sizeof(int));
- header = 0x00E1CE01;
- mpegfile.write((char*)&header,sizeof(int));
- if( !mpeg1 ) {
- short tmp=0x0000;
- header = 0xb5010000;
- mpegfile.write((char*)&header,sizeof(int));
- header = 0x01008A14;
- mpegfile.write((char*)&header,sizeof(int));
- mpegfile.write((char*)&tmp,sizeof(short));
- header = 0xb5010000;
- mpegfile.write((char*)&header,sizeof(int));
- header = 0x04050523;
- mpegfile.write((char*)&header,sizeof(int));
- header = intSwitch(width * (1<<18) + (1<<17) + height * (1<<3));
- mpegfile.write((char*)&header,sizeof(int));
- }
-}
-
-void writeGopHeader(std::ofstream& mpegfile, unsigned int frame, char mpeg1, char idp, char qst, char ivf, char as) {
- unsigned int header;
- int hours = frame / FPS / 60 / 60;
- int minutes = (frame % (FPS * 60 * 60)) / FPS / 60;
- int seconds = (frame % (FPS * 60)) / FPS;
- int ffs = frame % FPS;
-
- header = 0xb8010000;
- mpegfile.write((char*)&header,sizeof(int));
- header = intSwitch(hours * (1<<26) + minutes * (1<<20) + (1<<19) + seconds * (1<<13) + ffs * (1<<7) + (1<<6));
- mpegfile.write((char*)&header,sizeof(int));
- header = 0x00010000;
- mpegfile.write((char*)&header,sizeof(int));
- header = 0xf8ff0f00;
- mpegfile.write((char*)&header,sizeof(int));
- if( !mpeg1 ) {
- char tmp = 0x80;
- header = 0xb5010000;
- mpegfile.write((char*)&header,sizeof(int));
- header = intSwitch(0x8ffff000 + (idp*(1<<10)+3*(1<<8)+(1<<6)+1+qst+ivf+as));
- mpegfile.write((char*)&header,sizeof(int));
- mpegfile.write(&tmp,sizeof(char));
- }
- // Slice Header
- short tmp = 0x0000;
- mpegfile.write((char*)&tmp,sizeof(short));
- header = 0x010C0101;
- mpegfile.write((char*)&header,sizeof(int));
-}
-
-void writeGopFooter( std::ofstream &mpegfile ) {
- unsigned int header = 0x00000000;
- char tmp = 0x00;
- mpegfile.write((char*)&header,sizeof(int));
- mpegfile.write((char*)&header,sizeof(int));
- mpegfile.write((char*)&tmp,sizeof(char));
-}
-
-int main(int argc, char** argv) {
- if (argc < 3) {
- std::cout << "Usage: " << argv[0] << " input output" << std::endl;
- return 1;
- }
-
- std::ifstream ipufile(argv[1], std::ios::binary);
- std::ofstream mpegfile(argv[2], std::ios::binary);
- if (!ipufile.is_open()) throw std::runtime_error("Could not open IPU file");
-
- // Read IPU header
- IPUHeader ipu;
- ipufile.seekg(0x4, std::ios::cur);
- ipufile.read((char*)&ipu, sizeof(ipu));
- ipu.file_size += 8; // Add header size (ipum and filesize)
-
- std::cout << "FileSize: " << ipu.file_size << std::endl;
- std::cout << "Geometry: " << ipu.width << "x" << ipu.height << std::endl;
- std::cout << "Frames: " << ipu.frames << std::endl;
-
- for (unsigned int i = 0; i < ipu.frames; ++i) {
- std::vector<unsigned char> buffer_in, buffer_out;
- char flags = ipufile.get();
-
- IPUFrame frame;
- frame.id = i;
- frame.mpeg1 = flags&FLAG_MPEG_TYPE;
- frame.qst = flags&FLAG_MPEG_TYPE;
- frame.ivf = flags&FLAG_IVF;
- frame.as = flags&FLAG_AS;
- frame.dtd = flags&FLAG_DTD;
- frame.idp = flags&FLAG_IDP;
-
- if (frame.id == 0) writeMpegHeader(mpegfile, frame.mpeg1, ipu.width, ipu.height);
-
- writeGopHeader(mpegfile, frame.id, frame.mpeg1,frame.idp,frame.qst,frame.ivf,frame.as);
-
- if (frame.ivf) std::cerr << "Intra VLC Format not supported" << std::endl;
-
- for (unsigned j = 0; j < 4; ++j) buffer_in.push_back(ipufile.get());
-
- for (unsigned j = 3;; ++j) {
- unsigned char ch;
- if (buffer_in[j] == 0xb0 &&
- buffer_in[j-1] == 0x01 &&
- buffer_in[j-2] == 0x00 &&
- buffer_in[j-3] == 0x00)
- break;
- ipufile.read((char*)&ch,sizeof(char));
- buffer_in.push_back(ch);
- }
-
- //std::cout << frame.id << ": " << buffer_in.size() << std::endl;
- // FIXME: No implementation seemsto be written for this (and no data is ever output):
- //convertFrame(buffer_in,buffer_out,ipu,frame);
- // mpegfile.write(buffer_out); // pseudo-code
-
- writeGopFooter(mpegfile);
- }
-}
-
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Fri Jul 6 04:39:32 2012 +0300
Cleanup for ipu_decode.cpp. "Fixes" compile warnings. This should not affect behavior but no regression testing was done. The tool appears to be incomplete and not doing anything sensible anyway.
---
tools/ipu_decode.cpp | 139 +++++++++++++++++++++-----------------------------
1 files changed, 59 insertions(+), 80 deletions(-)
diff --git a/tools/ipu_decode.cpp b/tools/ipu_decode.cpp
index 90373d3..e241130 100644
--- a/tools/ipu_decode.cpp
+++ b/tools/ipu_decode.cpp
@@ -1,4 +1,3 @@
-#include <cstdlib>
#include <fstream>
#include <iostream>
#include <stdexcept>
@@ -13,12 +12,13 @@
#define FPS 25
-struct IPUFile {
+struct IPUHeader {
unsigned int file_size;
unsigned short width;
unsigned short height;
unsigned int frames;
};
+
struct IPUFrame {
unsigned int id;
char mpeg1;
@@ -29,10 +29,6 @@ struct IPUFrame {
char idp;
};
-void convertFrame( std::vector<unsigned char> &buffer_in, std::vector<unsigned char> buffer_out, struct IPUFile ipu,struct IPUFrame frame) {
- // Do things here
-}
-
int intSwitch( int in ) {
int result=0;
result |= (0x000000ff&in)<<24;
@@ -42,31 +38,31 @@ int intSwitch( int in ) {
return result;
}
-void writeMpegHeader( std::ofstream &m_f2, char mpeg1, short width, short height ) {
+void writeMpegHeader( std::ofstream &mpegfile, char mpeg1, short width, short height ) {
unsigned int header;
header = 0xB3010000;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
header = intSwitch(width * (1 << 20) + height * (1 << 8) + (1 << 4) + 3);
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
header = 0x00E1CE01;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
if( !mpeg1 ) {
short tmp=0x0000;
header = 0xb5010000;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
header = 0x01008A14;
- m_f2.write((char*)&header,sizeof(int));
- m_f2.write((char*)&tmp,sizeof(short));
+ mpegfile.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&tmp,sizeof(short));
header = 0xb5010000;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
header = 0x04050523;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
header = intSwitch(width * (1<<18) + (1<<17) + height * (1<<3));
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
}
}
-void writeGopHeader( std::ofstream &m_f2, unsigned int frame, char mpeg1, char idp, char qst,char ivf,char as ) {
+void writeGopHeader(std::ofstream& mpegfile, unsigned int frame, char mpeg1, char idp, char qst, char ivf, char as) {
unsigned int header;
int hours = frame / FPS / 60 / 60;
int minutes = (frame % (FPS * 60 * 60)) / FPS / 60;
@@ -74,70 +70,61 @@ void writeGopHeader( std::ofstream &m_f2, unsigned int frame, char mpeg1, char i
int ffs = frame % FPS;
header = 0xb8010000;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
header = intSwitch(hours * (1<<26) + minutes * (1<<20) + (1<<19) + seconds * (1<<13) + ffs * (1<<7) + (1<<6));
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
header = 0x00010000;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
header = 0xf8ff0f00;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
if( !mpeg1 ) {
char tmp = 0x80;
header = 0xb5010000;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
header = intSwitch(0x8ffff000 + (idp*(1<<10)+3*(1<<8)+(1<<6)+1+qst+ivf+as));
- m_f2.write((char*)&header,sizeof(int));
- m_f2.write(&tmp,sizeof(char));
+ mpegfile.write((char*)&header,sizeof(int));
+ mpegfile.write(&tmp,sizeof(char));
}
// Slice Header
short tmp = 0x0000;
- m_f2.write((char*)&tmp,sizeof(short));
+ mpegfile.write((char*)&tmp,sizeof(short));
header = 0x010C0101;
- m_f2.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
}
-void writeGopFooter( std::ofstream &m_f2 ) {
+void writeGopFooter( std::ofstream &mpegfile ) {
unsigned int header = 0x00000000;
char tmp = 0x00;
- m_f2.write((char*)&header,sizeof(int));
- m_f2.write((char*)&header,sizeof(int));
- m_f2.write((char*)&tmp,sizeof(char));
+ mpegfile.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&header,sizeof(int));
+ mpegfile.write((char*)&tmp,sizeof(char));
}
-int main( int argc, char** argv) {
- std::ifstream m_f1;
- std::ofstream m_f2;
- struct IPUFile ipu;
-
- if( argc < 3 ) {
+int main(int argc, char** argv) {
+ if (argc < 3) {
std::cout << "Usage: " << argv[0] << " input output" << std::endl;
- return EXIT_FAILURE;
+ return 1;
}
- m_f1.open(argv[1], std::ios::binary);
- m_f2.open(argv[2], std::ios::binary);
- if (!m_f1.is_open()) throw std::runtime_error("Could not open IPU file");
+ std::ifstream ipufile(argv[1], std::ios::binary);
+ std::ofstream mpegfile(argv[2], std::ios::binary);
+ if (!ipufile.is_open()) throw std::runtime_error("Could not open IPU file");
- m_f1.seekg(0x4, std::ios::cur);
- m_f1.read((char*)&ipu.file_size,sizeof(int));
- m_f1.read((char*)&ipu.width,sizeof(short));
- m_f1.read((char*)&ipu.height,sizeof(short));
- m_f1.read((char*)&ipu.frames,sizeof(int));
- ipu.file_size+=8; //Add header size (ipum and filesize)
+ // Read IPU header
+ IPUHeader ipu;
+ ipufile.seekg(0x4, std::ios::cur);
+ ipufile.read((char*)&ipu, sizeof(ipu));
+ ipu.file_size += 8; // Add header size (ipum and filesize)
std::cout << "FileSize: " << ipu.file_size << std::endl;
std::cout << "Geometry: " << ipu.width << "x" << ipu.height << std::endl;
std::cout << "Frames: " << ipu.frames << std::endl;
+ for (unsigned int i = 0; i < ipu.frames; ++i) {
+ std::vector<unsigned char> buffer_in, buffer_out;
+ char flags = ipufile.get();
- for( unsigned int i = 0 ; i < ipu.frames ; i++ ) {
- std::vector<unsigned char> buffer_in;
- std::vector<unsigned char> buffer_out;
- char flags;
- struct IPUFrame frame;
-
- m_f1.read(&flags,sizeof(char));
-
+ IPUFrame frame;
frame.id = i;
frame.mpeg1 = flags&FLAG_MPEG_TYPE;
frame.qst = flags&FLAG_MPEG_TYPE;
@@ -146,39 +133,31 @@ int main( int argc, char** argv) {
frame.dtd = flags&FLAG_DTD;
frame.idp = flags&FLAG_IDP;
- if( frame.id == 0 )
- writeMpegHeader(m_f2,frame.mpeg1,ipu.width,ipu.height);
+ if (frame.id == 0) writeMpegHeader(mpegfile, frame.mpeg1, ipu.width, ipu.height);
- writeGopHeader( m_f2, frame.id, frame.mpeg1,frame.idp,frame.qst,frame.ivf,frame.as);
- if( frame.ivf )
- std::cerr << "Intra VLC Format not supported" << std::endl;
+ writeGopHeader(mpegfile, frame.id, frame.mpeg1,frame.idp,frame.qst,frame.ivf,frame.as);
+
+ if (frame.ivf) std::cerr << "Intra VLC Format not supported" << std::endl;
- for( unsigned int j = 0 ; j < 4 ; j++ ) {
- unsigned char ch;
- m_f1.read((char*)&ch,sizeof(char));
- buffer_in.push_back(ch);
- }
- unsigned j = 3;
- while(1) {
+ for (unsigned j = 0; j < 4; ++j) buffer_in.push_back(ipufile.get());
+
+ for (unsigned j = 3;; ++j) {
unsigned char ch;
- if( buffer_in[j] == 0xb0 &&
- buffer_in[j-1] == 0x01 &&
- buffer_in[j-2] == 0x00 &&
- buffer_in[j-3] == 0x00 )
- break;
- m_f1.read((char*)&ch,sizeof(char));
+ if (buffer_in[j] == 0xb0 &&
+ buffer_in[j-1] == 0x01 &&
+ buffer_in[j-2] == 0x00 &&
+ buffer_in[j-3] == 0x00)
+ break;
+ ipufile.read((char*)&ch,sizeof(char));
buffer_in.push_back(ch);
- j++;
}
//std::cout << frame.id << ": " << buffer_in.size() << std::endl;
- convertFrame(buffer_in,buffer_out,ipu,frame);
- // m_f2.write(buffer_out); // pseudo-code
+ // FIXME: No implementation seemsto be written for this (and no data is ever output):
+ //convertFrame(buffer_in,buffer_out,ipu,frame);
+ // mpegfile.write(buffer_out); // pseudo-code
- writeGopFooter( m_f2 );
+ writeGopFooter(mpegfile);
}
-
- m_f1.close();
- m_f2.close();
- return EXIT_SUCCESS;
}
+
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:50:48
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Wed Jul 4 02:33:51 2012 +0300
Fix a song browser video playback regression introduced in da635890d22b18db56309c9d73f982dcadc10ee1.
Added the missing preparation pass.
---
game/screen_songs.cc | 5 +++++
game/screen_songs.hh | 1 +
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index 95a5d44..9dacfcf 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -164,6 +164,11 @@ void ScreenSongs::update() {
}
}
+void ScreenSongs::prepare() {
+ double time = m_audio.getPosition();
+ if (m_video) m_video->prepare(time);
+}
+
void ScreenSongs::drawJukebox() {
double pos = m_audio.getPosition();
double len = m_audio.getLength();
diff --git a/game/screen_songs.hh b/game/screen_songs.hh
index a04d18e..e8314cd 100644
--- a/game/screen_songs.hh
+++ b/game/screen_songs.hh
@@ -25,6 +25,7 @@ public:
void reloadGL();
void manageSharedKey(input::NavButton nav); ///< same behaviour for jukebox and normal mode
void manageEvent(SDL_Event event);
+ void prepare();
void draw();
void drawCovers(); ///< draw the cover browser
Surface& getCover(Song const& song); ///< get appropriate cover image for the song (incl. no cover)
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Tue Jul 3 07:17:45 2012 +0300
Add support for HDMI 3D modes 1280x1470 (720p) and 1920x2205 (1080p) in top/bottom mode. Requires custom modelines and manually setting the proper mode before starting Performous.
---
game/video_driver.cc | 21 +++++++++++++++++----
1 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 07f796a..c1ed465 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -201,7 +201,7 @@ void Window::render(boost::function<void (void)> drawFunc) {
glerror.check("setup");
// Can we do direct to framebuffer rendering (no FBO)?
if (!stereo || type == 2) { view(stereo); drawFunc(); return; }
- // Render both eyes to FBO (full resolution top/bottom)
+ // Render both eyes to FBO (full resolution top/bottom for anaglyph)
unsigned w = s_width;
unsigned h = 2 * s_height;
FBO fbo(w, h);
@@ -265,15 +265,28 @@ void Window::view(unsigned num) {
glEnable(GL_BLEND);
if (GL_EXT_framebuffer_sRGB) glEnable(GL_FRAMEBUFFER_SRGB);
shader("color").bind();
- // Setup views
+ // Setup views (with black bars for cropping)
double vx = 0.5f * (screen->w - s_width);
double vy = 0.5f * (screen->h - s_height);
double vw = s_width, vh = s_height;
if (num == 0) {
glViewport(vx, vy, vw, vh); // Drawable area of the window (excluding black bars)
} else {
- glViewportIndexedf(1, 0, vh / 2, vw, vh / 2); // Top half of the drawable area
- glViewportIndexedf(2, 0, 0, vw, vh / 2); // Bottom half of the drawable area
+ // Splitscreen stereo3d
+ if (screen->w == 1280 && screen->h == 1470) { // HDMI 720p 3D mode
+ glViewportIndexedf(1, 0, 750, 1280, 720);
+ glViewportIndexedf(2, 0, 0, 1280, 720);
+ s_width = 1280;
+ s_height = 720;
+ } else if (screen->w == 1920 && screen->h == 2205) { // HDMI 1080p 3D mode
+ glViewportIndexedf(1, 0, 1125, 1920, 1080);
+ glViewportIndexedf(2, 0, 0, 1920, 1080);
+ s_width = 1920;
+ s_height = 1080;
+ } else { // Regular top/bottom 3d
+ glViewportIndexedf(1, 0, vh / 2, vw, vh / 2); // Top half of the drawable area
+ glViewportIndexedf(2, 0, 0, vw, vh / 2); // Bottom half of the drawable area
+ }
}
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:50:36
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Tue Jul 3 06:47:54 2012 +0300
Improved behavior and debug when audio device fails to start.
---
game/audio.cc | 25 ++++++++++++-------------
1 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 7f09b92..224d024 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -385,8 +385,7 @@ Device::Device(unsigned int in, unsigned int out, double rate, unsigned int dev)
void Device::start() {
PaError err = Pa_StartStream(stream);
- if (err != paNoError) throw std::runtime_error("Cannot start PortAudio audio stream "
- + boost::lexical_cast<std::string>(dev) + ": " + Pa_GetErrorText(err));
+ if (err != paNoError) throw std::runtime_error(std::string("Pa_StartStream: ") + Pa_GetErrorText(err));
}
int Device::operator()(void const* input, void* output, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags) try {
@@ -478,13 +477,13 @@ struct Audio::Impl {
}
// Match found if we got here
int assigned_mics = 0;
- bool device_init_threw = true;
try {
- devices.push_back(new Device(params.in, params.out, params.rate, i));
- Device& d = devices.back();
- device_init_threw = false;
- // Start capture/playback on this device
- d.start();
+ Device* d = new Device(params.in, params.out, params.rate, i);
+ devices.push_back(d);
+ // Start capture/playback on this device (likely to throw due to audio system errors)
+ // NOTE: When it throws we want to keep the device in devices to avoid calling ~Device
+ // which often would hit the Pa_CloseStream hang bug and terminate the application.
+ d->start();
// Assign mics for all channels of the device
for (unsigned int j = 0; j < params.in; ++j) {
if (analyzers.size() >= 4) break; // Too many mics
@@ -497,15 +496,15 @@ struct Audio::Impl {
}
if (mic_used) continue;
// Add the new analyzer
- Analyzer* a = new Analyzer(d.rate, m);
+ Analyzer* a = new Analyzer(d->rate, m);
analyzers.push_back(a);
- d.mics[j] = a;
+ d->mics[j] = a;
++assigned_mics;
}
// Assign playback output for the first available stereo output
- if (!playback && d.out == 2) { d.outptr = &output; playback = true; }
- } catch (...) {
- if (!device_init_threw) devices.pop_back();
+ if (!playback && d->out == 2) { d->outptr = &output; playback = true; }
+ } catch (std::runtime_error& e) {
+ std::clog << "audio/warning: " << info.name << ": " << e.what() << std::endl;
if (dev > 0) { skip_partial = true; break; } // Numeric, end search
continue;
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:50:29
|
Author: Tapio Vierros <tap...@gm...>
Date: Thu Mar 29 20:50:58 2012 +0300
Mark some CMake variables advanced (most notably those hordes from OpenCV).
---
cmake/Modules/FindMsgfmt.cmake | 5 ++++-
cmake/Modules/FindOpenCV.cmake | 10 +++++++++-
cmake/Modules/FindPortMidi.cmake | 1 +
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/cmake/Modules/FindMsgfmt.cmake b/cmake/Modules/FindMsgfmt.cmake
index 8238cd1..14de5bd 100644
--- a/cmake/Modules/FindMsgfmt.cmake
+++ b/cmake/Modules/FindMsgfmt.cmake
@@ -10,4 +10,7 @@ if(Msgfmt_BIN)
set(Msgfmt_FOUND 1)
else()
set(Msgfmt_FOUND 0)
-endif(Msgfmt_BIN)
\ No newline at end of file
+endif(Msgfmt_BIN)
+
+mark_as_advanced(Msgfmt_BIN)
+
diff --git a/cmake/Modules/FindOpenCV.cmake b/cmake/Modules/FindOpenCV.cmake
index 27b383b..e7de88b 100644
--- a/cmake/Modules/FindOpenCV.cmake
+++ b/cmake/Modules/FindOpenCV.cmake
@@ -196,6 +196,9 @@ if(EXISTS "${OpenCV_DIR}")
set(OpenCV_LIBS ${OpenCV_LIBS} ${OpenCV_${__CVLIB}_LIBRARY})
endif(OpenCV_${__CVLIB}_LIBRARY)
+ #Avoid pollution
+ mark_as_advanced(OpenCV_${__CVLIB}_LIBRARY OpenCV_${__CVLIB}_LIBRARY_RELEASE OpenCV_${__CVLIB}_LIBRARY_DEBUG)
+
endforeach(__CVLIB)
@@ -243,7 +246,9 @@ if(EXISTS "${OpenCV_DIR}")
set(OpenCV_LIBS ${OpenCV_LIBS} ${OpenCV_${__CVLIB}_LIBRARY})
endif(OpenCV_${__CVLIB}_LIBRARY)
-
+ #Avoid pollution
+ mark_as_advanced(OpenCV_${__CVLIB}_LIBRARY OpenCV_${__CVLIB}_LIBRARY_RELEASE OpenCV_${__CVLIB}_LIBRARY_DEBUG)
+
endforeach(__CVLIB)
@@ -285,3 +290,6 @@ if(OpenCV_FOUND)
endif(OpenCV_BACKWARD_COMPA)
endif(OpenCV_FOUND)
##====================================================
+
+mark_as_advanced(OpenCV_DIR OpenCV_FOUND)
+
diff --git a/cmake/Modules/FindPortMidi.cmake b/cmake/Modules/FindPortMidi.cmake
index e3774ad..ef3fa1f 100644
--- a/cmake/Modules/FindPortMidi.cmake
+++ b/cmake/Modules/FindPortMidi.cmake
@@ -24,4 +24,5 @@ if (${PortTime_LIBRARY})
endif (${PortTime_LIBRARY})
libfind_process(PortMidi)
+mark_as_advanced(PortTime_LIBRARY)
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:50:21
|
Author: Tapio Vierros <tap...@gm...>
Date: Thu Mar 29 20:33:39 2012 +0300
Revert "Adjusted minimal libavformat version"
This reverts commit ba04de2b7b18d895f6695e6cd152863edb54604b.
---
game/ffmpeg.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index 114ac7f..1b9d874 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -36,7 +36,7 @@ FFmpeg::~FFmpeg() {
boost::mutex::scoped_lock l(s_avcodec_mutex); // avcodec_close is not thread-safe
if (m_resampleContext) audio_resample_close(m_resampleContext);
if (m_codecContext) avcodec_close(m_codecContext);
-#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 2, 0)
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0)
if (m_formatContext) avformat_close_input(&m_formatContext);
#else
if (m_formatContext) av_close_input_file(m_formatContext);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:50:18
|
Author: Tapio Vierros <tap...@gm...> Date: Wed Mar 28 12:19:47 2012 +0300 Added Chinese translation courtesy of Wei-Lun Chao. --- lang/zh.po | 798 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 798 insertions(+), 0 deletions(-) |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:50:15
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Mar 26 04:19:06 2012 +0300
Add a separate pass for preparing a screen, for slow operations that we don't want to do in draw(), and use that for loading the next video frame.
---
game/main.cc | 1 +
game/screen.hh | 4 ++++
game/screen_sing.cc | 7 ++++++-
game/screen_sing.hh | 1 +
game/screenmanager.cc | 4 ++++
game/video.cc | 22 ++++++++++++----------
game/video.hh | 4 ++--
7 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/game/main.cc b/game/main.cc
index a0bcc10..45f3a08 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -185,6 +185,7 @@ void mainLoop(std::string const& songlist) {
glFinish();
prof("swap");
updateSurfaces();
+ sm.prepareScreen();
glFinish();
prof("surfaces");
if (config["graphic/fps"].b()) {
diff --git a/game/screen.hh b/game/screen.hh
index 64d3e29..5c3e27a 100644
--- a/game/screen.hh
+++ b/game/screen.hh
@@ -19,6 +19,8 @@ class Screen {
virtual ~Screen() {}
/// eventhandler
virtual void manageEvent(SDL_Event event) = 0;
+ /// prepare screen for drawing
+ virtual void prepare() {}
/// draws screen
virtual void draw() = 0;
/// enters screen
@@ -49,6 +51,8 @@ class ScreenManager: public Singleton <ScreenManager> {
void activateScreen(std::string const& name);
/// Does actual switching of screens (if necessary)
void updateScreen();
+ /// Prepare (slow loading operations) of the current screen for rendering
+ void prepareScreen();
/// Draws the current screen and possible transition effects
void drawScreen();
/// Reload OpenGL resources (after fullscreen toggle etc)
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 7b16fb4..2a6bbd3 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -399,6 +399,11 @@ namespace {
}
+void ScreenSing::prepare() {
+ double time = m_audio.getPosition();
+ if (m_video) m_video->prepare(time);
+}
+
void ScreenSing::draw() {
// Get the time in the song
double length = m_audio.getLength();
@@ -432,7 +437,7 @@ void ScreenSing::draw() {
// Webcam
if (m_cam && config["graphic/webcam"].b()) m_cam->render();
// Video
- if (m_video /* && (!m_cam || !m_cam->is_good()) */) {
+ if (m_video) {
m_video->render(time); double tmp = m_video->dimensions().ar(); if (tmp > 0.0) ar = tmp;
}
// Top/bottom borders
diff --git a/game/screen_sing.hh b/game/screen_sing.hh
index a5a5a74..9d7438d 100644
--- a/game/screen_sing.hh
+++ b/game/screen_sing.hh
@@ -55,6 +55,7 @@ class ScreenSing: public Screen {
void exit();
void reloadGL();
void manageEvent(SDL_Event event);
+ void prepare();
void draw();
void setSong (boost::shared_ptr<Song> song_)
diff --git a/game/screenmanager.cc b/game/screenmanager.cc
index f3b30f7..5e1bb15 100644
--- a/game/screenmanager.cc
+++ b/game/screenmanager.cc
@@ -43,6 +43,10 @@ Screen* ScreenManager::getScreen(std::string const& name) {
}
}
+void ScreenManager::prepareScreen() {
+ getCurrentScreen()->prepare();
+}
+
void ScreenManager::drawScreen() {
getCurrentScreen()->draw();
drawLogo();
diff --git a/game/video.cc b/game/video.cc
index 09c104f..7adca6a 100644
--- a/game/video.cc
+++ b/game/video.cc
@@ -1,12 +1,11 @@
#include "video.hh"
#include "util.hh"
-
#include <cmath>
Video::Video(std::string const& _videoFile, double videoGap): m_mpeg(true, false, _videoFile), m_videoGap(videoGap), m_surfaceTime(), m_lastTime(), m_alpha(-0.5, 1.5) {}
-void Video::render(double time) {
+void Video::prepare(double time) {
time += m_videoGap;
VideoFrame& fr = m_videoFrame;
// Time to switch frame?
@@ -18,6 +17,17 @@ void Video::render(double time) {
m_surface.load(bitmap);
m_surfaceTime = fr.timestamp;
}
+ // Preload the next future frame
+ if (fr.data.empty()) while (m_mpeg.videoQueue.tryPop(fr) && fr.timestamp < time) {};
+ // Do a seek before next render, if required
+ if (time < m_lastTime - 1.0 || (!fr.data.empty() && time > fr.timestamp + 7.0)) {
+ m_mpeg.seek(std::max(0.0, time - 5.0)); // -5 to workaround ffmpeg inaccurate seeking
+ fr.data.clear();
+ }
+ m_lastTime = time;
+}
+
+void Video::render(double time) {
double tdist = std::abs(m_surfaceTime - time);
m_alpha.setTarget(tdist < 0.4 ? 1.2f : -0.5f);
float alpha = clamp(m_alpha.get());
@@ -33,13 +43,5 @@ void Video::render(double time) {
m_surface.draw();
}
}
- // Preload the next future frame
- if (fr.data.empty()) while (m_mpeg.videoQueue.tryPop(fr) && fr.timestamp < time) {};
- // Do a seek before next render, if required
- if (time < m_lastTime - 1.0 || (!fr.data.empty() && time > fr.timestamp + 7.0)) {
- m_mpeg.seek(std::max(0.0, time - 5.0)); // -5 to workaround ffmpeg inaccurate seeking
- fr.data.clear();
- }
- m_lastTime = time;
}
diff --git a/game/video.hh b/game/video.hh
index c1ed3ea..2390991 100644
--- a/game/video.hh
+++ b/game/video.hh
@@ -10,8 +10,8 @@ class Video {
public:
/// opens given video file
Video(std::string const& videoFile, double videoGap = 0.0);
- /// renders video
- void render(double time);
+ void prepare(double time); ///< Load the current video frame into a texture
+ void render(double time); ///< Render the prepared video frame
/// returns Dimensions of video clip
Dimensions& dimensions() { return m_surface.dimensions; }
/// returns Dimensions of video clip
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:50:09
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Mar 26 04:14:03 2012 +0300
Display FPS with flashMessage instead of std::cout.
---
game/main.cc | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/game/main.cc b/game/main.cc
index db690cc..a0bcc10 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -190,7 +190,9 @@ void mainLoop(std::string const& songlist) {
if (config["graphic/fps"].b()) {
++frames;
if (now() - time > 1.0) {
- std::cout << frames << " FPS" << std::endl;
+ std::ostringstream oss;
+ oss << frames << " FPS";
+ sm.flashMessage(oss.str());
time += 1.0;
frames = 0;
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:50:01
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Mar 26 03:40:26 2012 +0300
Profiler rewritten so that it can be used inside loops.
---
game/profiler.hh | 62 +++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/game/profiler.hh b/game/profiler.hh
index f56db2b..172f186 100644
--- a/game/profiler.hh
+++ b/game/profiler.hh
@@ -1,23 +1,69 @@
#pragma once
#include "xtime.hh"
+#include <iomanip>
#include <iostream>
+#include <map>
#include <sstream>
#include <string>
+#include <vector>
-/// easy access for profiling code
+struct ProfCP {
+ unsigned long samples;
+ double total;
+ double peak;
+ double avg;
+ ProfCP(): samples(), total(), peak(), avg() {}
+ void add(double t) {
+ ++samples;
+ total += t;
+ avg = total / samples;
+ if (peak < t) peak = t;
+ }
+};
+
+static inline std::ostream& operator<<(std::ostream& os, ProfCP const& cp) {
+ os << std::fixed << std::setprecision(1);
+ if (cp.samples == 0) return os << "no data";
+ if (cp.samples > 1) os << cp.samples << "x ";
+ os << cp.avg * 1000.0 << " ms";
+ if (cp.peak > 2.0 * cp.avg) os << " peak " << cp.peak * 1000.0 << " ms";
+ return os;
+}
+
+/// @short A simple performance profiling tool
class Profiler {
- std::ostringstream m_oss;
+ typedef std::map<std::string, ProfCP> Checkpoints;
+ typedef std::pair<std::string, ProfCP> Pair;
+ Checkpoints m_checkpoints;
+ std::string m_name;
boost::xtime m_time;
+ static bool cmpFunc(Pair const& a, Pair const& b) { return a.second.total > b.second.total; }
public:
- /// create a new profiler with a given name
- Profiler(std::string const& name): m_time(now()) { m_oss << "profiler-" << name << "/info: "; }
- ~Profiler() { std::clog << m_oss.str() << std::endl; }
- /// calling the object as a function will return the time since the start
- void operator()(std::string const& tag) {
+ /// Start a profiler with the given name
+ Profiler(std::string const& name): m_name(name), m_time(now()) {}
+ ~Profiler() { dump(); }
+ /// Profiling checkpoint: record the duration since construction or previous checkpoint.
+ /// If no tag is specified, no recording is done.
+ void operator()(std::string const& tag = std::string()) {
boost::xtime n = now();
std::swap(n, m_time);
- m_oss << unsigned((m_time - n) * 1000.0 + 0.5) << " ms (" << tag << ") ";
+ double t = m_time - n;
+ m_checkpoints[tag].add(t);
+ }
+ /// Dump current stats to log and reset
+ void dump(std::string const& level = "info") {
+ if (m_checkpoints.empty()) return;
+ if (level.empty()) { m_checkpoints.clear(); return; }
+ std::vector<Pair> cps(m_checkpoints.begin(), m_checkpoints.end());
+ m_checkpoints.clear();
+ std::sort(cps.begin(), cps.end(), cmpFunc);
+ std::ostringstream oss;
+ oss << "profiler-" << m_name << "/" << level << ":";
+ for (std::vector<Pair>::const_iterator it = cps.begin(); it != cps.end(); ++it) {
+ oss << " " << it->first << " (" << it->second << ")";
+ }
+ std::clog << oss.str() << std::endl;
}
};
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Mar 26 01:04:54 2012 +0300
Allow specifying audiodev in=N for input channels (useful with cards that require a large number of channels). Still requires mics= as well (TODO: auto-assign mics if not specified?).
---
game/audio.cc | 13 +++++++++----
1 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 8cd85f7..7f09b92 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -418,12 +418,13 @@ struct Audio::Impl {
for (ConfigItem::StringList::const_iterator it = devs.begin(), end = devs.end(); it != end; ++it) {
try {
struct Params {
- int out;
+ int out, in;
unsigned int rate;
std::string dev;
std::vector<std::string> mics;
} params = Params();
params.out = 0;
+ params.in = 0;
params.rate = 48000;
// Break into tokens:
std::map<std::string, std::string> keyvalues = parseKeyValuePairs(*it);
@@ -433,6 +434,7 @@ struct Audio::Impl {
std::string key = it2->first;
std::istringstream iss(it2->second);
if (key == "out") iss >> params.out;
+ else if (key == "in") iss >> params.in;
else if (key == "rate") iss >> params.rate;
else if (key == "dev") std::getline(iss, params.dev);
else if (key == "mics") {
@@ -442,6 +444,9 @@ struct Audio::Impl {
else throw std::runtime_error("Unknown device parameter " + key);
if (!iss.eof()) throw std::runtime_error("Syntax error parsing device parameter " + key);
}
+ // Sync mics/in settings together
+ if (params.in == 0) params.in = params.mics.size();
+ else params.mics.resize(params.in);
int count = portaudio::AudioDevices::count();
int dev = -1;
// Handle empty device
@@ -453,7 +458,7 @@ struct Audio::Impl {
if (iss >> tmp && iss.get() == EOF && tmp >= 0 && tmp < count) dev = tmp;
}
std::clog << "audio/info: Trying audio device \"" << params.dev << "\", id: " << dev
- << ", in: " << params.mics.size() << ", out: " << params.out << std::endl;
+ << ", in: " << params.in << ", out: " << params.out << std::endl;
bool skip_partial = false;
bool found = false;
portaudio::AudioDevices ad;
@@ -475,13 +480,13 @@ struct Audio::Impl {
int assigned_mics = 0;
bool device_init_threw = true;
try {
- devices.push_back(new Device(params.mics.size(), params.out, params.rate, i));
+ devices.push_back(new Device(params.in, params.out, params.rate, i));
Device& d = devices.back();
device_init_threw = false;
// Start capture/playback on this device
d.start();
// Assign mics for all channels of the device
- for (unsigned int j = 0; j < d.in; ++j) {
+ for (unsigned int j = 0; j < params.in; ++j) {
if (analyzers.size() >= 4) break; // Too many mics
std::string const& m = params.mics[j];
if (m.empty()) continue; // Input channel not used
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:49:46
|
Author: Vincent Le Ligeour <yo...@us...>
Date: Sun Mar 25 18:34:42 2012 +0200
Adjusted minimal libavformat version
---
game/ffmpeg.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index 1b9d874..114ac7f 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -36,7 +36,7 @@ FFmpeg::~FFmpeg() {
boost::mutex::scoped_lock l(s_avcodec_mutex); // avcodec_close is not thread-safe
if (m_resampleContext) audio_resample_close(m_resampleContext);
if (m_codecContext) avcodec_close(m_codecContext);
-#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0)
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 2, 0)
if (m_formatContext) avformat_close_input(&m_formatContext);
#else
if (m_formatContext) av_close_input_file(m_formatContext);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:49:40
|
Author: Lasse Karkkainen <tro...@tr...> Date: Fri Mar 23 01:30:50 2012 +0200 New FindOpenCV.cmake for OpenCV 2.x (instead of 0.x/1.0). https://code.ros.org/trac/opencv/attachment/ticket/597/FindOpenCV.cmake - Changes to CMakeLists.txt and webcam.cc accordingly. --- cmake/Modules/FindOpenCV.cmake | 476 ++++++++++++++++++++++------------------ game/CMakeLists.txt | 2 +- game/webcam.cc | 3 +- 3 files changed, 262 insertions(+), 219 deletions(-) |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:49:33
|
Author: Lasse Karkkainen <tro...@tr...> Date: Wed Mar 21 08:06:56 2012 +0200 FFmpeg internal cleanup. Will only decode one stream at a time now (not both audio and video). Refactoring of variable names, etc. --- game/ffmpeg.cc | 115 ++++++++++++++++++++++++++----------------------------- game/ffmpeg.hh | 22 ++++------ 2 files changed, 63 insertions(+), 74 deletions(-) |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:49:30
|
Author: Lasse Kärkkäinen <tronic+ndrm at trn.iki.fi> Date: Wed Mar 21 06:22:48 2012 +0200 Restore support for older libav versions (Ubuntu 11.10). --- game/ffmpeg.cc | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc index 32a6b78..c04ba8d 100644 --- a/game/ffmpeg.cc +++ b/game/ffmpeg.cc @@ -33,7 +33,11 @@ FFmpeg::~FFmpeg() { if (pResampleCtx) audio_resample_close(pResampleCtx); if (pAudioCodecCtx) avcodec_close(pAudioCodecCtx); if (pVideoCodecCtx) avcodec_close(pVideoCodecCtx); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0) if (pFormatCtx) avformat_close_input(&pFormatCtx); +#else + if (pFormatCtx) av_close_input_file(pFormatCtx); +#endif } double FFmpeg::duration() const { |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:49:23
|
Author: Lasse Kärkkäinen <tronic+ndrm at trn.iki.fi> Date: Tue Nov 29 11:24:11 2011 +0200 Use std::list for fs Paths instead of std::vector. --- game/fs.cc | 3 +-- game/fs.hh | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/game/fs.cc b/game/fs.cc index cb59487..718d630 100644 --- a/game/fs.cc +++ b/game/fs.cc @@ -214,8 +214,7 @@ Paths const& getPaths(bool refresh) { paths.clear(); std::remove_copy_if(dirs.begin(), dirs.end(), std::inserter(paths, paths.end()), pathNotExist); // Assure that each path appears only once - Paths::iterator it = std::unique(paths.begin(), paths.end()); - paths.resize(it - paths.begin()); + paths.erase(std::unique(paths.begin(), paths.end()), paths.end()); } return paths; } diff --git a/game/fs.hh b/game/fs.hh index a77265a..241d110 100644 --- a/game/fs.hh +++ b/game/fs.hh @@ -1,7 +1,7 @@ #pragma once #include <boost/filesystem.hpp> -#include <vector> +#include <list> // Define this useful alias for the overlong namespace name (yes, for everyone who includes this header) namespace fs = boost::filesystem; @@ -42,7 +42,7 @@ std::string getPath(fs::path const& filename); /** Get full path to a default conguration file **/ fs::path getDefaultConfig(fs::path const &configFile); -typedef std::vector<fs::path> Paths; +typedef std::list<fs::path> Paths; /** Get all shared data paths in preference order **/ Paths const& getPaths(bool refresh = false); |
Author: Lasse Karkkainen <tro...@tr...>
Date: Wed Mar 21 05:46:46 2012 +0200
Fix some issues with timecode calculation, should fix video being off sync in some cases (in particular, with very recent libav versions). May also make sync errors appear in songs made for Performous.
---
game/ffmpeg.cc | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index 8fdc974..32a6b78 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -135,10 +135,6 @@ struct ReadFramePacket: public AVPacket {
if (av_read_frame(s, this) < 0) throw FFmpeg::eof_error();
}
~ReadFramePacket() { av_free_packet(this); }
- double time() {
- return uint64_t(dts) == uint64_t(AV_NOPTS_VALUE) ?
- getNaN() : double(dts) * av_q2d(m_s->streams[stream_index]->time_base);
- }
};
void FFmpeg::decodePacket() {
@@ -179,7 +175,8 @@ int FFmpeg::decodeVideoFrame(ReadFramePacket& packet) {
int linesize = w * 3;
sws_scale(img_convert_ctx, videoFrame->data, videoFrame->linesize, 0, h, &data, &linesize);
}
- if (packet.time() == packet.time()) m_position = packet.time();
+ // Timecode calculation
+ m_position = double(videoFrame->pkt_pts) * av_q2d(pFormatCtx->streams[videoStream]->time_base);
// Construct a new video frame and push it to output queue
VideoFrame* tmp = new VideoFrame(m_position, w, h);
tmp->data.swap(buffer);
@@ -211,7 +208,9 @@ int FFmpeg::decodeAudioFrame(ReadFramePacket& packet) {
int frames = audio_resample(pResampleCtx, &resampled[0], audioFrames, outsize);
resampled.resize(frames * AUDIO_CHANNELS);
// Use timecode from packet if available
- if (packet.time() == packet.time()) m_position = packet.time();
+ if (uint64_t(packet.pts) != uint64_t(AV_NOPTS_VALUE)) {
+ m_position = double(packet.pts) * av_q2d(pFormatCtx->streams[audioStream]->time_base);
+ }
// Push to output queue (may block)
audioQueue.push(resampled, m_position);
// Increment current time
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:49:09
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Wed Mar 21 05:24:47 2012 +0200
Fix handling of odd audio timestamps. Should finally fix all the wrong song playing issues.
---
game/ffmpeg.hh | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/game/ffmpeg.hh b/game/ffmpeg.hh
index 25f15e8..4b0ecf5 100644
--- a/game/ffmpeg.hh
+++ b/game/ffmpeg.hh
@@ -133,9 +133,14 @@ class AudioBuffer {
mutex::scoped_lock l(m_mutex);
while (!condition()) m_cond.wait(l);
if (m_quit) return;
- if (m_pos == 0 && timestamp != 0.0) {
- std::clog << "ffmpeg/info: The first audio frame begins at " << timestamp << " seconds instead of zero." << std::endl;
+ if (timestamp < 0.0) {
+ std::clog << "ffmpeg/warn: Negative audio timestamp " << timestamp << " seconds, frame ignored." << std::endl;
+ return;
+ }
+ // Insert silence at the beginning if the stream starts later than 0.0
+ if (m_pos == 0 && timestamp > 0.0) {
m_pos = timestamp * m_sps;
+ m_data.resize(m_pos, 0);
}
m_data.insert(m_data.end(), data.begin(), data.end());
m_pos += data.size();
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:49:01
|
Author: Vincent Le Ligeour <yo...@us...> Date: Sun Mar 18 07:13:57 2012 +0100 Fixed some compilation errors by missing iostream include (for example continuous integration) --- game/ffmpeg.hh | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/game/ffmpeg.hh b/game/ffmpeg.hh index 6cbdd13..25f15e8 100644 --- a/game/ffmpeg.hh +++ b/game/ffmpeg.hh @@ -10,6 +10,7 @@ #include <boost/thread/recursive_mutex.hpp> #include <boost/thread/thread.hpp> #include <vector> +#include <iostream> using boost::uint8_t; using boost::int16_t; |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:54
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sat Mar 17 01:25:28 2012 +0200
Ffmpeg API keeps changing, fix some deprecation warnings...
---
game/ffmpeg.cc | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index 1f5d5b2..8fdc974 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -33,7 +33,7 @@ FFmpeg::~FFmpeg() {
if (pResampleCtx) audio_resample_close(pResampleCtx);
if (pAudioCodecCtx) avcodec_close(pAudioCodecCtx);
if (pVideoCodecCtx) avcodec_close(pVideoCodecCtx);
- if (pFormatCtx) av_close_input_file(pFormatCtx);
+ if (pFormatCtx) avformat_close_input(&pFormatCtx);
}
double FFmpeg::duration() const {
@@ -46,7 +46,7 @@ void FFmpeg::open() {
av_register_all();
av_log_set_level(AV_LOG_ERROR);
if (avformat_open_input(&pFormatCtx, m_filename.c_str(), NULL, NULL)) throw std::runtime_error("Cannot open input file");
- if (av_find_stream_info(pFormatCtx) < 0) throw std::runtime_error("Cannot find stream information");
+ if (avformat_find_stream_info(pFormatCtx, NULL) < 0) throw std::runtime_error("Cannot find stream information");
pFormatCtx->flags |= AVFMT_FLAG_GENPTS;
videoStream = -1;
audioStream = -1;
|