mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-23 19:31:44 +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",
|
||||
version, width, height, frame_rate, aspect_ratio);
|
||||
|
||||
duration = 0;
|
||||
|
||||
} catch (exception &ex) {
|
||||
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)
|
||||
return;
|
||||
|
||||
add_packetizer(new video_packetizer_c(this,
|
||||
mxsprintf("V_MPEG%d", version).c_str(),
|
||||
frame_rate, width, height, false, ti));
|
||||
// Unless overridden on the command line handle the embedded aspect ratio
|
||||
// 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;
|
||||
}
|
||||
add_packetizer(new mpeg_12_video_packetizer_c(this, version, frame_rate,
|
||||
width, height,
|
||||
(int)(height * aspect_ratio),
|
||||
height, ti));
|
||||
|
||||
mxinfo(FMT_TID "Using the video output module.\n", ti->fname.c_str(),
|
||||
(int64_t)0);
|
||||
mxinfo(FMT_TID "Using the MPEG 1/2 video output module.\n",
|
||||
ti->fname.c_str(), (int64_t)0);
|
||||
}
|
||||
|
||||
file_status_e
|
||||
mpeg_es_reader_c::read(generic_packetizer_c *,
|
||||
bool) {
|
||||
MPEGFrame *frame;
|
||||
unsigned char *chunk;
|
||||
int num_read;
|
||||
|
||||
if (!read_frame(m2v_parser, *mm_io)) {
|
||||
PTZR0->flush();
|
||||
chunk = (unsigned char *)safemalloc(20000);
|
||||
num_read = mm_io->read(chunk, 20000);
|
||||
if (num_read <= 0) {
|
||||
safefree(chunk);
|
||||
return FILE_STATUS_DONE;
|
||||
}
|
||||
|
||||
frame = m2v_parser.ReadFrame();
|
||||
if (!frame) {
|
||||
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;
|
||||
memory_c mem(chunk, num_read, true);
|
||||
PTZR0->process(mem);
|
||||
|
||||
bytes_processed = mm_io->getFilePointer();
|
||||
|
||||
@ -389,49 +374,6 @@ mpeg_ps_reader_c::read(generic_packetizer_c *,
|
||||
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
|
||||
mpeg_ps_reader_c::get_progress() {
|
||||
return 100 * bytes_processed / size;
|
||||
|
@ -30,8 +30,7 @@ class track_info_c;
|
||||
class mpeg_es_reader_c: public generic_reader_c {
|
||||
private:
|
||||
mm_io_c *mm_io;
|
||||
int64_t bytes_processed, size, duration;
|
||||
M2VParser m2v_parser;
|
||||
int64_t bytes_processed, size;
|
||||
|
||||
int version, width, height;
|
||||
double frame_rate, aspect_ratio;
|
||||
@ -91,9 +90,6 @@ public:
|
||||
virtual void identify();
|
||||
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);
|
||||
};
|
||||
|
||||
|
@ -384,3 +384,74 @@ video_packetizer_c::can_connect_to(generic_packetizer_c *src) {
|
||||
return CAN_CONNECT_NO_PARAMETERS;
|
||||
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 "mpeg4_common.h"
|
||||
#include "pr_generic.h"
|
||||
#include "M2VParser.h"
|
||||
|
||||
#define VFT_IFRAME -1
|
||||
#define VFT_PFRAMEAUTOMATIC -2
|
||||
#define VFT_NOBFRAME -1
|
||||
|
||||
class video_packetizer_c: public generic_packetizer_c {
|
||||
private:
|
||||
protected:
|
||||
double fps;
|
||||
int width, height, bpp, frames_output;
|
||||
int64_t ref_timecode, duration_shift;
|
||||
@ -64,4 +65,18 @@ protected:
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user