mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
Moved the MPEG 1/2 ES framing from the MPEG ES demuxer into a new packetizer.
This commit is contained in:
parent
7bb703c8aa
commit
f2357e2f13
@ -120,8 +120,6 @@ mpeg_es_reader_c::mpeg_es_reader_c(track_info_c *nti)
|
|||||||
mxverb(2, "mpeg_es_reader: v %d width %d height %d FPS %e AR %e\n",
|
mxverb(2, "mpeg_es_reader: v %d width %d height %d FPS %e AR %e\n",
|
||||||
version, width, height, frame_rate, aspect_ratio);
|
version, width, height, frame_rate, aspect_ratio);
|
||||||
|
|
||||||
duration = 0;
|
|
||||||
|
|
||||||
} catch (exception &ex) {
|
} catch (exception &ex) {
|
||||||
throw error_c("mpeg_es_reader: Could not open the file.");
|
throw error_c("mpeg_es_reader: Could not open the file.");
|
||||||
}
|
}
|
||||||
@ -138,43 +136,30 @@ mpeg_es_reader_c::create_packetizer(int64_t) {
|
|||||||
if (NPTZR() != 0)
|
if (NPTZR() != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
add_packetizer(new video_packetizer_c(this,
|
add_packetizer(new mpeg_12_video_packetizer_c(this, version, frame_rate,
|
||||||
mxsprintf("V_MPEG%d", version).c_str(),
|
width, height,
|
||||||
frame_rate, width, height, false, ti));
|
(int)(height * aspect_ratio),
|
||||||
// Unless overridden on the command line handle the embedded aspect ratio
|
height, ti));
|
||||||
// of the MPEG-1/-2 stream.
|
|
||||||
if (!PTZR0->ti->aspect_ratio_given && !PTZR0->ti->display_dimensions_given) {
|
|
||||||
PTZR0->ti->display_dimensions_given = true;
|
|
||||||
PTZR0->ti->display_width = (int)(height * aspect_ratio);
|
|
||||||
PTZR0->ti->display_height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
mxinfo(FMT_TID "Using the video output module.\n", ti->fname.c_str(),
|
mxinfo(FMT_TID "Using the MPEG 1/2 video output module.\n",
|
||||||
(int64_t)0);
|
ti->fname.c_str(), (int64_t)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_status_e
|
file_status_e
|
||||||
mpeg_es_reader_c::read(generic_packetizer_c *,
|
mpeg_es_reader_c::read(generic_packetizer_c *,
|
||||||
bool) {
|
bool) {
|
||||||
MPEGFrame *frame;
|
unsigned char *chunk;
|
||||||
|
int num_read;
|
||||||
|
|
||||||
if (!read_frame(m2v_parser, *mm_io)) {
|
chunk = (unsigned char *)safemalloc(20000);
|
||||||
PTZR0->flush();
|
num_read = mm_io->read(chunk, 20000);
|
||||||
|
if (num_read <= 0) {
|
||||||
|
safefree(chunk);
|
||||||
return FILE_STATUS_DONE;
|
return FILE_STATUS_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = m2v_parser.ReadFrame();
|
memory_c mem(chunk, num_read, true);
|
||||||
if (!frame) {
|
PTZR0->process(mem);
|
||||||
PTZR0->flush();
|
|
||||||
return FILE_STATUS_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memory_c mem(frame->data, frame->size, true);
|
|
||||||
PTZR0->process(mem, frame->timecode, frame->duration,
|
|
||||||
frame->firstRef, frame->secondRef);
|
|
||||||
|
|
||||||
frame->data = NULL;
|
|
||||||
delete frame;
|
|
||||||
|
|
||||||
bytes_processed = mm_io->getFilePointer();
|
bytes_processed = mm_io->getFilePointer();
|
||||||
|
|
||||||
@ -389,49 +374,6 @@ mpeg_ps_reader_c::read(generic_packetizer_c *,
|
|||||||
return FILE_STATUS_DONE;
|
return FILE_STATUS_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
mpeg_ps_reader_c::read_frame(M2VParser &parser,
|
|
||||||
mm_io_c &in,
|
|
||||||
int64_t max_size) {
|
|
||||||
// int bytes_probed;
|
|
||||||
|
|
||||||
// bytes_probed = 0;
|
|
||||||
// while (true) {
|
|
||||||
// int state;
|
|
||||||
|
|
||||||
// state = parser.GetState();
|
|
||||||
|
|
||||||
// if (state == MPV_PARSER_STATE_NEED_DATA) {
|
|
||||||
// unsigned char *buffer;
|
|
||||||
// int bytes_read, bytes_to_read;
|
|
||||||
|
|
||||||
// if ((max_size != -1) && (bytes_probed > max_size))
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
// bytes_to_read = (parser.GetFreeBufferSpace() < READ_SIZE) ?
|
|
||||||
// parser.GetFreeBufferSpace() : READ_SIZE;
|
|
||||||
// buffer = new unsigned char[bytes_to_read];
|
|
||||||
// bytes_read = in.read(buffer, bytes_to_read);
|
|
||||||
// if (bytes_read == 0) {
|
|
||||||
// delete [] buffer;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// bytes_probed += bytes_read;
|
|
||||||
|
|
||||||
// parser.WriteData(buffer, bytes_read);
|
|
||||||
// delete [] buffer;
|
|
||||||
|
|
||||||
// } else if (state == MPV_PARSER_STATE_FRAME)
|
|
||||||
// return true;
|
|
||||||
|
|
||||||
// else if ((state == MPV_PARSER_STATE_EOS) ||
|
|
||||||
// (state == MPV_PARSER_STATE_ERROR))
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
mpeg_ps_reader_c::get_progress() {
|
mpeg_ps_reader_c::get_progress() {
|
||||||
return 100 * bytes_processed / size;
|
return 100 * bytes_processed / size;
|
||||||
|
@ -30,8 +30,7 @@ class track_info_c;
|
|||||||
class mpeg_es_reader_c: public generic_reader_c {
|
class mpeg_es_reader_c: public generic_reader_c {
|
||||||
private:
|
private:
|
||||||
mm_io_c *mm_io;
|
mm_io_c *mm_io;
|
||||||
int64_t bytes_processed, size, duration;
|
int64_t bytes_processed, size;
|
||||||
M2VParser m2v_parser;
|
|
||||||
|
|
||||||
int version, width, height;
|
int version, width, height;
|
||||||
double frame_rate, aspect_ratio;
|
double frame_rate, aspect_ratio;
|
||||||
@ -91,9 +90,6 @@ public:
|
|||||||
virtual void identify();
|
virtual void identify();
|
||||||
virtual void create_packetizer(int64_t id);
|
virtual void create_packetizer(int64_t id);
|
||||||
|
|
||||||
static bool read_frame(M2VParser &parser, mm_io_c &in,
|
|
||||||
int64_t max_size = -1);
|
|
||||||
|
|
||||||
static int probe_file(mm_io_c *mm_io, int64_t size);
|
static int probe_file(mm_io_c *mm_io, int64_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -384,3 +384,74 @@ video_packetizer_c::can_connect_to(generic_packetizer_c *src) {
|
|||||||
return CAN_CONNECT_NO_PARAMETERS;
|
return CAN_CONNECT_NO_PARAMETERS;
|
||||||
return CAN_CONNECT_YES;
|
return CAN_CONNECT_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
|
||||||
|
mpeg_12_video_packetizer_c::
|
||||||
|
mpeg_12_video_packetizer_c(generic_reader_c *_reader,
|
||||||
|
int _version,
|
||||||
|
double _fps,
|
||||||
|
int _width,
|
||||||
|
int _height,
|
||||||
|
int _dwidth,
|
||||||
|
int _dheight,
|
||||||
|
track_info_c *_ti):
|
||||||
|
video_packetizer_c(_reader, "V_MPEG1", _fps, _width, _height, true, _ti) {
|
||||||
|
|
||||||
|
mpeg_video = (_version == 1) ? MPEG_VIDEO_V1 : MPEG_VIDEO_V2;
|
||||||
|
set_codec_id(mxsprintf("V_MPEG%d", _version));
|
||||||
|
if (!ti->aspect_ratio_given && !ti->display_dimensions_given) {
|
||||||
|
ti->display_dimensions_given = true;
|
||||||
|
ti->display_width = _dwidth;
|
||||||
|
ti->display_height = _dheight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mpeg_12_video_packetizer_c::process(memory_c &mem,
|
||||||
|
int64_t,
|
||||||
|
int64_t,
|
||||||
|
int64_t,
|
||||||
|
int64_t) {
|
||||||
|
unsigned char *data_ptr;
|
||||||
|
int new_bytes, state;
|
||||||
|
|
||||||
|
state = parser.GetState();
|
||||||
|
if ((state == MPV_PARSER_STATE_EOS) ||
|
||||||
|
(state == MPV_PARSER_STATE_ERROR))
|
||||||
|
return FILE_STATUS_DONE;
|
||||||
|
|
||||||
|
data_ptr = mem.data;
|
||||||
|
new_bytes = mem.size;
|
||||||
|
|
||||||
|
do {
|
||||||
|
int bytes_to_add;
|
||||||
|
|
||||||
|
bytes_to_add = (parser.GetFreeBufferSpace() < new_bytes) ?
|
||||||
|
parser.GetFreeBufferSpace() : new_bytes;
|
||||||
|
if (bytes_to_add > 0) {
|
||||||
|
parser.WriteData(data_ptr, bytes_to_add);
|
||||||
|
data_ptr += bytes_to_add;
|
||||||
|
new_bytes -= bytes_to_add;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = parser.GetState();
|
||||||
|
while (state == MPV_PARSER_STATE_FRAME) {
|
||||||
|
MPEGFrame *frame;
|
||||||
|
|
||||||
|
frame = parser.ReadFrame();
|
||||||
|
if (frame == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
memory_c new_mem(frame->data, frame->size, true);
|
||||||
|
video_packetizer_c::process(new_mem, frame->timecode, frame->duration,
|
||||||
|
frame->firstRef, frame->secondRef);
|
||||||
|
frame->data = NULL;
|
||||||
|
delete frame;
|
||||||
|
|
||||||
|
state = parser.GetState();
|
||||||
|
}
|
||||||
|
} while (new_bytes > 0);
|
||||||
|
|
||||||
|
return FILE_STATUS_MOREDATA;
|
||||||
|
}
|
||||||
|
@ -21,13 +21,14 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "mpeg4_common.h"
|
#include "mpeg4_common.h"
|
||||||
#include "pr_generic.h"
|
#include "pr_generic.h"
|
||||||
|
#include "M2VParser.h"
|
||||||
|
|
||||||
#define VFT_IFRAME -1
|
#define VFT_IFRAME -1
|
||||||
#define VFT_PFRAMEAUTOMATIC -2
|
#define VFT_PFRAMEAUTOMATIC -2
|
||||||
#define VFT_NOBFRAME -1
|
#define VFT_NOBFRAME -1
|
||||||
|
|
||||||
class video_packetizer_c: public generic_packetizer_c {
|
class video_packetizer_c: public generic_packetizer_c {
|
||||||
private:
|
protected:
|
||||||
double fps;
|
double fps;
|
||||||
int width, height, bpp, frames_output;
|
int width, height, bpp, frames_output;
|
||||||
int64_t ref_timecode, duration_shift;
|
int64_t ref_timecode, duration_shift;
|
||||||
@ -64,4 +65,18 @@ protected:
|
|||||||
virtual void extract_mpeg1_2_fps(const unsigned char *buffer, int size);
|
virtual void extract_mpeg1_2_fps(const unsigned char *buffer, int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class mpeg_12_video_packetizer_c: public video_packetizer_c {
|
||||||
|
protected:
|
||||||
|
M2VParser parser;
|
||||||
|
|
||||||
|
public:
|
||||||
|
mpeg_12_video_packetizer_c(generic_reader_c *_reader, int _version,
|
||||||
|
double _fps, int _width, int _height,
|
||||||
|
int _dwidth, int _dheight, track_info_c *_ti);
|
||||||
|
|
||||||
|
virtual int process(memory_c &mem, int64_t old_timecode = -1,
|
||||||
|
int64_t duration = -1, int64_t bref = VFT_IFRAME,
|
||||||
|
int64_t fref = VFT_NOBFRAME);
|
||||||
|
};
|
||||||
|
|
||||||
#endif // __P_VIDEO_H
|
#endif // __P_VIDEO_H
|
||||||
|
Loading…
Reference in New Issue
Block a user