summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/ad.h23
-rw-r--r--libmpcodecs/dec_video.c7
-rw-r--r--libmpcodecs/dec_video.h1
-rw-r--r--libmpcodecs/mpc_info.h24
-rw-r--r--libmpcodecs/vd.h32
-rw-r--r--libmpcodecs/vd_ffmpeg.c81
-rw-r--r--libmpcodecs/vf.c853
-rw-r--r--libmpcodecs/vf.h145
-rw-r--r--libmpcodecs/vf_scale.c4
9 files changed, 637 insertions, 533 deletions
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
+ // 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->flags&MP_IMGFLAG_DRAW_CALLBACK)
- if(vf->start_slice) vf->start_slice(vf,mpi);
- if(!(mpi->flags&MP_IMGFLAG_TYPE_DISPLAYED)){
- mp_msg(MSGT_DECVIDEO,MSGL_V,"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
- vf->info->name,
- (mpi->type==MP_IMGTYPE_EXPORT)?"Exporting":
- ((mpi->flags&MP_IMGFLAG_DIRECT)?"Direct Rendering":"Allocating"),
- (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)?" (slices)":"",
- mpi->width,mpi->height,mpi->bpp,
- (mpi->flags&MP_IMGFLAG_YUV)?"YUV":((mpi->flags&MP_IMGFLAG_SWAPPED)?"BGR":"RGB"),
- (mpi->flags&MP_IMGFLAG_PLANAR)?"planar":"packed",
- mpi->bpp*mpi->width*mpi->height/8);
- mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"(imgfmt: %x, planes: %p,%p,%p strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",
- mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2],
- mpi->stride[0], mpi->stride[1], mpi->stride[2],
- mpi->chroma_width, mpi->chroma_height, mpi->chroma_x_shift, mpi->chroma_y_shift);
- mpi->flags|=MP_IMGFLAG_TYPE_DISPLAYED;
+ 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_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) {
+ 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");
+ }
+ }
+ 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;
+ }
+ 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; // OK?
+ 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 & (VFCAP_CSP_SUPPORTED |
+ VFCAP_CSP_SUPPORTED_BY_HW)))
+ mp_msg(MSGT_DECVIDEO, MSGL_WARN,
+ "??? vf_get_image{vf->query_format(outfmt)} "
+ "failed!\n");
+ 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);
+ vf_mpi_clear(mpi, 0, 0, mpi->width, mpi->height);
+ }
+ }
+ if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
+ if (vf->start_slice)
+ vf->start_slice(vf, mpi);
+ if (!(mpi->flags & MP_IMGFLAG_TYPE_DISPLAYED)) {
+ mp_msg(MSGT_DECVIDEO, MSGL_V,
+ "*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
+ vf->info->name,
+ (mpi->type == MP_IMGTYPE_EXPORT) ? "Exporting" :
+ ((mpi->flags & MP_IMGFLAG_DIRECT) ?
+ "Direct Rendering" : "Allocating"),
+ (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) ? " (slices)" : "",
+ mpi->width, mpi->height, mpi->bpp,
+ (mpi->flags & MP_IMGFLAG_YUV) ? "YUV" :
+ ((mpi->flags & MP_IMGFLAG_SWAPPED) ? "BGR" : "RGB"),
+ (mpi->flags & MP_IMGFLAG_PLANAR) ? "planar" : "packed",
+ mpi->bpp * mpi->width * mpi->height / 8);
+ mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "(imgfmt: %x, planes: %p,%p,%p "
+ "strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",
+ mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2],
+ mpi->stride[0], mpi->stride[1], mpi->stride[2],
+ mpi->chroma_width, mpi->chroma_height,
+ mpi->chroma_x_shift, mpi->chroma_y_shift);
+ mpi->flags |= MP_IMGFLAG_TYPE_DISPLAYED;
+ }
+ mpi->qscale = NULL;
}
-
- mpi->qscale = NULL;
- }
- mpi->usage_count++;
-// printf("\rVF_MPI: %p %p %p %d %d %d \n",
-// mpi->planes[0],mpi->planes[1],mpi->planes[2],
-// mpi->stride[0],mpi->stride[1],mpi->stride[2]);
- return mpi;
+ mpi->usage_count++;
+ return mpi;
}
//============================================================================
// By default vf doesn't accept MPEGPES
-static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt){
- if(fmt == IMGFMT_MPEGPES) return 0;
- return vf_next_query_format(vf,fmt);
+static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt)
+{
+ if (fmt == IMGFMT_MPEGPES)
+ return 0;
+ return vf_next_query_format(vf, fmt);
}
struct vf_instance *vf_open_plugin_noerr(struct MPOpts *opts,
- const vf_info_t * const *filter_list,
+ const vf_info_t *const *filter_list,
vf_instance_t *next, const char *name,
char **args, int *retcode)
{
- vf_instance_t* vf;
+ vf_instance_t *vf;
int i;
- for(i=0;;i++){
- if(!filter_list[i]){
- mp_tmsg(MSGT_VFILTER,MSGL_ERR,"Couldn't find video filter '%s'.\n",name);
- return NULL; // no such filter!
- }
- if(!strcmp(filter_list[i]->name,name)) break;
+ for (i = 0;; i++) {
+ if (!filter_list[i]) {
+ mp_tmsg(MSGT_VFILTER, MSGL_ERR,
+ "Couldn't find video filter '%s'.\n", name);
+ return NULL; // no such filter!
+ }
+ if (!strcmp(filter_list[i]->name, name))
+ break;
}
vf = calloc(1, sizeof *vf);
vf->opts = opts;
- vf->info=filter_list[i];
- vf->next=next;
- vf->config=vf_next_config;
- vf->control=vf_next_control;
- vf->query_format=vf_default_query_format;
- vf->put_image=vf_next_put_image;
- vf->default_caps=VFCAP_ACCEPT_STRIDE;
- vf->default_reqs=0;
- if(vf->info->opts) { // vf_vo get some special argument
- const m_struct_t* st = vf->info->opts;
- void* vf_priv = m_struct_alloc(st);
- int n;
- for(n = 0 ; args && args[2*n] ; n++)
- m_struct_set(st, vf_priv, args[2*n], bstr(args[2*n+1]));
- vf->priv = vf_priv;
- args = NULL;
+ vf->info = filter_list[i];
+ vf->next = next;
+ vf->config = vf_next_config;
+ vf->control = vf_next_control;
+ vf->query_format = vf_default_query_format;
+ vf->put_image = vf_next_put_image;
+ vf->default_caps = VFCAP_ACCEPT_STRIDE;
+ vf->default_reqs = 0;
+ if (vf->info->opts) { // vf_vo get some special argument
+ const m_struct_t *st = vf->info->opts;
+ void *vf_priv = m_struct_alloc(st);
+ int n;
+ for (n = 0; args && args[2 * n]; n++)
+ m_struct_set(st, vf_priv, args[2 * n], bstr(args[2 * n + 1]));
+ vf->priv = vf_priv;
+ args = NULL;
} else // Otherwise we should have the '_oldargs_'
- if(args && !strcmp(args[0],"_oldargs_"))
- args = (char**)args[1];
- else
- args = NULL;
- *retcode = vf->info->vf_open(vf,(char*)args);
+ if (args && !strcmp(args[0], "_oldargs_"))
+ args = (char **)args[1];
+ else
+ args = NULL;
+ *retcode = vf->info->vf_open(vf, (char *)args);
if (*retcode > 0)
return vf;
free(vf);
@@ -466,7 +509,7 @@ struct vf_instance *vf_open_plugin_noerr(struct MPOpts *opts,
}
struct vf_instance *vf_open_plugin(struct MPOpts *opts,
- const vf_info_t * const *filter_list,
+ const vf_info_t *const *filter_list,
vf_instance_t *next, const char *name,
char **args)
{
@@ -478,30 +521,32 @@ struct vf_instance *vf_open_plugin(struct MPOpts *opts,
return vf;
}
-vf_instance_t* vf_open_filter(struct MPOpts *opts, vf_instance_t* next, const char *name, char **args){
- if(args && strcmp(args[0],"_oldargs_")) {
- int i,l = 0;
- for(i = 0 ;