mirror of
https://github.com/mpv-player/mpv
synced 2025-04-01 23:00:41 +00:00
Merge svn changes up to r30136
Ignore another broken correct-pts change in 30134.
This commit is contained in:
commit
d46b86bc7c
@ -1197,7 +1197,7 @@ amount of memory.
|
||||
Allows a socket to be reused by other processes as soon as it is closed.
|
||||
.
|
||||
.TP
|
||||
.B \-bandwidth <value> (network only)
|
||||
.B \-bandwidth <Bytes> (network only)
|
||||
Specify the maximum bandwidth for network streaming (for servers that are
|
||||
able to send content in different bitrates).
|
||||
Useful if you want to watch live streamed media behind a slow connection.
|
||||
|
@ -3581,6 +3581,9 @@ OSD 颜色(默认值是:0x00ffffff,对应不透明的白色)。
|
||||
此限制帧率到 (水平刷新率 / n)。
|
||||
需要 GLX_SGI_swap_control 的支持。
|
||||
某些(大多数/所有?)实现仅工作于全屏模式。
|
||||
.IPs ycbcr
|
||||
使用 GL_MESA_ycbcr_texture 扩展组件将 YUV 转换为 RGB 格式。
|
||||
在大多数情况下,该方法很可能比使用软件转换成 RGB 慢。
|
||||
.IPs yuv=<n>
|
||||
选择 YUV 到 RGB 转换的类型。
|
||||
.RSss
|
||||
@ -3620,9 +3623,6 @@ GL_ARB_fragment_shader!)。至少需要三个纹理单位。提供饱和度
|
||||
对红, 绿和蓝色, Gamma 也能被独立设置。
|
||||
速度比其他方法更多地依赖于 GPU 内存带宽。
|
||||
.RE
|
||||
.IPs ycbcr
|
||||
使用 GL_MESA_ycbcr_texture 扩展组件完成 YUV 至 RGB 的转换。
|
||||
在大多数情况下,这可能比使用软件方式转换至 RGB 要慢。
|
||||
.IPs lscale=<n>
|
||||
选择缩放功能供调节发光性。
|
||||
仅对 yuv 模式 2, 3, 4 和 6 有效。
|
||||
@ -3657,6 +3657,11 @@ GL_ARB_fragment_shader!)。至少需要三个纹理单位。提供饱和度
|
||||
如果启用(默认), 使用 GL_LINEAR 插值, 否则使用 GL_NEAREST 用于 customtex 纹理。
|
||||
.IPs (no)customtrect
|
||||
如果启用, 使用 texture_rectangle 用于 customtex 纹理。默认是停用。
|
||||
.IPs (no)mipmapgen
|
||||
一旦启用,将自动生成视频的贴图。该选项与 customprog 和 TXB 一起使用
|
||||
有助于实现一个具有大影响半径的模糊滤镜。
|
||||
对于大多数 OpenGL 的实现产品来说,该选项作用于任何非 RGB 的格式都很慢。
|
||||
默认值为禁用。
|
||||
.RE
|
||||
.sp 1
|
||||
.RS
|
||||
|
68
command.c
68
command.c
@ -824,23 +824,22 @@ static int mp_property_audio(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
struct MPOpts *opts = &mpctx->opts;
|
||||
int current_id = -1, tmp;
|
||||
int current_id, tmp;
|
||||
if (!mpctx->demuxer || !mpctx->demuxer->audio)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
current_id = mpctx->demuxer->audio->id;
|
||||
|
||||
switch (action) {
|
||||
case M_PROPERTY_GET:
|
||||
if (!mpctx->sh_audio)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
*(int *) arg = opts->audio_id;
|
||||
*(int *) arg = current_id;
|
||||
return M_PROPERTY_OK;
|
||||
case M_PROPERTY_PRINT:
|
||||
if (!mpctx->sh_audio)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
|
||||
if (opts->audio_id < 0)
|
||||
if (current_id < 0)
|
||||
*(char **) arg = strdup(_("disabled"));
|
||||
else {
|
||||
char lang[40] = _("unknown");
|
||||
@ -849,7 +848,7 @@ static int mp_property_audio(m_option_t *prop, int action, void *arg,
|
||||
av_strlcpy(lang, sh->lang, 40);
|
||||
#ifdef CONFIG_DVDREAD
|
||||
else if (mpctx->stream->type == STREAMTYPE_DVD) {
|
||||
int code = dvd_lang_from_aid(mpctx->stream, opts->audio_id);
|
||||
int code = dvd_lang_from_aid(mpctx->stream, current_id);
|
||||
if (code) {
|
||||
lang[0] = code >> 8;
|
||||
lang[1] = code;
|
||||
@ -860,22 +859,19 @@ static int mp_property_audio(m_option_t *prop, int action, void *arg,
|
||||
|
||||
#ifdef CONFIG_DVDNAV
|
||||
else if (mpctx->stream->type == STREAMTYPE_DVDNAV)
|
||||
mp_dvdnav_lang_from_aid(mpctx->stream, opts->audio_id, lang);
|
||||
mp_dvdnav_lang_from_aid(mpctx->stream, current_id, lang);
|
||||
#endif
|
||||
*(char **) arg = malloc(64);
|
||||
snprintf(*(char **) arg, 64, "(%d) %s", opts->audio_id, lang);
|
||||
snprintf(*(char **) arg, 64, "(%d) %s", current_id, lang);
|
||||
}
|
||||
return M_PROPERTY_OK;
|
||||
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_SET:
|
||||
if (!mpctx->demuxer)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
if (action == M_PROPERTY_SET && arg)
|
||||
tmp = *((int *) arg);
|
||||
else
|
||||
tmp = -1;
|
||||
current_id = mpctx->demuxer->audio->id;
|
||||
opts->audio_id = demuxer_switch_audio(mpctx->demuxer, tmp);
|
||||
if (opts->audio_id == -2
|
||||
|| (opts->audio_id > -1
|
||||
@ -903,34 +899,32 @@ static int mp_property_video(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
struct MPOpts *opts = &mpctx->opts;
|
||||
int current_id = -1, tmp;
|
||||
int current_id, tmp;
|
||||
if (!mpctx->demuxer || !mpctx->demuxer->video)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
current_id = mpctx->demuxer->video->id;
|
||||
|
||||
switch (action) {
|
||||
case M_PROPERTY_GET:
|
||||
if (!mpctx->sh_video)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
*(int *) arg = opts->video_id;
|
||||
*(int *) arg = current_id;
|
||||
return M_PROPERTY_OK;
|
||||
case M_PROPERTY_PRINT:
|
||||
if (!mpctx->sh_video)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
if (!arg)
|
||||
return M_PROPERTY_ERROR;
|
||||
|
||||
if (opts->video_id < 0)
|
||||
if (current_id < 0)
|
||||
*(char **) arg = strdup(_("disabled"));
|
||||
else {
|
||||
char lang[40] = _("unknown");
|
||||
*(char **) arg = malloc(64);
|
||||
snprintf(*(char **) arg, 64, "(%d) %s", opts->video_id, lang);
|
||||
snprintf(*(char **) arg, 64, "(%d) %s", current_id, lang);
|
||||
}
|
||||
return M_PROPERTY_OK;
|
||||
|
||||
case M_PROPERTY_STEP_UP:
|
||||
case M_PROPERTY_SET:
|
||||
current_id = mpctx->demuxer->video->id;
|
||||
if (action == M_PROPERTY_SET && arg)
|
||||
tmp = *((int *) arg);
|
||||
else
|
||||
@ -1363,9 +1357,6 @@ static int mp_property_aspect(m_option_t *prop, int action, void *arg,
|
||||
static int mp_property_sub_pos(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
if (!mpctx->sh_video)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
|
||||
switch (action) {
|
||||
case M_PROPERTY_SET:
|
||||
if (!arg)
|
||||
@ -2479,6 +2470,23 @@ static const struct {
|
||||
};
|
||||
#endif
|
||||
|
||||
static const char *property_error_string(int error_value)
|
||||
{
|
||||
switch (error_value) {
|
||||
case M_PROPERTY_ERROR:
|
||||
return "ERROR";
|
||||
case M_PROPERTY_UNAVAILABLE:
|
||||
return "PROPERTY_UNAVAILABLE";
|
||||
case M_PROPERTY_NOT_IMPLEMENTED:
|
||||
return "NOT_IMPLEMENTED";
|
||||
case M_PROPERTY_UNKNOWN:
|
||||
return "PROPERTY_UNKNOWN";
|
||||
case M_PROPERTY_DISABLED:
|
||||
return "DISABLED";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
{
|
||||
struct MPOpts *opts = &mpctx->opts;
|
||||
@ -2527,6 +2535,8 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
cmd->args[0].v.s, cmd->args[1].v.s);
|
||||
else if (case_fallthrough_hack)
|
||||
show_property_osd(mpctx, cmd->args[0].v.s);
|
||||
if (r <= 0)
|
||||
mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_ERROR=%s\n", property_error_string(r));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2573,16 +2583,20 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
cmd->args[0].v.s, cmd->args[1].v.f);
|
||||
else if (case_fallthrough_hack)
|
||||
show_property_osd(mpctx, cmd->args[0].v.s);
|
||||
if (r <= 0)
|
||||
mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_ERROR=%s\n", property_error_string(r));
|
||||
}
|
||||
break;
|
||||
|
||||
case MP_CMD_GET_PROPERTY:{
|
||||
char *tmp;
|
||||
if (mp_property_do(cmd->args[0].v.s, M_PROPERTY_TO_STRING,
|
||||
&tmp, mpctx) <= 0) {
|
||||
int r = mp_property_do(cmd->args[0].v.s, M_PROPERTY_TO_STRING,
|
||||
&tmp, mpctx);
|
||||
if (r <= 0) {
|
||||
mp_msg(MSGT_CPLAYER, MSGL_WARN,
|
||||
"Failed to get value of property '%s'.\n",
|
||||
cmd->args[0].v.s);
|
||||
mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_ERROR=%s\n", property_error_string(r));
|
||||
break;
|
||||
}
|
||||
mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_%s=%s\n",
|
||||
|
107
etc/codecs.conf
107
etc/codecs.conf
@ -2891,7 +2891,7 @@ videocodec ffinterplay
|
||||
fourcc INPV ; internal MPlayer FourCC
|
||||
driver ffmpeg
|
||||
dll "interplayvideo"
|
||||
out BGR8
|
||||
out BGR8,BGR15
|
||||
|
||||
videocodec ffvqa
|
||||
info "FFmpeg VQA Video"
|
||||
@ -3161,6 +3161,111 @@ videocodec rawy800
|
||||
fourcc y800,Y800
|
||||
out Y800,Y8
|
||||
|
||||
;lavc raw codecs
|
||||
|
||||
videocodec ffrawyuy2
|
||||
info "RAW YUY2"
|
||||
status working
|
||||
format 0x0
|
||||
format 0x20776172
|
||||
fourcc yuy2,YUY2
|
||||
fourcc V422,v422
|
||||
fourcc YUNV,yunv
|
||||
fourcc VYUY,vyuy
|
||||
fourcc yuvs,YUVS
|
||||
driver ffmpeg
|
||||
dll rawvideo
|
||||
out YUY2
|
||||
|
||||
videocodec ffrawyuv2
|
||||
info "RAW YUV2"
|
||||
status working
|
||||
format 0x0
|
||||
format 0x20776172
|
||||
fourcc yuv2,YUV2
|
||||
driver ffmpeg
|
||||
dll rawvideo
|
||||
out YUY2
|
||||
|
||||
videocodec ffrawuyvy
|
||||
info "RAW UYVY"
|
||||
status working
|
||||
format 0x0
|
||||
format 0x20776172
|
||||
fourcc uyvy,UYVY
|
||||
fourcc HDYC,hdyc
|
||||
fourcc UYNV,uynv
|
||||
fourcc UYNY,uyny
|
||||
fourcc uyv1,UYV1
|
||||
fourcc 2Vu1,2vu1,2VU1
|
||||
fourcc 2Vuy,2vuy,2VUY
|
||||
driver ffmpeg
|
||||
dll rawvideo
|
||||
out UYVY
|
||||
|
||||
videocodec ffraw444P
|
||||
info "RAW 444P"
|
||||
status working
|
||||
format 0x0
|
||||
format 0x20776172
|
||||
fourcc 444p,444P
|
||||
driver ffmpeg
|
||||
dll rawvideo
|
||||
out 444P
|
||||
|
||||
videocodec ffraw422P
|
||||
info "RAW 422P"
|
||||
status working
|
||||
format 0x0
|
||||
format 0x20776172
|
||||
fourcc 422p,422P
|
||||
fourcc P422,p422
|
||||
fourcc Y42B,y42b
|
||||
driver ffmpeg
|
||||
dll rawvideo
|
||||
out 422P
|
||||
|
||||
videocodec ffrawyv12
|
||||
info "RAW YV12"
|
||||
status working
|
||||
format 0x0
|
||||
format 0x20776172
|
||||
fourcc yv12,YV12
|
||||
driver ffmpeg
|
||||
dll rawvideo
|
||||
out YV12
|
||||
|
||||
videocodec ffrawi420
|
||||
info "RAW I420"
|
||||
status working
|
||||
format 0x0
|
||||
format 0x20776172
|
||||
fourcc i420,I420
|
||||
fourcc IYUV,iyuv
|
||||
driver ffmpeg
|
||||
dll rawvideo
|
||||
out I420,IYUV
|
||||
|
||||
videocodec ffrawyvu9
|
||||
info "RAW YVU9"
|
||||
status working
|
||||
format 0x0
|
||||
format 0x20776172
|
||||
fourcc yvu9,YVU9
|
||||
driver ffmpeg
|
||||
dll rawvideo
|
||||
out YVU9
|
||||
|
||||
videocodec ffrawy800
|
||||
info "RAW Y8/Y800"
|
||||
status working
|
||||
format 0x0
|
||||
format 0x20203859 ; "Y8 "
|
||||
fourcc y800,Y800
|
||||
driver ffmpeg
|
||||
dll rawvideo
|
||||
out Y800,Y8
|
||||
|
||||
; NULL codec - for testing.
|
||||
|
||||
videocodec null
|
||||
|
@ -167,7 +167,17 @@ static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int m
|
||||
int len2=maxlen;
|
||||
double pts;
|
||||
int x=ds_get_packet_pts(sh_audio->ds,&start, &pts);
|
||||
if(x<=0) break; // error
|
||||
if(x<=0) {
|
||||
start = NULL;
|
||||
x = 0;
|
||||
ds_parse(sh_audio->ds, &start, &x, MP_NOPTS_VALUE, 0);
|
||||
if (x <= 0)
|
||||
break; // error
|
||||
} else {
|
||||
int in_size = x;
|
||||
int consumed = ds_parse(sh_audio->ds, &start, &x, pts, 0);
|
||||
sh_audio->ds->buffer_pos -= in_size - consumed;
|
||||
}
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = start;
|
||||
pkt.size = x;
|
||||
@ -178,7 +188,8 @@ static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int m
|
||||
y=avcodec_decode_audio3(sh_audio->context,(int16_t*)buf,&len2,&pkt);
|
||||
//printf("return:%d samples_out:%d bitstream_in:%d sample_sum:%d\n", y, len2, x, len); fflush(stdout);
|
||||
if(y<0){ mp_msg(MSGT_DECAUDIO,MSGL_V,"lavc_audio: error\n");break; }
|
||||
if(y<x) sh_audio->ds->buffer_pos+=y-x; // put back data (HACK!)
|
||||
if(!sh_audio->needs_parsing && y<x)
|
||||
sh_audio->ds->buffer_pos+=y-x; // put back data (HACK!)
|
||||
if(len2>0){
|
||||
if (((AVCodecContext *)sh_audio->context)->channels >= 5) {
|
||||
int samplesize = av_get_bits_per_sample_format(((AVCodecContext *)
|
||||
|
@ -38,7 +38,7 @@
|
||||
#define MP_IMGFLAG_YUV 0x200
|
||||
// set if it's swapped (BGR or YVU) plane/byteorder
|
||||
#define MP_IMGFLAG_SWAPPED 0x400
|
||||
// using palette for RGB data
|
||||
// set if you want memory for palette allocated and managed by vf_get_image etc.
|
||||
#define MP_IMGFLAG_RGB_PALETTE 0x800
|
||||
|
||||
#define MP_IMGFLAGMASK_COLORS 0xF00
|
||||
@ -223,6 +223,8 @@ static inline void free_mp_image(mp_image_t* mpi){
|
||||
if(mpi->flags&MP_IMGFLAG_ALLOCATED){
|
||||
/* becouse we allocate the whole image in once */
|
||||
if(mpi->planes[0]) free(mpi->planes[0]);
|
||||
if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
|
||||
free(mpi->planes[1]);
|
||||
}
|
||||
free(mpi);
|
||||
}
|
||||
|
@ -29,6 +29,10 @@ static const vd_info_t info = {
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
#if AVPALETTE_SIZE > 1024
|
||||
#error palette too large, adapt libmpcodecs/vf.c:vf_get_image
|
||||
#endif
|
||||
|
||||
#if CONFIG_XVMC
|
||||
#include "libavcodec/xvmc.h"
|
||||
#endif
|
||||
@ -533,6 +537,8 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){
|
||||
mp_msg(MSGT_DECVIDEO, MSGL_DBG2, type== MP_IMGTYPE_IPB ? "using IPB\n" : "using IP\n");
|
||||
}
|
||||
|
||||
if (ctx->best_csp == IMGFMT_RGB8 || ctx->best_csp == IMGFMT_BGR8)
|
||||
flags |= MP_IMGFLAG_RGB_PALETTE;
|
||||
mpi= mpcodecs_get_image(sh, type, flags, width, height);
|
||||
if (!mpi) return -1;
|
||||
|
||||
@ -570,10 +576,6 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){
|
||||
}
|
||||
#endif
|
||||
|
||||
// Palette support: libavcodec copies palette to *data[1]
|
||||
if (mpi->bpp == 8)
|
||||
mpi->planes[1] = av_malloc(AVPALETTE_SIZE);
|
||||
|
||||
pic->data[0]= mpi->planes[0];
|
||||
pic->data[1]= mpi->planes[1];
|
||||
pic->data[2]= mpi->planes[2];
|
||||
|
@ -333,7 +333,6 @@ static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
|
||||
if (priv->palette)
|
||||
{
|
||||
mpi->planes[1] = priv->palette;
|
||||
mpi->flags |= MP_IMGFLAG_RGB_PALETTE;
|
||||
mp_dbg(MSGT_DECVIDEO, MSGL_DBG2, "Found and copied palette\n");
|
||||
}
|
||||
else
|
||||
|
@ -329,8 +329,8 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype,
|
||||
// keep buffer allocation status & color flags only:
|
||||
// mpi->flags&=~(MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE|MP_IMGFLAG_DIRECT);
|
||||
mpi->flags&=MP_IMGFLAG_ALLOCATED|MP_IMGFLAG_TYPE_DISPLAYED|MP_IMGFLAGMASK_COLORS;
|
||||
// accept restrictions & draw_slice flags only:
|
||||
mpi->flags|=mp_imgflag&(MP_IMGFLAGMASK_RESTRICTIONS|MP_IMGFLAG_DRAW_CALLBACK);
|
||||
// accept restrictions, draw_slice and palette flags only:
|
||||
mpi->flags|=mp_imgflag&(MP_IMGFLAGMASK_RESTRICTIONS|MP_IMGFLAG_DRAW_CALLBACK|MP_IMGFLAG_RGB_PALETTE);
|
||||
if(!vf->draw_slice) mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
|
||||
if(mpi->width!=w2 || mpi->height!=h){
|
||||
// printf("vf.c: MPI parameters changed! %dx%d -> %dx%d \n", mpi->width,mpi->height,w2,h);
|
||||
@ -413,6 +413,8 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype,
|
||||
} else {
|
||||
//if(!mpi->stride[0])
|
||||
mpi->stride[0]=mpi->width*mpi->bpp/8;
|
||||
if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
|
||||
mpi->planes[1] = memalign(64, 1024);
|
||||
}
|
||||
// printf("clearing img!\n");
|
||||
vf_mpi_clear(mpi,0,0,mpi->width,mpi->height);
|
||||
|
@ -76,6 +76,7 @@ static int config(struct vf_instance* vf,
|
||||
|
||||
static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){
|
||||
mp_image_t *dmpi;
|
||||
uint8_t *old_palette = mpi->planes[1];
|
||||
|
||||
// hope we'll get DR buffer:
|
||||
dmpi=vf_get_image(vf->next,vf->priv->fmt,
|
||||
@ -152,6 +153,7 @@ static int put_image(struct vf_instance* vf, mp_image_t *mpi, double pts){
|
||||
}
|
||||
}
|
||||
}
|
||||
mpi->planes[1] = old_palette;
|
||||
|
||||
return vf_next_put_image(vf,dmpi, pts);
|
||||
}
|
||||
|
@ -219,6 +219,7 @@ while(1){
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "aviheader", stream_id);
|
||||
memcpy(&sh_audio->audio,&h,sizeof(h));
|
||||
sh_audio->stream_delay = (float)sh_audio->audio.dwStart * sh_audio->audio.dwScale/sh_audio->audio.dwRate;
|
||||
sh_audio->needs_parsing = 1;
|
||||
}
|
||||
last_fccType=h.fccType;
|
||||
last_fccHandler=h.fccHandler;
|
||||
|
@ -270,6 +270,7 @@ static void new_audio_stream(demuxer_t *demux, int aid){
|
||||
sh_audio_t* sh_a;
|
||||
new_sh_audio(demux,aid);
|
||||
sh_a = (sh_audio_t*)demux->a_streams[aid];
|
||||
sh_a->needs_parsing = 1;
|
||||
switch(aid & 0xE0){ // 1110 0000 b (high 3 bit: type low 5: id)
|
||||
case 0x00: sh_a->format=0x50;break; // mpeg
|
||||
case 0xA0: sh_a->format=0x10001;break; // dvd pcm
|
||||
|
@ -305,6 +305,7 @@ static void ts_add_stream(demuxer_t * demuxer, ES_stream_t *es)
|
||||
if(sh)
|
||||
{
|
||||
const char *lang = pid_lang_from_pmt(priv, es->pid);
|
||||
sh->needs_parsing = 1;
|
||||
sh->format = IS_AUDIO(es->type) ? es->type : es->subtype;
|
||||
sh->ds = demuxer->audio;
|
||||
|
||||
|
@ -52,6 +52,13 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// This is quite experimental, in particular it will mess up the pts values
|
||||
// in the queue - on the other hand it might fix some issues like generating
|
||||
// broken files with mencoder and stream copy.
|
||||
// Better leave it disabled for now, if we find no use for it this code should
|
||||
// just be removed again.
|
||||
#define PARSE_ON_ADD 0
|
||||
|
||||
void resync_video_stream(sh_video_t *sh_video);
|
||||
void resync_audio_stream(sh_audio_t *sh_audio);
|
||||
|
||||
@ -276,6 +283,10 @@ static void free_sh_sub(sh_sub_t *sh)
|
||||
ass_free_track(sh->ass_track);
|
||||
#endif
|
||||
free(sh->lang);
|
||||
#ifdef CONFIG_LIBAVCODEC
|
||||
av_parser_close(sh->parser);
|
||||
av_freep(&sh->avctx);
|
||||
#endif
|
||||
free(sh);
|
||||
}
|
||||
|
||||
@ -314,6 +325,10 @@ void free_sh_audio(demuxer_t *demuxer, int id)
|
||||
free(sh->wf);
|
||||
free(sh->codecdata);
|
||||
free(sh->lang);
|
||||
#ifdef CONFIG_LIBAVCODEC
|
||||
av_parser_close(sh->parser);
|
||||
av_freep(&sh->avctx);
|
||||
#endif
|
||||
free(sh);
|
||||
}
|
||||
|
||||
@ -343,6 +358,10 @@ void free_sh_video(sh_video_t *sh)
|
||||
{
|
||||
mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing sh_video at %p\n", sh);
|
||||
free(sh->bih);
|
||||
#ifdef CONFIG_LIBAVCODEC
|
||||
av_parser_close(sh->parser);
|
||||
av_freep(&sh->avctx);
|
||||
#endif
|
||||
free(sh);
|
||||
}
|
||||
|
||||
@ -396,7 +415,7 @@ void free_demuxer(demuxer_t *demuxer)
|
||||
}
|
||||
|
||||
|
||||
void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
|
||||
static void ds_add_packet_internal(demux_stream_t *ds, demux_packet_t *dp)
|
||||
{
|
||||
// append packet to DS stream:
|
||||
++ds->packs;
|
||||
@ -416,6 +435,109 @@ void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
|
||||
ds->demuxer->video->packs);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LIBAVCODEC
|
||||
static void allocate_parser(AVCodecContext **avctx, AVCodecParserContext **parser, unsigned format)
|
||||
{
|
||||
enum CodecID codec_id = CODEC_ID_NONE;
|
||||
extern int avcodec_initialized;
|
||||
if (!avcodec_initialized) {
|
||||
avcodec_init();
|
||||
avcodec_register_all();
|
||||
avcodec_initialized = 1;
|
||||
}
|
||||
switch (format) {
|
||||
case 0x2000:
|
||||
case 0x332D6361:
|
||||
case 0x332D4341:
|
||||
case MKTAG('d', 'n', 'e', 't'):
|
||||
case MKTAG('s', 'a', 'c', '3'):
|
||||
codec_id = CODEC_ID_AC3;
|
||||
break;
|
||||
case MKTAG('E', 'A', 'C', '3'):
|
||||
codec_id = CODEC_ID_EAC3;
|
||||
break;
|
||||
case 0x2001:
|
||||
case 0x86:
|
||||
codec_id = CODEC_ID_DTS;
|
||||
break;
|
||||
case 0x55:
|
||||
case 0x5500736d:
|
||||
case MKTAG('.', 'm', 'p', '3'):
|
||||
case MKTAG('M', 'P', 'E', ' '):
|
||||
case MKTAG('L', 'A', 'M', 'E'):
|
||||
codec_id = CODEC_ID_MP3;
|
||||
break;
|
||||
case 0x50:
|
||||
case MKTAG('.', 'm', 'p', '2'):
|
||||
case MKTAG('.', 'm', 'p', '1'):
|
||||
codec_id = CODEC_ID_MP2;
|
||||
break;
|
||||
}
|
||||
if (codec_id != CODEC_ID_NONE) {
|
||||
*avctx = avcodec_alloc_context();
|
||||
if (!*avctx)
|
||||
return;
|
||||
*parser = av_parser_init(codec_id);
|
||||
if (!*parser)
|
||||
av_freep(avctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_parser(sh_common_t *sh, AVCodecContext **avctx, AVCodecParserContext **parser)
|
||||
{
|
||||
*avctx = NULL;
|
||||
*parser = NULL;
|
||||
|
||||
if (!sh || !sh->needs_parsing)
|
||||
return;
|
||||
|
||||
*avctx = sh->avctx;
|
||||
*parser = sh->parser;
|
||||
if (*parser)
|
||||
return;
|
||||
|
||||
allocate_parser(avctx, parser, sh->format);
|
||||
sh->avctx = *avctx;
|
||||
sh->parser = *parser;
|
||||
}
|
||||
|
||||
int ds_parse(demux_stream_t *ds, uint8_t **buffer, int *len, double pts, off_t pos)
|
||||
{
|
||||
AVCodecContext *avctx;
|
||||
AVCodecParserContext *parser;
|
||||
get_parser(ds->sh, &avctx, &parser);
|
||||
if (!parser)
|
||||
return *len;
|
||||
return av_parser_parse2(parser, avctx, buffer, len, *buffer, *len, pts, pts, pos);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
|
||||
{
|
||||
#if PARSE_ON_ADD && defined(CONFIG_LIBAVCODEC)
|
||||
int len = dp->len;
|
||||
int pos = 0;
|
||||
while (len > 0) {
|
||||
uint8_t *parsed_start = dp->buffer + pos;
|
||||
int parsed_len = len;
|
||||
int consumed = ds_parse(ds->sh, &parsed_start, &parsed_len, dp->pts, dp->pos);
|
||||
pos += consumed;
|
||||
len -= consumed;
|
||||
if (parsed_start == dp->buffer && parsed_len == dp->len) {
|
||||
ds_add_packet_internal(ds, dp);
|
||||
} else if (parsed_len) {
|
||||
demux_packet_t *dp2 = new_demux_packet(parsed_len);
|
||||
dp2->pos = dp->pos;
|
||||
dp2->pts = dp->pts; // should be parser->pts but that works badly
|
||||
memcpy(dp2->buffer, parsed_start, parsed_len);
|
||||
ds_add_packet_internal(ds, dp2);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ds_add_packet_internal(ds, dp);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ds_read_packet(demux_stream_t *ds, stream_t *stream, int len,
|
||||
double pts, off_t pos, int flags)
|
||||
{
|
||||
@ -526,6 +648,18 @@ int ds_fill_buffer(demux_stream_t *ds)
|
||||
break;
|
||||
}
|
||||
if (!demux_fill_buffer(demux, ds)) {
|
||||
#if PARSE_ON_ADD && defined(CONFIG_LIBAVCODEC)
|
||||
uint8_t *parsed_start = NULL;
|
||||
int parsed_len = 0;
|
||||
ds_parse(ds->sh, &parsed_start, &parsed_len, MP_NOPTS_VALUE, 0);
|
||||
if (parsed_len) {
|
||||
demux_packet_t *dp2 = new_demux_packet(parsed_len);
|
||||
dp2->pts = MP_NOPTS_VALUE;
|
||||
memcpy(dp2->buffer, parsed_start, parsed_len);
|
||||
ds_add_packet_internal(ds, dp2);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
mp_dbg(MSGT_DEMUXER, MSGL_DBG2,
|
||||
"ds_fill_buffer()->demux_fill_buffer() failed\n");
|
||||
break; // EOF
|
||||
|
@ -400,6 +400,7 @@ int ds_get_packet(demux_stream_t *ds,unsigned char **start);
|
||||
int ds_get_packet_pts(demux_stream_t *ds, unsigned char **start, double *pts);
|
||||
int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start);
|
||||
double ds_get_next_pts(demux_stream_t *ds);
|
||||
int ds_parse(demux_stream_t *sh, uint8_t **buffer, int *len, double pts, off_t pos);
|
||||
|
||||
// This is defined here because demux_stream_t ins't defined in stream.h
|
||||
stream_t* new_ds_stream(demux_stream_t *ds);
|
||||
|
@ -27,6 +27,12 @@
|
||||
|
||||
/*
|
||||
* An autodetection based on the extension is not a good idea, but we don't care ;-)
|
||||
*
|
||||
* You should not add anything here where autodetection can be easily fixed except in
|
||||
* order to speed up auto-detection, in particular for formats that are often streamed.
|
||||
* In particular you should not normally add any DEMUXER_TYPE_LAVF, adding the
|
||||
* format to preferred_list in libmpdemux/demuxer_lavf.c will usually achieve
|
||||
* the same effect in a much more reliable way.
|
||||
*/
|
||||
static struct {
|
||||
const char *extension;
|
||||
@ -38,9 +44,6 @@ static struct {
|
||||
{ "vob", DEMUXER_TYPE_MPEG_PS },
|
||||
{ "m2v", DEMUXER_TYPE_MPEG_PS },
|
||||
{ "avi", DEMUXER_TYPE_AVI },
|
||||
{ "mp4", DEMUXER_TYPE_LAVF },
|
||||
{ "mov", DEMUXER_TYPE_LAVF },
|
||||
{ "qt", DEMUXER_TYPE_LAVF },
|
||||
{ "asx", DEMUXER_TYPE_ASF },
|
||||
{ "asf", DEMUXER_TYPE_ASF },
|
||||
{ "wmv", DEMUXER_TYPE_ASF },
|
||||
@ -65,7 +68,6 @@ static struct {
|
||||
{ "it", DEMUXER_TYPE_XMMS },
|
||||
{ "mid", DEMUXER_TYPE_XMMS },
|
||||
{ "midi", DEMUXER_TYPE_XMMS },
|
||||
{ "vqf", DEMUXER_TYPE_LAVF },
|
||||
{ "nsv", DEMUXER_TYPE_NSV },
|
||||
{ "nsa", DEMUXER_TYPE_NSV },
|
||||
{ "mpc", DEMUXER_TYPE_MPC },
|
||||
@ -81,6 +83,7 @@ static struct {
|
||||
{ "eac3",DEMUXER_TYPE_LAVF },
|
||||
{ "mac", DEMUXER_TYPE_LAVF },
|
||||
{ "str", DEMUXER_TYPE_LAVF },
|
||||
{ "cdg", DEMUXER_TYPE_LAVF },
|
||||
|
||||
// At least the following are hacks against broken autodetection
|
||||
// that should not be there
|
||||
|
@ -26,14 +26,32 @@ struct demuxer;
|
||||
|
||||
// Stream headers:
|
||||
|
||||
#define SH_COMMON \
|
||||
struct MPOpts *opts; \
|
||||
struct demux_stream *ds; \
|
||||
struct codecs *codec; \
|
||||
unsigned int format; \
|
||||
int initialized; \
|
||||
float stream_delay; /* number of seconds stream should be delayed (according to dwStart or similar) */ \
|
||||
/* things needed for parsing */ \
|
||||
int needs_parsing; \
|
||||
struct AVCodecContext *avctx; \
|
||||
struct AVCodecParserContext *parser; \
|
||||
/* audio: last known pts value in output from decoder \
|
||||
* video: predicted/interpolated PTS of the current frame */ \
|
||||
double pts; \
|
||||
/* codec-specific: */ \
|
||||
void* context; /* codec-specific stuff (usually HANDLE or struct pointer) */ \
|
||||
char* lang; /* track language */ \
|
||||
int default_track; \
|
||||
|
||||
typedef struct sh_common {
|
||||
SH_COMMON
|
||||
} sh_common_t;
|
||||
|
||||
typedef struct sh_audio {
|
||||
struct MPOpts *opts;
|
||||
SH_COMMON
|
||||
int aid;
|
||||
struct demux_stream *ds;
|
||||
struct codecs *codec;
|
||||
unsigned int format;
|
||||
int initialized;
|
||||
float stream_delay; // number of seconds stream should be delayed (according to dwStart or similar)
|
||||
// output format:
|
||||
int sample_format;
|
||||
int samplerate;
|
||||
@ -65,29 +83,19 @@ typedef struct sh_audio {
|
||||
AVIStreamHeader audio;
|
||||
WAVEFORMATEX* wf;
|
||||
// codec-specific:
|
||||
void* context; // codec-specific stuff (usually HANDLE or struct pointer)
|
||||
unsigned char* codecdata; // extra header data passed from demuxer to codec
|
||||
int codecdata_len;
|
||||
double pts; // last known pts value in output from decoder
|
||||
int pts_bytes; // bytes output by decoder after last known pts
|
||||
char* lang; // track language
|
||||
int default_track;
|
||||
} sh_audio_t;
|
||||
|
||||
typedef struct sh_video {
|
||||
struct MPOpts *opts;
|
||||
SH_COMMON
|
||||
int vid;
|
||||
struct demux_stream *ds;
|
||||
struct codecs *codec;
|
||||
unsigned int format;
|
||||
int initialized;
|
||||
float timer; // absolute time in video stream, since last start/seek
|
||||
float stream_delay; // number of seconds stream should be delayed (according to dwStart or similar)
|
||||
// frame counters:
|
||||
float num_frames; // number of frames played
|
||||
int num_frames_decoded; // number of frames decoded
|
||||
// timing (mostly for mpeg):
|
||||
double pts; // predicted/interpolated PTS of the current frame
|
||||
double i_pts; // PTS for the _next_ I/P frame
|
||||
float next_frame_time;
|
||||
double last_pts;
|
||||
@ -120,19 +128,15 @@ typedef struct sh_video {
|
||||
AVIStreamHeader video;
|
||||
BITMAPINFOHEADER* bih;
|
||||
void* ImageDesc; // for quicktime codecs
|
||||
// codec-specific:
|
||||
void* context; // codec-specific stuff (usually HANDLE or struct pointer)
|
||||
} sh_video_t;
|
||||
|
||||
typedef struct sh_sub {
|
||||
struct MPOpts *opts;
|
||||
SH_COMMON
|
||||
int sid;
|
||||
char type; // t = text, v = VobSub, a = SSA/ASS
|
||||
unsigned char* extradata; // extra header data passed from demuxer
|
||||
int extradata_len;
|
||||
struct ass_track *ass_track; // for SSA/ASS streams (type == 'a')
|
||||
char* lang; // track language
|
||||
int default_track;
|
||||
} sh_sub_t;
|
||||
|
||||
// demuxer.c:
|
||||
|
@ -284,8 +284,6 @@ static void clearEOSD(void) {
|
||||
eosdtex = NULL;
|
||||
}
|
||||
|
||||
static void do_render_osd(int);
|
||||
|
||||
static inline int is_tinytex(ASS_Image *i, int tinytexcur) {
|
||||
return i->w < TINYTEX_SIZE && i->h < TINYTEX_SIZE && tinytexcur < TINYTEX_MAX;
|
||||
}
|
||||
@ -649,36 +647,6 @@ static void create_osd_texture(int x0, int y0, int w, int h,
|
||||
osdtexCnt++;
|
||||
}
|
||||
|
||||
static void draw_osd(void)
|
||||
{
|
||||
if (!use_osd) return;
|
||||
if (vo_osd_changed(0)) {
|
||||
int osd_h, osd_w;
|
||||
clearOSD();
|
||||
osd_w = scaled_osd ? image_width : vo_dwidth;
|
||||
osd_h = scaled_osd ? image_height : vo_dheight;
|
||||
vo_draw_text_ext(osd_w, osd_h, ass_border_x, ass_border_y, ass_border_x, ass_border_y,
|
||||
image_width, image_height, create_osd_texture);
|
||||
}
|
||||
if (vo_doublebuffering) do_render_osd(1);
|
||||
}
|
||||
|
||||
static void do_render(void) {
|
||||
// Enable(GL_TEXTURE_2D);
|
||||
// BindTexture(GL_TEXTURE_2D, texture_id);
|
||||
|
||||
Color3f(1,1,1);
|
||||
if (image_format == IMGFMT_YV12 || custom_prog)
|
||||
glEnableYUVConversion(gl_target, yuvconvtype);
|
||||
glDrawTex(0, 0, image_width, image_height,
|
||||
0, 0, image_width, image_height,
|
||||
texture_width, texture_height,
|
||||
use_rectangle == 1, image_format == IMGFMT_YV12,
|
||||
mpi_flipped ^ vo_flipped);
|
||||
if (image_format == IMGFMT_YV12 || custom_prog)
|
||||
glDisableYUVConversion(gl_target, yuvconvtype);
|
||||
}
|
||||
|
||||
/**
|
||||
* \param type bit 0: render OSD, bit 1: render EOSD
|
||||
*/
|
||||
@ -714,6 +682,36 @@ static void do_render_osd(int type) {
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_osd(void)
|
||||
{
|
||||
if (!use_osd) return;
|
||||
if (vo_osd_changed(0)) {
|
||||
int osd_h, osd_w;
|
||||
clearOSD();
|
||||
osd_w = scaled_osd ? image_width : vo_dwidth;
|
||||
osd_h = scaled_osd ? image_height : vo_dheight;
|
||||
vo_draw_text_ext(osd_w, osd_h, ass_border_x, ass_border_y, ass_border_x, ass_border_y,
|
||||
image_width, image_height, create_osd_texture);
|
||||
}
|
||||
if (vo_doublebuffering) do_render_osd(1);
|
||||
}
|
||||
|
||||
static void do_render(void) {
|
||||
// Enable(GL_TEXTURE_2D);
|
||||
// BindTexture(GL_TEXTURE_2D, texture_id);
|
||||
|
||||
Color3f(1,1,1);
|
||||
if (image_format == IMGFMT_YV12 || custom_prog)
|
||||
glEnableYUVConversion(gl_target, yuvconvtype);
|
||||
glDrawTex(0, 0, image_width, image_height,
|
||||
0, 0, image_width, image_height,
|
||||
texture_width, texture_height,
|
||||
use_rectangle == 1, image_format == IMGFMT_YV12,
|
||||
mpi_flipped ^ vo_flipped);
|
||||
if (image_format == IMGFMT_YV12 || custom_prog)
|
||||
glDisableYUVConversion(gl_target, yuvconvtype);
|
||||
}
|
||||
|
||||
static void flip_page(void) {
|
||||
if (vo_doublebuffering) {
|
||||
if (use_glFinish) Finish();
|
||||
|
@ -707,7 +707,7 @@ void vo_x11_decoration(struct vo *vo, int d)
|
||||
}
|
||||
}
|
||||
|
||||
void vo_x11_classhint(struct vo *vo, Window window, char *name)
|
||||
void vo_x11_classhint(struct vo *vo, Window window, const char *name)
|
||||
{
|
||||
struct vo_x11_state *x11 = vo->x11;
|
||||
XClassHint wmClass;
|
||||
|
@ -110,7 +110,7 @@ struct vo_x11_state *vo_x11_init_state(void);
|
||||
int vo_init(struct vo *vo);
|
||||
void vo_uninit(struct vo_x11_state *x11);
|
||||
void vo_x11_decoration(struct vo *vo, int d );
|
||||
void vo_x11_classhint(struct vo *vo, Window window, char *name);
|
||||
void vo_x11_classhint(struct vo *vo, Window window, const char *name);
|
||||
void vo_x11_sizehint(struct vo *vo, int x, int y, int width, int height, int max);
|
||||
int vo_x11_check_events(struct vo *vo);
|
||||
void vo_x11_selectinput_witherr(Display *display, Window w, long event_mask);
|
||||
|
@ -699,6 +699,7 @@ void exit_player_with_rc(struct MPContext *mpctx, exit_reason_t how, int rc)
|
||||
|
||||
#ifdef CONFIG_ASS
|
||||
ass_library_done(ass_library);
|
||||
ass_library = NULL;
|
||||
#endif
|
||||
|
||||
current_module="exit_player";
|
||||
@ -706,13 +707,19 @@ void exit_player_with_rc(struct MPContext *mpctx, exit_reason_t how, int rc)
|
||||
// free mplayer config
|
||||
if(mpctx->mconfig)
|
||||
m_config_free(mpctx->mconfig);
|
||||
mpctx->mconfig = NULL;
|
||||
|
||||
if(mpctx->playtree_iter)
|
||||
play_tree_iter_free(mpctx->playtree_iter);
|
||||
mpctx->playtree_iter = NULL;
|
||||
if(mpctx->playtree)
|
||||
play_tree_free(mpctx->playtree, 1);
|
||||
mpctx->playtree = NULL;
|
||||
|
||||
talloc_free(mpctx->key_fifo);
|
||||
|
||||
if(edl_records != NULL) free(edl_records); // free mem allocated for EDL
|
||||
edl_records = NULL;
|
||||
switch(how) {
|
||||
case EXIT_QUIT:
|
||||
mp_tmsg(MSGT_CPLAYER,MSGL_INFO,"\nExiting... (%s)\n","Quit");
|
||||
|
200
vobsub.c
200
vobsub.c
@ -39,8 +39,9 @@ typedef struct {
|
||||
unsigned long size;
|
||||
unsigned long pos;
|
||||
} rar_stream_t;
|
||||
static rar_stream_t *
|
||||
rar_open(const char *const filename, const char *const mode)
|
||||
|
||||
static rar_stream_t *rar_open(const char *const filename,
|
||||
const char *const mode)
|
||||
{
|
||||
rar_stream_t *stream;
|
||||
/* unrar_exec can only read */
|
||||
@ -69,8 +70,7 @@ rar_open(const char *const filename, const char *const mode)
|
||||
}
|
||||
strncpy(rar_filename, filename, l);
|
||||
strcpy(rar_filename + l, ".rar");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
rar_filename = malloc(strlen(filename) + 5);
|
||||
if (rar_filename == NULL) {
|
||||
free(stream);
|
||||
@ -103,7 +103,8 @@ rar_open(const char *const filename, const char *const mode)
|
||||
if (name_len >= demanded_ext_len && !strcasecmp (lp->item.Name + name_len - demanded_ext_len, demanded_ext)) {
|
||||
rc = unrar_exec_get(&stream->data, &stream->size,
|
||||
lp->item.Name, rar_filename);
|
||||
if (rc) break;
|
||||
if (rc)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,8 +123,7 @@ rar_open(const char *const filename, const char *const mode)
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int
|
||||
rar_close(rar_stream_t *stream)
|
||||
static int rar_close(rar_stream_t *stream)
|
||||
{
|
||||
if (stream->file)
|
||||
return fclose(stream->file);
|
||||
@ -131,24 +131,21 @@ rar_close(rar_stream_t *stream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rar_eof(rar_stream_t *stream)
|
||||
static int rar_eof(rar_stream_t *stream)
|
||||
{
|
||||
if (stream->file)
|
||||
return feof(stream->file);
|
||||
return stream->pos >= stream->size;
|
||||
}
|
||||
|
||||
static long
|
||||
rar_tell(rar_stream_t *stream)
|
||||
static long rar_tell(rar_stream_t *stream)
|
||||
{
|
||||
if (stream->file)
|
||||
return ftell(stream->file);
|
||||
return stream->pos;
|
||||
}
|
||||
|
||||
static int
|
||||
rar_seek(rar_stream_t *stream, long offset, int whence)
|
||||
static int rar_seek(rar_stream_t *stream, long offset, int whence)
|
||||
{
|
||||
if (stream->file)
|
||||
return fseek(stream->file, offset, whence);
|
||||
@ -181,8 +178,7 @@ rar_seek(rar_stream_t *stream, long offset, int whence)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rar_getc(rar_stream_t *stream)
|
||||
static int rar_getc(rar_stream_t *stream)
|
||||
{
|
||||
if (stream->file)
|
||||
return getc(stream->file);
|
||||
@ -191,8 +187,8 @@ rar_getc(rar_stream_t *stream)
|
||||
return stream->data[stream->pos++];
|
||||
}
|
||||
|
||||
static size_t
|
||||
rar_read(void *ptr, size_t size, size_t nmemb, rar_stream_t *stream)
|
||||
static size_t rar_read(void *ptr, size_t size, size_t nmemb,
|
||||
rar_stream_t *stream)
|
||||
{
|
||||
size_t res;
|
||||
unsigned long remain;
|
||||
@ -223,8 +219,7 @@ typedef FILE rar_stream_t;
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
static ssize_t
|
||||
vobsub_getline(char **lineptr, size_t *n, rar_stream_t *stream)
|
||||
static ssize_t vobsub_getline(char **lineptr, size_t *n, rar_stream_t *stream)
|
||||
{
|
||||
size_t res = 0;
|
||||
int c;
|
||||
@ -232,8 +227,7 @@ vobsub_getline(char **lineptr, size_t *n, rar_stream_t *stream)
|
||||
*lineptr = malloc(4096);
|
||||
if (*lineptr)
|
||||
*n = 4096;
|
||||
}
|
||||
else if (*n == 0) {
|
||||
} else if (*n == 0) {
|
||||
char *tmp = realloc(*lineptr, 4096);
|
||||
if (tmp) {
|
||||
*lineptr = tmp;
|
||||
@ -276,8 +270,7 @@ typedef struct {
|
||||
unsigned int packet_size;
|
||||
} mpeg_t;
|
||||
|
||||
static mpeg_t *
|
||||
mpeg_open(const char *filename)
|
||||
static mpeg_t *mpeg_open(const char *filename)
|
||||
{
|
||||
mpeg_t *res = malloc(sizeof(mpeg_t));
|
||||
int err = res == NULL;
|
||||
@ -297,8 +290,7 @@ mpeg_open(const char *filename)
|
||||
return err ? NULL : res;
|
||||
}
|
||||
|
||||
static void
|
||||
mpeg_free(mpeg_t *mpeg)
|
||||
static void mpeg_free(mpeg_t *mpeg)
|
||||
{
|
||||
if (mpeg->packet)
|
||||
free(mpeg->packet);
|
||||
@ -307,20 +299,17 @@ mpeg_free(mpeg_t *mpeg)
|
||||
free(mpeg);
|
||||
}
|
||||
|
||||
static int
|
||||
mpeg_eof(mpeg_t *mpeg)
|
||||
static int mpeg_eof(mpeg_t *mpeg)
|
||||
{
|
||||
return rar_eof(mpeg->stream);
|
||||
}
|
||||
|
||||
static off_t
|
||||
mpeg_tell(mpeg_t *mpeg)
|
||||
static off_t mpeg_tell(mpeg_t *mpeg)
|
||||
{
|
||||
return rar_tell(mpeg->stream);
|
||||
}
|
||||
|
||||
static int
|
||||
mpeg_run(mpeg_t *mpeg)
|
||||
static int mpeg_run(mpeg_t *mpeg)
|
||||
{
|
||||
unsigned int len, idx, version;
|
||||
int c;
|
||||
@ -357,12 +346,10 @@ mpeg_run(mpeg_t *mpeg)
|
||||
if (version == 4) {
|
||||
if (rar_seek(mpeg->stream, 9, SEEK_CUR))
|
||||
return -1;
|
||||
}
|
||||
else if (version == 2) {
|
||||
} else if (version == 2) {
|
||||
if (rar_seek(mpeg->stream, 7, SEEK_CUR))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
abort();
|
||||
break;
|
||||
case 0xbd: /* packet */
|
||||
@ -383,12 +370,10 @@ mpeg_run(mpeg_t *mpeg)
|
||||
if ((c & 0xf0) == 0x20) { /* System-1 stream timestamp */
|
||||
/* Do we need this? */
|
||||
abort();
|
||||
}
|
||||
else if ((c & 0xf0) == 0x30) {
|
||||
} else if ((c & 0xf0) == 0x30) {
|
||||
/* Do we need this? */
|
||||
abort();
|
||||
}
|
||||
else if ((c & 0xc0) == 0x80) { /* System-2 (.VOB) stream */
|
||||
} else if ((c & 0xc0) == 0x80) { /* System-2 (.VOB) stream */
|
||||
unsigned int pts_flags, hdrlen, dataidx;
|
||||
c = rar_getc(mpeg->stream);
|
||||
if (c < 0)
|
||||
@ -411,12 +396,10 @@ mpeg_run(mpeg_t *mpeg)
|
||||
mp_msg(MSGT_VOBSUB, MSGL_ERR, "vobsub PTS error: 0x%02x %02x%02x %02x%02x \n",
|
||||
buf[0], buf[1], buf[2], buf[3], buf[4]);
|
||||
mpeg->pts = 0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
mpeg->pts = ((buf[0] & 0x0e) << 29 | buf[1] << 22 | (buf[2] & 0xfe) << 14
|
||||
| buf[3] << 7 | (buf[4] >> 1));
|
||||
}
|
||||
else /* if ((pts_flags & 0xc0) == 0xc0) */ {
|
||||
} else /* if ((pts_flags & 0xc0) == 0xc0) */ {
|
||||
/* what's this? */
|
||||
/* abort(); */
|
||||
}
|
||||
@ -463,9 +446,7 @@ mpeg_run(mpeg_t *mpeg)
|
||||
len = buf[0] << 8 | buf[1];
|
||||
if (len > 0 && rar_seek(mpeg->stream, len, SEEK_CUR))
|
||||
return -1;
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mp_msg(MSGT_VOBSUB, MSGL_ERR, "unknown header 0x%02X%02X%02X%02X\n",
|
||||
buf[0], buf[1], buf[2], buf[3]);
|
||||
return -1;
|
||||
@ -493,8 +474,7 @@ typedef struct {
|
||||
unsigned int current_index;
|
||||
} packet_queue_t;
|
||||
|
||||
static void
|
||||
packet_construct(packet_t *pkt)
|
||||
static void packet_construct(packet_t *pkt)
|
||||
{
|
||||
pkt->pts100 = 0;
|
||||
pkt->filepos = 0;
|
||||
@ -502,15 +482,13 @@ packet_construct(packet_t *pkt)
|
||||
pkt->data = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
packet_destroy(packet_t *pkt)
|
||||
static void packet_destroy(packet_t *pkt)
|
||||
{
|
||||
if (pkt->data)
|
||||
free(pkt->data);
|
||||
}
|
||||
|
||||
static void
|
||||
packet_queue_construct(packet_queue_t *queue)
|
||||
static void packet_queue_construct(packet_queue_t *queue)
|
||||
{
|
||||
queue->id = NULL;
|
||||
queue->packets = NULL;
|
||||
@ -519,8 +497,7 @@ packet_queue_construct(packet_queue_t *queue)
|
||||
queue->current_index = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
packet_queue_destroy(packet_queue_t *queue)
|
||||
static void packet_queue_destroy(packet_queue_t *queue)
|
||||
{
|
||||
if (queue->packets) {
|
||||
while (queue->packets_size--)
|
||||
@ -532,8 +509,7 @@ packet_queue_destroy(packet_queue_t *queue)
|
||||
|
||||
/* Make sure there is enough room for needed_size packets in the
|
||||
packet queue. */
|
||||
static int
|
||||
packet_queue_ensure(packet_queue_t *queue, unsigned int needed_size)
|
||||
static int packet_queue_ensure(packet_queue_t *queue, unsigned int needed_size)
|
||||
{
|
||||
if (queue->packets_reserve < needed_size) {
|
||||
if (queue->packets) {
|
||||
@ -544,8 +520,7 @@ packet_queue_ensure(packet_queue_t *queue, unsigned int needed_size)
|
||||
}
|
||||
queue->packets = tmp;
|
||||
queue->packets_reserve *= 2;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
queue->packets = malloc(sizeof(packet_t));
|
||||
if (queue->packets == NULL) {
|
||||
mp_msg(MSGT_VOBSUB, MSGL_FATAL, "malloc failure");
|
||||
@ -558,8 +533,7 @@ packet_queue_ensure(packet_queue_t *queue, unsigned int needed_size)
|
||||
}
|
||||
|
||||
/* add one more packet */
|
||||
static int
|
||||
packet_queue_grow(packet_queue_t *queue)
|
||||
static int packet_queue_grow(packet_queue_t *queue)
|
||||
{
|
||||
if (packet_queue_ensure(queue, queue->packets_size + 1) < 0)
|
||||
return -1;
|
||||
@ -569,8 +543,7 @@ packet_queue_grow(packet_queue_t *queue)
|
||||
}
|
||||
|
||||
/* insert a new packet, duplicating pts from the current one */
|
||||
static int
|
||||
packet_queue_insert(packet_queue_t *queue)
|
||||
static int packet_queue_insert(packet_queue_t *queue)
|
||||
{
|
||||
packet_t *pkts;
|
||||
if (packet_queue_ensure(queue, queue->packets_size + 1) < 0)
|
||||
@ -606,8 +579,7 @@ typedef struct {
|
||||
} vobsub_t;
|
||||
|
||||
/* Make sure that the spu stream idx exists. */
|
||||
static int
|
||||
vobsub_ensure_spu_stream(vobsub_t *vob, unsigned int index)
|
||||
static int vobsub_ensure_spu_stream(vobsub_t *vob, unsigned int index)
|
||||
{
|
||||
if (index >= vob->spu_streams_size) {
|
||||
/* This is a new stream */
|
||||
@ -618,8 +590,7 @@ vobsub_ensure_spu_stream(vobsub_t *vob, unsigned int index)
|
||||
return -1;
|
||||
}
|
||||
vob->spu_streams = tmp;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
vob->spu_streams = malloc((index + 1) * sizeof(packet_queue_t));
|
||||
if (vob->spu_streams == NULL) {
|
||||
mp_msg(MSGT_VOBSUB, MSGL_ERR, "vobsub_ensure_spu_stream: malloc failure");
|
||||
@ -634,8 +605,8 @@ vobsub_ensure_spu_stream(vobsub_t *vob, unsigned int index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vobsub_add_id(vobsub_t *vob, const char *id, size_t idlen, const unsigned int index)
|
||||
static int vobsub_add_id(vobsub_t *vob, const char *id, size_t idlen,
|
||||
const unsigned int index)
|
||||
{
|
||||
if (vobsub_ensure_spu_stream(vob, index) < 0)
|
||||
return -1;
|
||||
@ -659,8 +630,7 @@ vobsub_add_id(vobsub_t *vob, const char *id, size_t idlen, const unsigned int in
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vobsub_add_timestamp(vobsub_t *vob, off_t filepos, int ms)
|
||||
static int vobsub_add_timestamp(vobsub_t *vob, off_t filepos, int ms)
|
||||
{
|
||||
packet_queue_t *queue;
|
||||
packet_t *pkt;
|
||||
@ -678,8 +648,7 @@ vobsub_add_timestamp(vobsub_t *vob, off_t filepos, int ms)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
vobsub_parse_id(vobsub_t *vob, const char *line)
|
||||
static int vobsub_parse_id(vobsub_t *vob, const char *line)
|
||||
{
|
||||
// id: xx, index: n
|
||||
size_t idlen;
|
||||
@ -706,8 +675,7 @@ vobsub_parse_id(vobsub_t *vob, const char *line)
|
||||
return vobsub_add_id(vob, p, idlen, atoi(q));
|
||||
}
|
||||
|
||||
static int
|
||||
vobsub_parse_timestamp(vobsub_t *vob, const char *line)
|
||||
static int vobsub_parse_timestamp(vobsub_t *vob, const char *line)
|
||||
{
|
||||
// timestamp: HH:MM:SS.mmm, filepos: 0nnnnnnnnn
|
||||
const char *p;
|
||||
@ -761,8 +729,7 @@ vobsub_parse_timestamp(vobsub_t *vob, const char *line)
|
||||
return vobsub_add_timestamp(vob, filepos, vob->delay + ms + 1000 * (s + 60 * (m + 60 * h)));
|
||||
}
|
||||
|
||||
static int
|
||||
vobsub_parse_origin(vobsub_t *vob, const char *line)
|
||||
static int vobsub_parse_origin(vobsub_t *vob, const char *line)
|
||||
{
|
||||
// org: X,Y
|
||||
char *p;
|
||||
@ -805,16 +772,14 @@ unsigned int vobsub_rgb_to_yuv(unsigned int rgb)
|
||||
return y << 16 | u << 8 | v;
|
||||
}
|
||||
|
||||
static int
|
||||
vobsub_parse_delay(vobsub_t *vob, const char *line)
|
||||
static int vobsub_parse_delay(vobsub_t *vob, const char *line)
|
||||
{
|
||||
int h, m, s, ms;
|
||||
int forward = 1;
|
||||
if (*(line + 7) == '+') {
|
||||
forward = 1;
|
||||
line++;
|
||||
}
|
||||
else if (*(line + 7) == '-'){
|
||||
} else if (*(line + 7) == '-') {
|
||||
forward = -1;
|
||||
line++;
|
||||
}
|
||||
@ -831,17 +796,16 @@ vobsub_parse_delay(vobsub_t *vob, const char *line)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vobsub_set_lang(const char *line)
|
||||
static int vobsub_set_lang(const char *line)
|
||||
{
|
||||
if (vobsub_id == -1)
|
||||
vobsub_id = atoi(line + 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vobsub_parse_one_line(vobsub_t *vob, rar_stream_t *fd,
|
||||
unsigned char **extradata, unsigned int *extradata_len)
|
||||
static int vobsub_parse_one_line(vobsub_t *vob, rar_stream_t *fd,
|
||||
unsigned char **extradata,
|
||||
unsigned int *extradata_len)
|
||||
{
|
||||
ssize_t line_size;
|
||||
int res = -1;
|
||||
@ -884,8 +848,8 @@ vobsub_parse_one_line(vobsub_t *vob, rar_stream_t *fd,
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force,
|
||||
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)
|
||||
{
|
||||
vobsub_t *vob = (vobsub_t*)this;
|
||||
@ -954,8 +918,8 @@ vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsi
|
||||
return res;
|
||||
}
|
||||
|
||||
void *
|
||||
vobsub_open(const char *const name,const char *const ifo,const int force,void** spu)
|
||||
void *vobsub_open(const char *const name, const char *const ifo,
|
||||
const int force, void** spu)
|
||||
{
|
||||
unsigned char *extradata = NULL;
|
||||
unsigned int extradata_len = 0;
|
||||
@ -1007,7 +971,6 @@ vobsub_open(const char *const name,const char *const ifo,const int force,void**
|
||||
if (force)
|
||||
mp_msg(MSGT_VOBSUB, MSGL_ERR, "VobSub: Can't open SUB file\n");
|
||||
else {
|
||||
|
||||
free(buf);
|
||||
free(vob);
|
||||
return NULL;
|
||||
@ -1054,8 +1017,7 @@ vobsub_open(const char *const name,const char *const ifo,const int force,void**
|
||||
mpg->packet_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
mp_msg(MSGT_VOBSUB, MSGL_WARN, "don't know what to do with subtitle #%u\n", sid);
|
||||
}
|
||||
}
|
||||
@ -1075,8 +1037,7 @@ vobsub_open(const char *const name,const char *const ifo,const int force,void**
|
||||
return vob;
|
||||
}
|
||||
|
||||
void
|
||||
vobsub_close(void *this)
|
||||
void vobsub_close(void *this)
|
||||
{
|
||||
vobsub_t *vob = (vobsub_t *)this;
|
||||
if (vob->spu_streams) {
|
||||
@ -1087,15 +1048,13 @@ vobsub_close(void *this)
|
||||
free(vob);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
vobsub_get_indexes_count(void *vobhandle)
|
||||
unsigned int vobsub_get_indexes_count(void *vobhandle)
|
||||
{
|
||||
vobsub_t *vob = (vobsub_t *) vobhandle;
|
||||
return vob->spu_valid_streams_size;
|
||||
}
|
||||
|
||||
char *
|
||||
vobsub_get_id(void *vobhandle, unsigned int index)
|
||||
char *vobsub_get_id(void *vobhandle, unsigned int index)
|
||||
{
|
||||
vobsub_t *vob = (vobsub_t *) vobhandle;
|
||||
return (index < vob->spu_streams_size) ? vob->spu_streams[index].id : NULL;
|
||||
@ -1130,8 +1089,7 @@ int vobsub_get_index_by_id(void *vobhandle, int id)
|
||||
return j;
|
||||
}
|
||||
|
||||
int
|
||||
vobsub_set_from_lang(void *vobhandle, unsigned char * lang)
|
||||
int vobsub_set_from_lang(void *vobhandle, unsigned char * lang)
|
||||
{
|
||||
int i;
|
||||
vobsub_t *vob= (vobsub_t *) vobhandle;
|
||||
@ -1150,7 +1108,8 @@ vobsub_set_from_lang(void *vobhandle, unsigned char * lang)
|
||||
}
|
||||
|
||||
/// make sure we seek to the first packet of packets having same pts values.
|
||||
static void vobsub_queue_reseek(packet_queue_t *queue, unsigned int pts100) {
|
||||
static void vobsub_queue_reseek(packet_queue_t *queue, unsigned int pts100)
|
||||
{
|
||||
int reseek_count = 0;
|
||||
unsigned int lastpts = 0;
|
||||
|
||||
@ -1180,8 +1139,8 @@ static void vobsub_queue_reseek(packet_queue_t *queue, unsigned int pts100) {
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
vobsub_get_packet(void *vobhandle, float pts,void** data, int* timestamp) {
|
||||
int vobsub_get_packet(void *vobhandle, float pts, void** data, int* timestamp)
|
||||
{
|
||||
vobsub_t *vob = (vobsub_t *)vobhandle;
|
||||
unsigned int pts100 = 90000 * pts;
|
||||
if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) {
|
||||
@ -1197,7 +1156,8 @@ vobsub_get_packet(void *vobhandle, float pts,void** data, int* timestamp) {
|
||||
*data = pkt->data;
|
||||
*timestamp = pkt->pts100;
|
||||
return pkt->size;
|
||||
} else break;
|
||||
} else
|
||||
break;
|
||||
else
|
||||
++queue->current_index;
|
||||
}
|
||||
@ -1205,8 +1165,7 @@ vobsub_get_packet(void *vobhandle, float pts,void** data, int* timestamp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
vobsub_get_next_packet(void *vobhandle, void** data, int* timestamp)
|
||||
int vobsub_get_next_packet(void *vobhandle, void** data, int* timestamp)
|
||||
{
|
||||
vobsub_t *vob = (vobsub_t *)vobhandle;
|
||||
if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) {
|
||||
@ -1238,8 +1197,7 @@ void vobsub_seek(void * vobhandle, float pts)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vobsub_reset(void *vobhandle)
|
||||
void vobsub_reset(void *vobhandle)
|
||||
{
|
||||
vobsub_t *vob = (vobsub_t *)vobhandle;
|
||||
if (vob->spu_streams) {
|
||||
@ -1259,8 +1217,8 @@ typedef struct {
|
||||
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)
|
||||
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,
|
||||
@ -1292,8 +1250,7 @@ create_idx(vobsub_out_t *me, const unsigned int *palette, unsigned int orig_widt
|
||||
"forced subs: OFF\n");
|
||||
}
|
||||
|
||||
void *
|
||||
vobsub_out_open(const char *basename, const unsigned int *palette,
|
||||
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)
|
||||
{
|
||||
@ -1321,8 +1278,7 @@ vobsub_out_open(const char *basename, const unsigned int *palette,
|
||||
fprintf(result->fidx, "\nid: %s, index: %u\n", id ? id : "xx", index);
|
||||
/* So that we can check the file now */
|
||||
fflush(result->fidx);
|
||||
}
|
||||
else
|
||||
} else
|
||||
perror("Error: vobsub_out_open index file open failed");
|
||||
free(filename);
|
||||
}
|
||||
@ -1330,8 +1286,7 @@ vobsub_out_open(const char *basename, const unsigned int *palette,
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
vobsub_out_close(void *me)
|
||||
void vobsub_out_close(void *me)
|
||||
{
|
||||
vobsub_out_t *vob = (vobsub_out_t*)me;
|
||||
if (vob->fidx)
|
||||
@ -1341,8 +1296,8 @@ vobsub_out_close(void *me)
|
||||
free(vob);
|
||||
}
|
||||
|
||||
void
|
||||
vobsub_out_output(void *me, const unsigned char *packet, int len, double pts)
|
||||
void vobsub_out_output(void *me, const unsigned char *packet,
|
||||
int len, double pts)
|
||||
{
|
||||
static double last_pts;
|
||||
static int last_pts_set = 0;
|
||||
@ -1415,8 +1370,7 @@ vobsub_out_output(void *me, const unsigned char *packet, int len, double pts)
|
||||
datalen -= pts_len;
|
||||
pts_len = 0;
|
||||
pad_len = 0;
|
||||
}
|
||||
else if (pad_len > 6)
|
||||
} else if (pad_len > 6)
|
||||
pad_len = 0;
|
||||
datalen += pad_len;
|
||||
|
||||
@ -1455,15 +1409,13 @@ vobsub_out_output(void *me, const unsigned char *packet, int len, double pts)
|
||||
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) {
|
||||
} 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)
|
||||
} else if (remain < 0)
|
||||
fprintf(stderr,
|
||||
"\nERROR: wrong thing happenned...\n"
|
||||
" I wrote a %i data bytes spu packet and that's too long\n", len);
|
||||
|
Loading…
Reference in New Issue
Block a user