summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/ad.c2
-rw-r--r--libmpcodecs/ad_ffmpeg.c3
-rw-r--r--libmpcodecs/ad_hwac3.c88
-rw-r--r--libmpcodecs/ad_pcm.c2
-rw-r--r--libmpcodecs/img_format.h16
-rw-r--r--libmpcodecs/vd.c13
-rw-r--r--libmpcodecs/ve_lavc.c29
-rw-r--r--libmpcodecs/vf_crop.c2
-rw-r--r--libmpcodecs/vf_cropdetect.c20
-rw-r--r--libmpcodecs/vf_fspp.c12
-rw-r--r--libmpcodecs/vf_halfpack.c24
-rw-r--r--libmpcodecs/vf_scale.c51
-rw-r--r--libmpcodecs/vf_spp.c10
13 files changed, 181 insertions, 91 deletions
diff --git a/libmpcodecs/ad.c b/libmpcodecs/ad.c
index c7e87cd92e..5843a49ae8 100644
--- a/libmpcodecs/ad.c
+++ b/libmpcodecs/ad.c
@@ -49,8 +49,8 @@ const ad_functions_t * const mpcodecs_ad_drivers[] =
#endif
#ifdef CONFIG_LIBA52
&mpcodecs_ad_liba52,
- &mpcodecs_ad_hwac3,
#endif
+ &mpcodecs_ad_hwac3,
&mpcodecs_ad_hwmpa,
#ifdef CONFIG_LIBAVCODEC
&mpcodecs_ad_ffmpeg,
diff --git a/libmpcodecs/ad_ffmpeg.c b/libmpcodecs/ad_ffmpeg.c
index 217ec25ff1..c99cd47fec 100644
--- a/libmpcodecs/ad_ffmpeg.c
+++ b/libmpcodecs/ad_ffmpeg.c
@@ -153,6 +153,7 @@ static int control(sh_audio_t *sh,int cmd,void* arg, ...)
switch(cmd){
case ADCTRL_RESYNC_STREAM:
avcodec_flush_buffers(lavc_context);
+ ds_clear_parser(sh->ds);
return CONTROL_TRUE;
}
return CONTROL_UNKNOWN;
@@ -188,7 +189,7 @@ static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int m
y=avcodec_decode_audio3(sh_audio->context,(int16_t*)buf,&len2,&pkt);
//printf("return:%d samples_out:%d bitstream_in:%d sample_sum:%d\n", y, len2, x, len); fflush(stdout);
if(y<0){ mp_msg(MSGT_DECAUDIO,MSGL_V,"lavc_audio: error\n");break; }
- if(!sh_audio->needs_parsing && y<x)
+ if(!sh_audio->parser && y<x)
sh_audio->ds->buffer_pos+=y-x; // put back data (HACK!)
if(len2>0){
if (((AVCodecContext *)sh_audio->context)->channels >= 5) {
diff --git a/libmpcodecs/ad_hwac3.c b/libmpcodecs/ad_hwac3.c
index 4dadf1723f..e6c7446631 100644
--- a/libmpcodecs/ad_hwac3.c
+++ b/libmpcodecs/ad_hwac3.c
@@ -15,15 +15,11 @@
#include "mp_msg.h"
#include "help_mp.h"
#include "mpbswap.h"
+#include "libavutil/common.h"
+#include "ffmpeg_files/intreadwrite.h"
#include "ad_internal.h"
-#ifdef CONFIG_LIBA52_INTERNAL
-#include "liba52/a52.h"
-#else
-#include <a52dec/a52.h>
-#endif
-
static int isdts = -1;
@@ -43,6 +39,44 @@ static int dts_syncinfo(uint8_t *indata_ptr, int *flags, int *sample_rate, int *
static int decode_audio_dts(unsigned char *indata_ptr, int len, unsigned char *buf);
+static int a52_syncinfo (uint8_t *buf, int *sample_rate, int *bit_rate)
+{
+ static const uint16_t rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320, 384, 448,
+ 512, 576, 640};
+ int frmsizecod;
+ int bitrate;
+ int half;
+
+ if (buf[0] != 0x0b || buf[1] != 0x77) /* syncword */
+ return 0;
+
+ if (buf[5] >= 0x60) /* bsid >= 12 */
+ return 0;
+ half = buf[5] >> 3;
+ half = FFMAX(half - 8, 0);
+
+ frmsizecod = buf[4] & 63;
+ if (frmsizecod >= 38)
+ return 0;
+ bitrate = rate[frmsizecod >> 1];
+ *bit_rate = (bitrate * 1000) >> half;
+
+ switch (buf[4] & 0xc0) {
+ case 0:
+ *sample_rate = 48000 >> half;
+ return 4 * bitrate;
+ case 0x40:
+ *sample_rate = 44100 >> half;
+ return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
+ case 0x80:
+ *sample_rate = 32000 >> half;
+ return 6 * bitrate;
+ default:
+ return 0;
+ }
+}
+
static int ac3dts_fillbuff(sh_audio_t *sh_audio)
{
int length = 0;
@@ -79,7 +113,7 @@ static int ac3dts_fillbuff(sh_audio_t *sh_audio)
}
else
{
- length = a52_syncinfo(sh_audio->a_in_buffer, &flags, &sample_rate, &bit_rate);
+ length = a52_syncinfo(sh_audio->a_in_buffer, &sample_rate, &bit_rate);
if(length >= 7 && length <= 3840)
{
if(isdts != 0)
@@ -101,12 +135,6 @@ static int ac3dts_fillbuff(sh_audio_t *sh_audio)
demux_read_data(sh_audio->ds, sh_audio->a_in_buffer + 12, length - 12);
sh_audio->a_in_buffer_len = length;
- // TODO: is DTS also checksummed?
-#ifdef CONFIG_LIBA52_INTERNAL
- if(isdts == 0 && crc16_block(sh_audio->a_in_buffer + 2, length - 2) != 0)
- mp_msg(MSGT_DECAUDIO, MSGL_STATUS, "a52: CRC check failed! \n");
-#endif
-
return length;
}
@@ -118,32 +146,26 @@ static int preinit(sh_audio_t *sh)
sh->audio_in_minsize = 8192;
sh->channels = 2;
sh->samplesize = 2;
- sh->sample_format = AF_FORMAT_AC3;
+ sh->sample_format = AF_FORMAT_AC3_BE;
+ // HACK for DTS where useless swapping can't easily be removed
+ if (sh->format == 0x2001)
+ sh->sample_format = AF_FORMAT_AC3_NE;
return 1;
}
static int init(sh_audio_t *sh_audio)
{
/* Dolby AC3 passthrough:*/
- a52_state_t *a52_state = a52_init(0);
- if(a52_state == NULL)
- {
- mp_msg(MSGT_DECAUDIO, MSGL_ERR, "A52 init failed\n");
- return 0;
- }
if(ac3dts_fillbuff(sh_audio) < 0)
{
- a52_free(a52_state);
mp_msg(MSGT_DECAUDIO, MSGL_ERR, "AC3/DTS sync failed\n");
return 0;
}
- sh_audio->context = a52_state;
return 1;
}
static void uninit(sh_audio_t *sh)
{
- a52_free(sh->context);
}
static int control(sh_audio_t *sh,int cmd,void* arg, ...)
@@ -174,22 +196,12 @@ static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int m
}
else if(isdts == 0)
{
- uint16_t *buf16 = (uint16_t *)buf;
- buf16[0] = 0xF872; // iec 61937 syncword 1
- buf16[1] = 0x4E1F; // iec 61937 syncword 2
- buf16[2] = 0x0001; // data-type ac3
- buf16[2] |= (sh_audio->a_in_buffer[5] & 0x7) << 8; // bsmod
- buf16[3] = len << 3; // number of bits in payload
-#if HAVE_BIGENDIAN
+ AV_WB16(buf, 0xF872); // iec 61937 syncword 1
+ AV_WB16(buf + 2, 0x4E1F); // iec 61937 syncword 2
+ buf[4] = sh_audio->a_in_buffer[5] & 0x7; // bsmod
+ buf[5] = 0x01; // data-type ac3
+ AV_WB16(buf + 6, len << 3); // number of bits in payload
memcpy(buf + 8, sh_audio->a_in_buffer, len);
-#else
- swab(sh_audio->a_in_buffer, buf + 8, len);
- if (len & 1) {
- buf[8+len-1] = 0;
- buf[8+len] = sh_audio->a_in_buffer[len-1];
- len++;
- }
-#endif
memset(buf + 8 + len, 0, 6144 - 8 - len);
return 6144;
diff --git a/libmpcodecs/ad_pcm.c b/libmpcodecs/ad_pcm.c
index 058f6c25cb..cc0de742d8 100644
--- a/libmpcodecs/ad_pcm.c
+++ b/libmpcodecs/ad_pcm.c
@@ -27,6 +27,8 @@ LIBAD_EXTERN(pcm)
static int init(sh_audio_t *sh_audio)
{
WAVEFORMATEX *h=sh_audio->wf;
+ if (!h)
+ return 0;
sh_audio->i_bps=h->nAvgBytesPerSec;
sh_audio->channels=h->nChannels;
sh_audio->samplerate=h->nSamplesPerSec;
diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h
index 6bab56632d..2aa037e5b7 100644
--- a/libmpcodecs/img_format.h
+++ b/libmpcodecs/img_format.h
@@ -35,12 +35,28 @@
#define IMGFMT_ARGB IMGFMT_BGR32
#define IMGFMT_RGBA (IMGFMT_BGR32|64)
#define IMGFMT_RGB48NE IMGFMT_RGB48BE
+#define IMGFMT_RGB15BE IMGFMT_RGB15
+#define IMGFMT_RGB15LE (IMGFMT_RGB15|64)
+#define IMGFMT_RGB16BE IMGFMT_RGB16
+#define IMGFMT_RGB16LE (IMGFMT_RGB16|64)
+#define IMGFMT_BGR15BE IMGFMT_BGR15
+#define IMGFMT_BGR15LE (IMGFMT_BGR15|64)
+#define IMGFMT_BGR16BE IMGFMT_BGR16
+#define IMGFMT_BGR16LE (IMGFMT_BGR16|64)
#else
#define IMGFMT_ABGR (IMGFMT_BGR32|64)
#define IMGFMT_BGRA IMGFMT_BGR32
#define IMGFMT_ARGB (IMGFMT_RGB32|64)
#define IMGFMT_RGBA IMGFMT_RGB32
#define IMGFMT_RGB48NE IMGFMT_RGB48LE
+#define IMGFMT_RGB15BE (IMGFMT_RGB15|64)
+#define IMGFMT_RGB15LE IMGFMT_RGB15
+#define IMGFMT_RGB16BE (IMGFMT_RGB16|64)
+#define IMGFMT_RGB16LE IMGFMT_RGB16
+#define IMGFMT_BGR15BE (IMGFMT_BGR15|64)
+#define IMGFMT_BGR15LE IMGFMT_BGR15
+#define IMGFMT_BGR16BE (IMGFMT_BGR16|64)
+#define IMGFMT_BGR16LE IMGFMT_BGR16
#endif
/* old names for compatibility */
diff --git a/libmpcodecs/vd.c b/libmpcodecs/vd.c
index 1910af62ee..1821498865 100644
--- a/libmpcodecs/vd.c
+++ b/libmpcodecs/vd.c
@@ -189,7 +189,7 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h,
} else {
// sws failed, if the last filter (vf_vo) support MPEGPES try
// to append vf_lavc
- vf_instance_t *vo, *vp = NULL, *ve;
+ vf_instance_t *vo, *vp = NULL, *ve, *vpp = NULL;
// Remove the scale filter if we added it ourselves
if (vf == sc) {
ve = vf;
@@ -197,8 +197,10 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h,
vf_uninit_filter(ve);
}
// Find the last filter (vf_vo)
- for (vo = vf; vo->next; vo = vo->next)
+ for (vo = vf; vo->next; vo = vo->next) {
+ vpp = vp;
vp = vo;
+ }
if (vo->query_format(vo, IMGFMT_MPEGPES)
&& (!vp || (vp && strcmp(vp->info->name, "lavc")))) {
ve = vf_open_filter(opts, vo, "lavc", NULL);
@@ -208,6 +210,13 @@ int mpcodecs_config_vo(sh_video_t *sh, int w, int h,
vf = ve;
goto csp_again;
}
+ if (vp && !strcmp(vp->info->name,"lavc")) {
+ if (vpp)
+ vpp->next = vo;
+ else
+ vf = vo;
+ vf_uninit_filter(vp);
+ }
}
mp_tmsg(MSGT_CPLAYER, MSGL_WARN,
"The selected video_out device is incompatible with this codec.\n"\
diff --git a/libmpcodecs/ve_lavc.c b/libmpcodecs/ve_lavc.c
index 3062d9ca5d..5955787204 100644
--- a/libmpcodecs/ve_lavc.c
+++ b/libmpcodecs/ve_lavc.c
@@ -15,6 +15,7 @@
#include "mp_msg.h"
#include "help_mp.h"
#include "av_opts.h"
+#include "osdep/strsep.h"
#include "codec-cfg.h"
#include "stream/stream.h"
@@ -24,6 +25,7 @@
#include "libmpdemux/muxer.h"
#include "img_format.h"
+#include "fmt-conversion.h"
#include "mp_image.h"
#include "vf.h"
@@ -593,30 +595,9 @@ static int config(struct vf_instance* vf,
}
mux_v->imgfmt = lavc_param_format;
- switch(lavc_param_format)
- {
- case IMGFMT_YV12:
- lavc_venc_context->pix_fmt = PIX_FMT_YUV420P;
- break;
- case IMGFMT_422P:
- lavc_venc_context->pix_fmt = PIX_FMT_YUV422P;
- break;
- case IMGFMT_444P:
- lavc_venc_context->pix_fmt = PIX_FMT_YUV444P;
- break;
- case IMGFMT_411P:
- lavc_venc_context->pix_fmt = PIX_FMT_YUV411P;
- break;
- case IMGFMT_YVU9:
- lavc_venc_context->pix_fmt = PIX_FMT_YUV410P;
- break;
- case IMGFMT_BGR32:
- lavc_venc_context->pix_fmt = PIX_FMT_RGB32;
- break;
- default:
- mp_msg(MSGT_MENCODER,MSGL_ERR,"%s is not a supported format\n", vo_format_name(lavc_param_format));
- return 0;
- }
+ lavc_venc_context->pix_fmt = imgfmt2pixfmt(lavc_param_format);
+ if (lavc_venc_context->pix_fmt == PIX_FMT_NONE)
+ return 0;
if(!stats_file) {
/* lavc internal 2pass bitrate control */
diff --git a/libmpcodecs/vf_crop.c b/libmpcodecs/vf_crop.c
index 877c01d3b3..d3773cb1fa 100644
--- a/libmpcodecs/vf_crop.c
+++ b/libmpcodecs/vf_crop.c
@@ -131,7 +131,7 @@ static void draw_slice(struct vf_instance* vf,
if (x+w > vf->priv->crop_w) w = vf->priv->crop_w-x;
if (y+h > vf->priv->crop_h) h = vf->priv->crop_h-y;
//mp_msg(MSGT_VFILTER, MSGL_V, "%d %d %d %d\n", w,h,x,y);
- if ((w < 0) || (h < 0)) return;
+ if (w <= 0 || h <= 0) return;
vf_next_draw_slice(vf,src2,stride,w,h,x,y);
}
diff --git a/libmpcodecs/vf_cropdetect.c b/libmpcodecs/vf_cropdetect.c
index e91f537a04..811df5416e 100644
--- a/libmpcodecs/vf_cropdetect.c
+++ b/libmpcodecs/vf_cropdetect.c
@@ -15,6 +15,7 @@ struct vf_priv_s {
int x1,y1,x2,y2;
int limit;
int round;
+ int reset_count;
int fno;
};
@@ -49,7 +50,7 @@ static int config(struct vf_instance* vf,
vf->priv->y1=height - 1;
vf->priv->x2=0;
vf->priv->y2=0;
- vf->priv->fno=0;
+ vf->priv->fno=-2;
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
}
@@ -72,7 +73,16 @@ static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){
dmpi->width=mpi->width;
dmpi->height=mpi->height;
-if(++vf->priv->fno>2){ // ignore first 2 frames - they may be empty
+if(++vf->priv->fno>0){ // ignore first 2 frames - they may be empty
+
+ // Reset the crop area every reset_count frames, if reset_count is > 0
+ if(vf->priv->reset_count > 0 && vf->priv->fno > vf->priv->reset_count){
+ vf->priv->x1=mpi->w-1;
+ vf->priv->y1=mpi->h-1;
+ vf->priv->x2=0;
+ vf->priv->y2=0;
+ vf->priv->fno=1;
+ }
for(y=0;y<vf->priv->y1;y++){
if(checkline(mpi->planes[0]+mpi->stride[0]*y,bpp,mpi->w,bpp)>vf->priv->limit){
@@ -153,9 +163,11 @@ static int open(vf_instance_t *vf, char* args){
vf->priv=malloc(sizeof(struct vf_priv_s));
vf->priv->limit=24; // should be option
vf->priv->round = 0;
- if(args) sscanf(args, "%d:%d",
+ vf->priv->reset_count = 0;
+ if(args) sscanf(args, "%d:%d:%d",
&vf->priv->limit,
- &vf->priv->round);
+ &vf->priv->round,
+ &vf->priv->reset_count);
return 1;
}
diff --git a/libmpcodecs/vf_fspp.c b/libmpcodecs/vf_fspp.c
index 7264199c21..8ef33381b1 100644
--- a/libmpcodecs/vf_fspp.c
+++ b/libmpcodecs/vf_fspp.c
@@ -533,9 +533,15 @@ static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts)
vf->priv->mpeg2= mpi->qscale_type;
if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){
- if(!vf->priv->non_b_qp)
- vf->priv->non_b_qp= malloc(mpi->qstride * ((mpi->h + 15) >> 4));
- fast_memcpy(vf->priv->non_b_qp, mpi->qscale, mpi->qstride * ((mpi->h + 15) >> 4));
+ int w = mpi->qstride;
+ int h = (mpi->h + 15) >> 4;
+ if (!w) {
+ w = (mpi->w + 15) >> 4;
+ h = 1;
+ }
+ if(!vf->priv->non_b_qp)
+ vf->priv->non_b_qp= malloc(w*h);
+ fast_memcpy(vf->priv->non_b_qp, mpi->qscale, w*h);
}
if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){
char *qp_tab= vf->priv->non_b_qp;
diff --git a/libmpcodecs/vf_halfpack.c b/libmpcodecs/vf_halfpack.c
index 682b80a91e..4a3bdb578f 100644
--- a/libmpcodecs/vf_halfpack.c
+++ b/libmpcodecs/vf_halfpack.c
@@ -10,11 +10,14 @@
#include "img_format.h"
#include "mp_image.h"
#include "vf.h"
+#include "vf_scale.h"
-#include "libswscale/rgb2rgb.h"
+#include "libswscale/swscale.h"
+#include "fmt-conversion.h"
struct vf_priv_s {
int field;
+ struct SwsContext *ctx;
};
#if HAVE_MMX
@@ -144,6 +147,10 @@ static void (*halfpack)(unsigned char *dst, unsigned char *src[3],
static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts)
{
+ const uint8_t *src[MP_MAX_PLANES] = {
+ mpi->planes[0] + mpi->stride[0]*vf->priv->field,
+ mpi->planes[1], mpi->planes[2], NULL};
+ int src_stride[MP_MAX_PLANES] = {mpi->stride[0]*2, mpi->stride[1], mpi->stride[2], 0};
mp_image_t *dmpi;
// hope we'll get DR buffer:
@@ -154,9 +161,8 @@ static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts)
switch(vf->priv->field) {
case 0:
case 1:
- yuv422ptoyuy2(mpi->planes[0] + mpi->stride[0]*vf->priv->field,
- mpi->planes[1], mpi->planes[2], dmpi->planes[0],
- mpi->w, mpi->h/2, mpi->stride[0]*2, mpi->stride[1], dmpi->stride[0]);
+ sws_scale(vf->priv->ctx, src, src_stride,
+ 0, mpi->h/2, dmpi->planes, dmpi->stride);
break;
default:
halfpack(dmpi->planes[0], mpi->planes, dmpi->stride[0],
@@ -170,6 +176,15 @@ static int config(struct vf_instance* vf,
int width, int height, int d_width, int d_height,
unsigned int flags, unsigned int outfmt)
{
+ if (vf->priv->field < 2) {
+ sws_freeContext(vf->priv->ctx);
+ // get unscaled 422p -> yuy2 conversion
+ vf->priv->ctx =
+ sws_getContext(width, height / 2, PIX_FMT_YUV422P,
+ width, height / 2, PIX_FMT_YUYV422,
+ SWS_POINT | SWS_PRINT_INFO | get_sws_cpuflags(),
+ NULL, NULL, NULL);
+ }
/* FIXME - also support UYVY output? */
return vf_next_config(vf, width, height/2, d_width, d_height, flags, IMGFMT_YUY2);
}
@@ -189,6 +204,7 @@ static int query_format(struct vf_instance* vf, unsigned int fmt)
static void uninit(struct vf_instance* vf)
{
+ sws_freeContext(vf->priv->ctx);
free(vf->priv);
}
diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c
index a38cf895d9..82a56535bb 100644
--- a/libmpcodecs/vf_scale.c
+++ b/libmpcodecs/vf_scale.c
@@ -31,7 +31,6 @@ static struct vf_priv_s {
int interlaced;
int noup;
int accurate_rnd;
- int query_format_cache[64];
} const vf_priv_dflt = {
-1,-1,
0,
@@ -92,18 +91,48 @@ static const unsigned int outfmt_list[]={
0
};
-static unsigned int find_best_out(vf_instance_t *vf){
+/**
+ * A list of preferred conversions, in order of preference.
+ * This should be used for conversions that e.g. involve no scaling
+ * or to stop vf_scale from choosing a conversion that has no
+ * fast assembler implementation.
+ */
+static int preferred_conversions[][2] = {
+ {IMGFMT_YUY2, IMGFMT_UYVY},
+ {IMGFMT_YUY2, IMGFMT_422P},
+ {IMGFMT_UYVY, IMGFMT_YUY2},
+ {IMGFMT_UYVY, IMGFMT_422P},
+ {IMGFMT_422P, IMGFMT_YUY2},
+ {IMGFMT_422P, IMGFMT_UYVY},
+ {0, 0}
+};
+
+static unsigned int find_best_out(vf_instance_t *vf, int in_format){
unsigned int best=0;
- int i;
+ int i = -1;
+ int j = -1;
+ int format = 0;
// find the best outfmt:
- for(i=0; i<sizeof(outfmt_list)/sizeof(int)-1; i++){
- const int format= outfmt_list[i];
- int ret= vf->priv->query_format_cache[i]-1;
- if(ret == -1){
- ret= vf_next_query_format(vf, outfmt_list[i]);
- vf->priv->query_format_cache[i]= ret+1;
+ while (1) {
+ int ret;
+ if (j < 0) {
+ format = in_format;
+ j = 0;
+ } else if (i < 0) {
+ while (preferred_conversions[j][0] &&
+ preferred_conversions[j][0] != in_format)
+ j++;
+ format = preferred_conversions[j++][1];
+ // switch to standard list
+ if (!format)
+ i = 0;
}
+ if (i >= 0)
+ format = outfmt_list[i++];
+ if (!format)
+ break;
+ ret = vf_next_query_format(vf, format);
mp_msg(MSGT_VFILTER,MSGL_DBG2,"scale: query(%s) -> %d\n",vo_format_name(format),ret&3);
if(ret&VFCAP_CSP_SUPPORTED_BY_HW){
@@ -120,7 +149,7 @@ static int config(struct vf_instance* vf,
int width, int height, int d_width, int d_height,
unsigned int flags, unsigned int outfmt){
struct MPOpts *opts = vf->opts;
- unsigned int best=find_best_out(vf);
+ unsigned int best=find_best_out(vf, outfmt);
int vo_flags;
int int_sws_flags=0;
int round_w=0, round_h=0;
@@ -494,7 +523,7 @@ static int query_format(struct vf_instance* vf, unsigned int fmt){
case IMGFMT_RGB48LE:
case IMGFMT_RGB48BE:
{
- unsigned int best=find_best_out(vf);
+ unsigned int best=find_best_out(vf, fmt);
int flags;
if(!best) return 0; // no matching out-fmt
flags=vf_next_query_format(vf,best);
diff --git a/libmpcodecs/vf_spp.c b/libmpcodecs/vf_spp.c
index 85d7ff9fc1..8dfcf41b5c 100644
--- a/libmpcodecs/vf_spp.c
+++ b/libmpcodecs/vf_spp.c
@@ -475,9 +475,15 @@ static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){
vf->priv->mpeg2= mpi->qscale_type;
if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){
+ int w = mpi->qstride;
+ int h = (mpi->h + 15) >> 4;
+ if (!w) {
+ w = (mpi->w + 15) >> 4;
+ h = 1;
+ }
if(!vf->priv->non_b_qp)
- vf->priv->non_b_qp= malloc(mpi->qstride * ((mpi->h + 15) >> 4));
- fast_memcpy(vf->priv->non_b_qp, mpi->qscale, mpi->qstride * ((mpi->h + 15) >> 4));
+ vf->priv->non_b_qp= malloc(w*h);
+ fast_memcpy(vf->priv->non_b_qp, mpi->qscale, w*h);
}
if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){
char *qp_tab= vf->priv->non_b_qp;