summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2009-12-30 00:53:08 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2009-12-30 00:56:10 +0200
commitd46b86bc7c39082b26ec71aa16431f3275d836ff (patch)
tree035da87ed658f7d75c0eba5a5d4de5462a4c8ddd
parenta06b32b64e91082c11f747e2910f10a4afd3dfa9 (diff)
parent3e8f2815c19703f5cb6f75db2910234d499d9676 (diff)
downloadmpv-d46b86bc7c39082b26ec71aa16431f3275d836ff.tar.bz2
mpv-d46b86bc7c39082b26ec71aa16431f3275d836ff.tar.xz
Merge svn changes up to r30136
Ignore another broken correct-pts change in 30134.
-rw-r--r--DOCS/man/en/mplayer.12
-rw-r--r--DOCS/man/zh_CN/mplayer.111
-rw-r--r--command.c68
-rw-r--r--etc/codecs.conf107
-rw-r--r--libmpcodecs/ad_ffmpeg.c15
-rw-r--r--libmpcodecs/mp_image.h4
-rw-r--r--libmpcodecs/vd_ffmpeg.c10
-rw-r--r--libmpcodecs/vd_vfw.c1
-rw-r--r--libmpcodecs/vf.c6
-rw-r--r--libmpcodecs/vf_palette.c2
-rw-r--r--libmpdemux/aviheader.c1
-rw-r--r--libmpdemux/demux_mpg.c1
-rw-r--r--libmpdemux/demux_ts.c1
-rw-r--r--libmpdemux/demuxer.c136
-rw-r--r--libmpdemux/demuxer.h1
-rw-r--r--libmpdemux/extension.c11
-rw-r--r--libmpdemux/stheader.h48
-rw-r--r--libvo/vo_gl.c62
-rw-r--r--libvo/x11_common.c2
-rw-r--r--libvo/x11_common.h2
-rw-r--r--mplayer.c7
-rw-r--r--vobsub.c1754
22 files changed, 1248 insertions, 1004 deletions
diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1
index 61d2e36adf..434f12c348 100644
--- a/DOCS/man/en/mplayer.1
+++ b/DOCS/man/en/mplayer.1
@@ -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.
diff --git a/DOCS/man/zh_CN/mplayer.1 b/DOCS/man/zh_CN/mplayer.1
index e026e4a002..c2bf86f4f3 100644
--- a/DOCS/man/zh_CN/mplayer.1
+++ b/DOCS/man/zh_CN/mplayer.1
@@ -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
diff --git a/command.c b/command.c
index 99387640a5..4e06611698 100644
--- a/command.c
+++ b/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",
diff --git a/etc/codecs.conf b/etc/codecs.conf
index 8f05bf9203..5f22c31a2d 100644
--- a/etc/codecs.conf
+++ b/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
diff --git a/libmpcodecs/ad_ffmpeg.c b/libmpcodecs/ad_ffmpeg.c
index 12bd6aef6a..217ec25ff1 100644
--- a/libmpcodecs/ad_ffmpeg.c
+++ b/libmpcodecs/ad_ffmpeg.c
@@ -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 *)
diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h
index 77ce04102a..a62f403e27 100644
--- a/libmpcodecs/mp_image.h
+++ b/libmpcodecs/mp_image.h
@@ -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);
}
diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c
index 52e11623db..a89e0a4dbe 100644
--- a/libmpcodecs/vd_ffmpeg.c
+++ b/libmpcodecs/vd_ffmpeg.c
@@ -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];
diff --git a/libmpcodecs/vd_vfw.c b/libmpcodecs/vd_vfw.c
index 197ead6bae..99b1cbeeb8 100644
--- a/libmpcodecs/vd_vfw.c
+++ b/libmpcodecs/vd_vfw.c
@@ -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
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index 5e7d1b4768..3c1c5e9538 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -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);
diff --git a/libmpcodecs/vf_palette.c b/libmpcodecs/vf_palette.c
index a867a4ce44..197a772dc9 100644
--- a/libmpcodecs/vf_palette.c
+++ b/libmpcodecs/vf_palette.c
@@ -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);
}
diff --git a/libmpdemux/aviheader.c b/libmpdemux/aviheader.c
index 230e769fe0..a57f55997e 100644
--- a/libmpdemux/aviheader.c
+++ b/libmpdemux/aviheader.c
@@ -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;
diff --git a/libmpdemux/demux_mpg.c b/libmpdemux/demux_mpg.c
index 3d74a0592b..8f6220be8f 100644
--- a/libmpdemux/demux_mpg.c
+++ b/libmpdemux/demux_mpg.c
@@ -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
diff --git a/libmpdemux/demux_ts.c b/libmpdemux/demux_ts.c
index c7966da9ba..af9e2109f4 100644
--- a/libmpdemux/demux_ts.c
+++ b/libmpdemux/demux_ts.c
@@ -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;
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index 564655609f..78c18e7640 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -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
diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h
index 44cd642ed3..5da35efa03 100644
--- a/libmpdemux/demuxer.h
+++ b/libmpdemux/demuxer.h
@@ -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);
diff --git a/libmpdemux/extension.c b/libmpdemux/extension.c
index 59d242e4dd..1d2ffb832e 100644
--- a/libmpdemux/extension.c
+++ b/libmpdemux/extension.c
@@ -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
diff --git a/libmpdemux/stheader.h b/libmpdemux/stheader.h
index 9b43f21dfd..b11b886ce1 100644
--- a/libmpdemux/stheader.h
+++ b/libmpdemux/stheader.h
@@ -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 {