mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-23 19:31:44 +00:00
Moved the bit_cursor_c class into its own file. Removed the byte_cursor_c class because its functionality is completely covered by mm_mem_io_c (and it was not used anywhere). Changed mpeg4_p2_find_frame_types to use a mm_mem_io_c instead of a bit_cursor_c because the former is WAY faster and bit-wise access is not needed.
This commit is contained in:
parent
58d81f2365
commit
19770e79dc
@ -16,6 +16,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bit_cursor.h"
|
||||
#include "common.h"
|
||||
#include "aac_common.h"
|
||||
#include "matroska.h"
|
||||
|
201
src/common/bit_cursor.h
Normal file
201
src/common/bit_cursor.h
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
Distributed under the GPL
|
||||
see the file COPYING for details
|
||||
or visit http://www.gnu.org/copyleft/gpl.html
|
||||
|
||||
$Id$
|
||||
|
||||
A class for file-like access on the bit level
|
||||
|
||||
The bit_cursor_c class was originally written by Peter Niemayer
|
||||
<niemayer@isg.de> and modified by Moritz Bunkus <moritz@bunkus.org>.
|
||||
*/
|
||||
|
||||
#ifndef __BIT_CURSOR_H
|
||||
#define __BIT_CURSOR_H
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "error.h"
|
||||
|
||||
class MTX_DLL_API bit_cursor_c {
|
||||
private:
|
||||
const unsigned char *end_of_data;
|
||||
const unsigned char *byte_position;
|
||||
const unsigned char *start_of_data;
|
||||
unsigned int bits_valid;
|
||||
|
||||
bool out_of_data;
|
||||
|
||||
public:
|
||||
bit_cursor_c(const unsigned char *data, unsigned int len):
|
||||
end_of_data(data + len), byte_position(data), start_of_data(data),
|
||||
bits_valid(8), out_of_data(false) {
|
||||
if (byte_position >= end_of_data)
|
||||
out_of_data = true;
|
||||
}
|
||||
|
||||
bool eof() {
|
||||
return out_of_data;
|
||||
}
|
||||
|
||||
bool get_bits(unsigned int n, uint64_t &r) {
|
||||
// returns false if less bits are available than asked for
|
||||
r = 0;
|
||||
|
||||
while (n > 0) {
|
||||
if (byte_position >= end_of_data) {
|
||||
out_of_data = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int b = 8; // number of bits to extract from the current byte
|
||||
if (b > n)
|
||||
b = n;
|
||||
if (b > bits_valid)
|
||||
b = bits_valid;
|
||||
|
||||
unsigned int rshift = bits_valid-b;
|
||||
|
||||
r <<= b;
|
||||
r |= ((*byte_position) >> rshift) & (0xff >> (8 - b));
|
||||
|
||||
bits_valid -= b;
|
||||
if (bits_valid == 0) {
|
||||
bits_valid = 8;
|
||||
byte_position += 1;
|
||||
}
|
||||
|
||||
n -= b;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_bits(unsigned int n, int64_t &r) {
|
||||
uint64_t t;
|
||||
bool b = get_bits(n, t);
|
||||
r = (int64_t)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool get_bits(unsigned int n, int &r) {
|
||||
uint64_t t;
|
||||
bool b = get_bits(n, t);
|
||||
r = (int)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool get_bits(unsigned int n, unsigned int &r) {
|
||||
uint64_t t;
|
||||
bool b = get_bits(n, t);
|
||||
r = (unsigned int)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool get_bit(bool &r) {
|
||||
uint64_t t;
|
||||
bool b = get_bits(1, t);
|
||||
r = (bool)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool peek_bits(unsigned int n, uint64_t &r) {
|
||||
int tmp_bits_valid;
|
||||
const unsigned char *tmp_byte_position;
|
||||
// returns false if less bits are available than asked for
|
||||
r = 0;
|
||||
tmp_byte_position = byte_position;
|
||||
tmp_bits_valid = bits_valid;
|
||||
|
||||
while (n > 0) {
|
||||
if (tmp_byte_position >= end_of_data)
|
||||
return false;
|
||||
|
||||
unsigned int b = 8; // number of bits to extract from the current byte
|
||||
if (b > n)
|
||||
b = n;
|
||||
if (b > tmp_bits_valid)
|
||||
b = tmp_bits_valid;
|
||||
|
||||
unsigned int rshift = tmp_bits_valid - b;
|
||||
|
||||
r <<= b;
|
||||
r |= ((*tmp_byte_position) >> rshift) & (0xff >> (8 - b));
|
||||
|
||||
tmp_bits_valid -= b;
|
||||
if (tmp_bits_valid == 0) {
|
||||
tmp_bits_valid = 8;
|
||||
tmp_byte_position += 1;
|
||||
}
|
||||
|
||||
n -= b;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool peek_bits(unsigned int n, int64_t &r) {
|
||||
uint64_t t;
|
||||
bool b = peek_bits(n, t);
|
||||
r = (int64_t)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool peek_bits(unsigned int n, int &r) {
|
||||
uint64_t t;
|
||||
bool b = peek_bits(n, t);
|
||||
r = (int)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool peek_bits(unsigned int n, unsigned int &r) {
|
||||
uint64_t t;
|
||||
bool b = peek_bits(n, t);
|
||||
r = (unsigned int)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool peek_bit(bool &r) {
|
||||
uint64_t t;
|
||||
bool b = peek_bits(1, t);
|
||||
r = (bool)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool byte_align() {
|
||||
if (out_of_data)
|
||||
return false;
|
||||
if (bits_valid == 8)
|
||||
return true;
|
||||
bits_valid = 0;
|
||||
byte_position += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_bit_position(unsigned int pos) {
|
||||
if (pos >= ((end_of_data - start_of_data) * 8)) {
|
||||
byte_position = end_of_data;
|
||||
out_of_data = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
byte_position = start_of_data + (pos / 8);
|
||||
bits_valid = 8 - (pos % 8);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int get_bit_position() {
|
||||
return (byte_position - start_of_data) * 8 + 8 - bits_valid;
|
||||
}
|
||||
|
||||
bool skip_bits(unsigned int num) {
|
||||
return set_bit_position(get_bit_position() + num);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __BIT_CURSOR_H
|
@ -96,7 +96,9 @@ chapter_error(const char *fmt,
|
||||
vsprintf(&new_error[strlen(new_error)], new_fmt.c_str(), ap);
|
||||
strcat(new_error, "\n");
|
||||
va_end(ap);
|
||||
throw error_c(new_error, true);
|
||||
new_fmt = new_error;
|
||||
safefree(new_error);
|
||||
throw error_c(new_fmt);
|
||||
}
|
||||
|
||||
/** \brief Reads the start of a file and checks for OGM style comments.
|
||||
|
@ -189,107 +189,6 @@ bitvalue_c::generate_random() {
|
||||
value[i] = (unsigned char)(255.0 * rand() / RAND_MAX);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
byte_cursor_c::byte_cursor_c(const unsigned char *ndata,
|
||||
int nsize):
|
||||
size(nsize),
|
||||
data(ndata) {
|
||||
pos = 0;
|
||||
if (nsize < 0)
|
||||
throw error_c("wrong usage: nsize < 0");
|
||||
}
|
||||
|
||||
unsigned char
|
||||
byte_cursor_c::get_uint8() {
|
||||
if ((pos + 1) > size)
|
||||
throw error_c("end-of-data");
|
||||
|
||||
pos++;
|
||||
|
||||
return data[pos - 1];
|
||||
}
|
||||
|
||||
unsigned short
|
||||
byte_cursor_c::get_uint16_be() {
|
||||
unsigned short v;
|
||||
|
||||
if ((pos + 2) > size)
|
||||
throw error_c("end-of-data");
|
||||
|
||||
v = ::get_uint16_be(&data[pos]);
|
||||
pos += 2;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
byte_cursor_c::get_uint32_be() {
|
||||
unsigned int v;
|
||||
|
||||
if ((pos + 4) > size)
|
||||
throw error_c("end-of-data");
|
||||
|
||||
v = ::get_uint32_be(&data[pos]);
|
||||
pos += 4;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
unsigned short
|
||||
byte_cursor_c::get_uint16_le() {
|
||||
unsigned short v;
|
||||
|
||||
if ((pos + 2) > size)
|
||||
throw error_c("end-of-data");
|
||||
|
||||
v = ::get_uint16_le(&data[pos]);
|
||||
pos += 2;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
byte_cursor_c::get_uint32_le() {
|
||||
unsigned int v;
|
||||
|
||||
if ((pos + 4) > size)
|
||||
throw error_c("end-of-data");
|
||||
|
||||
v = ::get_uint32_le(&data[pos]);
|
||||
pos += 4;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
byte_cursor_c::skip(int n) {
|
||||
if ((pos + n) > size)
|
||||
throw error_c("end-of-data");
|
||||
|
||||
pos += n;
|
||||
}
|
||||
|
||||
void
|
||||
byte_cursor_c::get_bytes(unsigned char *dst,
|
||||
int n) {
|
||||
if ((pos + n) > size)
|
||||
throw error_c("end-of-data");
|
||||
|
||||
memcpy(dst, &data[pos], n);
|
||||
pos += n;
|
||||
}
|
||||
|
||||
int
|
||||
byte_cursor_c::get_pos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
int
|
||||
byte_cursor_c::get_len() {
|
||||
return size - pos;
|
||||
}
|
||||
|
||||
/*
|
||||
Control functions
|
||||
*/
|
||||
|
@ -11,8 +11,6 @@
|
||||
definitions used in all programs, helper functions
|
||||
|
||||
Written by Moritz Bunkus <moritz@bunkus.org>.
|
||||
The bit_cursor_c class was originally written by Peter Niemayer
|
||||
<niemayer@isg.de> and modified by Moritz Bunkus <moritz@bunkus.org>.
|
||||
*/
|
||||
|
||||
#ifndef __COMMON_H
|
||||
@ -277,204 +275,6 @@ extern int MTX_DLL_API verbose;
|
||||
#define mxfind2(it, value, cont) \
|
||||
((id = std::find((cont).begin(), (cont).end(), value)) != (cont).end())
|
||||
|
||||
class MTX_DLL_API bit_cursor_c {
|
||||
private:
|
||||
const unsigned char *end_of_data;
|
||||
const unsigned char *byte_position;
|
||||
const unsigned char *start_of_data;
|
||||
unsigned int bits_valid;
|
||||
|
||||
bool out_of_data;
|
||||
|
||||
public:
|
||||
bit_cursor_c(const unsigned char *data, unsigned int len):
|
||||
end_of_data(data + len), byte_position(data), start_of_data(data),
|
||||
bits_valid(8), out_of_data(false) {
|
||||
if (byte_position >= end_of_data)
|
||||
out_of_data = true;
|
||||
}
|
||||
|
||||
bool eof() {
|
||||
return out_of_data;
|
||||
}
|
||||
|
||||
bool get_bits(unsigned int n, uint64_t &r) {
|
||||
// returns false if less bits are available than asked for
|
||||
r = 0;
|
||||
|
||||
while (n > 0) {
|
||||
if (byte_position >= end_of_data) {
|
||||
out_of_data = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int b = 8; // number of bits to extract from the current byte
|
||||
if (b > n)
|
||||
b = n;
|
||||
if (b > bits_valid)
|
||||
b = bits_valid;
|
||||
|
||||
unsigned int rshift = bits_valid-b;
|
||||
|
||||
r <<= b;
|
||||
r |= ((*byte_position) >> rshift) & (0xff >> (8 - b));
|
||||
|
||||
bits_valid -= b;
|
||||
if (bits_valid == 0) {
|
||||
bits_valid = 8;
|
||||
byte_position += 1;
|
||||
}
|
||||
|
||||
n -= b;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_bits(unsigned int n, int64_t &r) {
|
||||
uint64_t t;
|
||||
bool b = get_bits(n, t);
|
||||
r = (int64_t)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool get_bits(unsigned int n, int &r) {
|
||||
uint64_t t;
|
||||
bool b = get_bits(n, t);
|
||||
r = (int)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool get_bits(unsigned int n, unsigned int &r) {
|
||||
uint64_t t;
|
||||
bool b = get_bits(n, t);
|
||||
r = (unsigned int)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool get_bit(bool &r) {
|
||||
uint64_t t;
|
||||
bool b = get_bits(1, t);
|
||||
r = (bool)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool peek_bits(unsigned int n, uint64_t &r) {
|
||||
int tmp_bits_valid;
|
||||
const unsigned char *tmp_byte_position;
|
||||
// returns false if less bits are available than asked for
|
||||
r = 0;
|
||||
tmp_byte_position = byte_position;
|
||||
tmp_bits_valid = bits_valid;
|
||||
|
||||
while (n > 0) {
|
||||
if (tmp_byte_position >= end_of_data)
|
||||
return false;
|
||||
|
||||
unsigned int b = 8; // number of bits to extract from the current byte
|
||||
if (b > n)
|
||||
b = n;
|
||||
if (b > tmp_bits_valid)
|
||||
b = tmp_bits_valid;
|
||||
|
||||
unsigned int rshift = tmp_bits_valid - b;
|
||||
|
||||
r <<= b;
|
||||
r |= ((*tmp_byte_position) >> rshift) & (0xff >> (8 - b));
|
||||
|
||||
tmp_bits_valid -= b;
|
||||
if (tmp_bits_valid == 0) {
|
||||
tmp_bits_valid = 8;
|
||||
tmp_byte_position += 1;
|
||||
}
|
||||
|
||||
n -= b;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool peek_bits(unsigned int n, int64_t &r) {
|
||||
uint64_t t;
|
||||
bool b = peek_bits(n, t);
|
||||
r = (int64_t)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool peek_bits(unsigned int n, int &r) {
|
||||
uint64_t t;
|
||||
bool b = peek_bits(n, t);
|
||||
r = (int)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool peek_bits(unsigned int n, unsigned int &r) {
|
||||
uint64_t t;
|
||||
bool b = peek_bits(n, t);
|
||||
r = (unsigned int)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool peek_bit(bool &r) {
|
||||
uint64_t t;
|
||||
bool b = peek_bits(1, t);
|
||||
r = (bool)t;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool byte_align() {
|
||||
if (out_of_data)
|
||||
return false;
|
||||
if (bits_valid == 8)
|
||||
return true;
|
||||
bits_valid = 0;
|
||||
byte_position += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_bit_position(unsigned int pos) {
|
||||
if (pos >= ((end_of_data - start_of_data) * 8)) {
|
||||
byte_position = end_of_data;
|
||||
out_of_data = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
byte_position = start_of_data + (pos / 8);
|
||||
bits_valid = 8 - (pos % 8);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int get_bit_position() {
|
||||
return (byte_position - start_of_data) * 8 + 8 - bits_valid;
|
||||
}
|
||||
|
||||
bool skip_bits(unsigned int num) {
|
||||
return set_bit_position(get_bit_position() + num);
|
||||
}
|
||||
};
|
||||
|
||||
class MTX_DLL_API byte_cursor_c {
|
||||
private:
|
||||
int pos, size;
|
||||
const unsigned char *data;
|
||||
|
||||
public:
|
||||
byte_cursor_c(const unsigned char *ndata, int nsize);
|
||||
|
||||
virtual unsigned char get_uint8();
|
||||
virtual unsigned short get_uint16_le();
|
||||
virtual unsigned int get_uint32_le();
|
||||
virtual unsigned short get_uint16_be();
|
||||
virtual unsigned int get_uint32_be();
|
||||
virtual void get_bytes(unsigned char *dst, int n);
|
||||
|
||||
virtual void skip(int n);
|
||||
|
||||
virtual int get_pos();
|
||||
virtual int get_len();
|
||||
};
|
||||
|
||||
class MTX_DLL_API bitvalue_c {
|
||||
private:
|
||||
unsigned char *value;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bit_cursor.h"
|
||||
#include "common.h"
|
||||
#include "dts_common.h"
|
||||
|
||||
|
@ -18,27 +18,31 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class MTX_DLL_API error_c {
|
||||
private:
|
||||
string error;
|
||||
public:
|
||||
error_c() {
|
||||
error = "unknown error";
|
||||
};
|
||||
error_c(char *nerror, bool freeit = false) {
|
||||
error = nerror;
|
||||
if (freeit)
|
||||
safefree(nerror);
|
||||
};
|
||||
error_c(const char *nerror) { error = nerror; };
|
||||
error_c(const string &nerror) { error = nerror; };
|
||||
error_c(const error_c &e) { error = e.error; };
|
||||
const char *get_error() const { return error.c_str(); };
|
||||
operator const char *() const { return error.c_str(); };
|
||||
error_c():
|
||||
error("unknown error") {
|
||||
}
|
||||
|
||||
error_c(const char *_error):
|
||||
error(_error) {
|
||||
}
|
||||
|
||||
error_c(const string &_error):
|
||||
error(_error) {
|
||||
}
|
||||
|
||||
const char *get_error() const {
|
||||
return error.c_str();
|
||||
}
|
||||
|
||||
operator const char *() const {
|
||||
return error.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __ERROR_H
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "bit_cursor.h"
|
||||
#include "common.h"
|
||||
#include "mm_io.h"
|
||||
#include "mpeg4_common.h"
|
||||
@ -120,66 +121,75 @@ void
|
||||
mpeg4_p2_find_frame_types(const unsigned char *buffer,
|
||||
int size,
|
||||
vector<video_frame_t> &frames) {
|
||||
bit_cursor_c bits(buffer, size);
|
||||
mm_mem_io_c bytes(buffer, size);
|
||||
uint32_t marker, frame_type;
|
||||
int first_frame_start;
|
||||
bool first_frame;
|
||||
video_frame_t frame;
|
||||
vector<video_frame_t>::iterator fit;
|
||||
|
||||
frame.pos = 0;
|
||||
frames.clear();
|
||||
mxverb(3, "\nmpeg4_frames: start search in %d bytes\n", size);
|
||||
|
||||
if (4 > size)
|
||||
return;
|
||||
|
||||
frame.pos = 0;
|
||||
first_frame = true;
|
||||
first_frame_start = 0;
|
||||
mxverb(3, "\nmpeg4_frames: start search in %d bytes\n", size);
|
||||
while (!bits.eof()) {
|
||||
if (!bits.peek_bits(32, marker))
|
||||
break;
|
||||
|
||||
if ((marker & 0xffffff00) != 0x00000100) {
|
||||
bits.skip_bits(8);
|
||||
continue;
|
||||
try {
|
||||
marker = bytes.read_uint32_be();
|
||||
while (!bytes.eof()) {
|
||||
if ((marker & 0xffffff00) != 0x00000100) {
|
||||
marker <<= 8;
|
||||
marker |= bytes.read_uint8();
|
||||
continue;
|
||||
}
|
||||
|
||||
mxverb(3, "mpeg4_frames: found start code at %lld\n",
|
||||
bytes.getFilePointer() - 4);
|
||||
if (marker == MPEGVIDEO_OBJECT_PLAIN_START_CODE) {
|
||||
if (0 > first_frame_start)
|
||||
first_frame_start = bytes.getFilePointer() - 4;
|
||||
|
||||
frame_type = bytes.read_uint8() >> 6;
|
||||
if (!first_frame) {
|
||||
frame.size = bytes.getFilePointer() - 5 - frame.pos;
|
||||
frames.push_back(frame);
|
||||
frame.pos = bytes.getFilePointer() - 5;
|
||||
} else {
|
||||
first_frame = false;
|
||||
frame.pos = first_frame_start;
|
||||
}
|
||||
frame.type = frame_type == 0 ? 'I' : frame_type == 1 ? 'P' :
|
||||
frame_type == 2 ? 'B' : 'S';
|
||||
|
||||
} else if (first_frame &&
|
||||
((MPEGVIDEO_VOS_START_CODE == marker) ||
|
||||
(MPEGVIDEO_VISUAL_OBJECT_START_CODE == marker) ||
|
||||
(0x00000140 > marker)))
|
||||
first_frame_start = -1;
|
||||
else
|
||||
first_frame_start = bytes.getFilePointer() - 4;
|
||||
|
||||
marker = bytes.read_uint32_be();
|
||||
}
|
||||
|
||||
mxverb(3, "mpeg4_frames: found start code at %d\n",
|
||||
bits.get_bit_position() / 8);
|
||||
bits.skip_bits(32);
|
||||
if (marker == MPEGVIDEO_OBJECT_PLAIN_START_CODE) {
|
||||
if (0 > first_frame_start)
|
||||
first_frame_start = bits.get_bit_position() / 8 - 4;
|
||||
if (!first_frame) {
|
||||
frame.size = size - frame.pos;
|
||||
frames.push_back(frame);
|
||||
}
|
||||
|
||||
if (!bits.get_bits(2, frame_type))
|
||||
break;
|
||||
if (!first_frame) {
|
||||
frame.size = (bits.get_bit_position() / 8) - 4 - frame.pos;
|
||||
frames.push_back(frame);
|
||||
frame.pos = (bits.get_bit_position() / 8) - 4;
|
||||
} else {
|
||||
first_frame = false;
|
||||
frame.pos = first_frame_start;
|
||||
}
|
||||
frame.type = frame_type == 0 ? 'I' : frame_type == 1 ? 'P' :
|
||||
frame_type == 2 ? 'B' : 'S';
|
||||
bits.byte_align();
|
||||
|
||||
} else if (first_frame &&
|
||||
((MPEGVIDEO_VOS_START_CODE == marker) ||
|
||||
(MPEGVIDEO_VISUAL_OBJECT_START_CODE == marker) ||
|
||||
(0x00000140 > marker)))
|
||||
first_frame_start = -1;
|
||||
else
|
||||
first_frame_start = bits.get_bit_position() / 8 - 4;
|
||||
} catch(...) {
|
||||
}
|
||||
|
||||
if (!first_frame) {
|
||||
frame.size = size - frame.pos;
|
||||
frames.push_back(frame);
|
||||
if (2 <= verbose) {
|
||||
mxverb(2, "mpeg4_frames: summary: found %d frames ", frames.size());
|
||||
for (fit = frames.begin(); fit < frames.end(); fit++)
|
||||
mxverb(2, "'%c' (%d at %d) ", fit->type, fit->size, fit->pos);
|
||||
mxverb(2, "\n");
|
||||
}
|
||||
mxverb(2, "mpeg4_frames: summary: found %d frames ", frames.size());
|
||||
for (fit = frames.begin(); fit < frames.end(); fit++)
|
||||
mxverb(2, "'%c' (%d at %d) ",
|
||||
fit->type, fit->size, fit->pos);
|
||||
mxverb(2, "\n");
|
||||
|
||||
fit = frames.begin();
|
||||
while (fit < frames.end()) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <matroska/KaxSegment.h>
|
||||
#include <matroska/KaxSeekHead.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "commonebml.h"
|
||||
#include "error.h"
|
||||
#include "quickparser.h"
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <FLAC/stream_decoder.h>
|
||||
|
||||
#include "bit_cursor.h"
|
||||
#include "common.h"
|
||||
#include "flac_common.h"
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <matroska/KaxTrackVideo.h>
|
||||
|
||||
#include "bit_cursor.h"
|
||||
#include "common.h"
|
||||
#include "error.h"
|
||||
#include "p_aac.h"
|
||||
|
@ -295,6 +295,8 @@ mpeg1_2_video_packetizer_c::create_private_data() {
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
mpeg4_p2_video_packetizer_c::
|
||||
mpeg4_p2_video_packetizer_c(generic_reader_c *_reader,
|
||||
double _fps,
|
||||
@ -305,7 +307,7 @@ mpeg4_p2_video_packetizer_c(generic_reader_c *_reader,
|
||||
video_packetizer_c(_reader, MKV_V_MPEG4_ASP, _fps, _width, _height, _ti),
|
||||
timecodes_generated(0),
|
||||
aspect_ratio_extracted(false), input_is_native(_input_is_native),
|
||||
output_is_native(hack_engaged(ENGAGE_NATIVE_MPEG4)) {
|
||||
output_is_native(hack_engaged(ENGAGE_NATIVE_MPEG4)), csum(0) {
|
||||
|
||||
if (input_is_native && !output_is_native)
|
||||
mxerror("mkvmerge does not support muxing from native MPEG-4 to "
|
||||
@ -325,15 +327,28 @@ mpeg4_p2_video_packetizer_c(generic_reader_c *_reader,
|
||||
}
|
||||
}
|
||||
|
||||
mpeg4_p2_video_packetizer_c::~mpeg4_p2_video_packetizer_c() {
|
||||
mxinfo("\nCSUM: %lld\n", csum);
|
||||
}
|
||||
|
||||
int
|
||||
mpeg4_p2_video_packetizer_c::process(memory_c &mem,
|
||||
int64_t old_timecode,
|
||||
int64_t duration,
|
||||
int64_t bref,
|
||||
int64_t fref) {
|
||||
vector<video_frame_t> frames;
|
||||
vector<video_frame_t>::const_iterator frame;
|
||||
|
||||
if (!aspect_ratio_extracted)
|
||||
extract_aspect_ratio(mem.data, mem.size);
|
||||
|
||||
mpeg4_p2_find_frame_types(mem.data, mem.size, frames);
|
||||
foreach(frame, frames) {
|
||||
csum += frame->type + frame->size;
|
||||
mxinfo("\nFRAME: type %c size %d\n", frame->type, frame->size);
|
||||
}
|
||||
|
||||
if (input_is_native == output_is_native)
|
||||
return
|
||||
video_packetizer_c::process(mem, old_timecode, duration, bref, fref);
|
||||
|
@ -84,11 +84,13 @@ protected:
|
||||
int64_t timecodes_generated;
|
||||
video_frame_t bref_frame, fref_frame;
|
||||
bool aspect_ratio_extracted, input_is_native, output_is_native;
|
||||
int64_t csum;
|
||||
|
||||
public:
|
||||
mpeg4_p2_video_packetizer_c(generic_reader_c *_reader,
|
||||
double _fps, int _width, int _height,
|
||||
bool _input_is_native, track_info_c *_ti);
|
||||
virtual ~mpeg4_p2_video_packetizer_c();
|
||||
|
||||
virtual int process(memory_c &mem, int64_t old_timecode = -1,
|
||||
int64_t duration = -1, int64_t bref = VFT_IFRAME,
|
||||
|
Loading…
Reference in New Issue
Block a user