mirror of
https://github.com/mpv-player/mpv
synced 2024-12-28 06:03:45 +01:00
fixes for encoding of multiple files
- do not uninitialize video encoder between files - checks for image size & format change moved from mencoder.c to vfilters by Oded Shimon <ods15@ods15.dyndns.org> git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@14879 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
9bc6e80972
commit
18abbb69a1
@ -215,7 +215,7 @@ static char help_text[]=
|
||||
#define MSGTR_WritingAVIHeader "Writing AVI header...\n"
|
||||
#define MSGTR_DuplicateFrames "\n%d duplicate frame(s)!\n"
|
||||
#define MSGTR_SkipFrame "\nSkipping frame!\n"
|
||||
#define MSGTR_ResolutionDoesntMatch "\nNew video file has different resolution than the previous one.\n"
|
||||
#define MSGTR_ResolutionDoesntMatch "\nNew video file has different resolution or colorspace than the previous one.\n"
|
||||
#define MSGTR_FrameCopyFileMismatch "\nAll video files must have identical fps, resolution, and codec for -ovc copy.\n"
|
||||
#define MSGTR_AudioCopyFileMismatch "\nAll files must have identical audio codec and format for -oac copy.\n"
|
||||
#define MSGTR_ErrorWritingFile "%s: Error writing file.\n"
|
||||
|
@ -309,10 +309,10 @@ csp_again:
|
||||
|
||||
vf->w = sh->disp_w;
|
||||
vf->h = sh->disp_h;
|
||||
if(vf->config(vf,sh->disp_w,sh->disp_h,
|
||||
screen_size_x,screen_size_y,
|
||||
fullscreen|(vidmode<<1)|(softzoom<<2)|(flip<<3),
|
||||
out_fmt)==0){
|
||||
if(vf_config_wrapper(vf,sh->disp_w,sh->disp_h,
|
||||
screen_size_x,screen_size_y,
|
||||
fullscreen|(vidmode<<1)|(softzoom<<2)|(flip<<3),
|
||||
out_fmt)==0){
|
||||
// "MPlayer",out_fmt)){
|
||||
mp_msg(MSGT_CPLAYER,MSGL_WARN,MSGTR_CannotInitVO);
|
||||
sh->vf_inited=-1;
|
||||
|
@ -453,6 +453,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char* args){
|
||||
vf->config=config;
|
||||
vf->default_caps=VFCAP_CONSTANT;
|
||||
vf->control=control;
|
||||
vf->query_format=query_format;
|
||||
vf->put_image=put_image;
|
||||
|
@ -923,6 +923,7 @@ static void uninit(struct vf_instance_s* vf){
|
||||
static int vf_open(vf_instance_t *vf, char* args){
|
||||
vf->uninit=uninit;
|
||||
vf->config=config;
|
||||
vf->default_caps=VFCAP_CONSTANT;
|
||||
vf->control=control;
|
||||
vf->query_format=query_format;
|
||||
vf->put_image=put_image;
|
||||
|
@ -85,6 +85,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char* args){
|
||||
vf->config=config;
|
||||
vf->default_caps=VFCAP_CONSTANT;
|
||||
vf->control=control;
|
||||
vf->query_format=query_format;
|
||||
vf->put_image=put_image;
|
||||
|
@ -192,6 +192,7 @@ static void uninit(struct vf_instance_s* vf) {
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char* args){
|
||||
vf->config=config;
|
||||
vf->default_caps=VFCAP_CONSTANT;
|
||||
vf->control=control;
|
||||
vf->query_format=query_format;
|
||||
vf->put_image=put_image;
|
||||
|
@ -278,6 +278,7 @@ if(!codec_inited){
|
||||
static int vf_open(vf_instance_t *vf, char* args){
|
||||
OSErr cres = 1;
|
||||
vf->config=config;
|
||||
vf->default_caps=VFCAP_CONSTANT;
|
||||
vf->control=control;
|
||||
vf->query_format=query_format;
|
||||
vf->put_image=put_image;
|
||||
|
@ -125,6 +125,7 @@ static int put_image(struct vf_instance_s *vf, mp_image_t *mpi) {
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char* args){
|
||||
vf->config = config;
|
||||
vf->default_caps = VFCAP_CONSTANT;
|
||||
vf->control = control;
|
||||
vf->query_format = query_format;
|
||||
vf->put_image = put_image;
|
||||
|
@ -251,6 +251,7 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char* args){
|
||||
vf->config=config;
|
||||
vf->default_caps=VFCAP_CONSTANT;
|
||||
vf->control=control;
|
||||
vf->query_format=query_format;
|
||||
vf->put_image=put_image;
|
||||
|
@ -375,6 +375,7 @@ static int vf_open(vf_instance_t *vf, char *args) {
|
||||
h264_module_t *mod;
|
||||
|
||||
vf->config = config;
|
||||
vf->default_caps = VFCAP_CONSTANT;
|
||||
vf->control = control;
|
||||
vf->query_format = query_format;
|
||||
vf->put_image = put_image;
|
||||
|
@ -539,6 +539,7 @@ vf_open(vf_instance_t *vf, char* args)
|
||||
{
|
||||
XVID_INIT_PARAM params = { 0, 0, 0};
|
||||
vf->config = config;
|
||||
vf->default_caps = VFCAP_CONSTANT;
|
||||
vf->control = control;
|
||||
vf->uninit = uninit;
|
||||
vf->query_format = query_format;
|
||||
|
@ -546,6 +546,7 @@ vf_open(vf_instance_t *vf, char* args)
|
||||
|
||||
/* Setting libmpcodec module API pointers */
|
||||
vf->config = config;
|
||||
vf->default_caps = VFCAP_CONSTANT;
|
||||
vf->control = control;
|
||||
vf->uninit = uninit;
|
||||
vf->query_format = query_format;
|
||||
|
@ -541,6 +541,37 @@ void vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src){
|
||||
dst->qscale= src->qscale;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief Video config() function wrapper
|
||||
*
|
||||
* Blocks config() calls with different size or format for filters
|
||||
* with VFCAP_CONSTANT
|
||||
*
|
||||
* First call is redirected to vf->config.
|
||||
*
|
||||
* In following calls, it verifies that the configuration parameters
|
||||
* are unchanged, and returns either success or error.
|
||||
*
|
||||
*/
|
||||
int vf_config_wrapper(struct vf_instance_s* vf,
|
||||
int width, int height, int d_width, int d_height,
|
||||
unsigned int flags, unsigned int outfmt)
|
||||
{
|
||||
if ((vf->default_caps&VFCAP_CONSTANT) && vf->fmt.have_configured) {
|
||||
if ((vf->fmt.orig_width != width)
|
||||
|| (vf->fmt.orig_height != height)
|
||||
|| (vf->fmt.orig_fmt != outfmt)) {
|
||||
mp_msg(MSGT_VFILTER,MSGL_FATAL,MSGTR_ResolutionDoesntMatch);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
vf->fmt.have_configured = 1;
|
||||
vf->fmt.orig_height = height;
|
||||
vf->fmt.orig_width = width;
|
||||
vf->fmt.orig_fmt = outfmt;
|
||||
vf->config(vf, width, height, d_width, d_height, flags, outfmt);
|
||||
}
|
||||
|
||||
int vf_next_config(struct vf_instance_s* vf,
|
||||
int width, int height, int d_width, int d_height,
|
||||
@ -571,7 +602,7 @@ int vf_next_config(struct vf_instance_s* vf,
|
||||
vf->next=vf2;
|
||||
}
|
||||
vf->next->w = width; vf->next->h = height;
|
||||
return vf->next->config(vf->next,width,height,d_width,d_height,voflags,outfmt);
|
||||
return vf_config_wrapper(vf->next,width,height,d_width,d_height,voflags,outfmt);
|
||||
}
|
||||
|
||||
int vf_next_control(struct vf_instance_s* vf, int request, void* data){
|
||||
|
@ -19,6 +19,11 @@ typedef struct vf_image_context_s {
|
||||
int static_idx;
|
||||
} vf_image_context_t;
|
||||
|
||||
typedef struct vf_format_context_t {
|
||||
int have_configured;
|
||||
int orig_width, orig_height, orig_fmt;
|
||||
} vf_format_context_t;
|
||||
|
||||
typedef struct vf_instance_s {
|
||||
vf_info_t* info;
|
||||
// funcs:
|
||||
@ -44,6 +49,7 @@ typedef struct vf_instance_s {
|
||||
// data:
|
||||
int w, h;
|
||||
vf_image_context_t imgctx;
|
||||
vf_format_context_t fmt;
|
||||
struct vf_instance_s* next;
|
||||
mp_image_t *dmpi;
|
||||
struct vf_priv_s* priv;
|
||||
@ -99,3 +105,6 @@ void vf_list_plugins();
|
||||
void vf_uninit_filter(vf_instance_t* vf);
|
||||
void vf_uninit_filter_chain(vf_instance_t* vf);
|
||||
|
||||
int vf_config_wrapper(struct vf_instance_s* vf,
|
||||
int width, int height, int d_width, int d_height,
|
||||
unsigned int flags, unsigned int outfmt);
|
||||
|
@ -24,4 +24,6 @@
|
||||
#define VFCAP_ACCEPT_STRIDE 0x400
|
||||
// filter does postprocessing (so you shouldn't scale/filter image before it)
|
||||
#define VFCAP_POSTPROC 0x800
|
||||
// filter cannot be reconfigured to different size & format
|
||||
#define VFCAP_CONSTANT 0x1000
|
||||
|
||||
|
46
mencoder.c
46
mencoder.c
@ -392,8 +392,6 @@ char* frameno_filename="frameno.avi";
|
||||
int decoded_frameno=0;
|
||||
int next_frameno=-1;
|
||||
int curfile=0;
|
||||
int prevwidth = 0;
|
||||
int prevhieght = 0; ///< When different from 0, after decoding a frame, Resolution must be checked to match previous file
|
||||
|
||||
unsigned int timer_start;
|
||||
|
||||
@ -739,8 +737,9 @@ case VCODEC_FRAMENO:
|
||||
mux_v->bih->biSizeImage=mux_v->bih->biWidth*mux_v->bih->biHeight*(mux_v->bih->biBitCount/8);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
default: {
|
||||
static vf_instance_t * ve = NULL;
|
||||
if (!ve) {
|
||||
switch(mux_v->codec){
|
||||
case VCODEC_DIVX4:
|
||||
sh_video->vfilter=vf_open_encoder(NULL,"divx4",(char *)mux_v); break;
|
||||
@ -765,6 +764,8 @@ default:
|
||||
mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_EncoderOpenFailed);
|
||||
mencoder_exit(1,NULL);
|
||||
}
|
||||
ve = sh_video->vfilter;
|
||||
} else sh_video->vfilter = ve;
|
||||
// append 'expand' filter, it fixes stride problems and renders osd:
|
||||
if (auto_expand) {
|
||||
char* vf_args[] = { "osd", "1", NULL };
|
||||
@ -776,7 +777,7 @@ default:
|
||||
init_best_video_codec(sh_video,video_codec_list,video_fm_list);
|
||||
mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
|
||||
if(!sh_video->inited) mencoder_exit(1,NULL);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!curfile) {
|
||||
@ -1544,13 +1545,7 @@ default:
|
||||
blit_frame=decode_video(sh_video,start,in_size,
|
||||
skip_flag>0 && (!sh_video->vfilter || ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE));
|
||||
|
||||
if (prevwidth) {
|
||||
if ((mux_v->bih->biWidth != prevwidth) || (mux_v->bih->biHeight != prevhieght)) {
|
||||
mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ResolutionDoesntMatch);
|
||||
mencoder_exit(1,NULL);
|
||||
}
|
||||
prevhieght = prevwidth = 0;
|
||||
}
|
||||
if (sh_video->vf_inited < 0) mencoder_exit(1, NULL);
|
||||
|
||||
if(!blit_frame){
|
||||
badframes++;
|
||||
@ -1724,28 +1719,33 @@ if(sh_audio && !demuxer2){
|
||||
|
||||
} // while(!at_eof)
|
||||
|
||||
/* Emit the remaining frames in the video system */
|
||||
/*TODO emit frmaes delayed by decoder lag*/
|
||||
if(sh_video && sh_video->vfilter){
|
||||
mp_msg(MSGT_FIXME, MSGL_FIXME, "\nFlushing video frames\n");
|
||||
((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter,
|
||||
VFCTRL_FLUSH_FRAMES, 0);
|
||||
}
|
||||
|
||||
if (!interrupted && filelist[++curfile].name != 0) {
|
||||
// Before uniniting sh_video and the filter chain, break apart the VE.
|
||||
vf_instance_t * ve; // this will be the filter right before the ve.
|
||||
for (ve = sh_video->vfilter; ve->next && ve->next->next; ve = ve->next);
|
||||
if (ve->next)
|
||||
ve->next = NULL; // I'm telling the last filter, before the VE, there is nothing after it
|
||||
else // There is no chain except the VE.
|
||||
sh_video->vfilter = NULL;
|
||||
|
||||
if(sh_video){ uninit_video(sh_video);sh_video=NULL; }
|
||||
if(demuxer) free_demuxer(demuxer);
|
||||
if(stream) free_stream(stream); // kill cache thread
|
||||
|
||||
prevwidth = mux_v->bih->biWidth;
|
||||
prevhieght = mux_v->bih->biHeight;
|
||||
|
||||
at_eof = 0;
|
||||
|
||||
m_config_pop(mconfig);
|
||||
goto play_next_file;
|
||||
}
|
||||
|
||||
/* Emit the remaining frames in the video system */
|
||||
/*TODO emit frmaes delayed by decoder lag*/
|
||||
if(sh_video && sh_video->vfilter){
|
||||
mp_msg(MSGT_MENCODER, MSGL_INFO, "\nFlushing video frames\n");
|
||||
((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter,
|
||||
VFCTRL_FLUSH_FRAMES, 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_MP3LAME
|
||||
// fixup CBR mp3 audio header:
|
||||
if(sh_audio && mux_a->codec==ACODEC_VBRMP3 && !lame_param_vbr){
|
||||
|
Loading…
Reference in New Issue
Block a user