diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1 index cdeb5e692b..4192d385f2 100644 --- a/DOCS/man/en/mplayer.1 +++ b/DOCS/man/en/mplayer.1 @@ -364,27 +364,6 @@ will not be displayed. Particularly useful on slow terminals or broken ones that do not properly handle carriage return (i.e. \\r). .TP -.B \-useaviaspect -With this option MPlayer and MEncoder will read and write the aspect -setting from the OpenDML AVI Video Property Header. - -This is a different method than the "aspect=..." option of -libavcodec or XviD, and is prioritized over it during playback, -because this header is processed first. - -Generally, encoding AVIs with square pixels is still the best -choice, so aspect headers should be avoided. -Some players can understand it, while they may not understand the -aspect headers produced by the codec. - -.I EXAMPLE: -.PD 0 -.RSs -.IPs "\-aspect 16:9 \-useaviaspect" -will add a header specifying 16:9 aspect ratio. -.RE -.PD 1 -.TP .B \-v, \-verbose Increment verbose level (more \-v means more verbosity). . @@ -3795,6 +3774,10 @@ will have the output file contain 'div3' as video fourcc. .PD 1 . .TP +.B \-force-avi-aspect <0.2\-3.0> +Override the aspect stored in the AVI OpenDML vprp header. +This can be used to change the aspect ratio with \-ovc copy. +.TP .B \-info (AVI only) Specify the info header of the resulting AVI file. .br diff --git a/cfg-common.h b/cfg-common.h index 2cf84fb941..7bfe6c9bd8 100644 --- a/cfg-common.h +++ b/cfg-common.h @@ -119,9 +119,6 @@ {"dvbin", dvbin_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #endif - {"useaviaspect", &avi_use_vprp_aspect, CONF_TYPE_FLAG, 0, 0, 1, NULL}, - {"nouseaviaspect", &avi_use_vprp_aspect, CONF_TYPE_FLAG, 0, 1, 0, NULL}, - // ------------------------- a-v sync options -------------------- // AVI specific: A-V sync mode (bps vs. interleaving) @@ -319,8 +316,6 @@ extern int ts_prog; extern int ts_keep_broken; extern off_t ts_probe; -extern int avi_use_vprp_aspect; /* defined in aviheader.c */ - #include "libmpdemux/tv.h" #ifdef USE_EDL diff --git a/cfg-mencoder.h b/cfg-mencoder.h index ebc58435a1..a2f6ce2f0f 100644 --- a/cfg-mencoder.h +++ b/cfg-mencoder.h @@ -160,6 +160,8 @@ m_option_t of_conf[]={ {NULL, NULL, 0, 0, 0, 0, NULL} }; +extern float avi_aspect_override; /* defined in libmpdemux/muxer_avi.c */ + m_option_t mencoder_opts[]={ /* name, pointer, type, flags, min, max */ @@ -192,6 +194,9 @@ m_option_t mencoder_opts[]={ // override FOURCC in output file {"ffourcc", &force_fourcc, CONF_TYPE_STRING, 0, 4, 4, NULL}, + // override avi aspect autodetection + {"force-avi-aspect", &avi_aspect_override, CONF_TYPE_FLOAT, CONF_RANGE, 0.2, 3.0, NULL}, + {"pass", "The -pass option is obsolete. Use -lavcopts vpass=n or -divx4opts pass=n!\nRTFM!\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL}, {"passlogfile", &passtmpfile, CONF_TYPE_STRING, 0, 0, 0, NULL}, diff --git a/libmpcodecs/ve_divx4.c b/libmpcodecs/ve_divx4.c index 4640b1d672..d0549d02ba 100644 --- a/libmpcodecs/ve_divx4.c +++ b/libmpcodecs/ve_divx4.c @@ -211,6 +211,7 @@ static int config(struct vf_instance_s* vf, mux_v->bih->biWidth=width; mux_v->bih->biHeight=height; mux_v->bih->biSizeImage=width*height*3; + mux_v->aspect = (float)d_width/d_height; if(!divx4_param.bitrate) divx4_param.bitrate=800000; else if(divx4_param.bitrate<=16000) divx4_param.bitrate*=1000; diff --git a/libmpcodecs/ve_lavc.c b/libmpcodecs/ve_lavc.c index c3ae0f2c49..538d730b91 100644 --- a/libmpcodecs/ve_lavc.c +++ b/libmpcodecs/ve_lavc.c @@ -519,6 +519,7 @@ static int config(struct vf_instance_s* vf, #else lavc_venc_context->aspect_ratio= ratio; #endif + mux_v->aspect = ratio; mp_dbg(MSGT_MENCODER, MSGL_DBG2, "aspect_ratio: %f\n", ratio); } else { mp_dbg(MSGT_MENCODER, MSGL_ERR, "aspect ratio: cannot parse \"%s\"\n", lavc_param_aspect); @@ -529,8 +530,9 @@ static int config(struct vf_instance_s* vf, #if LIBAVCODEC_BUILD >= 4687 lavc_venc_context->sample_aspect_ratio = av_d2q((float)d_width/d_height*height / width, 255); #else - lavc_venc_context->aspect_ratio = (float)d_width/d_height; + lavc_venc_context->aspect_ratio = #endif + mux_v->aspect = (float)d_width/d_height; /* keyframe interval */ if (lavc_param_keyint >= 0) /* != -1 */ diff --git a/libmpcodecs/ve_libdv.c b/libmpcodecs/ve_libdv.c index 2e0478021e..8b18c2be74 100644 --- a/libmpcodecs/ve_libdv.c +++ b/libmpcodecs/ve_libdv.c @@ -55,6 +55,7 @@ static int config(struct vf_instance_s* vf, mux_v->bih->biWidth=width; mux_v->bih->biHeight=height; mux_v->bih->biSizeImage=mux_v->bih->biWidth*mux_v->bih->biHeight*(mux_v->bih->biBitCount/8); + mux_v->aspect = (float)d_width/d_height; return 1; } diff --git a/libmpcodecs/ve_nuv.c b/libmpcodecs/ve_nuv.c index 1cff9e28a2..50a75666e5 100644 --- a/libmpcodecs/ve_nuv.c +++ b/libmpcodecs/ve_nuv.c @@ -80,6 +80,7 @@ static int config(struct vf_instance_s* vf, mux_v->bih->biWidth=width; mux_v->bih->biHeight=height; mux_v->bih->biSizeImage=mux_v->bih->biWidth*mux_v->bih->biHeight*(mux_v->bih->biBitCount/8); + mux_v->aspect = (float)d_width/d_height; vf->priv->buffer = realloc(vf->priv->buffer,vf->priv->buf_size); vf->priv->tbl_wrote = 0; diff --git a/libmpcodecs/ve_qtvideo.c b/libmpcodecs/ve_qtvideo.c index 81d5c6812d..f47095a747 100644 --- a/libmpcodecs/ve_qtvideo.c +++ b/libmpcodecs/ve_qtvideo.c @@ -129,6 +129,7 @@ static int config(struct vf_instance_s* vf, mux_v->bih->biWidth=width; mux_v->bih->biHeight=height; mux_v->bih->biSizeImage=width*height*2; + mux_v->aspect = (float)d_width/d_height; diff --git a/libmpcodecs/ve_raw.c b/libmpcodecs/ve_raw.c index ddc93a606f..b9461497d2 100644 --- a/libmpcodecs/ve_raw.c +++ b/libmpcodecs/ve_raw.c @@ -83,6 +83,7 @@ static int config(struct vf_instance_s *vf, int ret; mux_v->bih->biWidth = width; mux_v->bih->biHeight = height; + mux_v->aspect = (float)d_width/d_height; ret = set_format(vf, outfmt); if (!ret) return 0; diff --git a/libmpcodecs/ve_vfw.c b/libmpcodecs/ve_vfw.c index 61aad0cd8f..7241dd1dca 100644 --- a/libmpcodecs/ve_vfw.c +++ b/libmpcodecs/ve_vfw.c @@ -217,6 +217,7 @@ static int config(struct vf_instance_s* vf, vfw_bih->biWidth=width; vfw_bih->biHeight=height; vfw_bih->biSizeImage=width*height*((vfw_bih->biBitCount+7)/8); + mux_v->aspect = (float)d_width/d_height; if(!vfw_start_encoder(vfw_bih, mux_v->bih)) return 0; diff --git a/libmpcodecs/ve_xvid.c b/libmpcodecs/ve_xvid.c index 2beab7e43f..ceedf07dc6 100644 --- a/libmpcodecs/ve_xvid.c +++ b/libmpcodecs/ve_xvid.c @@ -172,6 +172,7 @@ config(struct vf_instance_s* vf, fp->mux->bih->biWidth = width; fp->mux->bih->biHeight = height; fp->mux->bih->biSizeImage = fp->mux->bih->biWidth * fp->mux->bih->biHeight * 3; + fp->mux->aspect = (float)d_width/d_height; mp_msg(MSGT_MENCODER,MSGL_INFO,"videocodec: XViD (%dx%d fourcc=%x [%.4s])\n", width, height, fp->mux->bih->biCompression, (char *)&fp->mux->bih->biCompression); diff --git a/libmpcodecs/ve_xvid4.c b/libmpcodecs/ve_xvid4.c index 137fa207af..850373c9b6 100644 --- a/libmpcodecs/ve_xvid4.c +++ b/libmpcodecs/ve_xvid4.c @@ -339,6 +339,7 @@ config(struct vf_instance_s* vf, mod->mux->bih->biHeight = height; mod->mux->bih->biSizeImage = mod->mux->bih->biWidth * mod->mux->bih->biHeight * 3; + mod->mux->aspect = (float)d_width/d_height; /* Message the FourCC type */ mp_msg(MSGT_MENCODER, MSGL_INFO, diff --git a/libmpdemux/aviheader.c b/libmpdemux/aviheader.c index a52d883c2f..7727d5285c 100644 --- a/libmpdemux/aviheader.c +++ b/libmpdemux/aviheader.c @@ -28,8 +28,6 @@ extern void print_index(AVIINDEXENTRY *idx,int idx_size); extern void print_avistdindex_chunk(avistdindex_chunk *h); extern void print_avisuperindex_chunk(avisuperindex_chunk *h); -int avi_use_vprp_aspect = 0; - static int odml_get_vstream_id(int id, unsigned char res[]) { unsigned char *p = (unsigned char *)&id; @@ -345,7 +343,7 @@ while(1){ for (i=0; inbFieldPerFrame; i++) { le2me_VIDEO_FIELD_DESC(&vprp->FieldInfo[i]); } - if (avi_use_vprp_aspect && sh_video) { + if (sh_video) { sh_video->aspect = GET_AVI_ASPECT(vprp->dwFrameAspectRatio); } if(verbose>=1) print_vprp(vprp); diff --git a/libmpdemux/muxer.h b/libmpdemux/muxer.h index bf546fca1f..2056ee9c5c 100644 --- a/libmpdemux/muxer.h +++ b/libmpdemux/muxer.h @@ -17,6 +17,7 @@ typedef struct { uint32_t ckid; // chunk id (00dc 01wb etc) double timer; off_t size; + float aspect; // aspect ratio of this stream (set by ve_*.c) // buffering: unsigned char *buffer; unsigned int buffer_size; diff --git a/libmpdemux/muxer_avi.c b/libmpdemux/muxer_avi.c index abe4d5d9f7..de93e7a6fa 100644 --- a/libmpdemux/muxer_avi.c +++ b/libmpdemux/muxer_avi.c @@ -34,7 +34,7 @@ extern char *info_comment; #define ODML_NOTKEYFRAME 0x80000000U #define MOVIALIGN 0x00001000 -extern int avi_use_vprp_aspect; +float avi_aspect_override = -1.0; struct avi_odmlidx_entry { uint64_t ofs; @@ -57,6 +57,35 @@ struct avi_stream_info { struct avi_odmlsuperidx_entry *superidx; }; +static unsigned int avi_aspect(muxer_stream_t *vstream) +{ + int x,y; + float aspect = vstream->aspect; + + if (avi_aspect_override > 0.0) { + aspect = avi_aspect_override; + } + + if (aspect <= 0.0) return 0; + + if (aspect > 15.99/9.0 && aspect < 16.01/9.0) { + return MAKE_AVI_ASPECT(16, 9); + } + if (aspect > 3.99/3.0 && aspect < 4.01/3.0) { + return MAKE_AVI_ASPECT(4, 3); + } + + if (aspect >= 1.0) { + x = 16384; + y = (float)x / aspect; + } else { + y = 16384; + x = (float)y * aspect; + } + + return MAKE_AVI_ASPECT(x, y); +} + static muxer_stream_t* avifile_new_stream(muxer_t *muxer,int type){ struct avi_stream_info *si; muxer_stream_t* s; @@ -225,21 +254,6 @@ static void write_avi_list(FILE *f,unsigned int id,int len){ #define WFSIZE(wf) (sizeof(WAVEFORMATEX)+(wf)->cbSize) -static unsigned int avi_aspect(float aspect) -{ - if (aspect <= 0.0) { - aspect = 4.0/3.0; - } - if (aspect >= 3.99/3.0 && - aspect <= 4.01/3.0) return MAKE_AVI_ASPECT(4,3); - if (aspect >= 15.99/9.0 && - aspect <= 16.01/9.0) return MAKE_AVI_ASPECT(16,9); - if (aspect >= 0.99 && - aspect <= 1.01) return MAKE_AVI_ASPECT(1,1); - if (aspect<1.0) return MAKE_AVI_ASPECT((int)(aspect*8192),8192); - return MAKE_AVI_ASPECT(8192,(int)(8192/aspect)); -} - static void avifile_write_header(muxer_t *muxer){ uint32_t riff[3]; unsigned int dmlh[1]; @@ -248,10 +262,16 @@ static void avifile_write_header(muxer_t *muxer){ muxer_info_t info[16]; FILE *f = muxer->file; VideoPropHeader vprp; - + uint32_t aspect = avi_aspect(muxer->def_v); off_t pos; int isodml = muxer->file_end > ODML_CHUNKLEN ? 1 : 0; + if (aspect == 0) { + mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: Aspect information not (yet?) available or unspecified, not writing vprp header.\n"); + } else { + mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: vprp aspect is %d:%d.\n", aspect >> 16, aspect & 0xffff); + } + if (isodml) { for (pos = 0; pos < muxer->file_end; pos += ODML_CHUNKLEN) { unsigned int rifflen, movilen; @@ -316,7 +336,7 @@ static void avifile_write_header(muxer_t *muxer){ switch(muxer->streams[i]->type){ case MUXER_TYPE_VIDEO: hdrsize+=muxer->streams[i]->bih->biSize+8; // strf - if (avi_use_vprp_aspect) { + if (aspect != 0) { hdrsize+=8+4*(9+8*1); // vprp } break; @@ -351,14 +371,13 @@ static void avifile_write_header(muxer_t *muxer){ s->h.fccHandler = s->bih->biCompression; s->h.rcFrame.right = s->bih->biWidth; s->h.rcFrame.bottom = s->bih->biHeight; - if (avi_use_vprp_aspect) { - sh_video_t *sh_video = s->source; + if (aspect != 0) { // fill out vprp info memset(&vprp, 0, sizeof(vprp)); vprp.dwVerticalRefreshRate = (s->h.dwRate+s->h.dwScale-1)/s->h.dwScale; vprp.dwHTotalInT = muxer->avih.dwWidth; vprp.dwVTotalInLines = muxer->avih.dwHeight; - vprp.dwFrameAspectRatio = avi_aspect(sh_video->aspect); + vprp.dwFrameAspectRatio = aspect; vprp.dwFrameWidthInPixels = muxer->avih.dwWidth; vprp.dwFrameHeightInLines = muxer->avih.dwHeight; vprp.nbFieldPerFrame = 1; @@ -388,7 +407,7 @@ static void avifile_write_header(muxer_t *muxer){ write_avi_chunk(f,ckidSTREAMFORMAT,biSize,s->bih); /* BITMAPINFOHEADER */ le2me_BITMAPINFOHEADER(s->bih); - if (avi_use_vprp_aspect) { + if (aspect != 0) { int fields = vprp.nbFieldPerFrame; le2me_VideoPropHeader(&vprp); le2me_VIDEO_FIELD_DESC(&vprp.FieldInfo[0]); diff --git a/mencoder.c b/mencoder.c index 57ae80bd14..4adbd77d58 100644 --- a/mencoder.c +++ b/mencoder.c @@ -663,12 +663,6 @@ case VCODEC_COPY: mux_v->bih->biBitCount=24; // FIXME!!! mux_v->bih->biSizeImage=mux_v->bih->biWidth*mux_v->bih->biHeight*(mux_v->bih->biBitCount/8); } - /* - * FIXME: with -ovc copy we don't get aspect ratio information - * from the source stream. - */ - if(movie_aspect>-1.0) sh_video->aspect = movie_aspect; - printf("videocodec: framecopy (%dx%d %dbpp fourcc=%x)\n", mux_v->bih->biWidth, mux_v->bih->biHeight, mux_v->bih->biBitCount, mux_v->bih->biCompression);