Moved the MPEG 1/2 ES framing from the MPEG ES demuxer into a new packetizer.

This commit is contained in:
Moritz Bunkus 2004-12-28 16:22:33 +00:00
parent 7bb703c8aa
commit f2357e2f13
4 changed files with 102 additions and 78 deletions

View File

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

View File

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

View File

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

View File

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