diff --git a/src/input/r_mpeg.cpp b/src/input/r_mpeg.cpp index d7e1fd5c2..ab5e21632 100644 --- a/src/input/r_mpeg.cpp +++ b/src/input/r_mpeg.cpp @@ -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; diff --git a/src/input/r_mpeg.h b/src/input/r_mpeg.h index d825a6194..8f032ed1b 100644 --- a/src/input/r_mpeg.h +++ b/src/input/r_mpeg.h @@ -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); }; diff --git a/src/output/p_video.cpp b/src/output/p_video.cpp index 236d17000..65144ee3f 100644 --- a/src/output/p_video.cpp +++ b/src/output/p_video.cpp @@ -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; +} diff --git a/src/output/p_video.h b/src/output/p_video.h index cd530db43..625566bff 100644 --- a/src/output/p_video.h +++ b/src/output/p_video.h @@ -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