⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg2enc.cc

📁 Motion JPEG编解码器源代码
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* mpeg2enc.cc, YUV4MPEG / mjpegtools command line wrapper for * mpeg2enc++ library *//* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. *//* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose.  In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders.  Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * *//* Modifications and enhancements (C) 2000/2001 Andrew Stevens *//* These modifications are free software; you can redistribute it *  and/or modify it under the terms of the GNU General Public License *  as published by the Free Software Foundation; either version 2 of *  the License, or (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * */#include <config.h>#include <stdio.h>#ifdef HAVE_GETOPT_H#include <getopt.h>#endif#include <string.h>#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include "mpeg2encoder.hh"#include "mpeg2encoptions.hh"#include "encoderparams.hh"#include "picturereader.hh"#include "elemstrmwriter.hh"#include "quantize.hh"#include "ratectl.hh"#include "seqencoder.hh"#include "mpeg2coder.hh"#include "format_codes.h"#include "mpegconsts.h"#ifdef HAVE_ALTIVEC/* needed for ALTIVEC_BENCHMARK and print_benchmark_statistics() */#include "../utils/altivec/altivec_conf.h"#endif/************************** * * Derived class for File (actually: pipe and FIFO) based bitstream output * *************************/class FILE_StrmWriter : public ElemStrmWriter{public:    FILE_StrmWriter( EncoderParams &encparams, const char *outfilename )         {            /* open output file */            if (!(outfile=fopen(outfilename,"wb")))            {                mjpeg_error_exit1("Couldn't create output file %s",outfilename);            }        }    virtual void WriteOutBufferUpto( const uint8_t *buffer, const uint32_t flush_upto )        {            size_t written = fwrite( buffer,                                      sizeof(uint8_t),                                      static_cast<size_t>(flush_upto),                                     outfile );            if( written != static_cast<size_t>(flush_upto) )            {                mjpeg_error_exit1( strerror(ferror(outfile)) );            }	       flushed += flush_upto;        }    virtual ~FILE_StrmWriter()        {            fclose( outfile );        }            virtual size_t BitCount() { return flushed * 8LL; }private:    FILE *outfile;};/************************** * * Derived class for File (actually: pipe and FIFO) based input of frames * in the YUV4MPEG2 format * *************************/class Y4MPipeReader : public PictureReader{public:    Y4MPipeReader( EncoderParams &encparams, int istrm_fd );    ~Y4MPipeReader();    void StreamPictureParams( MPEG2EncInVidParams &strm );protected:    bool LoadFrame( );private:    int PipeRead(  uint8_t *buf, int len);    int pipe_fd;    y4m_stream_info_t _si;    y4m_frame_info_t _fi;}; Y4MPipeReader::Y4MPipeReader( EncoderParams &encparams, int istrm_fd ) :    PictureReader( encparams ),    pipe_fd( istrm_fd ){    y4m_init_stream_info(&_si);    y4m_init_frame_info(&_fi);}Y4MPipeReader::~Y4MPipeReader(){    y4m_fini_stream_info(&_si);    y4m_fini_frame_info(&_fi);}/**************************************** * * Initialise the reader and return the parameter of the video stream * to be encoded. * * WARNING: This routine must run before encoder parameters are defined. * TODO: Reader should be constructed before EncoderParams and this * routine invoked from EncoderParams constructor... * *****************************************/void Y4MPipeReader::StreamPictureParams( MPEG2EncInVidParams &strm ){   int n;   y4m_ratio_t sar;   if ((n = y4m_read_stream_header (pipe_fd, &_si)) != Y4M_OK) {       mjpeg_log( LOG_ERROR,                   "Could not read YUV4MPEG2 header: %s!",                  y4m_strerr(n));      exit (1);   }   strm.horizontal_size = y4m_si_get_width(&_si);   strm.vertical_size = y4m_si_get_height(&_si);   strm.frame_rate_code = mpeg_framerate_code(y4m_si_get_framerate(&_si));   strm.interlacing_code = y4m_si_get_interlace(&_si);   /* Deduce MPEG aspect ratio from stream's frame size and SAR...      (always as an MPEG-2 code; that's what caller expects). */   sar = y4m_si_get_sampleaspect(&_si);   strm.aspect_ratio_code =        mpeg_guess_mpeg_aspect_code(2, sar,                                    strm.horizontal_size,                                    strm.vertical_size);   if(strm.horizontal_size <= 0)   {       mjpeg_error_exit1("Horizontal size from input stream illegal");   }   if(strm.vertical_size <= 0)   {       mjpeg_error("Vertical size from input stream illegal");   }}/***************************** * * LoadFrame - pull in the image data planes from pipe (planar YUV420) * * RETURN: true iff EOF or ERROR * ****************************/bool Y4MPipeReader::LoadFrame( ){   int h,v,y;   int buffer_slot = frames_read % input_imgs_buf_size;   if ((y = y4m_read_frame_header (pipe_fd, &_si, &_fi)) != Y4M_OK)    {       if( y != Y4M_ERR_EOF )           mjpeg_log (LOG_WARN,                       "Error reading frame header (%d): code%s!",                       frames_read,                      y4m_strerr (y));       return true;      }         v = encparams.vertical_size;   h = encparams.horizontal_size;   int i;   for(i=0;i<v;i++)   {       if( PipeRead(input_imgs_buf[buffer_slot][0]+i*encparams.phy_width,h)!=h)           return true;   }   lum_mean[buffer_slot] = LumMean(input_imgs_buf[buffer_slot][0] );   v = encparams.vertical_size/2;   h = encparams.horizontal_size/2;   for(i=0;i<v;i++)   {       if(PipeRead(input_imgs_buf[buffer_slot][1]+i*encparams.phy_chrom_width,h)!=h)           return true;   }   for(i=0;i<v;i++)   {       if(PipeRead(input_imgs_buf[buffer_slot][2]+i*encparams.phy_chrom_width,h)!=h)           return true;   }   return false;}int Y4MPipeReader::PipeRead(uint8_t *buf, int len){   int n, r;   r = 0;   while(r<len)   {      n = read(pipe_fd,buf+r,len-r);      if(n==0) return r;      r += n;   }   return r;}/************************** * * Derived class for options set from command line * *************************/class MPEG2EncCmdLineOptions : public MPEG2EncOptions{public:    MPEG2EncCmdLineOptions();    int SetFromCmdLine(int argc, char *argv[] );    void Usage();    void StartupBanner();    void SetFormatPresets( const MPEG2EncInVidParams &strm );private:    void DisplayFrameRates();    void DisplayAspectRatios();    int ParseCustomMatrixFile(const char *fname, int dbug);    void ParseCustomOption(const char *arg);public:    int istrm_fd;    char *outfilename;};void MPEG2EncCmdLineOptions::SetFormatPresets( const MPEG2EncInVidParams &strm ){    if( MPEG2EncOptions::SetFormatPresets( strm ) )        Usage();}MPEG2EncCmdLineOptions::MPEG2EncCmdLineOptions() :    MPEG2EncOptions(){    outfilename = 0;    istrm_fd = 0;        }void MPEG2EncCmdLineOptions::DisplayFrameRates(void){ 	unsigned int i;	printf("Frame-rate codes:\n");    for( i = 1; mpeg_valid_framerate_code(i); ++i )	{		printf( "%2d - %s\n", i, mpeg_framerate_code_definition(i));	}	exit(0);}void MPEG2EncCmdLineOptions::DisplayAspectRatios(void){ 	unsigned int i;	printf("\nDisplay aspect ratio codes:\n");	for( i = 1; mpeg_valid_aspect_code(2, i); ++i )	{		printf( "%2d - %s\n", i, mpeg_aspect_code_definition(2,i));	}	exit(0);}int MPEG2EncCmdLineOptions::ParseCustomMatrixFile(const char *fname, int dbug){    FILE  *fp;    uint16_t  q[128];    int  i, j, row;    char line[80];    fp = fopen(fname, "r");    if  (!fp)    {        mjpeg_error("can not open custom matrix file '%s'", fname);        return(-1);    }    row = i = 0;    while   (fgets(line, sizeof(line), fp))    {        row++;        /* Empty lines (\n only) and comments are ignored */        if  ((strlen(line) == 1) || line[0] == '#')            continue;        j = sscanf(line, "%hu,%hu,%hu,%hu,%hu,%hu,%hu,%hu\n",                   &q[i+0], &q[i+1], &q[i+2], &q[i+3],                   &q[i+4], &q[i+5], &q[i+6], &q[i+7]);        if  (j != 8)        {            mjpeg_error("line %d ('%s') of '%s' malformed", row, line, fname);            break;        }        for (j = 0; j < 8; j++)        {            if  (q[i + j] < 1 || q[i + j] > 255)            {                mjpeg_error("entry %d (%u) in line %d from '%s' invalid",                            j, q[i + j], row, fname);                i = -1;                break;            }        }        i += 8;    }    fclose(fp);    if  (i != 128)    {        mjpeg_error("file '%s' did NOT have 128 values - ignoring custom matrix file", fname);        return(-1);    }    for (j = 0; j < 64; j++)    {        custom_intra_quantizer_matrix[j] = q[j];        custom_nonintra_quantizer_matrix[j] = q[j + 64];    }    if  (dbug)    {        mjpeg_info("INTRA and NONINTRA tables from '%s'",fname);        for (j = 0; j < 128; j += 8)        {            mjpeg_info("%u %u %u %u %u %u %u %u",                        q[j + 0], q[j + 1], q[j + 2], q[j + 3],                        q[j + 4], q[j + 5], q[j + 6], q[j + 7]);        }    }    return(0);}void MPEG2EncCmdLineOptions::ParseCustomOption(const char *arg){    if	(strcmp(arg, "kvcd") == 0)    	hf_quant = 3;    else if (strcmp(arg, "hi-res") == 0)    	hf_quant = 2;    else if (strcmp(arg, "default") == 0)    {    	hf_quant = 0;    	hf_q_boost = 0;    }    else if (strcmp(arg, "tmpgenc") == 0)    	hf_quant = 4;    else if (strncasecmp(arg, "file=", 5) == 0)    {    	if  (ParseCustomMatrixFile(arg + 5, arg[0] == 'F' ? 1 : 0) == 0)    	    hf_quant = 5;    }    else if (strcmp(arg, "help") == 0)    {    	fprintf(stderr, "Quantization matrix names:\n\n");    	fprintf(stderr, "\thelp - this message\n");    	fprintf(stderr, "\tkvcd - matrices from http://www.kvcd.net\n");    	fprintf(stderr, "\thi-res - high resolution tables (same as -H)\n");    	fprintf(stderr, "\tdefault - turn off -N or -H (use standard tables)\n");    	fprintf(stderr, "\ttmpgenc - TMPGEnc tables (http://www.tmpgenc.com)\n");    	fprintf(stderr, "\tfile=filename - filename contains custom matrices\n");    	fprintf(stderr, "\t\t8 comma separated values per line.  8 lines per matrix, INTRA matrix first, then NONINTRA\n");    	exit(0);    }    else    	mjpeg_error_exit1("Unknown type '%s' used with -K/--custom-quant", arg);}void MPEG2EncCmdLineOptions::Usage(){	fprintf(stderr,"--verbose|-v num\n" "    Level of verbosity. 0 = quiet, 1 = normal 2 = verbose/debug\n""--format|-f fmt\n""    Set pre-defined mux format fmt.\n""    [0 = Generic MPEG1, 1 = standard VCD, 2 = user VCD,\n""     3 = Generic MPEG2, 4 = standard SVCD, 5 = user SVCD,\n""     6 = VCD Stills sequences, 7 = SVCD Stills sequences, 8|9 = DVD]\n""--aspect|-a num\n""    Set displayed image aspect ratio image (default: 2 = 4:3)\n""    [1 = 1:1, 2 = 4:3, 3 = 16:9, 4 = 2.21:1]\n""--frame-rate|-F num\n""    Set playback frame rate of encoded video\n""    (default: frame rate of input stream)\n""    0 = Display frame rate code table\n""--video-bitrate|-b num\n""    Set Bitrate of compressed video in KBit/sec\n""    (default: 1152 for VCD, 2500 for SVCD, 7500 for DVD)\n""--nonvideo-bitrate|-B num\n""    Non-video data bitrate to assume for sequence splitting\n""    calculations (see also --sequence-length).\n""--quantisation|-q num\n""    Image data quantisation factor [1..31] (1 is best quality, no default)\n""    When quantisation is set variable bit-rate encoding is activated and\n""    the --bitrate value sets an *upper-bound* video data-rate\n""--output|-o pathname\n""    Pathname of output file or fifo (REQUIRED!!!)\n""--target-still-size|-T size\n""    Size in KB of VCD stills\n""--interlace-mode|-I num\n""    Sets MPEG 2 motion estimation and encoding modes:\n""    0 = Progressive (non-interlaced)(Movies)\n""    1 = Interlaced source material (video)\n""    2 = Interlaced source material, per-field-encoding (video)\n""--motion-search-radius|-r num\n""    Motion compensation search radius [0..32] (default 16)\n""--reduction-4x4|-4 num\n""    Reduction factor for 4x4 subsampled candidate motion estimates\n""    [1..4] [1 = max quality, 4 = max. speed] (default: 2)\n""--reduction-2x2|-2 num\n""    Reduction factor for 2x2 subsampled candidate motion estimates\n""    [1..4] [1 = max quality, 4 = max. speed] (default: 3)\n""--min-gop-size|-g num\n""    Minimum size Group-of-Pictures (default depends on selected format)\n""--max-gop-size|-G num\n""    Maximum size Group-of-Pictures (default depends on selected format)\n""    If min-gop is less than max-gop, mpeg2enc attempts to place GOP\n""    boundaries to coincide with scene changes\n""--closed-gop|-c\n""    All Group-of-Pictures are closed.  Useful for authoring multi-angle DVD\n""--force-b-b-p|-P\n""    Preserve two B frames between I/P frames when placing GOP boundaries\n""--quantisation-reduction|-Q num\n""    Max. quantisation reduction for highly active blocks\n""    [0.0 .. 4.0] (default: 0.0)\n""--quant-reduction-max-var|-X num\n""    Luma variance below which quantisation boost (-Q) is used\n""    [0.0 .. 2500.0](default: 0.0)\n""--video-buffer|-V num\n""    Target decoders video buffer size in KB (default 46)\n""--video-norm|-n n|p|s\n""    Tag output to suit playback in specified video norm\n""    (n = NTSC, p = PAL, s = SECAM) (default: PAL)\n""--sequence-length|-S num\n""    Place a sequence boundary in the video stream so they occur every\n""    num Mbytes once the video is multiplexed with audio etc.\n""    N.b. --non-video-bitrate is used to the bitrate of the other\n""    data that will be multiplexed with this video stream\n""--3-2-pulldown|-p\n""    Generate header flags for 3-2 pull down of 24fps movie material\n""--intra_dc_prec|-D [8..11]\n""    Set number of bits precision for DC (base colour) of blocks in MPEG-2\n""--reduce-hf|-N num\n""    [0.0..2.0] Reduce hf resolution (increase quantization) by num (default: 0.0)\n""--keep-hf|-H\n""    Maximise high-frequency resolution - useful for high quality sources\n""    and/or high bit-rates)\n""--sequence-header-every-gop|-s\n""    Include a sequence header every GOP if the selected format doesn't\n""    do so by default.\n""--no-dummy-svcd-SOF|-d\n""    Do not generate dummy SVCD scan-data for the ISO CD image\n""    generator \"vcdimager\" to fill in.\n""--playback-field-order|-z b|t\n"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -