mirror of https://github.com/mpv-player/mpv
Remove dead code
This was done with the help of callcatcher [1]. Only functions which are statically known to be unused are removed. Some unused functions are not removed yet, because they might be needed in the near future (such as open_output_stream for the encode branch). There is one user visible change: the --subcc option did nothing, and is removed with this commit. [1] http://www.skynet.ie/~caolan/Packages/callcatcher.html
This commit is contained in:
parent
7175f178de
commit
c92538dfaa
3
Makefile
3
Makefile
|
@ -370,8 +370,6 @@ SRCS_COMMON = asxparser.c \
|
|||
libmpdemux/mp_taglists.c \
|
||||
libmpdemux/mpeg_packetizer.c \
|
||||
libmpdemux/video.c \
|
||||
libmpdemux/yuv4mpeg.c \
|
||||
libmpdemux/yuv4mpeg_ratio.c \
|
||||
libvo/osd.c \
|
||||
libvo/eosd_packer.c \
|
||||
osdep/numcores.c \
|
||||
|
@ -392,7 +390,6 @@ SRCS_COMMON = asxparser.c \
|
|||
sub/find_subfiles.c \
|
||||
sub/spudec.c \
|
||||
sub/sub.c \
|
||||
sub/sub_cc.c \
|
||||
sub/subassconvert.c \
|
||||
sub/subreader.c \
|
||||
sub/vobsub.c \
|
||||
|
|
17
asxparser.c
17
asxparser.c
|
@ -68,9 +68,6 @@ asx_parse_attribs(ASX_Parser_t* parser,char* buffer,char*** _attribs);
|
|||
char*
|
||||
asx_get_attrib(const char* attrib,char** attribs);
|
||||
|
||||
int
|
||||
asx_attrib_to_enum(const char* val,char** valid_vals);
|
||||
|
||||
#define asx_free_attribs(a) asx_list_free(&a,free)
|
||||
|
||||
////// List utils
|
||||
|
@ -109,20 +106,6 @@ asx_get_attrib(const char* attrib,char** attribs) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
asx_attrib_to_enum(const char* val,char** valid_vals) {
|
||||
char** ptr;
|
||||
int r = 0;
|
||||
|
||||
if(valid_vals == NULL || val == NULL) return -2;
|
||||
for(ptr = valid_vals ; ptr[0] != NULL ; ptr++) {
|
||||
if(strcasecmp(val,ptr[0]) == 0) return r;
|
||||
r++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define asx_warning_attrib_required(p,e,a) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : element %s don't have the required attribute %s",p->line,e,a)
|
||||
#define asx_warning_body_parse_error(p,e) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing %s body",p->line,e)
|
||||
|
||||
|
|
|
@ -581,8 +581,6 @@ const m_option_t common_opts[] = {
|
|||
// specify IFO file for VOBSUB subtitle
|
||||
{"ifo", &spudec_ifo, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
// enable Closed Captioning display
|
||||
{"subcc", &subcc_enabled, CONF_TYPE_INT, CONF_RANGE, 0, 4, NULL},
|
||||
{"no-subcc", &subcc_enabled, CONF_TYPE_FLAG, 0, 1, 0, NULL},
|
||||
{"overlapsub", &suboverlap_enabled, CONF_TYPE_FLAG, 0, 0, 2, NULL},
|
||||
{"sub-bg-color", &sub_bg_color, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL},
|
||||
{"sub-bg-alpha", &sub_bg_alpha, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL},
|
||||
|
|
|
@ -859,30 +859,6 @@ int mp_input_add_key_fd(struct input_ctx *ictx, int fd, int select,
|
|||
return 1;
|
||||
}
|
||||
|
||||
int mp_input_parse_and_queue_cmds(struct input_ctx *ictx, const char *str)
|
||||
{
|
||||
int cmd_num = 0;
|
||||
|
||||
while (*str == '\n' || *str == '\r' || *str == ' ')
|
||||
++str;
|
||||
while (*str) {
|
||||
mp_cmd_t *cmd;
|
||||
size_t len = strcspn(str, "\r\n");
|
||||
char *cmdbuf = talloc_size(NULL, len + 1);
|
||||
av_strlcpy(cmdbuf, str, len + 1);
|
||||
cmd = mp_input_parse_cmd(cmdbuf);
|
||||
if (cmd) {
|
||||
mp_input_queue_cmd(ictx, cmd);
|
||||
++cmd_num;
|
||||
}
|
||||
str += len;
|
||||
while (*str == '\n' || *str == '\r' || *str == ' ')
|
||||
++str;
|
||||
talloc_free(cmdbuf);
|
||||
}
|
||||
return cmd_num;
|
||||
}
|
||||
|
||||
mp_cmd_t *mp_input_parse_cmd(char *str)
|
||||
{
|
||||
int i, l;
|
||||
|
|
|
@ -252,12 +252,6 @@ struct mp_cmd *mp_input_get_cmd(struct input_ctx *ictx, int time,
|
|||
/* Parse text and return corresponding struct mp_cmd. */
|
||||
struct mp_cmd *mp_input_parse_cmd(char *str);
|
||||
|
||||
/**
|
||||
* Parse and queue commands separated by '\n'.
|
||||
* Return number of commands queued.
|
||||
*/
|
||||
int mp_input_parse_and_queue_cmds(struct input_ctx *ictx, const char *str);
|
||||
|
||||
// After getting a command from mp_input_get_cmd you need to free it using this
|
||||
// function
|
||||
void mp_cmd_free(struct mp_cmd *cmd);
|
||||
|
|
|
@ -111,7 +111,6 @@
|
|||
|
||||
#define AF_FORMAT_IS_AC3(fmt) (((fmt) & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_AC3)
|
||||
|
||||
int af_str2fmt(const char *str);
|
||||
int af_str2fmt_short(const char *str);
|
||||
int af_fmt2bits(int format);
|
||||
int af_bits2fmt(int bits);
|
||||
|
|
|
@ -46,51 +46,6 @@ inline FLOAT_TYPE af_filter_fir(register unsigned int n, const FLOAT_TYPE* w,
|
|||
return y;
|
||||
}
|
||||
|
||||
/* C implementation of parallel FIR filter y(k)=w(k) * x(k) (where * denotes convolution)
|
||||
|
||||
n number of filter taps, where mod(n,4)==0
|
||||
d number of filters
|
||||
xi current index in xq
|
||||
w filter taps k by n big
|
||||
x input signal must be a circular buffers which are indexed backwards
|
||||
y output buffer
|
||||
s output buffer stride
|
||||
*/
|
||||
FLOAT_TYPE* af_filter_pfir(unsigned int n, unsigned int d, unsigned int xi,
|
||||
const FLOAT_TYPE** w, const FLOAT_TYPE** x, FLOAT_TYPE* y,
|
||||
unsigned int s)
|
||||
{
|
||||
register const FLOAT_TYPE* xt = *x + xi;
|
||||
register const FLOAT_TYPE* wt = *w;
|
||||
register int nt = 2*n;
|
||||
while(d-- > 0){
|
||||
*y = af_filter_fir(n,wt,xt);
|
||||
wt+=n;
|
||||
xt+=nt;
|
||||
y+=s;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
/* Add new data to circular queue designed to be used with a parallel
|
||||
FIR filter, with d filters. xq is the circular queue, in pointing
|
||||
at the new samples, xi current index in xq and n the length of the
|
||||
filter. xq must be n*2 by k big, s is the index for in.
|
||||
*/
|
||||
int af_filter_updatepq(unsigned int n, unsigned int d, unsigned int xi,
|
||||
FLOAT_TYPE** xq, const FLOAT_TYPE* in, unsigned int s)
|
||||
{
|
||||
register FLOAT_TYPE* txq = *xq + xi;
|
||||
register int nt = n*2;
|
||||
|
||||
while(d-- >0){
|
||||
*txq= *(txq+n) = *in;
|
||||
txq+=nt;
|
||||
in+=s;
|
||||
}
|
||||
return (++xi)&(n-1);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FIR filter design
|
||||
******************************************************************************/
|
||||
|
@ -234,51 +189,6 @@ int af_filter_design_fir(unsigned int n, FLOAT_TYPE* w, const FLOAT_TYPE* fc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Design polyphase FIR filter from prototype filter
|
||||
|
||||
n length of prototype filter
|
||||
k number of polyphase components
|
||||
w prototype filter taps
|
||||
pw Parallel FIR filter
|
||||
g Filter gain
|
||||
flags FWD forward indexing
|
||||
REW reverse indexing
|
||||
ODD multiply every 2nd filter tap by -1 => HP filter
|
||||
|
||||
returns 0 if OK, -1 if fail
|
||||
*/
|
||||
int af_filter_design_pfir(unsigned int n, unsigned int k, const FLOAT_TYPE* w,
|
||||
FLOAT_TYPE** pw, FLOAT_TYPE g, unsigned int flags)
|
||||
{
|
||||
int l = (int)n/k; // Length of individual FIR filters
|
||||
int i; // Counters
|
||||
int j;
|
||||
FLOAT_TYPE t; // g * w[i]
|
||||
|
||||
// Sanity check
|
||||
if(l<1 || k<1 || !w || !pw)
|
||||
return -1;
|
||||
|
||||
// Do the stuff
|
||||
if(flags&REW){
|
||||
for(j=l-1;j>-1;j--){//Columns
|
||||
for(i=0;i<(int)k;i++){//Rows
|
||||
t=g * *w++;
|
||||
pw[i][j]=t * ((flags & ODD) ? ((j & 1) ? -1 : 1) : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(j=0;j<l;j++){//Columns
|
||||
for(i=0;i<(int)k;i++){//Rows
|
||||
t=g * *w++;
|
||||
pw[i][j]=t * ((flags & ODD) ? ((j & 1) ? 1 : -1) : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* IIR filter design
|
||||
******************************************************************************/
|
||||
|
|
|
@ -56,22 +56,9 @@
|
|||
// Exported functions
|
||||
FLOAT_TYPE af_filter_fir(unsigned int n, const FLOAT_TYPE* w, const FLOAT_TYPE* x);
|
||||
|
||||
FLOAT_TYPE* af_filter_pfir(unsigned int n, unsigned int k,
|
||||
unsigned int xi, const FLOAT_TYPE** w,
|
||||
const FLOAT_TYPE** x, FLOAT_TYPE* y,
|
||||
unsigned int s);
|
||||
|
||||
//int af_filter_updateq(unsigned int n, unsigned int xi,
|
||||
// FLOAT_TYPE* xq, FLOAT_TYPE* in);
|
||||
int af_filter_updatepq(unsigned int n, unsigned int k, unsigned int xi,
|
||||
FLOAT_TYPE** xq, const FLOAT_TYPE* in, unsigned int s);
|
||||
|
||||
int af_filter_design_fir(unsigned int n, FLOAT_TYPE* w, const FLOAT_TYPE* fc,
|
||||
unsigned int flags, FLOAT_TYPE opt);
|
||||
|
||||
int af_filter_design_pfir(unsigned int n, unsigned int k, const FLOAT_TYPE* w,
|
||||
FLOAT_TYPE** pw, FLOAT_TYPE g, unsigned int flags);
|
||||
|
||||
int af_filter_szxform(const FLOAT_TYPE* a, const FLOAT_TYPE* b, FLOAT_TYPE Q,
|
||||
FLOAT_TYPE fc, FLOAT_TYPE fs, FLOAT_TYPE *k,
|
||||
FLOAT_TYPE *coef);
|
||||
|
|
|
@ -26,51 +26,6 @@
|
|||
|
||||
#include "af.h"
|
||||
|
||||
// Convert from string to format
|
||||
int af_str2fmt(const char* str)
|
||||
{
|
||||
int format=0;
|
||||
// Scan for endianness
|
||||
if(strstr(str,"be") || strstr(str,"BE"))
|
||||
format |= AF_FORMAT_BE;
|
||||
else if(strstr(str,"le") || strstr(str,"LE"))
|
||||
format |= AF_FORMAT_LE;
|
||||
else
|
||||
format |= AF_FORMAT_NE;
|
||||
|
||||
// Scan for special formats
|
||||
if(strstr(str,"mulaw") || strstr(str,"MULAW")){
|
||||
format |= AF_FORMAT_MU_LAW; return format;
|
||||
}
|
||||
if(strstr(str,"alaw") || strstr(str,"ALAW")){
|
||||
format |= AF_FORMAT_A_LAW; return format;
|
||||
}
|
||||
if(strstr(str,"ac3") || strstr(str,"AC3")){
|
||||
format |= AF_FORMAT_AC3 | AF_FORMAT_16BIT; return format;
|
||||
}
|
||||
if(strstr(str,"mpeg2") || strstr(str,"MPEG2")){
|
||||
format |= AF_FORMAT_MPEG2; return format;
|
||||
}
|
||||
if(strstr(str,"imaadpcm") || strstr(str,"IMAADPCM")){
|
||||
format |= AF_FORMAT_IMA_ADPCM; return format;
|
||||
}
|
||||
|
||||
// Scan for int/float
|
||||
if(strstr(str,"float") || strstr(str,"FLOAT")){
|
||||
format |= AF_FORMAT_F; return format;
|
||||
}
|
||||
else
|
||||
format |= AF_FORMAT_I;
|
||||
|
||||
// Scan for signed/unsigned
|
||||
if(strstr(str,"unsigned") || strstr(str,"UNSIGNED"))
|
||||
format |= AF_FORMAT_US;
|
||||
else
|
||||
format |= AF_FORMAT_SI;
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
int af_fmt2bits(int format)
|
||||
{
|
||||
if (AF_FORMAT_IS_AC3(format)) return 16;
|
||||
|
|
|
@ -72,19 +72,6 @@ int get_video_quality_max(sh_video_t *sh_video)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void set_video_quality(sh_video_t *sh_video, int quality)
|
||||
{
|
||||
vf_instance_t *vf = sh_video->vfilter;
|
||||
if (vf) {
|
||||
int ret = vf->control(vf, VFCTRL_SET_PP_LEVEL, (void *) (&quality));
|
||||
if (ret == CONTROL_TRUE)
|
||||
return; // success
|
||||
}
|
||||
const struct vd_functions *vd = sh_video->vd_driver;
|
||||
if (vd)
|
||||
vd->control(sh_video, VDCTRL_SET_PP_LEVEL, (void *) (&quality));
|
||||
}
|
||||
|
||||
int set_video_colors(sh_video_t *sh_video, const char *item, int value)
|
||||
{
|
||||
vf_instance_t *vf = sh_video->vfilter;
|
||||
|
|
|
@ -36,7 +36,6 @@ void *decode_video(sh_video_t *sh_video, struct demux_packet *packet,
|
|||
int filter_video(sh_video_t *sh_video, void *frame, double pts);
|
||||
|
||||
int get_video_quality_max(sh_video_t *sh_video);
|
||||
void set_video_quality(sh_video_t *sh_video, int quality);
|
||||
|
||||
int get_video_colors(sh_video_t *sh_video, const char *item, int *value);
|
||||
int set_video_colors(sh_video_t *sh_video, const char *item, int value);
|
||||
|
|
|
@ -442,21 +442,6 @@ void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b,
|
|||
c->head = c->head->next;
|
||||
}
|
||||
|
||||
void pullup_flush_fields(struct pullup_context *c)
|
||||
{
|
||||
struct pullup_field *f;
|
||||
|
||||
for (f = c->first; f && f != c->head; f = f->next) {
|
||||
pullup_release_buffer(f->buffer, f->parity);
|
||||
f->buffer = 0;
|
||||
}
|
||||
c->first = c->last = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -89,7 +89,6 @@ struct pullup_buffer *pullup_get_buffer(struct pullup_context *c, int parity);
|
|||
|
||||
void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b,
|
||||
int parity, double pts);
|
||||
void pullup_flush_fields(struct pullup_context *c);
|
||||
|
||||
struct pullup_frame *pullup_get_frame(struct pullup_context *c);
|
||||
void pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr);
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#define VFCAP_CSP_SUPPORTED_BY_HW 0x2
|
||||
// set if the driver/filter can draw OSD
|
||||
#define VFCAP_OSD 0x4
|
||||
// set if the driver/filter can handle compressed SPU stream
|
||||
#define VFCAP_SPU 0x8
|
||||
// scaling up/down by hardware, or software:
|
||||
#define VFCAP_HWSCALE_UP 0x10
|
||||
#define VFCAP_HWSCALE_DOWN 0x20
|
||||
|
|
|
@ -309,17 +309,6 @@ sh_sub_t *new_sh_sub_sid(demuxer_t *demuxer, int id, int sid)
|
|||
return demuxer->s_streams[id];
|
||||
}
|
||||
|
||||
struct sh_sub *new_sh_sub_sid_lang(struct demuxer *demuxer, int id, int sid,
|
||||
const char *lang)
|
||||
{
|
||||
struct sh_sub *sh = new_sh_sub_sid(demuxer, id, sid);
|
||||
if (lang && lang[0] && strcmp(lang, "und")) {
|
||||
sh->lang = talloc_strdup(sh, lang);
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_LANG=%s\n", sid, lang);
|
||||
}
|
||||
return sh;
|
||||
}
|
||||
|
||||
static void free_sh_sub(sh_sub_t *sh)
|
||||
{
|
||||
mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing sh_sub at %p\n", sh);
|
||||
|
@ -681,43 +670,6 @@ int demux_read_data(demux_stream_t *ds, unsigned char *mem, int len)
|
|||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief read data until the given 3-byte pattern is encountered, up to maxlen
|
||||
* \param mem memory to read data into, may be NULL to discard data
|
||||
* \param maxlen maximum number of bytes to read
|
||||
* \param read number of bytes actually read
|
||||
* \param pattern pattern to search for (lowest 8 bits are ignored)
|
||||
* \return whether pattern was found
|
||||
*/
|
||||
int demux_pattern_3(demux_stream_t *ds, unsigned char *mem, int maxlen,
|
||||
int *read, uint32_t pattern)
|
||||
{
|
||||
register uint32_t head = 0xffffff00;
|
||||
register uint32_t pat = pattern & 0xffffff00;
|
||||
int total_len = 0;
|
||||
do {
|
||||
register unsigned char *ds_buf = &ds->buffer[ds->buffer_size];
|
||||
int len = ds->buffer_size - ds->buffer_pos;
|
||||
register long pos = -len;
|
||||
if (unlikely(pos >= 0)) { // buffer is empty
|
||||
ds_fill_buffer(ds);
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
head |= ds_buf[pos];
|
||||
head <<= 8;
|
||||
} while (++pos && head != pat);
|
||||
len += pos;
|
||||
if (total_len + len > maxlen)
|
||||
len = maxlen - total_len;
|
||||
len = demux_read_data(ds, mem ? &mem[total_len] : NULL, len);
|
||||
total_len += len;
|
||||
} while ((head != pat || total_len < 3) && total_len < maxlen && !ds->eof);
|
||||
if (read)
|
||||
*read = total_len;
|
||||
return total_len >= 3 && head == pat;
|
||||
}
|
||||
|
||||
void ds_free_packs(demux_stream_t *ds)
|
||||
{
|
||||
demux_packet_t *dp = ds->first;
|
||||
|
|
|
@ -317,8 +317,6 @@ static inline int ds_tell_pts(struct demux_stream *ds)
|
|||
}
|
||||
|
||||
int demux_read_data(struct demux_stream *ds, unsigned char *mem, int len);
|
||||
int demux_pattern_3(struct demux_stream *ds, unsigned char *mem, int maxlen,
|
||||
int *read, uint32_t pattern);
|
||||
|
||||
#define demux_peekc(ds) ( \
|
||||
(likely(ds->buffer_pos<ds->buffer_size)) ? ds->buffer[ds->buffer_pos] \
|
||||
|
|
|
@ -145,26 +145,3 @@ send_mpeg_pes_packet (unsigned char *data, int len, int id, uint64_t pts,
|
|||
{
|
||||
return send_mpeg_pes_packet_ll(data, len, id, pts, type, NULL, 0, 0, my_write);
|
||||
}
|
||||
|
||||
|
||||
/* Send MPEG <type> PS packet */
|
||||
int
|
||||
send_mpeg_ps_packet(unsigned char *data, int len, int id, uint64_t pts, int type,
|
||||
int my_write (const unsigned char *data, int len))
|
||||
{
|
||||
if(type == 2)
|
||||
my_write (ps2_header, sizeof (ps2_header));
|
||||
else
|
||||
my_write (ps1_header, sizeof (ps1_header));
|
||||
return send_mpeg_pes_packet (data, len, id, pts, type, my_write);
|
||||
}
|
||||
|
||||
/* Send MPEG 2 LPCM packet */
|
||||
int
|
||||
send_mpeg_lpcm_packet(unsigned char* data, int len,
|
||||
int id, uint64_t pts, int freq_id,
|
||||
int my_write (const unsigned char *data, int len))
|
||||
{
|
||||
unsigned char header[7] = {0xA0, 0x07, 0x00, 0x04, 0x0C, 1 | (freq_id << 4), 0x80};
|
||||
return send_mpeg_pes_packet_ll(data, len, 0xBD, pts, 2, header, sizeof(header), 1, my_write);
|
||||
}
|
||||
|
|
|
@ -34,13 +34,4 @@
|
|||
int send_mpeg_pes_packet (unsigned char *data, int len, int id, uint64_t pts,
|
||||
int type, int my_write (const unsigned char *data, int len));
|
||||
|
||||
/* Send MPEG <type> PS packet */
|
||||
int send_mpeg_ps_packet (unsigned char *data, int len, int id, uint64_t pts,
|
||||
int type,int my_write (const unsigned char *data, int len));
|
||||
|
||||
/* Send MPEG 2 LPCM packet */
|
||||
int send_mpeg_lpcm_packet (unsigned char *data, int len,
|
||||
int id, uint64_t pts, int freq_id,
|
||||
int my_write (const unsigned char *data, int len));
|
||||
|
||||
#endif /* MPLAYER_MPEG_PACKETIZER_H */
|
||||
|
|
|
@ -159,8 +159,6 @@ struct sh_audio *new_sh_audio_aid(struct demuxer *demuxer, int id, int aid);
|
|||
struct sh_video *new_sh_video_vid(struct demuxer *demuxer, int id, int vid);
|
||||
#define new_sh_sub(d, i) new_sh_sub_sid(d, i, i)
|
||||
struct sh_sub *new_sh_sub_sid(struct demuxer *demuxer, int id, int sid);
|
||||
struct sh_sub *new_sh_sub_sid_lang(struct demuxer *demuxer, int id, int sid,
|
||||
const char *lang);
|
||||
void free_sh_audio(struct demuxer *demuxer, int id);
|
||||
void free_sh_video(struct sh_video *sh);
|
||||
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
#endif
|
||||
#include "stheader.h"
|
||||
|
||||
/* sub_cc (closed captions)*/
|
||||
#include "sub/sub_cc.h"
|
||||
|
||||
/* biCompression constant */
|
||||
#define BI_RGB 0L
|
||||
|
||||
|
|
|
@ -1,767 +0,0 @@
|
|||
/*
|
||||
* yuv4mpeg.c: Functions for reading and writing "new" YUV4MPEG streams
|
||||
*
|
||||
* Copyright (C) 2001 Matthew J. Marjanovic <maddog@mir.com>
|
||||
*
|
||||
* This file is part of the MJPEG Tools package (mjpeg.sourceforge.net).
|
||||
* Ported to mplayer by Rik Snel <rsnel@cube.dyndns.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "yuv4mpeg.h"
|
||||
#include "yuv4mpeg_intern.h"
|
||||
#include "mp_msg.h"
|
||||
#include "libavutil/attributes.h"
|
||||
|
||||
static int _y4mparam_allow_unknown_tags = 1; /* default is forgiveness */
|
||||
|
||||
static void *(*_y4m_alloc)(size_t bytes) = malloc;
|
||||
static void (*_y4m_free)(void *ptr) = free;
|
||||
|
||||
int y4m_allow_unknown_tags(int yn) {
|
||||
int old = _y4mparam_allow_unknown_tags;
|
||||
if (yn >= 0) _y4mparam_allow_unknown_tags = (yn) ? 1 : 0;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Convenience functions for fd read/write
|
||||
*
|
||||
* - guaranteed to transfer entire payload (or fail)
|
||||
* - returns:
|
||||
* 0 on complete success
|
||||
* +(# of remaining bytes) on eof (for y4m_read)
|
||||
* -(# of rem. bytes) on error (and ERRNO should be set)
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
ssize_t y4m_read(stream_t *s, char *buf, size_t len)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
while (len > 0) {
|
||||
n = stream_read(s, buf, len);
|
||||
if (n <= 0) {
|
||||
/* return amount left to read */
|
||||
if (n == 0)
|
||||
return len; /* n == 0 --> eof */
|
||||
else
|
||||
return -len; /* n < 0 --> error */
|
||||
}
|
||||
buf += n;
|
||||
len -= n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* not needed */
|
||||
ssize_t y4m_write(int fd, char *buf, size_t len)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
while (len > 0) {
|
||||
n = write(fd, buf, len);
|
||||
if (n < 0) return -len; /* return amount left to write */
|
||||
buf += n;
|
||||
len -= n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* "Extra tags" handling
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
static char *y4m_new_xtag(void)
|
||||
{
|
||||
return _y4m_alloc(Y4M_MAX_XTAG_SIZE);
|
||||
}
|
||||
|
||||
|
||||
void y4m_init_xtag_list(y4m_xtag_list_t *xtags)
|
||||
{
|
||||
int i;
|
||||
xtags->count = 0;
|
||||
for (i = 0; i < Y4M_MAX_XTAGS; i++) {
|
||||
xtags->tags[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void y4m_fini_xtag_list(y4m_xtag_list_t *xtags)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < Y4M_MAX_XTAGS; i++) {
|
||||
if (xtags->tags[i] != NULL) {
|
||||
_y4m_free(xtags->tags[i]);
|
||||
xtags->tags[i] = NULL;
|
||||
}
|
||||
}
|
||||
xtags->count = 0;
|
||||
}
|
||||
|
||||
|
||||
void y4m_copy_xtag_list(y4m_xtag_list_t *dest, const y4m_xtag_list_t *src)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < src->count; i++) {
|
||||
if (dest->tags[i] == NULL)
|
||||
dest->tags[i] = y4m_new_xtag();
|
||||
strncpy(dest->tags[i], src->tags[i], Y4M_MAX_XTAG_SIZE);
|
||||
}
|
||||
dest->count = src->count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
static int y4m_snprint_xtags(char *s, int maxn, y4m_xtag_list_t *xtags)
|
||||
{
|
||||
int i, room;
|
||||
|
||||
for (i = 0, room = maxn - 1; i < xtags->count; i++) {
|
||||
int n = snprintf(s, room + 1, " %s", xtags->tags[i]);
|
||||
if ((n < 0) || (n > room)) return Y4M_ERR_HEADER;
|
||||
s += n;
|
||||
room -= n;
|
||||
}
|
||||
s[0] = '\n'; /* finish off header with newline */
|
||||
s[1] = '\0'; /* ...and end-of-string */
|
||||
return Y4M_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int y4m_xtag_count(const y4m_xtag_list_t *xtags)
|
||||
{
|
||||
return xtags->count;
|
||||
}
|
||||
|
||||
|
||||
const char *y4m_xtag_get(const y4m_xtag_list_t *xtags, int n)
|
||||
{
|
||||
if (n >= xtags->count)
|
||||
return NULL;
|
||||
else
|
||||
return xtags->tags[n];
|
||||
}
|
||||
|
||||
|
||||
int y4m_xtag_add(y4m_xtag_list_t *xtags, const char *tag)
|
||||
{
|
||||
if (xtags->count >= Y4M_MAX_XTAGS) return Y4M_ERR_XXTAGS;
|
||||
if (xtags->tags[xtags->count] == NULL) {
|
||||
xtags->tags[xtags->count] = y4m_new_xtag();
|
||||
}
|
||||
strncpy(xtags->tags[xtags->count], tag, Y4M_MAX_XTAG_SIZE);
|
||||
(xtags->count)++;
|
||||
return Y4M_OK;
|
||||
}
|
||||
|
||||
|
||||
int y4m_xtag_remove(y4m_xtag_list_t *xtags, int n)
|
||||
{
|
||||
int i;
|
||||
char *q;
|
||||
|
||||
if ((n < 0) || (n >= xtags->count)) return Y4M_ERR_RANGE;
|
||||
q = xtags->tags[n];
|
||||
for (i = n; i < (xtags->count - 1); i++)
|
||||
xtags->tags[i] = xtags->tags[i+1];
|
||||
xtags->tags[i] = q;
|
||||
(xtags->count)--;
|
||||
return Y4M_OK;
|
||||
}
|
||||
|
||||
|
||||
int y4m_xtag_clearlist(y4m_xtag_list_t *xtags)
|
||||
{
|
||||
xtags->count = 0;
|
||||
return Y4M_OK;
|
||||
}
|
||||
|
||||
|
||||
int y4m_xtag_addlist(y4m_xtag_list_t *dest, const y4m_xtag_list_t *src)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if ((dest->count + src->count) > Y4M_MAX_XTAGS) return Y4M_ERR_XXTAGS;
|
||||
for (i = dest->count, j = 0;
|
||||
j < src->count;
|
||||
i++, j++) {
|
||||
if (dest->tags[i] == NULL)
|
||||
dest->tags[i] = y4m_new_xtag();
|
||||
strncpy(dest->tags[i], src->tags[i], Y4M_MAX_XTAG_SIZE);
|
||||
}
|
||||
dest->count += src->count;
|
||||
return Y4M_OK;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Creators/destructors for y4m_*_info_t structures
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
void y4m_init_stream_info(y4m_stream_info_t *info)
|
||||
{
|
||||
if (info == NULL) return;
|
||||
/* initialize info */
|
||||
info->width = Y4M_UNKNOWN;
|
||||
info->height = Y4M_UNKNOWN;
|
||||
info->interlace = Y4M_UNKNOWN;
|
||||
info->framerate = y4m_fps_UNKNOWN;
|
||||
info->sampleaspect = y4m_sar_UNKNOWN;
|
||||
y4m_init_xtag_list(&(info->x_tags));
|
||||
}
|
||||
|
||||
|
||||
void y4m_copy_stream_info(y4m_stream_info_t *dest, y4m_stream_info_t *src)
|
||||
{
|
||||
if ((dest == NULL) || (src == NULL)) return;
|
||||
/* copy info */
|
||||
dest->width = src->width;
|
||||
dest->height = src->height;
|
||||
dest->interlace = src->interlace;
|
||||
dest->framerate = src->framerate;
|
||||
dest->sampleaspect = src->sampleaspect;
|
||||
y4m_copy_xtag_list(&(dest->x_tags), &(src->x_tags));
|
||||
}
|
||||
|
||||
|
||||
void y4m_fini_stream_info(y4m_stream_info_t *info)
|
||||
{
|
||||
if (info == NULL) return;
|
||||
y4m_fini_xtag_list(&(info->x_tags));
|
||||
}
|
||||
|
||||
|
||||
void y4m_si_set_width(y4m_stream_info_t *si, int width)
|
||||
{
|
||||
si->width = width;
|
||||
si->framelength = (si->height * si->width) * 3 / 2;
|
||||
}
|
||||
|
||||
int y4m_si_get_width(y4m_stream_info_t *si)
|
||||
{ return si->width; }
|
||||
|
||||
void y4m_si_set_height(y4m_stream_info_t *si, int height)
|
||||
{
|
||||
si->height = height;
|
||||
si->framelength = (si->height * si->width) * 3 / 2;
|
||||
}
|
||||
|
||||
int y4m_si_get_height(y4m_stream_info_t *si)
|
||||
{ return si->height; }
|
||||
|
||||
void y4m_si_set_interlace(y4m_stream_info_t *si, int interlace)
|
||||
{ si->interlace = interlace; }
|
||||
|
||||
int y4m_si_get_interlace(y4m_stream_info_t *si)
|
||||
{ return si->interlace; }
|
||||
|
||||
void y4m_si_set_framerate(y4m_stream_info_t *si, y4m_ratio_t framerate)
|
||||
{ si->framerate = framerate; }
|
||||
|
||||
y4m_ratio_t y4m_si_get_framerate(y4m_stream_info_t *si)
|
||||
{ return si->framerate; }
|
||||
|
||||
void y4m_si_set_sampleaspect(y4m_stream_info_t *si, y4m_ratio_t sar)
|
||||
{ si->sampleaspect = sar; }
|
||||
|
||||
y4m_ratio_t y4m_si_get_sampleaspect(y4m_stream_info_t *si)
|
||||
{ return si->sampleaspect; }
|
||||
|
||||
int y4m_si_get_framelength(y4m_stream_info_t *si)
|
||||
{ return si->framelength; }
|
||||
|
||||
y4m_xtag_list_t *y4m_si_xtags(y4m_stream_info_t *si)
|
||||
{ return &(si->x_tags); }
|
||||
|
||||
|
||||
|
||||
void y4m_init_frame_info(y4m_frame_info_t *info)
|
||||
{
|
||||
if (info == NULL) return;
|
||||
/* initialize info */
|
||||
y4m_init_xtag_list(&(info->x_tags));
|
||||
}
|
||||
|
||||
|
||||
void y4m_copy_frame_info(y4m_frame_info_t *dest, y4m_frame_info_t *src)
|
||||
{
|
||||
if ((dest == NULL) || (src == NULL)) return;
|
||||
/* copy info */
|
||||
y4m_copy_xtag_list(&(dest->x_tags), &(src->x_tags));
|
||||
}
|
||||
|
||||
|
||||
void y4m_fini_frame_info(y4m_frame_info_t *info)
|
||||
{
|
||||
if (info == NULL) return;
|
||||
y4m_fini_xtag_list(&(info->x_tags));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Tag parsing
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
int y4m_parse_stream_tags(char *s, y4m_stream_info_t *i)
|
||||
{
|
||||
char *token, *value;
|
||||
char tag;
|
||||
int err;
|
||||
|
||||
/* parse fields */
|
||||
for (token = strtok(s, Y4M_DELIM);
|
||||
token != NULL;
|
||||
token = strtok(NULL, Y4M_DELIM)) {
|
||||
if (token[0] == '\0') continue; /* skip empty strings */
|
||||
tag = token[0];
|
||||
value = token + 1;
|
||||
switch (tag) {
|
||||
case 'W': /* width */
|
||||
i->width = atoi(value);
|
||||
if (i->width <= 0) return Y4M_ERR_RANGE;
|
||||
break;
|
||||
case 'H': /* height */
|
||||
i->height = atoi(value);
|
||||
if (i->height <= 0) return Y4M_ERR_RANGE;
|
||||
break;
|
||||
case 'F': /* frame rate (fps) */
|
||||
if ((err = y4m_parse_ratio(&(i->framerate), value)) != Y4M_OK)
|
||||
return err;
|
||||
if (i->framerate.n < 0) return Y4M_ERR_RANGE;
|
||||
break;
|
||||
case 'I': /* interlacing */
|
||||
switch (value[0]) {
|
||||
case 'p': i->interlace = Y4M_ILACE_NONE; break;
|
||||
case 't': i->interlace = Y4M_ILACE_TOP_FIRST; break;
|
||||
case 'b': i->interlace = Y4M_ILACE_BOTTOM_FIRST; break;
|
||||
case '?':
|
||||
default:
|
||||
i->interlace = Y4M_UNKNOWN; break;
|
||||
}
|
||||
break;
|
||||
case 'A': /* sample (pixel) aspect ratio */
|
||||
if ((err = y4m_parse_ratio(&(i->sampleaspect), value)) != Y4M_OK)
|
||||
return err;
|
||||
if (i->sampleaspect.n < 0) return Y4M_ERR_RANGE;
|
||||
break;
|
||||
case 'X': /* 'X' meta-tag */
|
||||
if ((err = y4m_xtag_add(&(i->x_tags), token)) != Y4M_OK) return err;
|
||||
break;
|
||||
default:
|
||||
/* possible error on unknown options */
|
||||
if (_y4mparam_allow_unknown_tags) {
|
||||
/* unknown tags ok: store in xtag list and warn... */
|
||||
if ((err = y4m_xtag_add(&(i->x_tags), token)) != Y4M_OK) return err;
|
||||
mp_msg(MSGT_DEMUX, MSGL_WARN, "Unknown stream tag encountered: '%s'\n", token);
|
||||
} else {
|
||||
/* unknown tags are *not* ok */
|
||||
return Y4M_ERR_BADTAG;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Error checking... width and height must be known since we can't
|
||||
* parse without them
|
||||
*/
|
||||
if( i->width == Y4M_UNKNOWN || i->height == Y4M_UNKNOWN )
|
||||
return Y4M_ERR_HEADER;
|
||||
/* ta da! done. */
|
||||
return Y4M_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int y4m_parse_frame_tags(char *s, y4m_frame_info_t *i)
|
||||
{
|
||||
char *token, *value av_unused;
|
||||
char tag;
|
||||
int err;
|
||||
|
||||
/* parse fields */
|
||||
for (token = strtok(s, Y4M_DELIM);
|
||||
token != NULL;
|
||||
token = strtok(NULL, Y4M_DELIM)) {
|
||||
if (token[0] == '\0') continue; /* skip empty strings */
|
||||
tag = token[0];
|
||||
value = token + 1;
|
||||
switch (tag) {
|
||||
case 'X': /* 'X' meta-tag */
|
||||
if ((err = y4m_xtag_add(&(i->x_tags), token)) != Y4M_OK) return err;
|
||||
break;
|
||||
default:
|
||||
/* possible error on unknown options */
|
||||
if (_y4mparam_allow_unknown_tags) {
|
||||
/* unknown tags ok: store in xtag list and warn... */
|
||||
if ((err = y4m_xtag_add(&(i->x_tags), token)) != Y4M_OK) return err;
|
||||
mp_msg(MSGT_DEMUX, MSGL_WARN, "Unknown frame tag encountered: '%s'\n", token);
|
||||
} else {
|
||||
/* unknown tags are *not* ok */
|
||||
return Y4M_ERR_BADTAG;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* ta da! done. */
|
||||
return Y4M_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Read/Write stream header
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
int y4m_read_stream_header(stream_t *s, y4m_stream_info_t *i)
|
||||
{
|
||||
char line[Y4M_LINE_MAX];
|
||||
char *p;
|
||||
int n;
|
||||
int err;
|
||||
|
||||
/* read the header line */
|
||||
for (n = 0, p = line; n < Y4M_LINE_MAX; n++, p++) {
|
||||
if (y4m_read(s, p, 1))
|
||||
return Y4M_ERR_SYSTEM;
|
||||
if (*p == '\n') {
|
||||
*p = '\0'; /* Replace linefeed by end of string */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n >= Y4M_LINE_MAX)
|
||||
return Y4M_ERR_HEADER;
|
||||
/* look for keyword in header */
|
||||
if (strncmp(line, Y4M_MAGIC, strlen(Y4M_MAGIC)))
|
||||
return Y4M_ERR_MAGIC;
|
||||
if ((err = y4m_parse_stream_tags(line + strlen(Y4M_MAGIC), i)) != Y4M_OK)
|
||||
return err;
|
||||
|
||||
i->framelength = (i->height * i->width) * 3 / 2;
|
||||
return Y4M_OK;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int y4m_write_stream_header(int fd, y4m_stream_info_t *i)
|
||||
{
|
||||
char s[Y4M_LINE_MAX+1];
|
||||
int n;
|
||||
int err;
|
||||
|
||||
y4m_ratio_reduce(&(i->framerate));
|
||||
y4m_ratio_reduce(&(i->sampleaspect));
|
||||
n = snprintf(s, sizeof(s), "%s W%d H%d F%d:%d I%s A%d:%d",
|
||||
Y4M_MAGIC,
|
||||
i->width,
|
||||
i->height,
|
||||
i->framerate.n, i->framerate.d,
|
||||
(i->interlace == Y4M_ILACE_NONE) ? "p" :
|
||||
(i->interlace == Y4M_ILACE_TOP_FIRST) ? "t" :
|
||||
(i->interlace == Y4M_ILACE_BOTTOM_FIRST) ? "b" : "?",
|
||||
i->sampleaspect.n, i->sampleaspect.d);
|
||||
if ((n < 0) || (n > Y4M_LINE_MAX)) return Y4M_ERR_HEADER;
|
||||
if ((err = y4m_snprint_xtags(s + n, sizeof(s) - n - 1, &(i->x_tags)))
|
||||
!= Y4M_OK)
|
||||
return err;
|
||||
/* non-zero on error */
|
||||
return (y4m_write(fd, s, strlen(s)) ? Y4M_ERR_SYSTEM : Y4M_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Read/Write frame header
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
int y4m_read_frame_header(stream_t *s, y4m_frame_info_t *i)
|
||||
{
|
||||
char line[Y4M_LINE_MAX];
|
||||
char *p;
|
||||
int n;
|
||||
ssize_t remain;
|
||||
|
||||
/* This is more clever than read_stream_header...
|
||||
Try to read "FRAME\n" all at once, and don't try to parse
|
||||
if nothing else is there...
|
||||
*/
|
||||
remain = y4m_read(s, line, sizeof(Y4M_FRAME_MAGIC));
|
||||
if (remain != 0)
|
||||
{
|
||||
/* A clean EOF should end exactly at a frame-boundary */
|
||||
if( remain == sizeof(Y4M_FRAME_MAGIC) )
|
||||
return Y4M_ERR_EOF;
|
||||
else
|
||||
return Y4M_ERR_SYSTEM;
|
||||
}
|
||||
if (strncmp(line, Y4M_FRAME_MAGIC, sizeof(Y4M_FRAME_MAGIC)-1))
|
||||
return Y4M_ERR_MAGIC;
|
||||
if (line[sizeof(Y4M_FRAME_MAGIC)-1] == '\n')
|
||||
return Y4M_OK; /* done -- no tags: that was the end-of-line. */
|
||||
|
||||
if (line[sizeof(Y4M_FRAME_MAGIC)-1] != Y4M_DELIM[0]) {
|
||||
return Y4M_ERR_MAGIC; /* wasn't a space -- what was it? */
|
||||
}
|
||||
|
||||
/* proceed to get the tags... (overwrite the magic) */
|
||||
for (n = 0, p = line; n < Y4M_LINE_MAX; n++, p++) {
|
||||
if (y4m_read(s, p, 1))
|
||||
return Y4M_ERR_SYSTEM;
|
||||
if (*p == '\n') {
|
||||
*p = '\0'; /* Replace linefeed by end of string */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n >= Y4M_LINE_MAX) return Y4M_ERR_HEADER;
|
||||
/* non-zero on error */
|
||||
return y4m_parse_frame_tags(line, i);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int y4m_write_frame_header(int fd, y4m_frame_info_t *i)
|
||||
{
|
||||
char s[Y4M_LINE_MAX+1];
|
||||
int n;
|
||||
int err;
|
||||
|
||||
n = snprintf(s, sizeof(s), "%s", Y4M_FRAME_MAGIC);
|
||||
if ((n < 0) || (n > Y4M_LINE_MAX)) return Y4M_ERR_HEADER;
|
||||
if ((err = y4m_snprint_xtags(s + n, sizeof(s) - n - 1, &(i->x_tags)))
|
||||
!= Y4M_OK)
|
||||
return err;
|
||||
/* non-zero on error */
|
||||
return (y4m_write(fd, s, strlen(s)) ? Y4M_ERR_SYSTEM : Y4M_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Read/Write entire frame
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
int y4m_read_frame(stream_t *s, y4m_stream_info_t *si,
|
||||
y4m_frame_info_t *fi, unsigned char *yuv[3])
|
||||
{
|
||||
int err;
|
||||
int w = si->width;
|
||||
int h = si->height;
|
||||
|
||||
/* Read frame header */
|
||||
if ((err = y4m_read_frame_header(s, fi)) != Y4M_OK) return err;
|
||||
/* Read luminance scanlines */
|
||||
if (y4m_read(s, yuv[0], w*h)) return Y4M_ERR_SYSTEM;
|
||||
/* Read chrominance scanlines */
|
||||
if (y4m_read(s, yuv[1], w*h/4)) return Y4M_ERR_SYSTEM;
|
||||
if (y4m_read(s, yuv[2], w*h/4)) return Y4M_ERR_SYSTEM;
|
||||
|
||||
return Y4M_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
int y4m_write_frame(int fd, y4m_stream_info_t *si,
|
||||
y4m_frame_info_t *fi, unsigned char *yuv[3])
|
||||
{
|
||||
int err;
|
||||
int w = si->width;
|
||||
int h = si->height;
|
||||
|
||||
/* Write frame header */
|
||||
if ((err = y4m_write_frame_header(fd, fi)) != Y4M_OK) return err;
|
||||
/* Write luminance,chrominance scanlines */
|
||||
if (y4m_write(fd, yuv[0], w*h) ||
|
||||
y4m_write(fd, yuv[1], w*h/4) ||
|
||||
y4m_write(fd, yuv[2], w*h/4))
|
||||
return Y4M_ERR_SYSTEM;
|
||||
return Y4M_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Read/Write entire frame, (de)interleaved (to)from two separate fields
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
#if 0
|
||||
int y4m_read_fields(int fd, y4m_stream_info_t *si, y4m_frame_info_t *fi,
|
||||
unsigned char *upper_field[3],
|
||||
unsigned char *lower_field[3])
|
||||
{
|
||||
int i, y, err;
|
||||
int width = si->width;
|
||||
int height = si->height;
|
||||
|
||||
/* Read frame header */
|
||||
if ((err = y4m_read_frame_header(fd, fi)) != Y4M_OK) return err;
|
||||
/* Read Y', Cb, and Cr planes */
|
||||
for (i = 0; i < 3; i++) {
|
||||
unsigned char *srctop = upper_field[i];
|
||||
unsigned char *srcbot = lower_field[i];
|
||||
/* alternately write one line from each */
|
||||
for (y = 0; y < height; y += 2) {
|
||||
if (y4m_read(fd, srctop, width)) return Y4M_ERR_SYSTEM;
|
||||
srctop += width;
|
||||
if (y4m_read(fd, srcbot, width)) return Y4M_ERR_SYSTEM;
|
||||
srcbot += width;
|
||||
}
|
||||
/* for chroma, width/height are half as big */
|
||||
if (i == 0) {
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
}
|
||||
return Y4M_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int y4m_write_fields(int fd, y4m_stream_info_t *si, y4m_frame_info_t *fi,
|
||||
unsigned char *upper_field[3],
|
||||
unsigned char *lower_field[3])
|
||||
{
|
||||
int i, y, err;
|
||||
int width = si->width;
|
||||
int height = si->height;
|
||||
|
||||
/* Write frame header */
|
||||
if ((err = y4m_write_frame_header(fd, fi)) != Y4M_OK) return err;
|
||||
/* Write Y', Cb, and Cr planes */
|
||||
for (i = 0; i < 3; i++) {
|
||||
unsigned char *srctop = upper_field[i];
|
||||
unsigned char *srcbot = lower_field[i];
|
||||
/* alternately write one line from each */
|
||||
for (y = 0; y < height; y += 2) {
|
||||
if (y4m_write(fd, srctop, width)) return Y4M_ERR_SYSTEM;
|
||||
srctop += width;
|
||||
if (y4m_write(fd, srcbot, width)) return Y4M_ERR_SYSTEM;
|
||||
srcbot += width;
|
||||
}
|
||||
/* for chroma, width/height are half as big */
|
||||
if (i == 0) {
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
}
|
||||
return Y4M_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Handy logging of stream info
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
void y4m_log_stream_info(const char *prefix, y4m_stream_info_t *i)
|
||||
{
|
||||
char s[256];
|
||||
|
||||
snprintf(s, sizeof(s), " frame size: ");
|
||||
if (i->width == Y4M_UNKNOWN)
|
||||
snprintf(s+strlen(s), sizeof(s)-strlen(s), "(?)x");
|
||||
else
|
||||
snprintf(s+strlen(s), sizeof(s)-strlen(s), "%dx", i->width);
|
||||
if (i->height == Y4M_UNKNOWN)
|
||||
snprintf(s+strlen(s), sizeof(s)-strlen(s), "(?) pixels ");
|
||||
else
|
||||
snprintf(s+strlen(s), sizeof(s)-strlen(s), "%d pixels ", i->height);
|
||||
if (i->framelength == Y4M_UNKNOWN)
|
||||
snprintf(s+strlen(s), sizeof(s)-strlen(s), "(? bytes)");
|
||||
else
|
||||
snprintf(s+strlen(s), sizeof(s)-strlen(s), "(%d bytes)", i->framelength);
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "%s%s\n", prefix, s);
|
||||
if ((i->framerate.n == 0) && (i->framerate.d == 0))
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "%s frame rate: ??? fps\n", prefix);
|
||||
else
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "%s frame rate: %d/%d fps (~%f)\n", prefix,
|
||||
i->framerate.n, i->framerate.d,
|
||||
(double) i->framerate.n / (double) i->framerate.d);
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "%s interlace: %s\n", prefix,
|
||||
(i->interlace == Y4M_ILACE_NONE) ? "none/progressive" :
|
||||
(i->interlace == Y4M_ILACE_TOP_FIRST) ? "top-field-first" :
|
||||
(i->interlace == Y4M_ILACE_BOTTOM_FIRST) ? "bottom-field-first" :
|
||||
"anyone's guess");
|
||||
if ((i->sampleaspect.n == 0) && (i->sampleaspect.d == 0))
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "%ssample aspect ratio: ?:?\n", prefix);
|
||||
else
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "%ssample aspect ratio: %d:%d\n", prefix,
|
||||
i->sampleaspect.n, i->sampleaspect.d);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Convert error code to string
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
const char *y4m_strerr(int err)
|
||||
{
|
||||
switch (err) {
|
||||
case Y4M_OK: return "no error";
|
||||
case Y4M_ERR_RANGE: return "parameter out of range";
|
||||
case Y4M_ERR_SYSTEM: return "stream ended unexpectedly (failed read/write)";
|
||||
case Y4M_ERR_HEADER: return "bad stream or frame header";
|
||||
case Y4M_ERR_BADTAG: return "unknown header tag";
|
||||
case Y4M_ERR_MAGIC: return "bad header magic";
|
||||
case Y4M_ERR_XXTAGS: return "too many xtags";
|
||||
case Y4M_ERR_EOF: return "end-of-file";
|
||||
default:
|
||||
return "unknown error code";
|
||||
}
|
||||
}
|
|
@ -1,452 +0,0 @@
|
|||
/*
|
||||
* yuv4mpeg.h: Functions for reading and writing "new" YUV4MPEG2 streams.
|
||||
*
|
||||
* Stream format is described at the end of this file.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2001 Matthew J. Marjanovic <maddog@mir.com>
|
||||
*
|
||||
* This file is part of the MJPEG Tools package (mjpeg.sourceforge.net).
|
||||
* Ported to mplayer by Rik Snel <rsnel@cube.dyndns.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_YUV4MPEG_H
|
||||
#define MPLAYER_YUV4MPEG_H
|
||||
|
||||
#include <stdlib.h>
|
||||
//#include "mp_msg.h"
|
||||
#include "stream/stream.h"
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* error codes returned by y4m_* functions
|
||||
************************************************************************/
|
||||
#define Y4M_OK 0
|
||||
#define Y4M_ERR_RANGE 1
|
||||
#define Y4M_ERR_SYSTEM 2
|
||||
#define Y4M_ERR_HEADER 3
|
||||
#define Y4M_ERR_BADTAG 4
|
||||
#define Y4M_ERR_MAGIC 5
|
||||
#define Y4M_ERR_EOF 6
|
||||
#define Y4M_ERR_XXTAGS 7
|
||||
|
||||
|
||||
/* generic 'unknown' value for integer parameters (e.g. interlace, height) */
|
||||
#define Y4M_UNKNOWN -1
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* 'ratio' datatype, for rational numbers
|
||||
* (see 'ratio' functions down below)
|
||||
************************************************************************/
|
||||
typedef struct y4m_ratio {
|
||||
int n; /* numerator */
|
||||
int d; /* denominator */
|
||||
} y4m_ratio_t;
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* useful standard framerates (as ratios)
|
||||
************************************************************************/
|
||||
extern const y4m_ratio_t y4m_fps_UNKNOWN;
|
||||
extern const y4m_ratio_t y4m_fps_NTSC_FILM; /* 24000/1001 film (in NTSC) */
|
||||
extern const y4m_ratio_t y4m_fps_FILM; /* 24fps film */
|
||||
extern const y4m_ratio_t y4m_fps_PAL; /* 25fps PAL */
|
||||
extern const y4m_ratio_t y4m_fps_NTSC; /* 30000/1001 NTSC */
|
||||
extern const y4m_ratio_t y4m_fps_30; /* 30fps */
|
||||
extern const y4m_ratio_t y4m_fps_PAL_FIELD; /* 50fps PAL field rate */
|
||||
extern const y4m_ratio_t y4m_fps_NTSC_FIELD; /* 60000/1001 NTSC field rate */
|
||||
extern const y4m_ratio_t y4m_fps_60; /* 60fps */
|
||||
|
||||
/************************************************************************
|
||||
* useful standard sample (pixel) aspect ratios
|
||||
************************************************************************/
|
||||
extern const y4m_ratio_t y4m_sar_UNKNOWN;
|
||||
extern const y4m_ratio_t y4m_sar_SQUARE; /* square pixels */
|
||||
extern const y4m_ratio_t y4m_sar_NTSC_CCIR601; /* 525-line (NTSC) Rec.601 */
|
||||
extern const y4m_ratio_t y4m_sar_NTSC_16_9; /* 16:9 NTSC/Rec.601 */
|
||||
extern const y4m_ratio_t y4m_sar_NTSC_SVCD_4_3; /* NTSC SVCD 4:3 */
|
||||
extern const y4m_ratio_t y4m_sar_NTSC_SVCD_16_9;/* NTSC SVCD 16:9 */
|
||||
extern const y4m_ratio_t y4m_sar_PAL_CCIR601; /* 625-line (PAL) Rec.601 */
|
||||
extern const y4m_ratio_t y4m_sar_PAL_16_9; /* 16:9 PAL/Rec.601 */
|
||||
extern const y4m_ratio_t y4m_sar_PAL_SVCD_4_3; /* PAL SVCD 4:3 */
|
||||
extern const y4m_ratio_t y4m_sar_PAL_SVCD_16_9; /* PAL SVCD 16:9 */
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* 'xtag_list' --- list of unparsed and/or meta/X header tags
|
||||
*
|
||||
* Do not touch this structure directly!
|
||||
*
|
||||
* Use the y4m_xtag_*() functions (see below).
|
||||
* You must initialize/finalize this structure before/after use.
|
||||
************************************************************************/
|
||||
#define Y4M_MAX_XTAGS 32 /* maximum number of xtags in list */
|
||||
#define Y4M_MAX_XTAG_SIZE 32 /* max length of an xtag (including 'X') */
|
||||
typedef struct y4m_xtag_list {
|
||||
int count;
|
||||
char *tags[Y4M_MAX_XTAGS];
|
||||
} y4m_xtag_list_t;
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* 'stream_info' --- stream header information
|
||||
*
|
||||
* Do not touch this structure directly!
|
||||
*
|
||||
* Use the y4m_si_*() functions (see below).
|
||||
* You must initialize/finalize this structure before/after use.
|
||||
************************************************************************/
|
||||
typedef struct y4m_stream_info {
|
||||
/* values from header */
|
||||
int width;
|
||||
int height;
|
||||
int interlace; /* see Y4M_ILACE_* definitions below */
|
||||
y4m_ratio_t framerate; /* frames-per-second; 0:0 == unknown */
|
||||
y4m_ratio_t sampleaspect; /* pixel width/height; 0:0 == unknown */
|
||||
/* computed/derivative values */
|
||||
int framelength; /* bytes of data per frame (not including header) */
|
||||
/* mystical X tags */
|
||||
y4m_xtag_list_t x_tags;
|
||||
} y4m_stream_info_t;
|
||||
|
||||
/* possible options for the interlace parameter */
|
||||
#define Y4M_ILACE_NONE 0 /* non-interlaced, progressive frame */
|
||||
#define Y4M_ILACE_TOP_FIRST 1 /* interlaced, top-field first */
|
||||
#define Y4M_ILACE_BOTTOM_FIRST 2 /* interlaced, bottom-field first */
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* 'frame_info' --- frame header information
|
||||
*
|
||||
* Do not touch this structure directly!
|
||||
*
|
||||
* Use the y4m_fi_*() functions (see below).
|
||||
* You must initialize/finalize this structure before/after use.
|
||||
************************************************************************/
|
||||
typedef struct y4m_frame_info {
|
||||
/* mystical X tags */
|
||||
y4m_xtag_list_t x_tags;
|
||||
} y4m_frame_info_t;
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#else
|
||||
#endif
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* 'ratio' functions
|
||||
************************************************************************/
|
||||
|
||||
/* 'normalize' a ratio (remove common factors) */
|
||||
void y4m_ratio_reduce(y4m_ratio_t *r);
|
||||
|
||||
/* parse "nnn:ddd" into a ratio (returns Y4M_OK or Y4M_ERR_RANGE) */
|
||||
int y4m_parse_ratio(y4m_ratio_t *r, const char *s);
|
||||
|
||||
/* quick test of two ratios for equality (i.e. identical components) */
|
||||
#define Y4M_RATIO_EQL(a,b) ( ((a).n == (b).n) && ((a).d == (b).d) )
|
||||
|
||||
/* quick conversion of a ratio to a double (no divide-by-zero check!) */
|
||||
#define Y4M_RATIO_DBL(r) ((double)(r).n / (double)(r).d)
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* 'xtag' functions
|
||||
*
|
||||
* o Before using an xtag_list (but after the structure/memory has been
|
||||
* allocated), you must initialize it via y4m_init_xtag_list().
|
||||
* o After using an xtag_list (but before the structure is released),
|
||||
* call y4m_fini_xtag_list() to free internal memory.
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
/* initialize an xtag_list structure */
|
||||
void y4m_init_xtag_list(y4m_xtag_list_t *xtags);
|
||||
|
||||
/* finalize an xtag_list structure */
|
||||
void y4m_fini_xtag_list(y4m_xtag_list_t *xtags);
|
||||
|
||||
/* make one xtag_list into a copy of another */
|
||||
void y4m_copy_xtag_list(y4m_xtag_list_t *dest, const y4m_xtag_list_t *src);
|
||||
|
||||
/* return number of tags in an xtag_list */
|
||||
int y4m_xtag_count(const y4m_xtag_list_t *xtags);
|
||||
|
||||
/* access n'th tag in an xtag_list */
|
||||
const char *y4m_xtag_get(const y4m_xtag_list_t *xtags, int n);
|
||||
|
||||
/* append a new tag to an xtag_list
|
||||
returns: Y4M_OK - success
|
||||
Y4M_ERR_XXTAGS - list is already full */
|
||||
int y4m_xtag_add(y4m_xtag_list_t *xtags, const char *tag);
|
||||
|
||||
/* remove a tag from an xtag_list
|
||||
returns: Y4M_OK - success
|
||||
Y4M_ERR_RANGE - n is out of range */
|
||||
int y4m_xtag_remove(y4m_xtag_list_t *xtags, int n);
|
||||
|
||||
/* remove all tags from an xtag_list
|
||||
returns: Y4M_OK - success */
|
||||
int y4m_xtag_clearlist(y4m_xtag_list_t *xtags);
|
||||
|
||||
/* append copies of tags from src list to dest list
|
||||
returns: Y4M_OK - success
|
||||
Y4M_ERR_XXTAGS - operation would overfill dest list */
|
||||
int y4m_xtag_addlist(y4m_xtag_list_t *dest, const y4m_xtag_list_t *src);
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* '*_info' functions
|
||||
*
|
||||
* o Before using a *_info structure (but after the structure/memory has
|
||||
* been allocated), you must initialize it via y4m_init_*_info().
|
||||
* o After using a *_info structure (but before the structure is released),
|
||||
* call y4m_fini_*_info() to free internal memory.
|
||||
* o Use the 'set' and 'get' accessors to modify or access the fields in
|
||||
* the structures; don't touch the structure directly. (Ok, so there
|
||||
* is no really convenient C syntax to prevent you from doing this,
|
||||
* but we are all responsible programmers here, so just don't do it!)
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
/* initialize a stream_info structure */
|
||||
void y4m_init_stream_info(y4m_stream_info_t *i);
|
||||
|
||||
/* finalize a stream_info structure */
|
||||
void y4m_fini_stream_info(y4m_stream_info_t *i);
|
||||
|
||||
/* make one stream_info into a copy of another */
|
||||
void y4m_copy_stream_info(y4m_stream_info_t *dest, y4m_stream_info_t *src);
|
||||
|
||||
/* access or set stream_info fields */
|
||||
void y4m_si_set_width(y4m_stream_info_t *si, int width);
|
||||
int y4m_si_get_width(y4m_stream_info_t *si);
|
||||
void y4m_si_set_height(y4m_stream_info_t *si, int height);
|
||||
int y4m_si_get_height(y4m_stream_info_t *si);
|
||||
void y4m_si_set_interlace(y4m_stream_info_t *si, int interlace);
|
||||
int y4m_si_get_interlace(y4m_stream_info_t *si);
|
||||
void y4m_si_set_framerate(y4m_stream_info_t *si, y4m_ratio_t framerate);
|
||||
y4m_ratio_t y4m_si_get_framerate(y4m_stream_info_t *si);
|
||||
void y4m_si_set_sampleaspect(y4m_stream_info_t *si, y4m_ratio_t sar);
|
||||
y4m_ratio_t y4m_si_get_sampleaspect(y4m_stream_info_t *si);
|
||||
int y4m_si_get_framelength(y4m_stream_info_t *si);
|
||||
|
||||
/* access stream_info xtag_list */
|
||||
y4m_xtag_list_t *y4m_si_xtags(y4m_stream_info_t *si);
|
||||
|
||||
|
||||
/* initialize a frame_info structure */
|
||||
void y4m_init_frame_info(y4m_frame_info_t *i);
|
||||
|
||||
/* finalize a frame_info structure */
|
||||
void y4m_fini_frame_info(y4m_frame_info_t *i);
|
||||
|
||||
/* make one frame_info into a copy of another */
|
||||
void y4m_copy_frame_info(y4m_frame_info_t *dest, y4m_frame_info_t *src);
|
||||
|
||||
/* access frame_info xtag_list */
|
||||
y4m_xtag_list_t *y4m_fi_xtags(y4m_frame_info_t *fi);
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* blocking read and write functions
|
||||
*
|
||||
* o guaranteed to transfer entire payload (or fail)
|
||||
* o return values:
|
||||
* 0 (zero) complete success
|
||||
* -(# of remaining bytes) error (and errno left set)
|
||||
* +(# of remaining bytes) EOF (for y4m_read only)
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
/* read len bytes from fd into buf */
|
||||
ssize_t y4m_read(stream_t *s, char *buf, size_t len);
|
||||
|
||||
#if 0
|
||||
/* write len bytes from fd into buf */
|
||||
ssize_t y4m_write(int fd, char *buf, size_t len);
|
||||
#endif
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* stream header processing functions
|
||||
*
|
||||
* o return values:
|
||||
* Y4M_OK - success
|
||||
* Y4M_ERR_* - error (see y4m_strerr() for descriptions)
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
/* parse a string of stream header tags */
|
||||
int y4m_parse_stream_tags(char *s, y4m_stream_info_t *i);
|
||||
|
||||
/* read a stream header from file descriptor fd */
|
||||
int y4m_read_stream_header(stream_t *s, y4m_stream_info_t *i);
|
||||
|
||||
#if 0
|
||||
/* write a stream header to file descriptor fd */
|
||||
int y4m_write_stream_header(int fd, y4m_stream_info_t *i);
|
||||
#endif
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* frame processing functions
|
||||
*
|
||||
* o return values:
|
||||
* Y4M_OK - success
|
||||
* Y4M_ERR_* - error (see y4m_strerr() for descriptions)
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
/* read a frame header from file descriptor fd */
|
||||
int y4m_read_frame_header(stream_t *s, y4m_frame_info_t *i);
|
||||
|
||||
#if 0
|
||||
/* write a frame header to file descriptor fd */
|
||||
int y4m_write_frame_header(int fd, y4m_frame_info_t *i);
|
||||
#endif
|
||||
|
||||
/* read a complete frame (header + data)
|
||||
o yuv[3] points to three buffers, one each for Y, U, V planes */
|
||||
int y4m_read_frame(stream_t *s, y4m_stream_info_t *si,
|
||||
y4m_frame_info_t *fi, unsigned char *yuv[3]);
|
||||
|
||||
#if 0
|
||||
/* write a complete frame (header + data)
|
||||
o yuv[3] points to three buffers, one each for Y, U, V planes */
|
||||
int y4m_write_frame(int fd, y4m_stream_info_t *si,
|
||||
y4m_frame_info_t *fi, unsigned char *yuv[3]);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* read a complete frame (header + data), but de-interleave fields
|
||||
into two separate buffers
|
||||
o upper_field[3] same as yuv[3] above, but for upper field
|
||||
o lower_field[3] same as yuv[3] above, but for lower field
|
||||
*/
|
||||
int y4m_read_fields(int fd, y4m_stream_info_t *si, y4m_frame_info_t *fi,
|
||||
unsigned char *upper_field[3],
|
||||
unsigned char *lower_field[3]);
|
||||
|
||||
/* write a complete frame (header + data), but interleave fields
|
||||
from two separate buffers
|
||||
o upper_field[3] same as yuv[3] above, but for upper field
|
||||
o lower_field[3] same as yuv[3] above, but for lower field
|
||||
*/
|
||||
int y4m_write_fields(int fd, y4m_stream_info_t *si, y4m_frame_info_t *fi,
|
||||
unsigned char *upper_field[3],
|
||||
unsigned char *lower_field[3]);
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
* miscellaneous functions
|
||||
************************************************************************/
|
||||
|
||||
/* convenient dump of stream header info via mjpeg_log facility
|
||||
* - each logged/printed line is prefixed by 'prefix'
|
||||
*/
|
||||
void y4m_log_stream_info(const char *prefix, y4m_stream_info_t *i);
|
||||
|
||||
/* convert a Y4M_ERR_* error code into mildly explanatory string */
|
||||
const char *y4m_strerr(int err);
|
||||
|
||||
/* set 'allow_unknown_tag' flag for library...
|
||||
o yn = 0 : unknown header tags will produce a parsing error
|
||||
o yn = 1 : unknown header tags/values will produce a warning, but
|
||||
are otherwise passed along via the xtags list
|
||||
o yn = -1: don't change, just return current setting
|
||||
|
||||
return value: previous setting of flag
|
||||
*/
|
||||
int y4m_allow_unknown_tags(int yn);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
************************************************************************
|
||||
|
||||
Description of the (new!, forever?) YUV4MPEG2 stream format:
|
||||
|
||||
STREAM consists of
|
||||
o one '\n' terminated STREAM-HEADER
|
||||
o unlimited number of FRAMEs
|
||||
|
||||
FRAME consists of
|
||||
o one '\n' terminated FRAME-HEADER
|
||||
o "length" octets of planar YCrCb 4:2:0 image data
|
||||
(if frame is interlaced, then the two fields are interleaved)
|
||||
|
||||
|
||||
STREAM-HEADER consists of
|
||||
o string "YUV4MPEG2 " (note the space after the '2')
|
||||
o unlimited number of ' ' separated TAGGED-FIELDs
|
||||
o '\n' line terminator
|
||||
|
||||
FRAME-HEADER consists of
|
||||
o string "FRAME " (note the space after the 'E')
|
||||
o unlimited number of ' ' separated TAGGED-FIELDs
|
||||
o '\n' line terminator
|
||||
|
||||
|
||||
TAGGED-FIELD consists of
|
||||
o single ascii character tag
|
||||
o VALUE (which does not contain whitespace)
|
||||
|
||||
VALUE consists of
|
||||
o integer (base 10 ascii representation)
|
||||
or o RATIO
|
||||
or o single ascii character
|
||||
or o generic ascii string
|
||||
|
||||
RATIO consists of
|
||||
o numerator (integer)
|
||||
o ':' (a colon)
|
||||
o denominator (integer)
|
||||
|
||||
|
||||
The currently supported tags for the STREAM-HEADER:
|
||||
W - [integer] frame width, pixels, should be > 0
|
||||
H - [integer] frame height, pixels, should be > 0
|
||||
I - [char] interlacing: p - progressive (none)
|
||||
t - top-field-first
|
||||
b - bottom-field-first
|
||||
? - unknown
|
||||
F - [ratio] frame-rate, 0:0 == unknown
|
||||
A - [ratio] sample (pixel) aspect ratio, 0:0 == unknown
|
||||
X - [character string] 'metadata' (unparsed, but passed around)
|
||||
|
||||
The currently supported tags for the FRAME-HEADER:
|
||||
X - character string 'metadata' (unparsed, but passed around)
|
||||
|
||||
************************************************************************
|
||||
************************************************************************/
|
||||
|
||||
#endif /* MPLAYER_YUV4MPEG_H */
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* yuv4mpeg_intern.h: Internal constants for "new" YUV4MPEG streams
|
||||
*
|
||||
* Copyright (C) 2001 Andrew Stevens <andrew.stevens@philips.com>
|
||||
*
|
||||
* This file is part of the MJPEG Tools package (mjpeg.sourceforge.net).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_YUV4MPEG_INTERN_H
|
||||
#define MPLAYER_YUV4MPEG_INTERN_H
|
||||
|
||||
|
||||
#define Y4M_MAGIC "YUV4MPEG2"
|
||||
#define Y4M_FRAME_MAGIC "FRAME"
|
||||
|
||||
#define Y4M_DELIM " " /* single-character(space) separating tagged fields */
|
||||
|
||||
#define Y4M_LINE_MAX 256 /* max number of characters in a header line
|
||||
(including the '\n', but not the '\0') */
|
||||
|
||||
|
||||
/* standard framerate ratios */
|
||||
#define Y4M_FPS_UNKNOWN { 0, 0 }
|
||||
#define Y4M_FPS_NTSC_FILM { 24000, 1001 }
|
||||
#define Y4M_FPS_FILM { 24, 1 }
|
||||
#define Y4M_FPS_PAL { 25, 1 }
|
||||
#define Y4M_FPS_NTSC { 30000, 1001 }
|
||||
#define Y4M_FPS_30 { 30, 1 }
|
||||
#define Y4M_FPS_PAL_FIELD { 50, 1 }
|
||||
#define Y4M_FPS_NTSC_FIELD { 60000, 1001 }
|
||||
#define Y4M_FPS_60 { 60, 1 }
|
||||
|
||||
/* standard sample/pixel aspect ratios */
|
||||
#define Y4M_SAR_UNKNOWN { 0, 0 }
|
||||
#define Y4M_SAR_SQUARE { 1, 1 }
|
||||
#define Y4M_SAR_NTSC_CCIR601 { 10, 11 }
|
||||
#define Y4M_SAR_NTSC_16_9 { 40, 33 }
|
||||
#define Y4M_SAR_NTSC_SVCD_4_3 { 15, 11 }
|
||||
#define Y4M_SAR_NTSC_SVCD_16_9 { 20, 11 }
|
||||
#define Y4M_SAR_PAL_CCIR601 { 59, 54 }
|
||||
#define Y4M_SAR_PAL_16_9 { 118, 81 }
|
||||
#define Y4M_SAR_PAL_SVCD_4_3 { 59, 36 }
|
||||
#define Y4M_SAR_PAL_SVCD_16_9 { 59, 27 }
|
||||
|
||||
#define Y4M_SAR_MPEG1_1 Y4M_SAR_SQUARE
|
||||
#define Y4M_SAR_MPEG1_2 { 10000, 6735 }
|
||||
#define Y4M_SAR_MPEG1_3 { 10000, 7031 } /* Anamorphic 16:9 PAL */
|
||||
#define Y4M_SAR_MPEG1_4 { 10000, 7615 }
|
||||
#define Y4M_SAR_MPEG1_5 { 10000, 8055 }
|
||||
#define Y4M_SAR_MPEG1_6 { 10000, 8437 } /* Anamorphic 16:9 NTSC */
|
||||
#define Y4M_SAR_MPEG1_7 { 10000, 8935 }
|
||||
#define Y4M_SAR_MPEG1_8 { 10000, 9375 } /* PAL/SECAM 4:3 */
|
||||
#define Y4M_SAR_MPEG1_9 { 10000, 9815 }
|
||||
#define Y4M_SAR_MPEG1_10 { 10000, 10255 }
|
||||
#define Y4M_SAR_MPEG1_11 { 10000, 10695 }
|
||||
#define Y4M_SAR_MPEG1_12 { 10000, 11250 } /* NTSC 4:3 */
|
||||
#define Y4M_SAR_MPEG1_13 { 10000, 11575 }
|
||||
#define Y4M_SAR_MPEG1_14 { 10000, 12015 }
|
||||
|
||||
#define Y4M_DAR_MPEG2_1 { 1, 1}
|
||||
#define Y4M_DAR_MPEG2_2 { 4, 3 }
|
||||
#define Y4M_DAR_MPEG2_3 { 16, 9 }
|
||||
#define Y4M_DAR_MPEG2_4 { 221, 100 }
|
||||
|
||||
#endif /* MPLAYER_YUV4MPEG_INTERN_H */
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* yuv4mpeg_ratio.c: Functions for dealing with y4m_ratio_t datatype.
|
||||
*
|
||||
* Copyright (C) 2001 Matthew J. Marjanovic <maddog@mir.com>
|
||||
*
|
||||
* This file is part of the MJPEG Tools package (mjpeg.sourceforge.net).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "yuv4mpeg.h"
|
||||
#include "yuv4mpeg_intern.h"
|
||||
|
||||
|
||||
/* useful list of standard framerates */
|
||||
const y4m_ratio_t y4m_fps_UNKNOWN = Y4M_FPS_UNKNOWN;
|
||||
const y4m_ratio_t y4m_fps_NTSC_FILM = Y4M_FPS_NTSC_FILM;
|
||||
const y4m_ratio_t y4m_fps_FILM = Y4M_FPS_FILM;
|
||||
const y4m_ratio_t y4m_fps_PAL = Y4M_FPS_PAL;
|
||||
const y4m_ratio_t y4m_fps_NTSC = Y4M_FPS_NTSC;
|
||||
const y4m_ratio_t y4m_fps_30 = Y4M_FPS_30;
|
||||
const y4m_ratio_t y4m_fps_PAL_FIELD = Y4M_FPS_PAL_FIELD;
|
||||
const y4m_ratio_t y4m_fps_NTSC_FIELD = Y4M_FPS_NTSC_FIELD;
|
||||
const y4m_ratio_t y4m_fps_60 = Y4M_FPS_60;
|
||||
|
||||
/* useful list of standard pixel aspect ratios */
|
||||
const y4m_ratio_t y4m_sar_UNKNOWN = Y4M_SAR_UNKNOWN;
|
||||
const y4m_ratio_t y4m_sar_SQUARE = Y4M_SAR_SQUARE;
|
||||
const y4m_ratio_t y4m_sar_NTSC_CCIR601 = Y4M_SAR_NTSC_CCIR601;
|
||||
const y4m_ratio_t y4m_sar_NTSC_16_9 = Y4M_SAR_NTSC_16_9;
|
||||
const y4m_ratio_t y4m_sar_NTSC_SVCD_4_3 = Y4M_SAR_NTSC_SVCD_4_3;
|
||||
const y4m_ratio_t y4m_sar_NTSC_SVCD_16_9 = Y4M_SAR_NTSC_SVCD_16_9;
|
||||
const y4m_ratio_t y4m_sar_PAL_CCIR601 = Y4M_SAR_PAL_CCIR601;
|
||||
const y4m_ratio_t y4m_sar_PAL_16_9 = Y4M_SAR_PAL_16_9;
|
||||
const y4m_ratio_t y4m_sar_PAL_SVCD_4_3 = Y4M_SAR_PAL_SVCD_4_3;
|
||||
const y4m_ratio_t y4m_sar_PAL_SVCD_16_9 = Y4M_SAR_PAL_SVCD_16_9;
|
||||
|
||||
|
||||
/*
|
||||
* Euler's algorithm for greatest common divisor
|
||||
*/
|
||||
|
||||
static int gcd(int a, int b)
|
||||
{
|
||||
a = (a >= 0) ? a : -a;
|
||||
b = (b >= 0) ? b : -b;
|
||||
|
||||
while (b > 0) {
|
||||
int x = b;
|
||||
b = a % b;
|
||||
a = x;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Remove common factors from a ratio
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
void y4m_ratio_reduce(y4m_ratio_t *r)
|
||||
{
|
||||
int d;
|
||||
if ((r->n == 0) && (r->d == 0)) return; /* "unknown" */
|
||||
d = gcd(r->n, r->d);
|
||||
r->n /= d;
|
||||
r->d /= d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Parse "nnn:ddd" into a ratio
|
||||
*
|
||||
* returns: Y4M_OK - success
|
||||
* Y4M_ERR_RANGE - range error
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
int y4m_parse_ratio(y4m_ratio_t *r, const char *s)
|
||||
{
|
||||
char *t = strchr(s, ':');
|
||||
|
||||
if (t == NULL) return Y4M_ERR_RANGE;
|
||||
r->n = atoi(s);
|
||||
r->d = atoi(t+1);
|
||||
if (r->d < 0) return Y4M_ERR_RANGE;
|
||||
/* 0:0 == unknown, so that is ok, otherwise zero denominator is bad */
|
||||
if ((r->d == 0) && (r->n != 0)) return Y4M_ERR_RANGE;
|
||||
y4m_ratio_reduce(r);
|
||||
return Y4M_OK;
|
||||
}
|
|
@ -143,11 +143,6 @@ static void panscan_calc_internal(struct vo *vo, int zoom)
|
|||
vo->panscan_y = vo_panscan_area * vo->panscan_amount;
|
||||
}
|
||||
|
||||
void panscan_calc(struct vo *vo)
|
||||
{
|
||||
panscan_calc_internal(vo, A_ZOOM);
|
||||
}
|
||||
|
||||
/**
|
||||
* vos that set vo_dwidth and v_dheight correctly should call this to update
|
||||
* vo_panscan_x and vo_panscan_y
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
struct vo;
|
||||
void panscan_init(struct vo *vo);
|
||||
void panscan_calc(struct vo *vo);
|
||||
void panscan_calc_windowed(struct vo *vo);
|
||||
|
||||
void aspect_save_orig(struct vo *vo, int orgw, int orgh);
|
||||
|
|
14
libvo/osd.c
14
libvo/osd.c
|
@ -128,20 +128,6 @@ void vo_draw_alpha_yuy2(int w,int h, unsigned char* src, unsigned char *srca, in
|
|||
#endif
|
||||
}
|
||||
|
||||
void vo_draw_alpha_uyvy(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
|
||||
#if ARCH_X86
|
||||
// ordered by speed / fastest first
|
||||
if(gCpuCaps.hasMMX2)
|
||||
vo_draw_alpha_uyvy_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
|
||||
else if(gCpuCaps.hasMMX)
|
||||
vo_draw_alpha_uyvy_MMX(w, h, src, srca, srcstride, dstbase, dststride);
|
||||
else
|
||||
vo_draw_alpha_uyvy_X86(w, h, src, srca, srcstride, dstbase, dststride);
|
||||
#else
|
||||
vo_draw_alpha_uyvy_C(w, h, src, srca, srcstride, dstbase, dststride);
|
||||
#endif
|
||||
}
|
||||
|
||||
void vo_draw_alpha_rgb24(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
|
||||
#if ARCH_X86
|
||||
// ordered by speed / fastest first
|
||||
|
|
|
@ -26,7 +26,6 @@ void vo_draw_alpha_init(void); // build tables
|
|||
|
||||
void vo_draw_alpha_yv12(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
|
||||
void vo_draw_alpha_yuy2(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
|
||||
void vo_draw_alpha_uyvy(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
|
||||
void vo_draw_alpha_rgb24(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
|
||||
void vo_draw_alpha_rgb32(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
|
||||
void vo_draw_alpha_rgb12(int w, int h, unsigned char* src, unsigned char *srca,
|
||||
|
|
|
@ -177,30 +177,6 @@ static inline void RENAME(vo_draw_alpha_yuy2)(int w,int h, unsigned char* src, u
|
|||
return;
|
||||
}
|
||||
|
||||
static inline void RENAME(vo_draw_alpha_uyvy)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
|
||||
int y;
|
||||
#if defined(FAST_OSD)
|
||||
w=w>>1;
|
||||
#endif
|
||||
for(y=0;y<h;y++){
|
||||
register int x;
|
||||
for(x=0;x<w;x++){
|
||||
#ifdef FAST_OSD
|
||||
if(srca[2*x+0]) dstbase[4*x+2]=src[2*x+0];
|
||||
if(srca[2*x+1]) dstbase[4*x+0]=src[2*x+1];
|
||||
#else
|
||||
if(srca[x]) {
|
||||
dstbase[2*x+1]=((dstbase[2*x+1]*srca[x])>>8)+src[x];
|
||||
dstbase[2*x]=((((signed)dstbase[2*x]-128)*srca[x])>>8)+128;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
src+=srcstride;
|
||||
srca+=srcstride;
|
||||
dstbase+=dststride;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void RENAME(vo_draw_alpha_rgb24)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
|
||||
int y;
|
||||
#if HAVE_MMX
|
||||
|
|
|
@ -49,7 +49,6 @@ enum mp_voctrl {
|
|||
/* libmpcodecs direct rendering */
|
||||
VOCTRL_GET_IMAGE,
|
||||
VOCTRL_DRAW_IMAGE,
|
||||
VOCTRL_SET_SPU_PALETTE,
|
||||
VOCTRL_GET_PANSCAN,
|
||||
VOCTRL_SET_PANSCAN,
|
||||
VOCTRL_SET_EQUALIZER, // struct voctrl_set_equalizer_args
|
||||
|
|
36
m_struct.c
36
m_struct.c
|
@ -80,27 +80,6 @@ int m_struct_set(const m_struct_t *st, void *obj, const char *field,
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
m_struct_reset(const m_struct_t* st, void* obj, const char* field) {
|
||||
const m_option_t* f;
|
||||
|
||||
if(!field) { // Reset all options
|
||||
int i;
|
||||
for(i = 0 ; st->fields[i].name ; i++)
|
||||
m_option_copy(&st->fields[i],M_ST_MB_P(obj,st->fields[i].p),M_ST_MB_P(st->defaults,st->fields[i].p));
|
||||
return;
|
||||
}
|
||||
|
||||
// Only one
|
||||
f = m_struct_get_field(st,field);
|
||||
if(!f) {
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Struct %s doesn't have any %s field\n",
|
||||
st->name,field);
|
||||
return;
|
||||
}
|
||||
m_option_copy(f,M_ST_MB_P(obj,f->p),M_ST_MB_P(st->defaults,f->p));
|
||||
}
|
||||
|
||||
/// Free an allocated struct
|
||||
void
|
||||
m_struct_free(const m_struct_t* st, void* obj) {
|
||||
|
@ -110,18 +89,3 @@ m_struct_free(const m_struct_t* st, void* obj) {
|
|||
m_option_free(&st->fields[i],M_ST_MB_P(obj,st->fields[i].p));
|
||||
free(obj);
|
||||
}
|
||||
|
||||
void*
|
||||
m_struct_copy(const m_struct_t* st, void* obj) {
|
||||
void* r = malloc(st->size);
|
||||
int i;
|
||||
|
||||
memcpy(r,obj,st->size);
|
||||
for(i = 0 ; st->fields[i].name ; i++) {
|
||||
if(st->fields[i].type->flags & M_OPT_TYPE_DYNAMIC)
|
||||
memset(M_ST_MB_P(r,st->fields[i].p),0,st->fields[i].type->size);
|
||||
m_option_copy(&st->fields[i],M_ST_MB_P(r,st->fields[i].p),M_ST_MB_P(obj,st->fields[i].p));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
16
m_struct.h
16
m_struct.h
|
@ -92,22 +92,6 @@ m_struct_alloc(const m_struct_t* st);
|
|||
int m_struct_set(const m_struct_t *st, void *obj, const char *field,
|
||||
struct bstr param);
|
||||
|
||||
/// Reset a field (or all if field == NULL) to defaults.
|
||||
/** \param st Struct definition.
|
||||
* \param obj Pointer to the struct to set.
|
||||
* \param field Name of the field to reset, if NULL all fields are reseted.
|
||||
*/
|
||||
void
|
||||
m_struct_reset(const m_struct_t* st, void* obj, const char* field);
|
||||
|
||||
/// Create a copy of an existing struct.
|
||||
/** \param st Struct definition.
|
||||
* \param obj Pointer to the struct to copy.
|
||||
* \return Newly allocated copy of obj.
|
||||
*/
|
||||
void*
|
||||
m_struct_copy(const m_struct_t* st, void* obj);
|
||||
|
||||
/// Free an allocated struct.
|
||||
/** \param st Struct definition.
|
||||
* \param obj Pointer to the struct to copy.
|
||||
|
|
|
@ -74,7 +74,6 @@
|
|||
#include "sub/subreader.h"
|
||||
#include "sub/find_subfiles.h"
|
||||
#include "sub/dec_sub.h"
|
||||
#include "sub/sub_cc.h"
|
||||
|
||||
#include "mp_osd.h"
|
||||
#include "libvo/video_out.h"
|
||||
|
@ -4091,8 +4090,6 @@ goto_enable_cache:
|
|||
|
||||
reinit_video_chain(mpctx);
|
||||
if (mpctx->sh_video) {
|
||||
if (mpctx->sh_video->output_flags & VFCAP_SPU && vo_spudec)
|
||||
spudec_set_hw_spu(vo_spudec, mpctx->video_out);
|
||||
osd_font_invalidate();
|
||||
} else if (!mpctx->sh_audio)
|
||||
goto goto_next_file;
|
||||
|
|
19
sub/spudec.c
19
sub/spudec.c
|
@ -1209,16 +1209,6 @@ nothing_to_do:
|
|||
}
|
||||
}
|
||||
|
||||
void spudec_update_palette(void * this, unsigned int *palette)
|
||||
{
|
||||
spudec_handle_t *spu = this;
|
||||
if (spu && palette) {
|
||||
memcpy(spu->global_palette, palette, sizeof(spu->global_palette));
|
||||
if(spu->hw_spu)
|
||||
vo_control(spu->hw_spu, VOCTRL_SET_SPU_PALETTE, spu->global_palette);
|
||||
}
|
||||
}
|
||||
|
||||
void spudec_set_font_factor(void * this, double factor)
|
||||
{
|
||||
spudec_handle_t *spu = this;
|
||||
|
@ -1334,15 +1324,6 @@ void spudec_free(void *this)
|
|||
}
|
||||
}
|
||||
|
||||
void spudec_set_hw_spu(void *this, struct vo *hw_spu)
|
||||
{
|
||||
spudec_handle_t *spu = this;
|
||||
if (!spu)
|
||||
return;
|
||||
spu->hw_spu = hw_spu;
|
||||
vo_control(hw_spu, VOCTRL_SET_SPU_PALETTE, spu->global_palette);
|
||||
}
|
||||
|
||||
/**
|
||||
* palette must contain at least 256 32-bit entries, otherwise crashes
|
||||
* are possible
|
||||
|
|
|
@ -26,14 +26,12 @@ void spudec_assemble(void *this, unsigned char *packet, unsigned int len, int pt
|
|||
void spudec_draw(void *this, void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx);
|
||||
void spudec_draw_scaled(void *this, unsigned int dxs, unsigned int dys, void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx);
|
||||
int spudec_apply_palette_crop(void *this, uint32_t palette, int sx, int ex, int sy, int ey);
|
||||
void spudec_update_palette(void *this, unsigned int *palette);
|
||||
void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height, uint8_t *extradata, int extradata_len);
|
||||
void *spudec_new(unsigned int *palette);
|
||||
void spudec_free(void *this);
|
||||
void spudec_reset(void *this); // called after seek
|
||||
int spudec_visible(void *this); // check if spu is visible
|
||||
void spudec_set_font_factor(void * this, double factor); // sets the equivalent to ffactor
|
||||
void spudec_set_hw_spu(void *this, struct vo *hw_spu);
|
||||
int spudec_changed(void *this);
|
||||
void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox);
|
||||
void spudec_set_forced_subs_only(void * const this, const unsigned int flag);
|
||||
|
|
70
sub/sub.c
70
sub/sub.c
|
@ -94,39 +94,6 @@ float font_factor = 0.75;
|
|||
float sub_delay = 0;
|
||||
float sub_fps = 0;
|
||||
|
||||
// renders char to a big per-object buffer where alpha and bitmap are separated
|
||||
void draw_alpha_buf(mp_osd_obj_t* obj, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)
|
||||
{
|
||||
int dststride = obj->stride;
|
||||
int dstskip = obj->stride-w;
|
||||
int srcskip = stride-w;
|
||||
int i, j;
|
||||
unsigned char *b = obj->bitmap_buffer + (y0-obj->bbox.y1)*dststride + (x0-obj->bbox.x1);
|
||||
unsigned char *a = obj->alpha_buffer + (y0-obj->bbox.y1)*dststride + (x0-obj->bbox.x1);
|
||||
unsigned char *bs = src;
|
||||
unsigned char *as = srca;
|
||||
|
||||
if (x0 < obj->bbox.x1 || x0+w > obj->bbox.x2 || y0 < obj->bbox.y1 || y0+h > obj->bbox.y2) {
|
||||
fprintf(stderr, "osd text out of range: bbox [%d %d %d %d], txt [%d %d %d %d]\n",
|
||||
obj->bbox.x1, obj->bbox.x2, obj->bbox.y1, obj->bbox.y2,
|
||||
x0, x0+w, y0, y0+h);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
for (j = 0; j < w; j++, b++, a++, bs++, as++) {
|
||||
if (*b < *bs) *b = *bs;
|
||||
if (*as) {
|
||||
if (*a == 0 || *a > *as) *a = *as;
|
||||
}
|
||||
}
|
||||
b+= dstskip;
|
||||
a+= dstskip;
|
||||
bs+= srcskip;
|
||||
as+= srcskip;
|
||||
}
|
||||
}
|
||||
|
||||
// allocates/enlarges the alpha/bitmap buffer
|
||||
void osd_alloc_buf(mp_osd_obj_t* obj)
|
||||
{
|
||||
|
@ -160,20 +127,6 @@ void vo_draw_text_from_buffer(mp_osd_obj_t* obj,void (*draw_alpha)(void *ctx, in
|
|||
}
|
||||
}
|
||||
|
||||
unsigned utf8_get_char(const char **str) {
|
||||
const uint8_t *strp = (const uint8_t *)*str;
|
||||
unsigned c;
|
||||
GET_UTF8(c, *strp++, goto no_utf8;);
|
||||
*str = (const char *)strp;
|
||||
return c;
|
||||
|
||||
no_utf8:
|
||||
strp = (const uint8_t *)*str;
|
||||
c = *strp++;
|
||||
*str = (const char *)strp;
|
||||
return c;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DVDNAV
|
||||
void osd_set_nav_box (uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey) {
|
||||
nav_hl.sx = sx;
|
||||
|
@ -392,28 +345,6 @@ void osd_set_text(struct osd_state *osd, const char *text) {
|
|||
osd->osd_text = talloc_strdup(osd, text);
|
||||
}
|
||||
|
||||
int vo_osd_changed_flag=0;
|
||||
|
||||
void osd_remove_text(struct osd_state *osd, int dxs, int dys,
|
||||
void (*remove)(int x0, int y0, int w, int h))
|
||||
{
|
||||
mp_osd_obj_t* obj=vo_osd_list;
|
||||
osd_update(osd, dxs, dys);
|
||||
while(obj){
|
||||
if(((obj->flags&OSDFLAG_CHANGED) || (obj->flags&OSDFLAG_VISIBLE)) &&
|
||||
(obj->flags&OSDFLAG_OLD_BBOX)){
|
||||
int w=obj->old_bbox.x2-obj->old_bbox.x1;
|
||||
int h=obj->old_bbox.y2-obj->old_bbox.y1;
|
||||
if(w>0 && h>0){
|
||||
vo_osd_changed_flag=obj->flags&OSDFLAG_CHANGED; // temp hack
|
||||
remove(obj->old_bbox.x1,obj->old_bbox.y1,w,h);
|
||||
}
|
||||
// obj->flags&=~OSDFLAG_OLD_BBOX;
|
||||
}
|
||||
obj=obj->next;
|
||||
}
|
||||
}
|
||||
|
||||
void osd_draw_text_ext(struct osd_state *osd, int dxs, int dys,
|
||||
int left_border, int top_border, int right_border,
|
||||
int bottom_border, int orig_w, int orig_h,
|
||||
|
@ -428,7 +359,6 @@ void osd_draw_text_ext(struct osd_state *osd, int dxs, int dys,
|
|||
bottom_border, orig_w, orig_h);
|
||||
while(obj){
|
||||
if(obj->flags&OSDFLAG_VISIBLE){
|
||||
vo_osd_changed_flag=obj->flags&OSDFLAG_CHANGED; // temp hack
|
||||
switch(obj->type){
|
||||
case OSDTYPE_SPU:
|
||||
vo_draw_spudec_sub(obj, draw_alpha, ctx); // FIXME
|
||||
|
|
|
@ -166,8 +166,6 @@ void osd_draw_text_ext(struct osd_state *osd, int dxs, int dys,
|
|||
unsigned char *srca,
|
||||
int stride),
|
||||
void *ctx);
|
||||
void osd_remove_text(struct osd_state *osd, int dxs, int dys,
|
||||
void (*remove)(int x0, int y0, int w, int h));
|
||||
|
||||
struct osd_state *osd_create(struct MPOpts *opts, struct ass_library *asslib);
|
||||
void osd_set_text(struct osd_state *osd, const char *text);
|
||||
|
@ -177,10 +175,6 @@ void vo_osd_resized(void);
|
|||
int vo_osd_check_range_update(int,int,int,int);
|
||||
void osd_free(struct osd_state *osd);
|
||||
|
||||
extern int vo_osd_changed_flag;
|
||||
|
||||
unsigned utf8_get_char(const char **str);
|
||||
|
||||
#ifdef CONFIG_DVDNAV
|
||||
#include <inttypes.h>
|
||||
void osd_set_nav_box (uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey);
|
||||
|
@ -193,7 +187,6 @@ void osd_set_nav_box (uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey);
|
|||
|
||||
// used only by osd_ft.c or osd_libass.c
|
||||
void osd_alloc_buf(mp_osd_obj_t* obj);
|
||||
void draw_alpha_buf(mp_osd_obj_t* obj, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride);
|
||||
void vo_draw_text_from_buffer(mp_osd_obj_t* obj,void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx);
|
||||
|
||||
// defined in osd_ft.c or osd_libass.c
|
||||
|
|
349
sub/sub_cc.c
349
sub/sub_cc.c
|
@ -1,349 +0,0 @@
|
|||
/*
|
||||
* decoder for Closed Captions
|
||||
*
|
||||
* This decoder relies on MPlayer's OSD to display subtitles.
|
||||
* Be warned that decoding is somewhat preliminary, though it basically works.
|
||||
*
|
||||
* Most notably, only the text information is decoded as of now, discarding
|
||||
* color, background and position info (see source below).
|
||||
*
|
||||
* uses source from the xine closed captions decoder
|
||||
*
|
||||
* Copyright (C) 2002 Matteo Giani
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "sub_cc.h"
|
||||
|
||||
#include "subreader.h"
|
||||
|
||||
#include "libvo/video_out.h"
|
||||
#include "sub.h"
|
||||
|
||||
|
||||
#define CC_MAX_LINE_LENGTH 64
|
||||
|
||||
static char chartbl[128];
|
||||
|
||||
static subtitle buf1,buf2;
|
||||
static subtitle *fb,*bb;
|
||||
|
||||
static unsigned int cursor_pos=0;
|
||||
|
||||
static int initialized=0;
|
||||
|
||||
#define CC_ROLLON 1
|
||||
#define CC_ROLLUP 2
|
||||
|
||||
static int cc_mode=CC_ROLLON;
|
||||
static int cc_lines=4; ///< number of visible rows in CC roll-up mode, not used in CC roll-on mode
|
||||
|
||||
int subcc_enabled = 0;
|
||||
|
||||
static void build_char_table(void)
|
||||
{
|
||||
int i;
|
||||
/* first the normal ASCII codes */
|
||||
for (i = 0; i < 128; i++)
|
||||
chartbl[i] = (char) i;
|
||||
/* now the special codes */
|
||||
chartbl[0x2a] = 'á';
|
||||
chartbl[0x5c] = 'é';
|
||||
chartbl[0x5e] = 'í';
|
||||
chartbl[0x5f] = 'ó';
|
||||
chartbl[0x60] = 'ú';
|
||||
chartbl[0x7b] = 'ç';
|
||||
chartbl[0x7c] = '÷';
|
||||
chartbl[0x7d] = 'Ñ';
|
||||
chartbl[0x7e] = 'ñ';
|
||||
chartbl[0x7f] = '¤'; /* FIXME: this should be a solid block */
|
||||
}
|
||||
|
||||
static void clear_buffer(subtitle *buf)
|
||||
{
|
||||
int i;
|
||||
buf->lines=0;
|
||||
for (i = 0; i < SUB_MAX_TEXT; i++) {
|
||||
free(buf->text[i]);
|
||||
buf->text[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief scroll buffer one line up
|
||||
\param buf buffer to scroll
|
||||
*/
|
||||
static void scroll_buffer(subtitle* buf)
|
||||
{
|
||||
int i;
|
||||
|
||||
while(buf->lines > cc_lines)
|
||||
{
|
||||
free(buf->text[0]);
|
||||
|
||||
for(i = 0; i < buf->lines - 1; i++) buf->text[i] = buf->text[i+1];
|
||||
|
||||
buf->text[buf->lines-1] = NULL;
|
||||
buf->lines--;
|
||||
}
|
||||
}
|
||||
|
||||
static int channel;
|
||||
|
||||
void subcc_init(void)
|
||||
{
|
||||
int i;
|
||||
//printf("subcc_init(): initing...\n");
|
||||
build_char_table();
|
||||
for(i=0;i<SUB_MAX_TEXT;i++) {buf1.text[i]=buf2.text[i]=NULL;}
|
||||
buf1.lines=buf2.lines=0;
|
||||
fb=&buf1;
|
||||
bb=&buf2;
|
||||
channel = -1;
|
||||
|
||||
initialized=1;
|
||||
}
|
||||
|
||||
|
||||
static void display_buffer(subtitle *buf)
|
||||
{
|
||||
vo_sub = buf;
|
||||
vo_osd_changed(OSDTYPE_SUBTITLE);
|
||||
}
|
||||
|
||||
|
||||
static void append_char(char c)
|
||||
{
|
||||
if(!bb->lines) {bb->lines++; cursor_pos=0;}
|
||||
if(bb->text[bb->lines - 1]==NULL)
|
||||
{
|
||||
bb->text[bb->lines - 1] = calloc(1, CC_MAX_LINE_LENGTH);
|
||||
cursor_pos=0;
|
||||
}
|
||||
|
||||
if(c=='\n')
|
||||
{
|
||||
if(cursor_pos>0 && bb->lines < SUB_MAX_TEXT)
|
||||
{
|
||||
bb->lines++;cursor_pos=0;
|
||||
if(cc_mode==CC_ROLLUP){ //Carriage return - scroll buffer one line up
|
||||
bb->text[bb->lines - 1]=calloc(1, CC_MAX_LINE_LENGTH);
|
||||
scroll_buffer(bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cursor_pos==CC_MAX_LINE_LENGTH-1)
|
||||
{
|
||||
fprintf(stderr,"CC: append_char() reached CC_MAX_LINE_LENGTH!\n");
|
||||
return;
|
||||
}
|
||||
bb->text[bb->lines - 1][cursor_pos++]=c;
|
||||
}
|
||||
//In CC roll-up mode data should be shown immediately
|
||||
if(cc_mode==CC_ROLLUP) display_buffer(bb);
|
||||
}
|
||||
|
||||
|
||||
static void swap_buffers(void)
|
||||
{
|
||||
subtitle *foo;
|
||||
foo=fb;
|
||||
fb=bb;
|
||||
bb=foo;
|
||||
}
|
||||
|
||||
static int selected_channel(void)
|
||||
{
|
||||
return subcc_enabled - 1;
|
||||
}
|
||||
|
||||
static void cc_decode_EIA608(unsigned short int data)
|
||||
{
|
||||
|
||||
static unsigned short int lastcode=0x0000;
|
||||
uint8_t c1 = data & 0x7f;
|
||||
uint8_t c2 = (data >> 8) & 0x7f;
|
||||
|
||||
if (c1 & 0x60) { /* normal character, 0x20 <= c1 <= 0x7f */
|
||||
if (channel != (selected_channel() & 1))
|
||||
return;
|
||||
append_char(chartbl[c1]);
|
||||
if(c2 & 0x60) /*c2 might not be a normal char even if c1 is*/
|
||||
append_char(chartbl[c2]);
|
||||
}
|
||||
else if (c1 & 0x10) // control code / special char
|
||||
{
|
||||
channel = (c1 & 0x08) >> 3;
|
||||
if (channel != (selected_channel() & 1))
|
||||
return;
|
||||
c1&=~0x08;
|
||||
if(data!=lastcode)
|
||||
{
|
||||
if(c2 & 0x40) { /*PAC, Preamble Address Code */
|
||||
append_char('\n'); /*FIXME properly interpret PACs*/
|
||||
}
|
||||
else
|
||||
switch(c1)
|
||||
{
|
||||
case 0x10: break; // ext attribute
|
||||
case 0x11:
|
||||
if((c2 & 0x30)==0x30)
|
||||
{
|
||||
//printf("[debug]:Special char (ignored)\n");
|
||||
/*cc_decode_special_char()*/;
|
||||
}
|
||||
else if (c2 & 0x20)
|
||||
{
|
||||
//printf("[debug]: midrow_attr (ignored)\n");
|
||||
/*cc_decode_midrow_attr()*/;
|
||||
}
|
||||
break;
|
||||
case 0x14:
|
||||
switch(c2)
|
||||
{
|
||||
case 0x00: //CC roll-on mode
|
||||
cc_mode=CC_ROLLON;
|
||||
break;
|
||||
case 0x25: //CC roll-up, 2 rows
|
||||
case 0x26: //CC roll-up, 3 rows
|
||||
case 0x27: //CC roll-up, 4 rows
|
||||
cc_lines=c2-0x23;
|
||||
cc_mode=CC_ROLLUP;
|
||||
break;
|
||||
case 0x2C: display_buffer(NULL); //EDM
|
||||
clear_buffer(fb); break;
|
||||
case 0x2d: append_char('\n'); //carriage return
|
||||
break;
|
||||
case 0x2e: clear_buffer(bb); //ENM
|
||||
break;
|
||||
case 0x2f: swap_buffers(); //Swap buffers
|
||||
display_buffer(fb);
|
||||
clear_buffer(bb);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x17:
|
||||
if( c2>=0x21 && c2<=0x23) //TAB
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lastcode=data;
|
||||
}
|
||||
|
||||
static void subcc_decode(const uint8_t *inputbuffer, unsigned int inputlength)
|
||||
{
|
||||
/* The first number may denote a channel number. I don't have the
|
||||
* EIA-708 standard, so it is hard to say.
|
||||
* From what I could figure out so far, the general format seems to be:
|
||||
*
|
||||
* repeat
|
||||
*
|
||||
* 0xfe starts 2 byte sequence of unknown purpose. It might denote
|
||||
* field #2 in line 21 of the VBI.
|
||||
* Treating it identical of 0xff fixes
|
||||
* http://samples.mplayerhq.hu/MPEG-VOB/ClosedCaptions/Starship_Troopers.vob
|
||||
*
|
||||
* 0xff starts 2 byte EIA-608 sequence, field #1 in line 21 of the VBI.
|
||||
* Followed by a 3-code triplet that starts either with 0xff or
|
||||
* 0xfe. In either case, the following triplet needs to be ignored
|
||||
* for line 21, field 1.
|
||||
*
|
||||
* 0x00 is padding, followed by 2 more 0x00.
|
||||
*
|
||||
* 0x01 always seems to appear at the beginning, always seems to
|
||||
* be followed by 0xf8, 8-bit number.
|
||||
* The lower 7 bits of this 8-bit number seem to denote the
|
||||
* number of code triplets that follow.
|
||||
* The most significant bit denotes whether the Line 21 field 1
|
||||
* captioning information is at odd or even triplet offsets from this
|
||||
* beginning triplet. 1 denotes odd offsets, 0 denotes even offsets.
|
||||
*
|
||||
* Most captions are encoded with odd offsets, so this is what we
|
||||
* will assume.
|
||||
*
|
||||
* until end of packet
|
||||
*/
|
||||
const uint8_t *current = inputbuffer;
|
||||
unsigned int curbytes = 0;
|
||||
uint8_t data1, data2;
|
||||
uint8_t cc_code;
|
||||
int odd_offset = 1;
|
||||
|
||||
while (curbytes < inputlength) {
|
||||
cc_code = current[0];
|
||||
|
||||
if (inputlength - curbytes < 2) {
|
||||
#ifdef LOG_DEBUG
|
||||
fprintf(stderr, "Not enough data for 2-byte CC encoding\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
data1 = current[1];
|
||||
data2 = current[2];
|
||||
current += 3; curbytes += 3;
|
||||
|
||||
switch (cc_code) {
|
||||
case 0xfe:
|
||||
case 0xff:
|
||||
odd_offset ^= 1;
|
||||
if (odd_offset != selected_channel() >> 1)
|
||||
break;
|
||||
/* expect EIA-608 CC1/CC2 encoding */
|
||||
// FIXME check parity!
|
||||
// Parity check omitted assuming we are reading from a DVD and therefore
|
||||
// we should encounter no "transmission errors".
|
||||
cc_decode_EIA608(data1 | (data2 << 8));
|
||||
break;
|
||||
|
||||
case 0x00:
|
||||
/* This seems to be just padding */
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
odd_offset = data2 >> 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
//#ifdef LOG_DEBUG
|
||||
fprintf(stderr, "Unknown CC encoding: %x\n", cc_code);
|
||||
//#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void subcc_process_data(const uint8_t *inputdata, unsigned int len)
|
||||
{
|
||||
if(!subcc_enabled) return;
|
||||
if(!initialized) subcc_init();
|
||||
|
||||
subcc_decode(inputdata, len);
|
||||
}
|
29
sub/sub_cc.h
29
sub/sub_cc.h
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_SUB_CC_H
|
||||
#define MPLAYER_SUB_CC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern int subcc_enabled;
|
||||
|
||||
void subcc_init(void);
|
||||
void subcc_process_data(const uint8_t *inputdata, unsigned int len);
|
||||
|
||||
#endif /* MPLAYER_SUB_CC_H */
|
259
sub/subreader.c
259
sub/subreader.c
|
@ -1790,265 +1790,6 @@ if ((suboverlap_enabled == 2) ||
|
|||
return subt_data;
|
||||
}
|
||||
|
||||
void list_sub_file(sub_data* subd){
|
||||
int i,j;
|
||||
subtitle *subs = subd->subtitles;
|
||||
|
||||
for(j=0; j < subd->sub_num; j++){
|
||||
subtitle* egysub=&subs[j];
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"%i line%c (%li-%li)\n",
|
||||
egysub->lines,
|
||||
(1==egysub->lines)?' ':'s',
|
||||
egysub->start,
|
||||
egysub->end);
|
||||
for (i=0; i<egysub->lines; i++) {
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"\t\t%d: %s%s", i,egysub->text[i], i==egysub->lines-1?"":" \n ");
|
||||
}
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"\n");
|
||||
}
|
||||
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"Subtitle format %s time.\n",
|
||||
subd->sub_uses_time ? "uses":"doesn't use");
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"Read %i subtitles, %i errors.\n", subd->sub_num, subd->sub_errs);
|
||||
}
|
||||
|
||||
void dump_srt(sub_data* subd, float fps){
|
||||
int i,j;
|
||||
int h,m,s,ms;
|
||||
FILE * fd;
|
||||
subtitle * onesub;
|
||||
unsigned long temp;
|
||||
subtitle *subs = subd->subtitles;
|
||||
|
||||
if (!subd->sub_uses_time && sub_fps == 0)
|
||||
sub_fps = fps;
|
||||
fd=fopen("dumpsub.srt","w");
|
||||
if(!fd)
|
||||
{
|
||||
perror("dump_srt: fopen");
|
||||
return;
|
||||
}
|
||||
for(i=0; i < subd->sub_num; i++)
|
||||
{
|
||||
onesub=subs+i; //=&subs[i];
|
||||
fprintf(fd,"%d\n",i+1);//line number
|
||||
|
||||
temp=onesub->start;
|
||||
if (!subd->sub_uses_time)
|
||||
temp = temp * 100 / sub_fps;
|
||||
temp -= sub_delay * 100;
|
||||
h=temp/360000;temp%=360000; //h =1*100*60*60
|
||||
m=temp/6000; temp%=6000; //m =1*100*60
|
||||
s=temp/100; temp%=100; //s =1*100
|
||||
ms=temp*10; //ms=1*10
|
||||
fprintf(fd,"%02d:%02d:%02d,%03d --> ",h,m,s,ms);
|
||||
|
||||
temp=onesub->end;
|
||||
if (!subd->sub_uses_time)
|
||||
temp = temp * 100 / sub_fps;
|
||||
temp -= sub_delay * 100;
|
||||
h=temp/360000;temp%=360000;
|
||||
m=temp/6000; temp%=6000;
|
||||
s=temp/100; temp%=100;
|
||||
ms=temp*10;
|
||||
fprintf(fd,"%02d:%02d:%02d,%03d\n",h,m,s,ms);
|
||||
|
||||
for(j=0;j<onesub->lines;j++)
|
||||
fprintf(fd,"%s\n",onesub->text[j]);
|
||||
|
||||
fprintf(fd,"\n");
|
||||
}
|
||||
fclose(fd);
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dumpsub.srt\'.\n");
|
||||
}
|
||||
|
||||
void dump_mpsub(sub_data* subd, float fps){
|
||||
int i,j;
|
||||
FILE *fd;
|
||||
float a,b;
|
||||
subtitle *subs = subd->subtitles;
|
||||
|
||||
mpsub_position = subd->sub_uses_time? (sub_delay*100) : (sub_delay*fps);
|
||||
if (sub_fps==0) sub_fps=fps;
|
||||
|
||||
fd=fopen ("dump.mpsub", "w");
|
||||
if (!fd) {
|
||||
perror ("dump_mpsub: fopen");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (subd->sub_uses_time) fprintf (fd,"FORMAT=TIME\n\n");
|
||||
else fprintf (fd, "FORMAT=%5.2f\n\n", fps);
|
||||
|
||||
for(j=0; j < subd->sub_num; j++){
|
||||
subtitle* egysub=&subs[j];
|
||||
if (subd->sub_uses_time) {
|
||||
a=((egysub->start-mpsub_position)/100.0);
|
||||
b=((egysub->end-egysub->start)/100.0);
|
||||
if ( (float)((int)a) == a)
|
||||
fprintf (fd, "%.0f",a);
|
||||
else
|
||||
fprintf (fd, "%.2f",a);
|
||||
|
||||
if ( (float)((int)b) == b)
|
||||
fprintf (fd, " %.0f\n",b);
|
||||
else
|
||||
fprintf (fd, " %.2f\n",b);
|
||||
} else {
|
||||
fprintf (fd, "%ld %ld\n", (long)((egysub->start*(fps/sub_fps))-((mpsub_position*(fps/sub_fps)))),
|
||||
(long)(((egysub->end)-(egysub->start))*(fps/sub_fps)));
|
||||
}
|
||||
|
||||
mpsub_position = egysub->end;
|
||||
for (i=0; i<egysub->lines; i++) {
|
||||
fprintf (fd, "%s\n",egysub->text[i]);
|
||||
}
|
||||
fprintf (fd, "\n");
|
||||
}
|
||||
fclose (fd);
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dump.mpsub\'.\n");
|
||||
}
|
||||
|
||||
void dump_microdvd(sub_data* subd, float fps) {
|
||||
int i, delay;
|
||||
FILE *fd;
|
||||
subtitle *subs = subd->subtitles;
|
||||
if (sub_fps == 0)
|
||||
sub_fps = fps;
|
||||
fd = fopen("dumpsub.sub", "w");
|
||||
if (!fd) {
|
||||
perror("dumpsub.sub: fopen");
|
||||
return;
|
||||
}
|
||||
delay = sub_delay * sub_fps;
|
||||
for (i = 0; i < subd->sub_num; ++i) {
|
||||
int j, start, end;
|
||||
start = subs[i].start;
|
||||
end = subs[i].end;
|
||||
if (subd->sub_uses_time) {
|
||||
start = start * sub_fps / 100 ;
|
||||
end = end * sub_fps / 100;
|
||||
}
|
||||
else {
|
||||
start = start * sub_fps / fps;
|
||||
end = end * sub_fps / fps;
|
||||
}
|
||||
start -= delay;
|
||||
end -= delay;
|
||||
fprintf(fd, "{%d}{%d}", start, end);
|
||||
for (j = 0; j < subs[i].lines; ++j)
|
||||
fprintf(fd, "%s%s", j ? "|" : "", subs[i].text[j]);
|
||||
fprintf(fd, "\n");
|
||||
}
|
||||
fclose(fd);
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dumpsub.sub\'.\n");
|
||||
}
|
||||
|
||||
void dump_jacosub(sub_data* subd, float fps) {
|
||||
int i,j;
|
||||
int h,m,s,cs;
|
||||
FILE * fd;
|
||||
subtitle * onesub;
|
||||
unsigned long temp;
|
||||
subtitle *subs = subd->subtitles;
|
||||
|
||||
if (!subd->sub_uses_time && sub_fps == 0)
|
||||
sub_fps = fps;
|
||||
fd=fopen("dumpsub.jss","w");
|
||||
if(!fd)
|
||||
{
|
||||
perror("dump_jacosub: fopen");
|
||||
return;
|
||||
}
|
||||
fprintf(fd, "#TIMERES %d\n", (subd->sub_uses_time) ? 100 : (int)sub_fps);
|
||||
for(i=0; i < subd->sub_num; i++)
|
||||
{
|
||||
onesub=subs+i; //=&subs[i];
|
||||
|
||||
temp=onesub->start;
|
||||
if (!subd->sub_uses_time)
|
||||
temp = temp * 100 / sub_fps;
|
||||
temp -= sub_delay * 100;
|
||||
h=temp/360000;temp%=360000; //h =1*100*60*60
|
||||
m=temp/6000; temp%=6000; //m =1*100*60
|
||||
s=temp/100; temp%=100; //s =1*100
|
||||
cs=temp; //cs=1*10
|
||||
fprintf(fd,"%02d:%02d:%02d.%02d ",h,m,s,cs);
|
||||
|
||||
temp=onesub->end;
|
||||
if (!subd->sub_uses_time)
|
||||
temp = temp * 100 / sub_fps;
|
||||
temp -= sub_delay * 100;
|
||||
h=temp/360000;temp%=360000;
|
||||
m=temp/6000; temp%=6000;
|
||||
s=temp/100; temp%=100;
|
||||
cs=temp;
|
||||
fprintf(fd,"%02d:%02d:%02d.%02d {~} ",h,m,s,cs);
|
||||
|
||||
for(j=0;j<onesub->lines;j++)
|
||||
fprintf(fd,"%s%s",j ? "\\n" : "", onesub->text[j]);
|
||||
|
||||
fprintf(fd,"\n");
|
||||
}
|
||||
fclose(fd);
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dumpsub.js\'.\n");
|
||||
}
|
||||
|
||||
void dump_sami(sub_data* subd, float fps) {
|
||||
int i,j;
|
||||
FILE * fd;
|
||||
subtitle * onesub;
|
||||
unsigned long temp;
|
||||
subtitle *subs = subd->subtitles;
|
||||
|
||||
if (!subd->sub_uses_time && sub_fps == 0)
|
||||
sub_fps = fps;
|
||||
fd=fopen("dumpsub.smi","w");
|
||||
if(!fd)
|
||||
{
|
||||
perror("dump_jacosub: fopen");
|
||||
return;
|
||||
}
|
||||
fprintf(fd, "<SAMI>\n"
|
||||
"<HEAD>\n"
|
||||
" <STYLE TYPE=\"Text/css\">\n"
|
||||
" <!--\n"
|
||||
" P {margin-left: 29pt; margin-right: 29pt; font-size: 24pt; text-align: center; font-family: Tahoma; font-weight: bold; color: #FCDD03; background-color: #000000;}\n"
|
||||
" .SUBTTL {Name: 'Subtitles'; Lang: en-US; SAMIType: CC;}\n"
|
||||
" -->\n"
|
||||
" </STYLE>\n"
|
||||
"</HEAD>\n"
|
||||
"<BODY>\n");
|
||||
for(i=0; i < subd->sub_num; i++)
|
||||
{
|
||||
onesub=subs+i; //=&subs[i];
|
||||
|
||||
temp=onesub->start;
|
||||
if (!subd->sub_uses_time)
|
||||
temp = temp * 100 / sub_fps;
|
||||
temp -= sub_delay * 100;
|
||||
fprintf(fd,"\t<SYNC Start=%lu>\n"
|
||||
"\t <P>", temp * 10);
|
||||
|
||||
for(j=0;j<onesub->lines;j++)
|
||||
fprintf(fd,"%s%s",j ? "<br>" : "", onesub->text[j]);
|
||||
|
||||
fprintf(fd,"\n");
|
||||
|
||||
temp=onesub->end;
|
||||
if (!subd->sub_uses_time)
|
||||
temp = temp * 100 / sub_fps;
|
||||
temp -= sub_delay * 100;
|
||||
fprintf(fd,"\t<SYNC Start=%lu>\n"
|
||||
"\t <P> \n", temp * 10);
|
||||
}
|
||||
fprintf(fd, "</BODY>\n"
|
||||
"</SAMI>\n");
|
||||
fclose(fd);
|
||||
mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dumpsub.smi\'.\n");
|
||||
}
|
||||
|
||||
void sub_free( sub_data * subd )
|
||||
{
|
||||
int i, j;
|
||||
|
|
|
@ -91,12 +91,6 @@ void subcp_close (void); /* for demux_ogg.c */
|
|||
const char* guess_buffer_cp(unsigned char* buffer, int buflen, const char *preferred_language, const char *fallback);
|
||||
const char* guess_cp(struct stream *st, const char *preferred_language, const char *fallback);
|
||||
#endif
|
||||
void list_sub_file(sub_data* subd);
|
||||
void dump_srt(sub_data* subd, float fps);
|
||||
void dump_mpsub(sub_data* subd, float fps);
|
||||
void dump_microdvd(sub_data* subd, float fps);
|
||||
void dump_jacosub(sub_data* subd, float fps);
|
||||
void dump_sami(sub_data* subd, float fps);
|
||||
void sub_free( sub_data * subd );
|
||||
struct MPContext;
|
||||
void find_sub(struct MPContext *mpctx, sub_data* subd,int key);
|
||||
|
|
241
sub/vobsub.c
241
sub/vobsub.c
|
@ -963,22 +963,6 @@ int vobsub_get_packet(void *vobhandle, float pts, void** data, int* timestamp)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int vobsub_get_next_packet(void *vobhandle, void** data, int* timestamp)
|
||||
{
|
||||
vobsub_t *vob = vobhandle;
|
||||
if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) {
|
||||
packet_queue_t *queue = vob->spu_streams + vobsub_id;
|
||||
if (queue->current_index < queue->packets_size) {
|
||||
packet_t *pkt = queue->packets + queue->current_index;
|
||||
++queue->current_index;
|
||||
*data = pkt->data;
|
||||
*timestamp = pkt->pts100;
|
||||
return pkt->size;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void vobsub_seek(void * vobhandle, float pts)
|
||||
{
|
||||
vobsub_t * vob = vobhandle;
|
||||
|
@ -994,228 +978,3 @@ void vobsub_seek(void * vobhandle, float pts)
|
|||
vobsub_queue_reseek(queue, seek_pts100);
|
||||
}
|
||||
}
|
||||
|
||||
void vobsub_reset(void *vobhandle)
|
||||
{
|
||||
vobsub_t *vob = vobhandle;
|
||||
if (vob->spu_streams) {
|
||||
unsigned int n = vob->spu_streams_size;
|
||||
while (n-- > 0)
|
||||
vob->spu_streams[n].current_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Vobsub output
|
||||
**********************************************************************/
|
||||
|
||||
typedef struct {
|
||||
FILE *fsub;
|
||||
FILE *fidx;
|
||||
unsigned int aid;
|
||||
} vobsub_out_t;
|
||||
|
||||
static void create_idx(vobsub_out_t *me, const unsigned int *palette,
|
||||
unsigned int orig_width, unsigned int orig_height)
|
||||
{
|
||||
int i;
|
||||
fprintf(me->fidx,
|
||||
"# VobSub index file, v7 (do not modify this line!)\n"
|
||||
"#\n"
|
||||
"# Generated by %s\n"
|
||||
"# See <URL:http://www.mplayerhq.hu/> for more information about MPlayer\n"
|
||||
"# See <URL:http://wiki.multimedia.cx/index.php?title=VOBsub> for more information about Vobsub\n"
|
||||
"#\n"
|
||||
"size: %ux%u\n",
|
||||
mplayer_version, orig_width, orig_height);
|
||||
if (palette) {
|
||||
fputs("palette:", me->fidx);
|
||||
for (i = 0; i < 16; ++i) {
|
||||
const double y = palette[i] >> 16 & 0xff,
|
||||
u = (palette[i] >> 8 & 0xff) - 128.0,
|
||||
v = (palette[i] & 0xff) - 128.0;
|
||||
if (i)
|
||||
putc(',', me->fidx);
|
||||
fprintf(me->fidx, " %02x%02x%02x",
|
||||
av_clip_uint8(y + 1.4022 * u),
|
||||
av_clip_uint8(y - 0.3456 * u - 0.7145 * v),
|
||||
av_clip_uint8(y + 1.7710 * v));
|
||||
}
|
||||
putc('\n', me->fidx);
|
||||
}
|
||||
|
||||
fprintf(me->fidx, "# ON: displays only forced subtitles, OFF: shows everything\n"
|
||||
"forced subs: OFF\n");
|
||||
}
|
||||
|
||||
void *vobsub_out_open(const char *basename, const unsigned int *palette,
|
||||
unsigned int orig_width, unsigned int orig_height,
|
||||
const char *id, unsigned int index)
|
||||
{
|
||||
vobsub_out_t *result = NULL;
|
||||
char *filename;
|
||||
filename = malloc(strlen(basename) + 5);
|
||||
if (filename) {
|
||||
result = malloc(sizeof(vobsub_out_t));
|
||||
if (result) {
|
||||
result->aid = index;
|
||||
strcpy(filename, basename);
|
||||
strcat(filename, ".sub");
|
||||
result->fsub = fopen(filename, "ab");
|
||||
if (result->fsub == NULL)
|
||||
perror("Error: vobsub_out_open subtitle file open failed");
|
||||
strcpy(filename, basename);
|
||||
strcat(filename, ".idx");
|
||||
result->fidx = fopen(filename, "ab");
|
||||
if (result->fidx) {
|
||||
if (ftell(result->fidx) == 0) {
|
||||
create_idx(result, palette, orig_width, orig_height);
|
||||
/* Make the selected language the default language */
|
||||
fprintf(result->fidx, "\n# Language index in use\nlangidx: %u\n", index);
|
||||
}
|
||||
fprintf(result->fidx, "\nid: %s, index: %u\n", id ? id : "xx", index);
|
||||
/* So that we can check the file now */
|
||||
fflush(result->fidx);
|
||||
} else
|
||||
perror("Error: vobsub_out_open index file open failed");
|
||||
free(filename);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void vobsub_out_close(void *me)
|
||||
{
|
||||
vobsub_out_t *vob = me;
|
||||
if (vob->fidx)
|
||||
fclose(vob->fidx);
|
||||
if (vob->fsub)
|
||||
fclose(vob->fsub);
|
||||
free(vob);
|
||||
}
|
||||
|
||||
void vobsub_out_output(void *me, const unsigned char *packet,
|
||||
int len, double pts)
|
||||
{
|
||||
static double last_pts;
|
||||
static int last_pts_set = 0;
|
||||
vobsub_out_t *vob = me;
|
||||
if (vob->fsub) {
|
||||
/* Windows' Vobsub require that every packet is exactly 2kB long */
|
||||
unsigned char buffer[2048];
|
||||
unsigned char *p;
|
||||
int remain = 2048;
|
||||
/* Do not output twice a line with the same timestamp, this
|
||||
breaks Windows' Vobsub */
|
||||
if (vob->fidx && (!last_pts_set || last_pts != pts)) {
|
||||
static unsigned int last_h = 9999, last_m = 9999, last_s = 9999, last_ms = 9999;
|
||||
unsigned int h, m, ms;
|
||||
double s;
|
||||
s = pts;
|
||||
h = s / 3600;
|
||||
s -= h * 3600;
|
||||
m = s / 60;
|
||||
s -= m * 60;
|
||||
ms = (s - (unsigned int) s) * 1000;
|
||||
if (ms >= 1000) /* prevent overflows or bad float stuff */
|
||||
ms = 0;
|
||||
if (h != last_h || m != last_m || (unsigned int) s != last_s || ms != last_ms) {
|
||||
fprintf(vob->fidx, "timestamp: %02u:%02u:%02u:%03u, filepos: %09lx\n",
|
||||
h, m, (unsigned int) s, ms, ftell(vob->fsub));
|
||||
last_h = h;
|
||||
last_m = m;
|
||||
last_s = (unsigned int) s;
|
||||
last_ms = ms;
|
||||
}
|
||||
}
|
||||
last_pts = pts;
|
||||
last_pts_set = 1;
|
||||
|
||||
/* Packet start code: Windows' Vobsub needs this */
|
||||
p = buffer;
|
||||
*p++ = 0; /* 0x00 */
|
||||
*p++ = 0;
|
||||
*p++ = 1;
|
||||
*p++ = 0xba;
|
||||
*p++ = 0x40;
|
||||
memset(p, 0, 9);
|
||||
p += 9;
|
||||
{ /* Packet */
|
||||
static unsigned char last_pts[5] = { 0, 0, 0, 0, 0};
|
||||
unsigned char now_pts[5];
|
||||
int pts_len, pad_len, datalen = len;
|
||||
pts *= 90000;
|
||||
now_pts[0] = 0x21 | (((unsigned long)pts >> 29) & 0x0e);
|
||||
now_pts[1] = ((unsigned long)pts >> 22) & 0xff;
|
||||
now_pts[2] = 0x01 | (((unsigned long)pts >> 14) & 0xfe);
|
||||
now_pts[3] = ((unsigned long)pts >> 7) & 0xff;
|
||||
now_pts[4] = 0x01 | (((unsigned long)pts << 1) & 0xfe);
|
||||
pts_len = memcmp(last_pts, now_pts, sizeof(now_pts)) ? sizeof(now_pts) : 0;
|
||||
memcpy(last_pts, now_pts, sizeof(now_pts));
|
||||
|
||||
datalen += 3; /* Version, PTS_flags, pts_len */
|
||||
datalen += pts_len;
|
||||
datalen += 1; /* AID */
|
||||
pad_len = 2048 - (p - buffer) - 4 /* MPEG ID */ - 2 /* payload len */ - datalen;
|
||||
/* XXX - Go figure what should go here! In any case the
|
||||
packet has to be completely filled. If I can fill it
|
||||
with padding (0x000001be) latter I'll do that. But if
|
||||
there is only room for 6 bytes then I can not write a
|
||||
padding packet. So I add some padding in the PTS
|
||||
field. This looks like a dirty kludge. Oh well... */
|
||||
if (pad_len < 0) {
|
||||
/* Packet is too big. Let's try omitting the PTS field */
|
||||
datalen -= pts_len;
|
||||
pts_len = 0;
|
||||
pad_len = 0;
|
||||
} else if (pad_len > 6)
|
||||
pad_len = 0;
|
||||
datalen += pad_len;
|
||||
|
||||
*p++ = 0; /* 0x0e */
|
||||
*p++ = 0;
|
||||
*p++ = 1;
|
||||
*p++ = 0xbd;
|
||||
|
||||
*p++ = (datalen >> 8) & 0xff; /* length of payload */
|
||||
*p++ = datalen & 0xff;
|
||||
*p++ = 0x80; /* System-2 (.VOB) stream */
|
||||
*p++ = pts_len ? 0x80 : 0x00; /* pts_flags */
|
||||
*p++ = pts_len + pad_len;
|
||||
memcpy(p, now_pts, pts_len);
|
||||
p += pts_len;
|
||||
memset(p, 0, pad_len);
|
||||
p += pad_len;
|
||||
}
|
||||
*p++ = 0x20 | vob->aid; /* aid */
|
||||
if (fwrite(buffer, p - buffer, 1, vob->fsub) != 1
|
||||
|| fwrite(packet, len, 1, vob->fsub) != 1)
|
||||
perror("ERROR: vobsub write failed");
|
||||
else
|
||||
remain -= p - buffer + len;
|
||||
|
||||
/* Padding */
|
||||
if (remain >= 6) {
|
||||
p = buffer;
|
||||
*p++ = 0x00;
|
||||
*p++ = 0x00;
|
||||
*p++ = 0x01;
|
||||
*p++ = 0xbe;
|
||||
*p++ = (remain - 6) >> 8;
|
||||
*p++ = (remain - 6) & 0xff;
|
||||
/* for better compression, blank this */
|
||||
memset(buffer + 6, 0, remain - (p - buffer));
|
||||
if (fwrite(buffer, remain, 1, vob->fsub) != 1)
|
||||
perror("ERROR: vobsub padding write failed");
|
||||
} else if (remain > 0) {
|
||||
/* I don't know what to output. But anyway the block
|
||||
needs to be 2KB big */
|
||||
memset(buffer, 0, remain);
|
||||
if (fwrite(buffer, remain, 1, vob->fsub) != 1)
|
||||
perror("ERROR: vobsub blank padding write failed");
|
||||
} else if (remain < 0)
|
||||
fprintf(stderr,
|
||||
"\nERROR: wrong thing happened...\n"
|
||||
" I wrote a %i data bytes spu packet and that's too long\n", len);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ void *vobsub_open(const char *subname, const char *const ifo, const int force, v
|
|||
void vobsub_reset(void *vob);
|
||||
int vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force, int sid, char *langid);
|
||||
int vobsub_get_packet(void *vobhandle, float pts,void** data, int* timestamp);
|
||||
int vobsub_get_next_packet(void *vobhandle, void** data, int* timestamp);
|
||||
void vobsub_close(void *this);
|
||||
unsigned int vobsub_get_indexes_count(void * /* vobhandle */);
|
||||
char *vobsub_get_id(void * /* vobhandle */, unsigned int /* index */);
|
||||
|
@ -38,9 +37,6 @@ unsigned int vobsub_palette_to_yuv(unsigned int pal);
|
|||
/// Convert rgb value to yuv.
|
||||
unsigned int vobsub_rgb_to_yuv(unsigned int rgb);
|
||||
|
||||
void *vobsub_out_open(const char *basename, const unsigned int *palette, unsigned int orig_width, unsigned int orig_height, const char *id, unsigned int index);
|
||||
void vobsub_out_output(void *me, const unsigned char *packet, int len, double pts);
|
||||
void vobsub_out_close(void *me);
|
||||
int vobsub_set_from_lang(void *vobhandle, char **lang);
|
||||
void vobsub_seek(void * vobhandle, float pts);
|
||||
|
||||
|
|
|
@ -336,11 +336,3 @@ int strargcmp(strarg_t *arg, const char *str) {
|
|||
res = arg->len - strlen(str);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** \brief compare the stings just as strcasecmp does */
|
||||
int strargcasecmp(strarg_t *arg, char *str) {
|
||||
int res = strncasecmp(arg->str, str, arg->len);
|
||||
if (!res && arg->len != strlen(str))
|
||||
res = arg->len - strlen(str);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,5 @@ int int_non_neg(void *iptr);
|
|||
int int_pos(void *iptr);
|
||||
|
||||
int strargcmp(strarg_t *arg, const char *str);
|
||||
int strargcasecmp(strarg_t *arg, char *str);
|
||||
|
||||
#endif /* MPLAYER_SUBOPT_HELPER_H */
|
||||
|
|
Loading…
Reference in New Issue