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
This commit is contained in:
Ilari Liusvaara 2012-02-16 16:57:13 +02:00
parent 37761ac6f5
commit 298ead2f6c
5 changed files with 23 additions and 66 deletions

View file

@ -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;

View file

@ -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<uint32_t>(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;

View file

@ -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;
}

View file

@ -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;

View file

@ -1,4 +1,5 @@
#include "video/avi/writer.hpp"
#include "core/misc.hpp"
#include <sstream>
#include <iomanip>
@ -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();