mirror of https://github.com/mpv-player/mpv
Quicktime 8BPS decoder
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10713 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
a4510b38e2
commit
1f6287474f
|
@ -125,6 +125,13 @@ videocodec qtsmc
|
|||
driver qtsmc
|
||||
out BGR32,BGR24
|
||||
|
||||
videocodec qt8bps
|
||||
info "Planar RGB (Photoshop)"
|
||||
status working
|
||||
fourcc 8BPS
|
||||
driver qt8bps
|
||||
out BGR32,BGR24,BGR8 query
|
||||
|
||||
videocodec cyuv
|
||||
info "Creative YUV (native codec)"
|
||||
status working
|
||||
|
|
|
@ -10,7 +10,7 @@ AUDIO_SRCS_OPT=ad_acm.c ad_dshow.c ad_dmo.c ad_qtaudio.c ad_ffmpeg.c ad_faad.c a
|
|||
AUDIO_SRCS=dec_audio.c ad.c $(AUDIO_SRCS_LIB) $(AUDIO_SRCS_NAT) $(AUDIO_SRCS_OPT)
|
||||
|
||||
VIDEO_SRCS_LIB=vd_libmpeg2.c vd_nuv.c vd_lzo.c
|
||||
VIDEO_SRCS_NAT=vd_null.c vd_cinepak.c vd_qtrpza.c vd_raw.c vd_hmblck.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_msrle.c vd_mpegpes.c vd_lcl.c vd_mtga.c vd_sgi.c
|
||||
VIDEO_SRCS_NAT=vd_null.c vd_cinepak.c vd_qtrpza.c vd_raw.c vd_hmblck.c vd_msvidc.c vd_fli.c vd_qtrle.c vd_qtsmc.c vd_roqvideo.c vd_cyuv.c vd_msrle.c vd_mpegpes.c vd_lcl.c vd_mtga.c vd_sgi.c vd_qt8bps.c
|
||||
VIDEO_SRCS_OPT=vd_realvid.c vd_ffmpeg.c vd_dshow.c vd_dmo.c vd_vfw.c vd_vfwex.c vd_odivx.c vd_divx4.c vd_xanim.c vd_xvid.c vd_libdv.c vd_qtvideo.c vd_theora.c
|
||||
VIDEO_SRCS=dec_video.c vd.c $(VIDEO_SRCS_NAT) $(VIDEO_SRCS_LIB) $(VIDEO_SRCS_OPT)
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ extern vd_functions_t mpcodecs_vd_libdv;
|
|||
extern vd_functions_t mpcodecs_vd_lcl;
|
||||
extern vd_functions_t mpcodecs_vd_lzo;
|
||||
extern vd_functions_t mpcodecs_vd_qtvideo;
|
||||
extern vd_functions_t mpcodecs_vd_qt8bps;
|
||||
|
||||
vd_functions_t* mpcodecs_vd_drivers[] = {
|
||||
&mpcodecs_vd_null,
|
||||
|
@ -125,6 +126,7 @@ vd_functions_t* mpcodecs_vd_drivers[] = {
|
|||
#if defined(USE_QTX_CODECS) || defined(MACOSX)
|
||||
&mpcodecs_vd_qtvideo,
|
||||
#endif
|
||||
&mpcodecs_vd_qt8bps,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
*
|
||||
* QuickTime 8BPS decoder for Mplayer
|
||||
* (c) 2003 Roberto Togni
|
||||
*
|
||||
* Fourcc: 8BPS
|
||||
*
|
||||
* Supports 8bpp (paletted), 24bpp and 32bpp (4th plane ignored)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "bswap.h"
|
||||
|
||||
#include "mp_msg.h"
|
||||
|
||||
#include "vd_internal.h"
|
||||
|
||||
|
||||
static vd_info_t info = {
|
||||
"8BPS Video decoder",
|
||||
"qt8bps",
|
||||
"Roberto Togni",
|
||||
"Roberto Togni",
|
||||
"native codec"
|
||||
};
|
||||
|
||||
LIBVD_EXTERN(qt8bps)
|
||||
|
||||
|
||||
/*
|
||||
* Decoder context
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char planes;
|
||||
unsigned char planemap[4];
|
||||
unsigned char *palette;
|
||||
} qt8bps_context_t;
|
||||
|
||||
|
||||
/*
|
||||
* Internal function prototypes
|
||||
*/
|
||||
|
||||
|
||||
// to set/get/query special features/parameters
|
||||
static int control(sh_video_t *sh,int cmd,void* arg,...)
|
||||
{
|
||||
qt8bps_context_t *hc = (qt8bps_context_t *) sh->context; // Decoder context
|
||||
|
||||
if (cmd == VDCTRL_QUERY_FORMAT)
|
||||
switch (hc->planes) {
|
||||
case 1:
|
||||
if (*((int*)arg) == IMGFMT_BGR8)
|
||||
return CONTROL_TRUE;
|
||||
else
|
||||
return CONTROL_FALSE;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
if ((*((int*)arg) == IMGFMT_BGR24) || (*((int*)arg) == IMGFMT_BGR32))
|
||||
return CONTROL_TRUE;
|
||||
else
|
||||
return CONTROL_FALSE;
|
||||
break;
|
||||
default:
|
||||
return CONTROL_FALSE;
|
||||
}
|
||||
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Init 8BPS decoder
|
||||
*
|
||||
*/
|
||||
static int init(sh_video_t *sh)
|
||||
{
|
||||
int vo_ret; // Video output init ret value
|
||||
qt8bps_context_t *hc; // Decoder context
|
||||
BITMAPINFOHEADER *bih = sh->bih;
|
||||
int i;
|
||||
unsigned char *psrc, *pdest;
|
||||
|
||||
if ((hc = malloc(sizeof(qt8bps_context_t))) == NULL) {
|
||||
mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate memory for 8BPS decoder context.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sh->context = (void *)hc;
|
||||
hc->palette = NULL;
|
||||
|
||||
switch (bih->biBitCount) {
|
||||
case 8:
|
||||
hc->planes = 1;
|
||||
hc->planemap[0] = 0; // 1st plane is palette indexes
|
||||
if (bih->biSize > sizeof(BITMAPINFOHEADER)) {
|
||||
psrc = (unsigned char*)bih + sizeof(BITMAPINFOHEADER);
|
||||
pdest = hc->palette = (unsigned char *)malloc(256*3);
|
||||
for (i = 0; i < 256; i++) {
|
||||
*pdest++ = *psrc++;
|
||||
*pdest++ = *psrc++;
|
||||
*pdest++ = *psrc++;
|
||||
psrc++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
hc->planes = 3;
|
||||
hc->planemap[0] = 2; // 1st plane is red
|
||||
hc->planemap[1] = 1; // 2nd plane is green
|
||||
hc->planemap[2] = 0; // 3rd plane is blue
|
||||
break;
|
||||
case 32:
|
||||
hc->planes = 4;
|
||||
hc->planemap[0] = 2; // 1st plane is red
|
||||
hc->planemap[1] = 1; // 2nd plane is green
|
||||
hc->planemap[2] = 0; // 3rd plane is blue
|
||||
hc->planemap[3] = 3; // 4th plane is alpha???
|
||||
mp_msg(MSGT_DECVIDEO, MSGL_WARN, "[8BPS] Ignoring 4th (alpha?) plane.\n");
|
||||
break;
|
||||
default:
|
||||
mp_msg(MSGT_DECVIDEO, MSGL_ERR, "[8BPS] Unsupported color depth: %u.\n", bih->biBitCount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize video output device
|
||||
*/
|
||||
vo_ret = mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_BGR24);
|
||||
|
||||
return vo_ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Uninit 8BPS decoder
|
||||
*
|
||||
*/
|
||||
static void uninit(sh_video_t *sh)
|
||||
{
|
||||
qt8bps_context_t *hc = (qt8bps_context_t *) sh->context; // Decoder context
|
||||
|
||||
if (sh->context) {
|
||||
if (hc->palette)
|
||||
free (hc->palette);
|
||||
free(sh->context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Decode a frame
|
||||
*
|
||||
*/
|
||||
static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags)
|
||||
{
|
||||
mp_image_t* mpi;
|
||||
unsigned char *encoded = (unsigned char *)data;
|
||||
qt8bps_context_t *hc = (qt8bps_context_t *) sh->context; // Decoder context
|
||||
unsigned char *outptr, *pixptr;
|
||||
unsigned int height = sh->disp_h; // Real image height
|
||||
unsigned int dlen, p, row;
|
||||
unsigned char *lp, *dp;
|
||||
unsigned char count;
|
||||
unsigned int px_inc;
|
||||
unsigned int planes = hc->planes;
|
||||
unsigned char *planemap = hc->planemap;
|
||||
|
||||
|
||||
// Skipped frame
|
||||
if(len <= 0)
|
||||
return NULL;
|
||||
|
||||
/* Get output image buffer */
|
||||
mpi=mpcodecs_get_image(sh, MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE, sh->disp_w, sh->disp_h);
|
||||
if (!mpi) {
|
||||
mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate mpi image for 8BPS codec.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
outptr = mpi->planes[0]; // Output image pointer
|
||||
px_inc = mpi->bpp/8;
|
||||
|
||||
/* Set data pointer after line lengths */
|
||||
dp = encoded + hc->planes*(height << 1);
|
||||
|
||||
/* Ignore alpha plane, don't know what to do with it */
|
||||
if (planes == 4)
|
||||
planes--;
|
||||
|
||||
for (p = 0; p < planes; p++) {
|
||||
/* Lines length pointer for this plane */
|
||||
lp = encoded + p*(height << 1);
|
||||
|
||||
/* Decode a plane */
|
||||
for(row = 0; row < height; row++) {
|
||||
pixptr = outptr + row * mpi->stride[0] + planemap[p];
|
||||
dlen = be2me_16(*(unsigned short *)(lp+row*2));
|
||||
/* Decode a row of this plane */
|
||||
while(dlen > 0) {
|
||||
if ((count = *dp++) <= 127) {
|
||||
count++;
|
||||
dlen -= count + 1;
|
||||
while(count--) {
|
||||
*pixptr = *dp++;
|
||||
pixptr += px_inc;
|
||||
}
|
||||
} else {
|
||||
count = 257 - count;
|
||||
while(count--) {
|
||||
*pixptr = *dp;
|
||||
pixptr += px_inc;
|
||||
}
|
||||
dp++;
|
||||
dlen -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hc->palette)
|
||||
mpi->planes[1] = hc->palette;
|
||||
|
||||
return mpi;
|
||||
}
|
Loading…
Reference in New Issue