diff options
-rw-r--r-- | cfg-mplayer.h | 1 | ||||
-rw-r--r-- | command.c | 2 | ||||
-rwxr-xr-x | debian/rules | 2 | ||||
-rw-r--r-- | libao2/ao_coreaudio.c | 92 | ||||
-rw-r--r-- | libmpcodecs/ad.h | 23 | ||||
-rw-r--r-- | libmpcodecs/dec_video.c | 7 | ||||
-rw-r--r-- | libmpcodecs/dec_video.h | 1 | ||||
-rw-r--r-- | libmpcodecs/mpc_info.h | 24 | ||||
-rw-r--r-- | libmpcodecs/vd.h | 32 | ||||
-rw-r--r-- | libmpcodecs/vd_ffmpeg.c | 81 | ||||
-rw-r--r-- | libmpcodecs/vf.c | 853 | ||||
-rw-r--r-- | libmpcodecs/vf.h | 145 | ||||
-rw-r--r-- | libmpcodecs/vf_scale.c | 4 | ||||
-rw-r--r-- | mplayer.c | 24 | ||||
-rw-r--r-- | options.h | 1 | ||||
-rw-r--r-- | subopt-helper.c | 33 |
16 files changed, 732 insertions, 593 deletions
diff --git a/cfg-mplayer.h b/cfg-mplayer.h index 9c97caa93a..c8ca92e3a3 100644 --- a/cfg-mplayer.h +++ b/cfg-mplayer.h @@ -901,6 +901,7 @@ const m_option_t mplayer_opts[]={ OPT_MAKE_FLAGS("initial-audio-sync", initial_audio_sync, 0), OPT_CHOICE("hr-seek", hr_seek, 0, ({"off", -1}, {"absolute", 0}, {"always", 1}, {"on", 1})), + OPT_FLOATRANGE("hr-seek-demuxer-offset", hr_seek_demuxer_offset, 0, -9, 99), OPT_FLAG_CONSTANTS("noautosync", autosync, 0, 0, -1), OPT_INTRANGE("autosync", autosync, 0, 0, 10000), @@ -2949,7 +2949,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd) opts->movie_aspect = (float) sh_video->disp_w / sh_video->disp_h; else opts->movie_aspect = cmd->args[0].v.f; - mpcodecs_config_vo(sh_video, sh_video->disp_w, sh_video->disp_h, 0); + video_reset_aspect(sh_video); break; case MP_CMD_SPEED_INCR: { diff --git a/debian/rules b/debian/rules index 5a775b8906..d72bef3434 100755 --- a/debian/rules +++ b/debian/rules @@ -69,7 +69,7 @@ binary-arch: build install -D -m 644 etc/example.conf $(prefix)/etc/mplayer/mplayer.conf dh_installdocs -X.svn -Xmplayer.1 DOCS/* - dh_installexamples etc/example.conf etc/dvb-menu.conf etc/input.conf etc/menu.conf + dh_installexamples etc/example.conf etc/input.conf dh_installmime dh_installinfo dh_installchangelogs diff --git a/libao2/ao_coreaudio.c b/libao2/ao_coreaudio.c index cf43800659..34374f4c9c 100644 --- a/libao2/ao_coreaudio.c +++ b/libao2/ao_coreaudio.c @@ -133,7 +133,10 @@ static int write_buffer(unsigned char* data, int len){ static int read_buffer(unsigned char* data,int len){ int buffered = av_fifo_size(ao->buffer); if (len > buffered) len = buffered; - av_fifo_generic_read(ao->buffer, data, len, NULL); + if (data) + av_fifo_generic_read(ao->buffer, data, len, NULL); + else + av_fifo_drain(ao->buffer, len); return len; } @@ -657,25 +660,32 @@ static int OpenSPDIF(void) goto err_out; } + property_address.mSelector = kAudioDevicePropertySupportsMixing; + property_address.mScope = kAudioObjectPropertyScopeGlobal; + property_address.mElement = kAudioObjectPropertyElementMaster; + /* Set mixable to false if we are allowed to. */ - err = IsAudioPropertySettable(ao->i_selected_dev, - kAudioDevicePropertySupportsMixing, - &b_writeable); - err = GetAudioProperty(ao->i_selected_dev, - kAudioDevicePropertySupportsMixing, - sizeof(UInt32), &b_mix); - if (err != noErr && b_writeable) - { - b_mix = 0; - err = SetAudioProperty(ao->i_selected_dev, + if (AudioObjectHasProperty(ao->i_selected_dev, &property_address)) { + /* Set mixable to false if we are allowed to. */ + err = IsAudioPropertySettable(ao->i_selected_dev, + kAudioDevicePropertySupportsMixing, + &b_writeable); + err = GetAudioProperty(ao->i_selected_dev, kAudioDevicePropertySupportsMixing, sizeof(UInt32), &b_mix); - ao->b_changed_mixing = 1; - } - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); - goto err_out; + if (err == noErr && b_writeable) + { + b_mix = 0; + err = SetAudioProperty(ao->i_selected_dev, + kAudioDevicePropertySupportsMixing, + sizeof(UInt32), &b_mix); + ao->b_changed_mixing = 1; + } + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); + goto err_out; + } } /* Get a list of all the streams on this device. */ @@ -696,11 +706,11 @@ static int OpenSPDIF(void) for (i = 0; i < i_streams && ao->i_stream_index < 0; ++i) { /* Find a stream with a cac3 stream. */ - AudioStreamBasicDescription *p_format_list = NULL; + AudioStreamRangedDescription *p_format_list = NULL; int i_formats = 0, j = 0, b_digital = 0; i_param_size = GetGlobalAudioPropertyArray(p_streams[i], - kAudioStreamPropertyPhysicalFormats, + kAudioStreamPropertyAvailablePhysicalFormats, (void **)&p_format_list); if (!i_param_size) { @@ -709,13 +719,15 @@ static int OpenSPDIF(void) continue; } - i_formats = i_param_size / sizeof(AudioStreamBasicDescription); + i_formats = i_param_size / sizeof(AudioStreamRangedDescription); /* Check if one of the supported formats is a digital format. */ for (j = 0; j < i_formats; ++j) { - if (p_format_list[j].mFormatID == 'IAC3' || - p_format_list[j].mFormatID == kAudioFormat60958AC3) + if (p_format_list[j].mFormat.mFormatID == 'IAC3' || + p_format_list[j].mFormat.mFormatID == 'iac3' || + p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || + p_format_list[j].mFormat.mFormatID == kAudioFormatAC3) { b_digital = 1; break; @@ -750,25 +762,27 @@ static int OpenSPDIF(void) } for (j = 0; j < i_formats; ++j) - if (p_format_list[j].mFormatID == 'IAC3' || - p_format_list[j].mFormatID == kAudioFormat60958AC3) + if (p_format_list[j].mFormat.mFormatID == 'IAC3' || + p_format_list[j].mFormat.mFormatID == 'iac3' || + p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || + p_format_list[j].mFormat.mFormatID == kAudioFormatAC3) { - if (p_format_list[j].mSampleRate == ao->stream_format.mSampleRate) + if (p_format_list[j].mFormat.mSampleRate == ao->stream_format.mSampleRate) { i_requested_rate_format = j; break; } - if (p_format_list[j].mSampleRate == ao->sfmt_revert.mSampleRate) + if (p_format_list[j].mFormat.mSampleRate == ao->sfmt_revert.mSampleRate) i_current_rate_format = j; - else if (i_backup_rate_format < 0 || p_format_list[j].mSampleRate > p_format_list[i_backup_rate_format].mSampleRate) + else if (i_backup_rate_format < 0 || p_format_list[j].mFormat.mSampleRate > p_format_list[i_backup_rate_format].mFormat.mSampleRate) i_backup_rate_format = j; } if (i_requested_rate_format >= 0) /* We prefer to output at the samplerate of the original audio. */ - ao->stream_format = p_format_list[i_requested_rate_format]; + ao->stream_format = p_format_list[i_requested_rate_format].mFormat; else if (i_current_rate_format >= 0) /* If not possible, we will try to use the current samplerate of the device. */ - ao->stream_format = p_format_list[i_current_rate_format]; - else ao->stream_format = p_format_list[i_backup_rate_format]; /* And if we have to, any digital format will be just fine (highest rate possible). */ + ao->stream_format = p_format_list[i_current_rate_format].mFormat; + else ao->stream_format = p_format_list[i_backup_rate_format].mFormat; /* And if we have to, any digital format will be just fine (highest rate possible). */ } free(p_format_list); } @@ -913,12 +927,12 @@ static int AudioDeviceSupportsDigital( AudioDeviceID i_dev_id ) static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ) { UInt32 i_param_size; - AudioStreamBasicDescription *p_format_list = NULL; + AudioStreamRangedDescription *p_format_list = NULL; int i, i_formats, b_return = CONTROL_FALSE; /* Retrieve all the stream formats supported by each output stream. */ i_param_size = GetGlobalAudioPropertyArray(i_stream_id, - kAudioStreamPropertyPhysicalFormats, + kAudioStreamPropertyAvailablePhysicalFormats, (void **)&p_format_list); if (!i_param_size) { @@ -926,14 +940,16 @@ static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ) return CONTROL_FALSE; } - i_formats = i_param_size / sizeof(AudioStreamBasicDescription); + i_formats = i_param_size / sizeof(AudioStreamRangedDescription); for (i = 0; i < i_formats; ++i) { - print_format(MSGL_V, "supported format:", &p_format_list[i]); + print_format(MSGL_V, "supported format:", &(p_format_list[i].mFormat)); - if (p_format_list[i].mFormatID == 'IAC3' || - p_format_list[i].mFormatID == kAudioFormat60958AC3) + if (p_format_list[i].mFormat.mFormatID == 'IAC3' || + p_format_list[i].mFormat.mFormatID == 'iac3' || + p_format_list[i].mFormat.mFormatID == kAudioFormat60958AC3 || + p_format_list[i].mFormat.mFormatID == kAudioFormatAC3) b_return = CONTROL_OK; } @@ -1143,7 +1159,7 @@ static void uninit(int immed) if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) { UInt32 b_mix; - Boolean b_writeable; + Boolean b_writeable = 0; /* Revert mixable to true if we are allowed to. */ err = IsAudioPropertySettable(ao->i_selected_dev, kAudioDevicePropertySupportsMixing, @@ -1151,7 +1167,7 @@ static void uninit(int immed) err = GetAudioProperty(ao->i_selected_dev, kAudioDevicePropertySupportsMixing, sizeof(UInt32), &b_mix); - if (err != noErr && b_writeable) + if (err == noErr && b_writeable) { b_mix = 1; err = SetAudioProperty(ao->i_selected_dev, diff --git a/libmpcodecs/ad.h b/libmpcodecs/ad.h index 9b1daf9e48..5396085d04 100644 --- a/libmpcodecs/ad.h +++ b/libmpcodecs/ad.h @@ -22,32 +22,33 @@ #include "mpc_info.h" #include "libmpdemux/stheader.h" -typedef mp_codec_info_t ad_info_t; +typedef struct mp_codec_info ad_info_t; /* interface of video decoder drivers */ typedef struct ad_functions { - const ad_info_t *info; - int (*preinit)(sh_audio_t *sh); - int (*init)(sh_audio_t *sh); - void (*uninit)(sh_audio_t *sh); - int (*control)(sh_audio_t *sh,int cmd,void* arg, ...); - int (*decode_audio)(sh_audio_t *sh,unsigned char* buffer,int minlen,int maxlen); + const ad_info_t *info; + int (*preinit)(sh_audio_t *sh); + int (*init)(sh_audio_t *sh); + void (*uninit)(sh_audio_t *sh); + int (*control)(sh_audio_t *sh,int cmd,void* arg, ...); + int (*decode_audio)(sh_audio_t *sh, unsigned char *buffer, int minlen, + int maxlen); } ad_functions_t; // NULL terminated array of all drivers extern const ad_functions_t * const mpcodecs_ad_drivers[]; // fallback if ADCTRL_RESYNC not implemented: sh_audio->a_in_buffer_len=0; -#define ADCTRL_RESYNC_STREAM 1 /* resync, called after seeking! */ +#define ADCTRL_RESYNC_STREAM 1 // resync, called after seeking // fallback if ADCTRL_SKIP not implemented: ds_fill_buffer(sh_audio->ds); -#define ADCTRL_SKIP_FRAME 2 /* skip block/frame, called while seeking! */ +#define ADCTRL_SKIP_FRAME 2 // skip block/frame, called while seeking // fallback if ADCTRL_QUERY_FORMAT not implemented: sh_audio->sample_format -#define ADCTRL_QUERY_FORMAT 3 /* test for availabilty of a format */ +#define ADCTRL_QUERY_FORMAT 3 // test for availabilty of a format // fallback: use hw mixer in libao -#define ADCTRL_SET_VOLUME 4 /* set volume (used for mp3lib and liba52) */ +#define ADCTRL_SET_VOLUME 4 // not used at the moment #endif /* MPLAYER_AD_H */ diff --git a/libmpcodecs/dec_video.c b/libmpcodecs/dec_video.c index 91b255114a..cd3083faa4 100644 --- a/libmpcodecs/dec_video.c +++ b/libmpcodecs/dec_video.c @@ -212,6 +212,13 @@ void resync_video_stream(sh_video_t *sh_video) sh_video->prev_sorted_pts = MP_NOPTS_VALUE; } +void video_reset_aspect(struct sh_video *sh_video) +{ + int r = sh_video->vd_driver->control(sh_video, VDCTRL_RESET_ASPECT, NULL); + if (r != true) + mpcodecs_config_vo(sh_video, sh_video->disp_w, sh_video->disp_h, 0); +} + int get_current_video_decoder_lag(sh_video_t *sh_video) { const struct vd_functions *vd = sh_video->vd_driver; diff --git a/libmpcodecs/dec_video.h b/libmpcodecs/dec_video.h index 60a9e5f2d2..f7210e02c3 100644 --- a/libmpcodecs/dec_video.h +++ b/libmpcodecs/dec_video.h @@ -46,6 +46,7 @@ void set_video_colorspace(struct sh_video *sh); int set_rectangle(sh_video_t *sh_video, int param, int value); int redraw_osd(struct sh_video *sh_video, struct osd_state *osd); void resync_video_stream(sh_video_t *sh_video); +void video_reset_aspect(struct sh_video *sh_video); int get_current_video_decoder_lag(sh_video_t *sh_video); extern int divx_quality; diff --git a/libmpcodecs/mpc_info.h b/libmpcodecs/mpc_info.h index 8554699120..45139947cb 100644 --- a/libmpcodecs/mpc_info.h +++ b/libmpcodecs/mpc_info.h @@ -19,19 +19,19 @@ #ifndef MPLAYER_MPC_INFO_H #define MPLAYER_MPC_INFO_H -typedef struct mp_codec_info_s +struct mp_codec_info { - /* codec long name ("Autodesk FLI/FLC Animation decoder" */ - const char *name; - /* short name (same as driver name in codecs.conf) ("dshow") */ - const char *short_name; - /* interface author/maintainer */ - const char *maintainer; - /* codec author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */ - const char *author; - /* any additional comments */ - const char *comment; -} mp_codec_info_t; + /* codec long name ("Autodesk FLI/FLC Animation decoder" */ + const char *name; + /* short name (same as driver name in codecs.conf) ("dshow") */ + const char *short_name; + /* interface author/maintainer */ + const char *maintainer; + /* codec author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */ + const char *author; + /* any additional comments */ + const char *comment; +}; #define CONTROL_OK 1 #define CONTROL_TRUE 1 diff --git a/libmpcodecs/vd.h b/libmpcodecs/vd.h index 88837188f6..8b0f9c1aea 100644 --- a/libmpcodecs/vd.h +++ b/libmpcodecs/vd.h @@ -23,7 +23,7 @@ #include "mpc_info.h" #include "libmpdemux/stheader.h" -typedef mp_codec_info_t vd_info_t; +typedef struct mp_codec_info vd_info_t; struct demux_packet; @@ -33,37 +33,39 @@ typedef struct vd_functions const vd_info_t *info; int (*init)(sh_video_t *sh); void (*uninit)(sh_video_t *sh); - int (*control)(sh_video_t *sh,int cmd,void* arg, ...); - mp_image_t* (*decode)(sh_video_t *sh,void* data,int len,int flags); + int (*control)(sh_video_t *sh, int cmd, void *arg, ...); + mp_image_t * (*decode)(sh_video_t * sh, void *data, int len, int flags); struct mp_image *(*decode2)(struct sh_video *sh, struct demux_packet *pkt, void *data, int len, int flags, double *reordered_pts); } vd_functions_t; // NULL terminated array of all drivers -extern const vd_functions_t * const mpcodecs_vd_drivers[]; +extern const vd_functions_t *const mpcodecs_vd_drivers[]; -#define VDCTRL_QUERY_FORMAT 3 /* test for availabilty of a format */ -#define VDCTRL_QUERY_MAX_PP_LEVEL 4 /* test for postprocessing support (max level) */ -#define VDCTRL_SET_PP_LEVEL 5 /* set postprocessing level */ -#define VDCTRL_SET_EQUALIZER 6 /* set color options (brightness,contrast etc) */ -#define VDCTRL_GET_EQUALIZER 7 /* get color options (brightness,contrast etc) */ -#define VDCTRL_RESYNC_STREAM 8 /* seeking */ -#define VDCTRL_QUERY_UNSEEN_FRAMES 9 /* current decoder lag */ +#define VDCTRL_QUERY_FORMAT 3 // test for availabilty of a format +#define VDCTRL_QUERY_MAX_PP_LEVEL 4 // query max postprocessing level (if any) +#define VDCTRL_SET_PP_LEVEL 5 // set postprocessing level +#define VDCTRL_SET_EQUALIZER 6 // set color options (brightness,contrast etc) +#define VDCTRL_GET_EQUALIZER 7 // get color options (brightness,contrast etc) +#define VDCTRL_RESYNC_STREAM 8 // reset decode state after seeking +#define VDCTRL_QUERY_UNSEEN_FRAMES 9 // current decoder lag +#define VDCTRL_RESET_ASPECT 10 // reinit filter/VO chain for new aspect ratio // callbacks: int mpcodecs_config_vo2(sh_video_t *sh, int w, int h, const unsigned int *outfmts, unsigned int preferred_outfmt); + static inline int mpcodecs_config_vo(sh_video_t *sh, int w, int h, unsigned int preferred_outfmt) { return mpcodecs_config_vo2(sh, w, h, NULL, preferred_outfmt); } -mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h); -void mpcodecs_draw_slice(sh_video_t *sh, unsigned char** src, int* stride, int w,int h, int x, int y); - -#define VDFLAGS_DROPFRAME 3 +mp_image_t *mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, + int w, int h); +void mpcodecs_draw_slice(sh_video_t *sh, unsigned char **src, int *stride, + int w, int h, int x, int y); #endif /* MPLAYER_VD_H */ diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c index 21fa55c2e5..b7f189ec5f 100644 --- a/libmpcodecs/vd_ffmpeg.c +++ b/libmpcodecs/vd_ffmpeg.c @@ -119,40 +119,6 @@ static enum AVDiscard str2AVDiscard(char *str) return AVDISCARD_DEFAULT; } -static int control(sh_video_t *sh, int cmd, void *arg, ...) -{ - vd_ffmpeg_ctx *ctx = sh->context; - AVCodecContext *avctx = ctx->avctx; - switch (cmd) { - case VDCTRL_QUERY_FORMAT: - { - int format = (*((int *)arg)); - if (format == ctx->best_csp) - return CONTROL_TRUE; - // possible conversions: - switch (format) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - // "converted" using pointer/stride modification - if (ctx->best_csp == IMGFMT_YV12) - return CONTROL_TRUE; // u/v swap - if (ctx->best_csp == IMGFMT_422P && !ctx->do_dr1) - return CONTROL_TRUE; // half stride - break; - } - return CONTROL_FALSE; - } - case VDCTRL_RESYNC_STREAM: - avcodec_flush_buffers(avctx); - return CONTROL_TRUE; - case VDCTRL_QUERY_UNSEEN_FRAMES:; - int delay = avctx->has_b_frames; - return delay + 10; - } - return CONTROL_UNKNOWN; -} - static int init(sh_video_t *sh) { struct lavc_param *lavc_param = &sh->opts->lavc_param; @@ -684,15 +650,6 @@ static struct mp_image *decode(struct sh_video *sh, struct demux_packet *packet, if (!dr1) avctx->draw_horiz_band = NULL; - if (ctx->vo_initialized && !(flags & 3) && !dr1) { - mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, MP_IMGFLAG_PRESERVE | - (ctx->do_slices ? MP_IMGFLAG_DRAW_CALLBACK : 0), - sh->disp_w, sh->disp_h); - if (mpi && mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) { - // vd core likes slices! - avctx->draw_horiz_band = draw_slice; - } - } if (flags & 2) avctx->skip_frame = AVDISCARD_ALL; @@ -873,6 +830,44 @@ static enum PixelFormat get_format(struct AVCodecContext *avctx, return fmt[i]; } +static int control(sh_video_t *sh, int cmd, void *arg, ...) +{ + vd_ffmpeg_ctx *ctx = sh->context; + AVCodecContext *avctx = ctx->avctx; + switch (cmd) { + case VDCTRL_QUERY_FORMAT: { + int format = (*((int *)arg)); + if (format == ctx->best_csp) + return CONTROL_TRUE; + // possible conversions: + switch (format) { + case IMGFMT_YV12: + case IMGFMT_IYUV: + case IMGFMT_I420: + // "converted" using pointer/stride modification + if (ctx->best_csp == IMGFMT_YV12) + return CONTROL_TRUE; // u/v swap + if (ctx->best_csp == IMGFMT_422P && !ctx->do_dr1) + return CONTROL_TRUE; // half stride + break; + } + return CONTROL_FALSE; + } + case VDCTRL_RESYNC_STREAM: + avcodec_flush_buffers(avctx); + return CONTROL_TRUE; + case VDCTRL_QUERY_UNSEEN_FRAMES:; + int delay = avctx->has_b_frames; + return delay + 10; + case VDCTRL_RESET_ASPECT: + if (ctx->vo_initialized) + ctx->vo_initialized = false; + init_vo(sh, avctx->pix_fmt); + return true; + } + return CONTROL_UNKNOWN; +} + const struct vd_functions mpcodecs_vd_ffmpeg = { .info = &info, .init = init, diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c index d7ecb2deaa..8bd8145042 100644 --- a/libmpcodecs/vf.c +++ b/libmpcodecs/vf.c @@ -116,7 +116,7 @@ extern const vf_info_t vf_info_fixpts; extern const vf_info_t vf_info_stereo3d; // list of available filters: -static const vf_info_t* const filter_list[]={ +static const vf_info_t *const filter_list[] = { &vf_info_rectangle, #ifdef HAVE_POSIX_SELECT &vf_info_bmovl, @@ -209,40 +209,49 @@ static const vf_info_t* const filter_list[]={ // For the vf option const m_obj_list_t vf_obj_list = { - (void**)filter_list, - M_ST_OFF(vf_info_t,name), - M_ST_OFF(vf_info_t,info), - M_ST_OFF(vf_info_t,opts) + (void **)filter_list, + M_ST_OFF(vf_info_t, name), + M_ST_OFF(vf_info_t, info), + M_ST_OFF(vf_info_t, opts) }; //============================================================================ // mpi stuff: -void vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h){ +void vf_mpi_clear(mp_image_t *mpi, int x0, int y0, int w, int h) +{ int y; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - y0&=~1;h+=h&1; - if(x0==0 && w==mpi->width){ - // full width clear: - memset(mpi->planes[0]+mpi->stride[0]*y0,0,mpi->stride[0]*h); - memset(mpi->planes[1]+mpi->stride[1]*(y0>>mpi->chroma_y_shift),128,mpi->stride[1]*(h>>mpi->chroma_y_shift)); - memset(mpi->planes[2]+mpi->stride[2]*(y0>>mpi->chroma_y_shift),128,mpi->stride[2]*(h>>mpi->chroma_y_shift)); - } else - for(y=y0;y<y0+h;y+=2){ - memset(mpi->planes[0]+x0+mpi->stride[0]*y,0,w); - memset(mpi->planes[0]+x0+mpi->stride[0]*(y+1),0,w); - memset(mpi->planes[1]+(x0>>mpi->chroma_x_shift)+mpi->stride[1]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift)); - memset(mpi->planes[2]+(x0>>mpi->chroma_x_shift)+mpi->stride[2]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift)); - } - return; + if (mpi->flags & MP_IMGFLAG_PLANAR) { + y0 &= ~1; + h += h & 1; + if (x0 == 0 && w == mpi->width) { + // full width clear: + memset(mpi->planes[0] + mpi->stride[0] * y0, 0, mpi->stride[0] * h); + memset(mpi->planes[1] + mpi->stride[1] *(y0 >> mpi->chroma_y_shift), + 128, mpi->stride[1] * (h >> mpi->chroma_y_shift)); + memset(mpi->planes[2] + mpi->stride[2] *(y0 >> mpi->chroma_y_shift), + 128, mpi->stride[2] * (h >> mpi->chroma_y_shift)); + } else + for (y = y0; y < y0 + h; y += 2) { + memset(mpi->planes[0] + x0 + mpi->stride[0] * y, 0, w); + memset(mpi->planes[0] + x0 + mpi->stride[0] * (y + 1), 0, w); + memset(mpi->planes[1] + (x0 >> mpi->chroma_x_shift) + + mpi->stride[1] * (y >> mpi->chroma_y_shift), + 128, (w >> mpi->chroma_x_shift)); + memset(mpi->planes[2] + (x0 >> mpi->chroma_x_shift) + + mpi->stride[2] * (y >> mpi->chroma_y_shift), + 128, (w >> mpi->chroma_x_shift)); + } + return; } // packed: - for(y=y0;y<y0+h;y++){ - unsigned char* dst=mpi->planes[0]+mpi->stride[0]*y+(mpi->bpp>>3)*x0; - if(mpi->flags&MP_IMGFLAG_YUV){ - unsigned int* p=(unsigned int*) dst; - int size=(mpi->bpp>>3)*w/4; - int i; + for (y = y0; y < y0 + h; y++) { + unsigned char *dst = mpi->planes[0] + mpi->stride[0] * y + + (mpi->bpp >> 3) * x0; + if (mpi->flags & MP_IMGFLAG_YUV) { + unsigned int *p = (unsigned int *) dst; + int size = (mpi->bpp >> 3) * w / 4; + int i; #if HAVE_BIGENDIAN #define CLEAR_PACKEDYUV_PATTERN 0x00800080 #define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x80008000 @@ -250,215 +259,249 @@ void vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h){ #define CLEAR_PACKEDYUV_PATTERN 0x80008000 #define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x00800080 #endif - if(mpi->flags&MP_IMGFLAG_SWAPPED){ - for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN_SWAPPED; - for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN_SWAPPED; - } else { - for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN; - for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN; - } - } else - memset(dst,0,(mpi->bpp>>3)*w); + if (mpi->flags & MP_IMGFLAG_SWAPPED) { + for (i = 0; i < size - 3; i += 4) + p[i] = p[i + 1] = p[i + 2] = p[i + 3] = CLEAR_PACKEDYUV_PATTERN_SWAPPED; + for (; i < size; i++) + p[i] = CLEAR_PACKEDYUV_PATTERN_SWAPPED; + } else { + for (i = 0; i < size - 3; i += 4) + p[i] = p[i + 1] = p[i + 2] = p[i + 3] = CLEAR_PACKEDYUV_PATTERN; + for (; i < size; i++) + p[i] = CLEAR_PACKEDYUV_PATTERN; + } + } else + memset(dst, 0, (mpi->bpp >> 3) * w); } } -mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h){ - mp_image_t* mpi=NULL; - int w2; - int number = mp_imgtype >> 16; - - assert(w == -1 || w >= vf->w); - assert(h == -1 || h >= vf->h); - assert(vf->w > 0); - assert(vf->h > 0); - -// fprintf(stderr, "get_image: %d:%d, vf: %d:%d\n", w,h,vf->w,vf->h); - - if (w == -1) w = vf->w; - if (h == -1) h = vf->h; - - w2=(mp_imgflag&MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE)?((w+15)&(~15)):w; - - if(vf->put_image==vf_next_put_image){ - // passthru mode, if the filter uses the fallback/default put_image() code - return vf_get_image(vf->next,outfmt,mp_imgtype,mp_imgflag,w,h); - } - - // Note: we should call libvo first to check if it supports direct rendering - // and if not, then fallback to software buffers: - switch(mp_imgtype & 0xff){ - case MP_IMGTYPE_EXPORT: - if(!vf->imgctx.export_images[0]) vf->imgctx.export_images[0]=new_mp_image(w2,h); - mpi=vf->imgctx.export_images[0]; - break; - case MP_IMGTYPE_STATIC: - if(!vf->imgctx.static_images[0]) vf->imgctx.static_images[0]=new_mp_image(w2,h); - mpi=vf->imgctx.static_images[0]; - break; - case MP_IMGTYPE_TEMP: - if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=new_mp_image(w2,h); - mpi=vf->imgctx.temp_images[0]; - break; - case MP_IMGTYPE_IPB: - if(!(mp_imgflag&MP_IMGFLAG_READABLE)){ // B frame: - if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=new_mp_image(w2,h); - mpi=vf->imgctx.temp_images[0]; - break; - } - case MP_IMGTYPE_IP: - if(!vf->imgctx.static_images[vf->imgctx.static_idx]) vf->imgctx.static_images[vf->imgctx.static_idx]=new_mp_image(w2,h); - mpi=vf->imgctx.static_images[vf->imgctx.static_idx]; - vf->imgctx.static_idx^=1; - break; - case MP_IMGTYPE_NUMBERED: - if (number == -1) { - int i; - for (i = 0; i < NUM_NUMBERED_MPI; i++) - if (!vf->imgctx.numbered_images[i] || !vf->imgctx.numbered_images[i]->usage_count) - break; - number = i; - } - if (number < 0 || number >= NUM_NUMBERED_MPI) return NULL; - if (!vf->imgctx.numbered_images[number]) vf->imgctx.numbered_images[number] = new_mp_image(w2,h); - mpi = vf->imgctx.numbered_images[number]; - mpi->number = number; - break; - } - if(mpi){ - mpi->type=mp_imgtype; - mpi->w=vf->w; mpi->h=vf->h; - // keep buffer allocation status & color flags only: -// mpi->flags&=~(MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE|MP_IMGFLAG_DIRECT); - mpi->flags&=MP_IMGFLAG_ALLOCATED|MP_IMGFLAG_TYPE_DISPLAYED|MP_IMGFLAGMASK_COLORS; - // accept restrictions, draw_slice and palette flags only: - mpi->flags|=mp_imgflag&(MP_IMGFLAGMASK_RESTRICTIONS|MP_IMGFLAG_DRAW_CALLBACK|MP_IMGFLAG_RGB_PALETTE); - if(!vf->draw_slice) mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK; - if(mpi->width!=w2 || mpi->height!=h){ -// printf("vf.c: MPI parameters changed! %dx%d -> %dx%d \n", mpi->width,mpi->height,w2,h); - if(mpi->flags&MP_IMGFLAG_ALLOCATED){ - if(mpi->width<w2 || mpi->height<h){ - // need to re-allocate buffer memory: - av_free(mpi->planes[0]); - mpi->flags&=~MP_IMGFLAG_ALLOCATED; - mp_msg(MSGT_VFILTER,MSGL_V,"vf.c: have to REALLOCATE buffer memory :(\n"); - } -// } else { - } { - mpi->width=w2; mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift; - mpi->height=h; mpi->chroma_height=(h + (1<<mpi->chroma_y_shift) - 1)>>mpi->chroma_y_shift; - } +mp_image_t *vf_get_image(vf_instance_t *vf, unsigned int outfmt, + int mp_imgtype, int mp_imgflag, int w, int h) +{ + mp_image_t *mpi = NULL; + int w2; + int number = mp_imgtype >> 16; + + assert(w == -1 || w >= vf->w); + assert(h == -1 || h >= vf->h); + assert(vf->w > 0); + assert(vf->h > 0); + + if (w == -1) + w = vf->w; + if (h == -1) + h = vf->h; + + w2 = (mp_imgflag & MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE) ? + ((w + 15) & (~15)) : w; + + if (vf->put_image == vf_next_put_image) { + // passthru mode, if the filter uses the fallback/default put_image() + return vf_get_image(vf->next, outfmt, mp_imgtype, mp_imgflag, w, h); } - if(!mpi->bpp) mp_image_setfmt(mpi,outfmt); - if(!(mpi->flags&MP_IMGFLAG_ALLOCATED) && mpi->type>MP_IMGTYPE_EXPORT){ - - // check libvo first! - if(vf->get_image) vf->get_image(vf,mpi); - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // non-direct and not yet allocated image. allocate it! - if (!mpi->bpp) { // no way we can allocate this - mp_msg(MSGT_DECVIDEO, MSGL_FATAL, - "vf_get_image: Tried to allocate a format that can not be allocated!\n"); - return NULL; - } - - // check if codec prefer aligned stride: - if(mp_imgflag&MP_IMGFLAG_PREFER_ALIGNED_STRIDE){ - int align=(mpi->flags&MP_IMGFLAG_PLANAR && - mpi->flags&MP_IMGFLAG_YUV) ? - (8<<mpi->chroma_x_shift)-1 : 15; // -- maybe FIXME - w2=((w+align)&(~align)); - if(mpi->width!=w2){ - // we have to change width... check if we CAN co it: - int flags=vf->query_format(vf,outfmt); // should not fail - if(!(flags&3)) mp_msg(MSGT_DECVIDEO,MSGL_WARN,"??? vf_get_image{vf->query_format(outfmt)} failed!\n"); -// printf("query -> 0x%X \n",flags); - if(flags&VFCAP_ACCEPT_STRIDE){ - mpi->width=w2; - mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift; - } - } - } - - mp_image_alloc_planes(mpi); -// printf("clearing img!\n"); - vf_mpi_clear(mpi,0,0,mpi->width,mpi->height); + + // Note: we should call libvo first to check if it supports direct rendering |