mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
support for retrieving BITMAPINFOHEADER and WAVEFORMATEX from the AVI and storing it in KaxCodecPrivate
This commit is contained in:
parent
c5a35ce427
commit
d50b2de695
@ -12,9 +12,9 @@ mkvmerge_SOURCES = mkvmerge.cpp mkvmerge.h \
|
||||
mp3_common.cpp mp3_common.h \
|
||||
p_mp3.cpp p_mp3.h \
|
||||
p_video.cpp p_video.h \
|
||||
pr_generic.h pr_generic.cpp \
|
||||
queue.cpp queue.h \
|
||||
r_avi.cpp r_avi.h \
|
||||
rp_generic.h
|
||||
r_avi.cpp r_avi.h
|
||||
|
||||
#mkvmerge_LDADD = @OGG_LIBS@ @VORBIS_LIBS@ @VORBISENC_LIBS@ @AVILIB_LIBS@ \
|
||||
# @DMALLOC_LIBS@ @PROFILING_LIBS@ @MATROSKA_LIBS@
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: p_mp3.cpp,v 1.2 2003/02/16 20:19:48 mosu Exp $
|
||||
\version \$Id: p_mp3.cpp,v 1.3 2003/02/19 09:31:24 mosu Exp $
|
||||
\brief MP3 output module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -34,7 +34,8 @@
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
mp3_packetizer_c::mp3_packetizer_c(unsigned long nsamples_per_sec,
|
||||
mp3_packetizer_c::mp3_packetizer_c(void *pr_data, int pd_size,
|
||||
unsigned long nsamples_per_sec,
|
||||
int nchannels, int nmp3rate,
|
||||
audio_sync_t *nasync, range_t *nrange)
|
||||
throw (error_c) : q_c() {
|
||||
@ -47,6 +48,7 @@ mp3_packetizer_c::mp3_packetizer_c(unsigned long nsamples_per_sec,
|
||||
packet_buffer = NULL;
|
||||
buffer_size = 0;
|
||||
packetno = 0;
|
||||
set_private_data(pr_data, pd_size);
|
||||
set_header();
|
||||
}
|
||||
|
||||
|
5
p_mp3.h
5
p_mp3.h
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: p_mp3.h,v 1.1 2003/02/16 17:04:38 mosu Exp $
|
||||
\version \$Id: p_mp3.h,v 1.2 2003/02/19 09:31:24 mosu Exp $
|
||||
\brief class definition for the MP3 output module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -39,7 +39,8 @@ class mp3_packetizer_c: public q_c {
|
||||
int buffer_size;
|
||||
|
||||
public:
|
||||
mp3_packetizer_c(unsigned long nsamples_per_sec, int nchannels,
|
||||
mp3_packetizer_c(void *pr_data, int pd_size,
|
||||
unsigned long nsamples_per_sec, int nchannels,
|
||||
int nmp3rate, audio_sync_t *nasync,
|
||||
range_t *nrange) throw (error_c);
|
||||
virtual ~mp3_packetizer_c();
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: p_video.cpp,v 1.1 2003/02/16 17:04:39 mosu Exp $
|
||||
\version \$Id: p_video.cpp,v 1.2 2003/02/19 09:31:24 mosu Exp $
|
||||
\brief video output module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -35,7 +35,8 @@
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
video_packetizer_c::video_packetizer_c(char *ncodec, double nfps, int nwidth,
|
||||
video_packetizer_c::video_packetizer_c(void *pr_data, int pd_size,
|
||||
char *ncodec, double nfps, int nwidth,
|
||||
int nheight, int nbpp,
|
||||
int nmax_frame_size, audio_sync_t *as,
|
||||
range_t *nrange, int navi_compat_mode)
|
||||
@ -56,6 +57,7 @@ video_packetizer_c::video_packetizer_c(char *ncodec, double nfps, int nwidth,
|
||||
range.end *= fps;
|
||||
avi_compat_mode = navi_compat_mode;
|
||||
frames_output = 0;
|
||||
set_private_data(pr_data, pd_size);
|
||||
set_header();
|
||||
// add_index(serialno);
|
||||
}
|
||||
@ -94,7 +96,7 @@ void video_packetizer_c::set_header() {
|
||||
if (set_codec_private || avi_compat_mode) {
|
||||
KaxCodecPrivate &codec_private =
|
||||
GetChild<KaxCodecPrivate>(static_cast<KaxTrackEntry &>(*track_entry));
|
||||
codec_private.CopyBuffer((binary *)codec, countof(codec));
|
||||
codec_private.CopyBuffer((binary *)private_data, private_data_size);
|
||||
}
|
||||
|
||||
KaxTrackVideo &track_video =
|
||||
@ -110,7 +112,6 @@ void video_packetizer_c::set_header() {
|
||||
*(static_cast<EbmlFloat *>(&frate)) = fps;
|
||||
}
|
||||
|
||||
|
||||
int video_packetizer_c::process(char *buf, int size, int num_frames,
|
||||
int key, int last_frame) {
|
||||
if (size > max_frame_size) {
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: p_video.h,v 1.1 2003/02/16 17:04:39 mosu Exp $
|
||||
\version \$Id: p_video.h,v 1.2 2003/02/19 09:31:24 mosu Exp $
|
||||
\brief class definition for the video output module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -36,8 +36,8 @@ class video_packetizer_c: public q_c {
|
||||
int avi_compat_mode;
|
||||
range_t range;
|
||||
public:
|
||||
video_packetizer_c(char *, double, int, int, int, int, audio_sync_t *,
|
||||
range_t *nrange, int) throw (error_c);
|
||||
video_packetizer_c(void *, int, char *, double, int, int, int, int,
|
||||
audio_sync_t *, range_t *nrange, int) throw (error_c);
|
||||
virtual ~video_packetizer_c();
|
||||
|
||||
virtual int process(char *buf, int size, int num_frames, int key,
|
||||
|
13
pr_generic.h
13
pr_generic.h
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: pr_generic.h,v 1.1 2003/02/16 17:04:39 mosu Exp $
|
||||
\version \$Id: pr_generic.h,v 1.2 2003/02/19 09:31:24 mosu Exp $
|
||||
\brief class definition for the generic reader and packetizer
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -35,23 +35,26 @@ struct packet_t;
|
||||
typedef class generic_packetizer_c {
|
||||
protected:
|
||||
int serialno;
|
||||
void *private_data;
|
||||
int private_data_size;
|
||||
public:
|
||||
LIBMATROSKA_NAMESPACE::KaxTrackEntry *track_entry;
|
||||
|
||||
generic_packetizer_c() { track_entry = NULL; };
|
||||
virtual ~generic_packetizer_c() {};
|
||||
generic_packetizer_c();
|
||||
virtual ~generic_packetizer_c();
|
||||
virtual int packet_available() = 0;
|
||||
virtual packet_t *get_packet() = 0;
|
||||
virtual void set_header() = 0;
|
||||
virtual stamp_t get_smallest_timestamp() = 0;
|
||||
virtual void set_private_data(void *data, int size);
|
||||
} generic_packetizer_c;
|
||||
|
||||
typedef class generic_reader_c {
|
||||
// protected:
|
||||
// vorbis_comment *chapter_info;
|
||||
public:
|
||||
generic_reader_c() {};
|
||||
virtual ~generic_reader_c() {};
|
||||
generic_reader_c();
|
||||
virtual ~generic_reader_c();
|
||||
virtual int read() = 0;
|
||||
virtual packet_t *get_packet() = 0;
|
||||
virtual int display_priority() = 0;
|
||||
|
154
r_avi.cpp
154
r_avi.cpp
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: r_avi.cpp,v 1.5 2003/02/18 10:46:49 mosu Exp $
|
||||
\version \$Id: r_avi.cpp,v 1.6 2003/02/19 09:31:24 mosu Exp $
|
||||
\brief AVI demultiplexer module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -41,6 +41,58 @@ extern "C" {
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static void dump_bih(BITMAPINFOHEADER *b) {
|
||||
char *bi_compression = (char *)&b->bi_compression;
|
||||
int i;
|
||||
|
||||
if (b == NULL) {
|
||||
fprintf(stdout, "[bih] IS NULL\n");
|
||||
return;
|
||||
}
|
||||
fprintf(stdout, "[bih] size: %u, width: %u, height: %u\n", b->bi_size,
|
||||
b->bi_width, b->bi_height);
|
||||
fprintf(stdout, "[bih] planes: %u, bit_count: %u, compression: 0x%04x "
|
||||
"(%c%c%c%c)\n",
|
||||
b->bi_planes, b->bi_bit_count, b->bi_compression, bi_compression[0],
|
||||
bi_compression[1], bi_compression[2], bi_compression[3]);
|
||||
fprintf(stdout, "[bih] size_image: %u xppm: %u yppm: %u\n", b->bi_size_image,
|
||||
b->bi_x_pels_per_meter, b->bi_y_pels_per_meter);
|
||||
fprintf(stdout, "[bih] clr_used: %u, clr_important: %d\n", b->bi_clr_used,
|
||||
b->bi_clr_important);
|
||||
if (b->bi_size > sizeof(BITMAPINFOHEADER)) {
|
||||
unsigned char *data = (unsigned char *)b + sizeof(BITMAPINFOHEADER);
|
||||
fprintf(stdout, "[bih] data: ");
|
||||
for (i = 0; i < (b->bi_size - sizeof(BITMAPINFOHEADER)); i++)
|
||||
fprintf(stdout, "%x%x ", (data[i] & 0xf0) >> 4, data[i] & 0x0f);
|
||||
fprintf(stdout, "\n\n");
|
||||
} else
|
||||
fprintf(stdout, "[bih] no additional data\n\n");
|
||||
}
|
||||
|
||||
static void dump_wfe(WAVEFORMATEX *w) {
|
||||
int i;
|
||||
|
||||
if (w == NULL) {
|
||||
fprintf(stdout, "[wfe] IS NULL\n");
|
||||
return;
|
||||
}
|
||||
fprintf(stdout, "[wfe] format 0x%04x, channels %u, samp/sec %u\n",
|
||||
w->w_format_tag, w->n_channels, w->n_samples_per_sec);
|
||||
fprintf(stdout, "[wfe] avg b/s %u, block align %u, bits/sam %u\n",
|
||||
w->n_avg_bytes_per_sec, w->n_block_align, w->w_bits_per_sample);
|
||||
fprintf(stdout, "[wfe] size %u\n", w->cb_size);
|
||||
if (w->cb_size > 0) {
|
||||
unsigned char *data = (unsigned char *)w + sizeof(WAVEFORMATEX);
|
||||
fprintf(stdout, "[wfe] data: ");
|
||||
for (i = 0; i < w->cb_size; i++)
|
||||
fprintf(stdout, "%x%x ", (data[i] & 0xf0) >> 4, data[i] & 0x0f);
|
||||
fprintf(stdout, "\n\n");
|
||||
} else
|
||||
fprintf(stdout, "[wfe] no additional data\n\n");
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
int avi_reader_c::probe_file(FILE *file, u_int64_t size) {
|
||||
char data[12];
|
||||
|
||||
@ -57,80 +109,6 @@ int avi_reader_c::probe_file(FILE *file, u_int64_t size) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void dump_bih(BITMAPINFOHEADER &b) {
|
||||
char *bi_compression = (char *)&b.bi_compression;
|
||||
int i;
|
||||
|
||||
fprintf(stdout, "[bih] size: %u, width: %u, height: %u\n", b.bi_size,
|
||||
b.bi_width, b.bi_height);
|
||||
fprintf(stdout, "[bih] planes: %u, bit_count: %u, compression: 0x%04x "
|
||||
"(%c%c%c%c)\n",
|
||||
b.bi_planes, b.bi_bit_count, b.bi_compression, bi_compression[0],
|
||||
bi_compression[1], bi_compression[2], bi_compression[3]);
|
||||
fprintf(stdout, "[bih] size_image: %u xppm: %u yppm: %u\n", b.bi_size_image,
|
||||
b.bi_x_pels_per_meter, b.bi_y_pels_per_meter);
|
||||
fprintf(stdout, "[bih] clr_used: %u, clr_important: %d\n", b.bi_clr_used,
|
||||
b.bi_clr_important);
|
||||
fprintf(stdout, "[bih] data: %p\n", b.data);
|
||||
if (b.data != NULL) {
|
||||
fprintf(stdout, "[bih] ");
|
||||
for (i = 0; i < (b.bi_size - sizeof(BITMAPINFOHEADER) + sizeof(void *));
|
||||
i++) {
|
||||
unsigned char c = ((unsigned char *)b.data)[i];
|
||||
fprintf(stdout, "%x%x ", (c & 0xf0) >> 4, c & 0x0f);
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
static void dump_asi(AVISTREAMINFO &a) {
|
||||
int i;
|
||||
char *fcc_type = (char *)&a.fcc_type;
|
||||
char *fcc_handler = (char *)&a.fcc_handler;
|
||||
|
||||
fprintf(stdout, "[asi] fcc_type '%c%c%c%c' fcc_handler '%c%c%c%c'\n",
|
||||
fcc_type[0], fcc_type[1], fcc_type[2], fcc_type[3],
|
||||
fcc_handler[0], fcc_handler[1], fcc_handler[2], fcc_handler[3]);
|
||||
fprintf(stdout, "[asi] flags %u, caps %u, prio %u, lang %u\n",
|
||||
a.dw_flags, a.dw_caps, a.w_priority, a.w_language);
|
||||
fprintf(stdout, "[asi] scale %u, rate %u, start %u, length %u\n",
|
||||
a.dw_scale, a.dw_rate, a.dw_start, a.dw_length);
|
||||
fprintf(stdout, "[asi] ini_fr %u, sug_b_s %u, qual %u, sam_si %u\n",
|
||||
a.dw_initial_frames, a.dw_suggested_buffer_size, a.dw_quality,
|
||||
a.dw_sample_size);
|
||||
fprintf(stdout, "[asi] left %u, top %u, right %u, bottom %u\n",
|
||||
a.dw_left, a.dw_top, a.dw_right, a.dw_bottom);
|
||||
fprintf(stdout, "[asi] edit_count %u, format_change_count %u\n",
|
||||
a.dw_edit_count, a.dw_format_change_count);
|
||||
|
||||
fprintf(stdout, "[asi] sz_name '");
|
||||
for (i = 0; (i < 64) && a.sz_name[i]; i++)
|
||||
fprintf(stdout, "%c", a.sz_name[i]);
|
||||
fprintf(stdout, "'\n\n");
|
||||
}
|
||||
|
||||
static void dump_wfe(WAVEFORMATEX &w) {
|
||||
int i;
|
||||
|
||||
fprintf(stdout, "[wfe] format 0x%04x, channels %u, samp/sec %u\n",
|
||||
w.w_format_tag, w.n_channels, w.n_samples_per_sec);
|
||||
fprintf(stdout, "[wfe] avg b/s %u, block align %u, bits/sam %u\n",
|
||||
w.n_avg_bytes_per_sec, w.n_block_align, w.w_bits_per_sample);
|
||||
fprintf(stdout, "[wfe] size %u, data %p\n", w.cb_size, w.data);
|
||||
if (w.data != NULL) {
|
||||
fprintf(stdout, "[wfe] ");
|
||||
for (i = 0; i < w.cb_size; i++) {
|
||||
unsigned char c = ((unsigned char *)w.data)[i];
|
||||
fprintf(stdout, "%x%x ", (c & 0xf0) >> 4, c & 0x0f);
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
/*
|
||||
* allocates and initializes local storage for a particular
|
||||
* substream conversion.
|
||||
@ -175,11 +153,6 @@ avi_reader_c::avi_reader_c(char *fname, unsigned char *astreams,
|
||||
throw error_c(s);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_asi(avi->avi_stream_info);
|
||||
dump_bih(avi->bitmap_info_header);
|
||||
#endif
|
||||
|
||||
if (astreams != NULL)
|
||||
this->astreams = (unsigned char *)strdup((char *)astreams);
|
||||
else
|
||||
@ -233,7 +206,10 @@ avi_reader_c::avi_reader_c(char *fname, unsigned char *astreams,
|
||||
|
||||
if (nfourcc != NULL)
|
||||
codec = nfourcc;
|
||||
vpacketizer = new video_packetizer_c(codec, AVI_frame_rate(avi),
|
||||
vpacketizer = new video_packetizer_c(avi->bitmap_info_header,
|
||||
avi->bitmap_info_header == NULL ? 0 :
|
||||
sizeof(BITMAPINFOHEADER),
|
||||
codec, AVI_frame_rate(avi),
|
||||
AVI_video_width(avi),
|
||||
AVI_video_height(avi),
|
||||
24, // fixme!
|
||||
@ -243,6 +219,10 @@ avi_reader_c::avi_reader_c(char *fname, unsigned char *astreams,
|
||||
} else
|
||||
vpacketizer = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_bih(avi->bitmap_info_header);
|
||||
#endif
|
||||
|
||||
memcpy(&async, nasync, sizeof(audio_sync_t));
|
||||
memcpy(&range, nrange, sizeof(range_t));
|
||||
ademuxers = NULL;
|
||||
@ -324,9 +304,6 @@ int avi_reader_c::add_audio_demuxer(avi_t *avi, int aid) {
|
||||
while ((append_to != NULL) && (append_to->next != NULL))
|
||||
append_to = append_to->next;
|
||||
AVI_set_audio_track(avi, aid);
|
||||
#ifdef DEBUG
|
||||
dump_wfe(avi->wave_format_ex[aid]);
|
||||
#endif
|
||||
demuxer = (avi_demuxer_t *)malloc(sizeof(avi_demuxer_t));
|
||||
if (demuxer == NULL)
|
||||
die("malloc");
|
||||
@ -352,7 +329,10 @@ int avi_reader_c::add_audio_demuxer(avi_t *avi, int aid) {
|
||||
demuxer->samples_per_second = AVI_audio_rate(avi);
|
||||
demuxer->channels = AVI_audio_channels(avi);
|
||||
demuxer->bits_per_sample = AVI_audio_mp3rate(avi);
|
||||
demuxer->packetizer = new mp3_packetizer_c(demuxer->samples_per_second,
|
||||
demuxer->packetizer = new mp3_packetizer_c(avi->wave_format_ex[aid],
|
||||
avi->wave_format_ex[aid] ?
|
||||
sizeof(WAVEFORMATEX) : 0,
|
||||
demuxer->samples_per_second,
|
||||
demuxer->channels,
|
||||
demuxer->bits_per_sample,
|
||||
&async, &range);
|
||||
@ -380,6 +360,10 @@ int avi_reader_c::add_audio_demuxer(avi_t *avi, int aid) {
|
||||
else
|
||||
append_to->next = demuxer;
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_wfe(avi->wave_format_ex[aid]);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user