From 298ead2f6c0f05c84fd9f829dceaab3e4485484f Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Thu, 16 Feb 2012 16:57:13 +0200 Subject: [PATCH] AVI dumping fixups - Write video dimensions correctly if codec pads the video - Uncompressed: Pad video right - CSCD: Pad video right - Print message when starting a new segment - Delete some unused code --- include/video/avi/codec.hpp | 4 +- src/video/avi/codec.cpp | 57 ++-------------------- src/video/avi/codec/video/cscd.cpp | 19 ++++---- src/video/avi/codec/video/uncompressed.cpp | 6 +-- src/video/avi/writer.cpp | 3 ++ 5 files changed, 23 insertions(+), 66 deletions(-) diff --git a/include/video/avi/codec.hpp b/include/video/avi/codec.hpp index 4f0c2ebc..1fd79bd2 100644 --- a/include/video/avi/codec.hpp +++ b/include/video/avi/codec.hpp @@ -44,7 +44,9 @@ struct avi_video_codec */ struct format { - format(uint32_t compression, uint16_t bitcount); + format(uint32_t _width, uint32_t _height, uint32_t compression, uint16_t bitcount); + uint32_t width; + uint32_t height; uint32_t suggested_buffer_size; uint32_t max_bytes_per_sec; uint16_t planes; diff --git a/src/video/avi/codec.cpp b/src/video/avi/codec.cpp index c83a3532..00660597 100644 --- a/src/video/avi/codec.cpp +++ b/src/video/avi/codec.cpp @@ -6,8 +6,10 @@ avi_video_codec::~avi_video_codec() {}; avi_audio_codec::~avi_audio_codec() {}; -avi_video_codec::format::format(uint32_t _compression, uint16_t bitcount) +avi_video_codec::format::format(uint32_t _width, uint32_t _height, uint32_t _compression, uint16_t bitcount) { + width = _width; + height = _height; suggested_buffer_size = 1000000; max_bytes_per_sec = 10000000; planes = 1; @@ -39,55 +41,6 @@ uint32_t get_actual_packet_type(uint8_t trackid, uint16_t typecode) return t1 | t2 << 8 | static_cast(typecode) << 16; } -void fill_avi_structure(header_list& avih, avi_video_codec& vcodec, avi_audio_codec& acodec, uint32_t width, - uint32_t height, uint32_t fps_n, uint32_t fps_d, uint32_t samplerate, uint16_t channels) -{ - avi_audio_codec::format afmt = acodec.reset(samplerate, channels); - avi_video_codec::format vfmt = vcodec.reset(width, height, fps_n, fps_d); - - avih.avih.microsec_per_frame = (uint64_t)1000000 * fps_d / fps_n; - avih.avih.max_bytes_per_sec = afmt.max_bytes_per_sec + vfmt.max_bytes_per_sec; - avih.avih.padding_granularity = 0; - avih.avih.flags = 2064; //Trust chunk types, has index. - avih.avih.initial_frames = 0; - avih.avih.suggested_buffer_size = 1048576; //Just some value. - avih.videotrack.strh.handler = 0; - avih.videotrack.strh.flags = 0; - avih.videotrack.strh.priority = 0; - avih.videotrack.strh.language = 0; - avih.videotrack.strh.initial_frames = 0; - avih.videotrack.strh.start = 0; - avih.videotrack.strh.suggested_buffer_size = vfmt.suggested_buffer_size; - avih.videotrack.strh.quality = vfmt.quality; - avih.videotrack.strf.width = width; - avih.videotrack.strf.height = height; - avih.videotrack.strf.planes = vfmt.planes; - avih.videotrack.strf.bit_count = vfmt.bit_count; - avih.videotrack.strf.compression = vfmt.compression; - avih.videotrack.strf.size_image = (vfmt.bit_count + 7) / 8 * width * height; - avih.videotrack.strf.resolution_x = vfmt.resolution_x; - avih.videotrack.strf.resolution_y = vfmt.resolution_y; - avih.videotrack.strf.clr_used = vfmt.clr_used; - avih.videotrack.strf.clr_important = vfmt.clr_important; - avih.videotrack.strf.fps_n = fps_n; - avih.videotrack.strf.fps_d = fps_d; - avih.audiotrack.strh.handler = 0; - avih.audiotrack.strh.flags = 0; - avih.audiotrack.strh.priority = 0; - avih.audiotrack.strh.language = 0; - avih.audiotrack.strh.initial_frames = 0; - avih.audiotrack.strh.start = 0; - avih.audiotrack.strh.suggested_buffer_size = afmt.suggested_buffer_size; - avih.audiotrack.strh.quality = afmt.quality; - avih.audiotrack.strf.format_tag = afmt.format_tag; - avih.audiotrack.strf.channels = channels; - avih.audiotrack.strf.samples_per_second = samplerate; - avih.audiotrack.strf.average_bytes_per_second = afmt.average_rate; - avih.audiotrack.strf.block_align = afmt.alignment; - avih.audiotrack.strf.bits_per_sample = afmt.bitdepth; - avih.audiotrack.strf.blocksize = channels * (afmt.bitdepth + 7) / 8; -} - #define PADGRANULARITY 2 @@ -153,8 +106,8 @@ void avi_output_stream::start(std::ostream& out, avi_video_codec& _vcodec, avi_a avih.videotrack.strh.start = 0; avih.videotrack.strh.suggested_buffer_size = vfmt.suggested_buffer_size; avih.videotrack.strh.quality = vfmt.quality; - avih.videotrack.strf.width = width; - avih.videotrack.strf.height = height; + avih.videotrack.strf.width = vfmt.width; + avih.videotrack.strf.height = vfmt.height; avih.videotrack.strf.planes = vfmt.planes; avih.videotrack.strf.bit_count = vfmt.bit_count; avih.videotrack.strf.compression = vfmt.compression; diff --git a/src/video/avi/codec/video/cscd.cpp b/src/video/avi/codec/video/cscd.cpp index 796ec81a..fc33e48f 100644 --- a/src/video/avi/codec/video/cscd.cpp +++ b/src/video/avi/codec/video/cscd.cpp @@ -62,7 +62,7 @@ namespace prevframe.resize(3 * ewidth * eheight); memset(&row[0], 0, 3 * ewidth); memset(&prevframe[0], 0, 3 * ewidth * eheight); - avi_video_codec::format fmt(0x44435343, 24); + avi_video_codec::format fmt(ewidth, eheight, 0x44435343, 24); return fmt; } @@ -102,26 +102,25 @@ namespace out.payload[0] = (keyframe ? 0x3 : 0x2) | (level << 4); out.payload[1] = 8; //RGB24. - uint32_t iy = 0; - for(uint32_t y = eheight - 1; y < eheight; y--, iy++) { + for(uint32_t y = 0; y < eheight; y++) { bool done = true; - if(y >= iheight) + if(y < eheight - iheight) readrow(NULL); else - readrow(data + y * iwidth); + readrow(data + (eheight - y - 1) * iwidth); if(keyframe) { - memcpy(&prevframe[3 * iy * ewidth], &row[0], 3 * ewidth); + memcpy(&prevframe[3 * y * ewidth], &row[0], 3 * ewidth); } else { //Ew, we need to have prevframe = row, row = row - prevframe at the same time. for(unsigned i = 0; i < 3 * ewidth; i++) { uint8_t tmp = row[i]; - row[i] -= prevframe[3 * iy * ewidth + i]; - prevframe[3 * iy * ewidth + i] = tmp; + row[i] -= prevframe[3 * y * ewidth + i]; + prevframe[3 * y * ewidth + i] = tmp; } } zlib.next_in = &row[0]; zlib.avail_in = row.size(); - if(y == 0) + if(y == eheight - 1) done = false; while(zlib.avail_in || !done) { //Make space in output buffer. @@ -135,7 +134,7 @@ namespace zlib.avail_out = ctmp.size(); buffer_loaded = true; } - r = deflate(&zlib, (y == 0) ? Z_FINISH : 0); + r = deflate(&zlib, (y == eheight - 1) ? Z_FINISH : 0); if(r == Z_STREAM_END) done = true; } diff --git a/src/video/avi/codec/video/uncompressed.cpp b/src/video/avi/codec/video/uncompressed.cpp index 21881eff..f8beb3a2 100644 --- a/src/video/avi/codec/video/uncompressed.cpp +++ b/src/video/avi/codec/video/uncompressed.cpp @@ -42,7 +42,7 @@ namespace ready_flag = true; row.resize(3 * ewidth); memset(&row[0], 0, 3 * ewidth); - avi_video_codec::format fmt(0, 24); //Is 0 correct value for compression? + avi_video_codec::format fmt(ewidth, eheight, 0, 24); //Is 0 correct value for compression? return fmt; } @@ -53,10 +53,10 @@ namespace uint32_t s = 0; for(uint32_t y = 0; y < eheight; y++) { bool done = true; - if(y >= iheight) + if(y < eheight - iheight) readrow(NULL); else - readrow(data + (iheight - y - 1) * iwidth); + readrow(data + (eheight - y - 1) * iwidth); memcpy(&out.payload[3 * ewidth * y], &row[0], 3 * ewidth); } out.typecode = 0x6264; diff --git a/src/video/avi/writer.cpp b/src/video/avi/writer.cpp index 8232fbcd..15f2b2c8 100644 --- a/src/video/avi/writer.cpp +++ b/src/video/avi/writer.cpp @@ -1,4 +1,5 @@ #include "video/avi/writer.hpp" +#include "core/misc.hpp" #include #include @@ -72,6 +73,8 @@ void avi_writer::flush(bool force) aviout.start(avifile, vcodec, acodec, curwidth, curheight, curfps_n, curfps_d, samplerate, channels); closed = false; + messages << "Start AVI: " << curwidth << "x" << curheight << "@" << curfps_n << "/" << curfps_d + << " to '" << aviname << "'" << std::endl; } if(aviout.readqueue(f.data, aqueue, force)) vqueue.pop_front();