MPlayer-cvslog
Threads by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
December 2009
- 10 participants
- 123 discussions
Author: reimar
Date: Wed Dec 30 13:06:09 2009
New Revision: 30142
Log:
Support 440P in scale filter.
Modified:
trunk/libmpcodecs/vf_scale.c
Modified: trunk/libmpcodecs/vf_scale.c
==============================================================================
--- trunk/libmpcodecs/vf_scale.c Wed Dec 30 13:03:53 2009 (r30141)
+++ trunk/libmpcodecs/vf_scale.c Wed Dec 30 13:06:09 2009 (r30142)
@@ -63,6 +63,7 @@ static unsigned int outfmt_list[]={
IMGFMT_NV21,
IMGFMT_YUY2,
IMGFMT_UYVY,
+ IMGFMT_440P,
// RGB and grayscale (Y8 and Y800):
IMGFMT_BGR32,
IMGFMT_RGB32,
@@ -472,6 +473,7 @@ static int query_format(struct vf_instan
case IMGFMT_444P:
case IMGFMT_422P:
case IMGFMT_411P:
+ case IMGFMT_440P:
case IMGFMT_BGR8:
case IMGFMT_RGB8:
case IMGFMT_BG4B:
1
0
Author: reimar
Date: Wed Dec 30 13:03:53 2009
New Revision: 30141
Log:
FFmpeg JPEG codecs can output 440p format.
Modified:
trunk/etc/codecs.conf
Modified: trunk/etc/codecs.conf
==============================================================================
--- trunk/etc/codecs.conf Wed Dec 30 13:03:17 2009 (r30140)
+++ trunk/etc/codecs.conf Wed Dec 30 13:03:53 2009 (r30141)
@@ -1305,6 +1305,7 @@ videocodec ffmjpeg
dll mjpeg
out 444P
out 422P
+ out 440P
out YUY2 ; queried (conversion from yuv422p)
out YV12,I420,IYUV
out BGR32 ; lossless JPEG
@@ -1319,6 +1320,7 @@ videocodec ffmjpegb
dll mjpegb
out 444P
out 422P
+ out 440P
out YUY2 ; queryed (conversion from yuv422p)
out YV12,I420,IYUV
1
0
Author: reimar
Date: Wed Dec 30 12:32:24 2009
New Revision: 30139
Log:
Support all planar YUV formats in OpenGL vos.
Modified:
trunk/libvo/gl_common.c
trunk/libvo/gl_common.h
trunk/libvo/vo_gl.c
trunk/libvo/vo_gl2.c
Modified: trunk/libvo/gl_common.c
==============================================================================
--- trunk/libvo/gl_common.c Wed Dec 30 12:08:44 2009 (r30138)
+++ trunk/libvo/gl_common.c Wed Dec 30 12:32:24 2009 (r30139)
@@ -234,6 +234,10 @@ int glFindFormat(uint32_t fmt, int *bpp,
if (!gl_format) gl_format = &dummy2;
if (!gl_type) gl_type = &dummy2;
+ // these are all the same for our purpose
+ if (mp_get_chroma_shift(fmt, NULL, NULL))
+ fmt = IMGFMT_YV12;
+
*bpp = IMGFMT_IS_BGR(fmt)?IMGFMT_BGR_DEPTH(fmt):IMGFMT_RGB_DEPTH(fmt);
*gl_texfmt = 3;
switch (fmt) {
@@ -1323,9 +1327,9 @@ static void glSetupYUVFragprog(gl_conver
add_scaler(YUV_LUM_SCALER(type), &prog_pos, &prog_remain, lum_scale_texs,
'0', 'r', rect, texw, texh, params->filter_strength);
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
- '1', 'g', rect, texw / 2, texh / 2, params->filter_strength);
+ '1', 'g', rect, params->chrom_texw, params->chrom_texh, params->filter_strength);
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
- '2', 'b', rect, texw / 2, texh / 2, params->filter_strength);
+ '2', 'b', rect, params->chrom_texw, params->chrom_texh, params->filter_strength);
get_yuv2rgb_coeffs(params, yuv2rgb);
switch (YUV_CONVERSION(type)) {
case YUV_CONVERSION_FRAGMENT:
@@ -1496,14 +1500,19 @@ void glDisableYUVConversion(GLenum targe
* \param sx width of texture in pixels
* \param sy height of texture in pixels
* \param rect_tex whether this texture uses texture_rectangle extension
- * \param is_yv12 if set, also draw the textures from units 1 and 2
+ * \param is_yv12 if != 0, also draw the textures from units 1 and 2,
+ * bits 8 - 15 and 16 - 23 specify the x and y scaling of those textures
* \param flip flip the texture upside down
* \ingroup gltexture
*/
void glDrawTex(GLfloat x, GLfloat y, GLfloat w, GLfloat h,
GLfloat tx, GLfloat ty, GLfloat tw, GLfloat th,
int sx, int sy, int rect_tex, int is_yv12, int flip) {
- GLfloat tx2 = tx / 2, ty2 = ty / 2, tw2 = tw / 2, th2 = th / 2;
+ int chroma_x_shift = (is_yv12 >> 8) & 31;
+ int chroma_y_shift = (is_yv12 >> 16) & 31;
+ GLfloat xscale = 1 << chroma_x_shift;
+ GLfloat yscale = 1 << chroma_y_shift;
+ GLfloat tx2 = tx / xscale, ty2 = ty / yscale, tw2 = tw / xscale, th2 = th / yscale;
if (!rect_tex) {
tx /= sx; ty /= sy; tw /= sx; th /= sy;
tx2 = tx, ty2 = ty, tw2 = tw, th2 = th;
Modified: trunk/libvo/gl_common.h
==============================================================================
--- trunk/libvo/gl_common.h Wed Dec 30 12:08:44 2009 (r30138)
+++ trunk/libvo/gl_common.h Wed Dec 30 12:32:24 2009 (r30139)
@@ -339,6 +339,8 @@ typedef struct {
float bgamma;
int texw;
int texh;
+ int chrom_texw;
+ int chrom_texh;
float filter_strength;
} gl_conversion_params_t;
Modified: trunk/libvo/vo_gl.c
==============================================================================
--- trunk/libvo/vo_gl.c Wed Dec 30 12:08:44 2009 (r30138)
+++ trunk/libvo/vo_gl.c Wed Dec 30 12:32:24 2009 (r30139)
@@ -93,6 +93,7 @@ static int use_ycbcr;
#define MASK_NOT_COMBINERS (~((1 << YUV_CONVERSION_NONE) | (1 << YUV_CONVERSION_COMBINERS) | (1 << YUV_CONVERSION_COMBINERS_ATI)))
#define MASK_GAMMA_SUPPORT (MASK_NOT_COMBINERS & ~(1 << YUV_CONVERSION_FRAGMENT))
static int use_yuv;
+static int is_yuv;
static int lscale;
static int cscale;
static float filter_strength;
@@ -206,6 +207,7 @@ static void texSize(int w, int h, int *t
//! maximum size of custom fragment program
#define MAX_CUSTOM_PROG_SIZE (1024 * 1024)
static void update_yuvconv(void) {
+ int xs, ys;
float bri = eq_bri / 100.0;
float cont = (eq_cont + 100) / 100.0;
float hue = eq_hue / 100.0 * 3.1415927;
@@ -215,7 +217,10 @@ static void update_yuvconv(void) {
float bgamma = exp(log(8.0) * eq_bgamma / 100.0);
gl_conversion_params_t params = {gl_target, yuvconvtype,
bri, cont, hue, sat, rgamma, ggamma, bgamma,
- texture_width, texture_height, filter_strength};
+ texture_width, texture_height, 0, 0, filter_strength};
+ mp_get_chroma_shift(image_format, &xs, &ys);
+ params.chrom_texw = params.texw >> xs;
+ params.chrom_texh = params.texh >> ys;
glSetupYUVConversion(¶ms);
if (custom_prog) {
FILE *f = fopen(custom_prog, "r");
@@ -478,8 +483,10 @@ static int initGl(uint32_t d_width, uint
mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",
texture_width, texture_height);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
int i;
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
GenTextures(21, default_texs);
default_texs[21] = 0;
for (i = 0; i < 7; i++) {
@@ -490,18 +497,18 @@ static int initGl(uint32_t d_width, uint
}
ActiveTexture(GL_TEXTURE1);
glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
if (mipmap_gen)
TexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE);
ActiveTexture(GL_TEXTURE2);
glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
if (mipmap_gen)
TexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE);
ActiveTexture(GL_TEXTURE0);
BindTexture(gl_target, 0);
}
- if (image_format == IMGFMT_YV12 || custom_prog)
+ if (is_yuv || custom_prog)
{
if ((MASK_NOT_COMBINERS & (1 << use_yuv)) || custom_prog) {
if (!GenPrograms || !BindProgram) {
@@ -533,9 +540,12 @@ static int initGl(uint32_t d_width, uint
static int
config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
{
+ int xs, ys;
image_height = height;
image_width = width;
image_format = format;
+ is_yuv = mp_get_chroma_shift(image_format, &xs, &ys) > 0;
+ is_yuv |= (xs << 8) | (ys << 16);
glFindFormat(format, NULL, &gl_texfmt, &gl_format, &gl_type);
int_pause = 0;
@@ -712,14 +722,14 @@ static void do_render(void) {
// BindTexture(GL_TEXTURE_2D, texture_id);
Color3f(1,1,1);
- if (image_format == IMGFMT_YV12 || custom_prog)
+ if (is_yuv || 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,
+ use_rectangle == 1, is_yuv,
mpi_flipped ^ vo_flipped);
- if (image_format == IMGFMT_YV12 || custom_prog)
+ if (is_yuv || custom_prog)
glDisableYUVConversion(gl_target, yuvconvtype);
}
@@ -748,13 +758,15 @@ static int draw_slice(uint8_t *src[], in
mpi_flipped = stride[0] < 0;
glUploadTex(gl_target, gl_format, gl_type, src[0], stride[0],
x, y, w, h, slice_height);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
ActiveTexture(GL_TEXTURE1);
glUploadTex(gl_target, gl_format, gl_type, src[1], stride[1],
- x / 2, y / 2, w / 2, h / 2, slice_height);
+ x >> xs, y >> ys, w >> xs, h >> ys, slice_height);
ActiveTexture(GL_TEXTURE2);
glUploadTex(gl_target, gl_format, gl_type, src[2], stride[2],
- x / 2, y / 2, w / 2, h / 2, slice_height);
+ x >> xs, y >> ys, w >> xs, h >> ys, slice_height);
ActiveTexture(GL_TEXTURE0);
}
return 0;
@@ -812,14 +824,16 @@ static uint32_t get_image(mp_image_t *mp
err_shown = 1;
return VO_FALSE;
}
- if (mpi->imgfmt == IMGFMT_YV12) {
- // YV12
+ if (is_yuv) {
+ // planar YUV
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
mpi->flags |= MP_IMGFLAG_COMMON_STRIDE | MP_IMGFLAG_COMMON_PLANE;
mpi->stride[0] = mpi->width;
mpi->planes[1] = mpi->planes[0] + mpi->stride[0] * mpi->height;
- mpi->stride[1] = mpi->width >> 1;
- mpi->planes[2] = mpi->planes[1] + mpi->stride[1] * (mpi->height >> 1);
- mpi->stride[2] = mpi->width >> 1;
+ mpi->stride[1] = mpi->width >> xs;
+ mpi->planes[2] = mpi->planes[1] + mpi->stride[1] * (mpi->height >> ys);
+ mpi->stride[2] = mpi->width >> xs;
if (ati_hack && !mesa_buffer) {
mpi->flags &= ~MP_IMGFLAG_COMMON_PLANE;
if (!gl_buffer_uv[0]) GenBuffers(2, gl_buffer_uv);
@@ -869,17 +883,19 @@ static uint32_t draw_image(mp_image_t *m
mpi2.flags = 0; mpi2.type = MP_IMGTYPE_TEMP;
mpi2.width = mpi2.w; mpi2.height = mpi2.h;
if (force_pbo && !(mpi->flags & MP_IMGFLAG_DIRECT) && !gl_bufferptr && get_image(&mpi2) == VO_TRUE) {
- int bpp = mpi->imgfmt == IMGFMT_YV12 ? 8 : mpi->bpp;
+ int bpp = is_yuv ? 8 : mpi->bpp;
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
memcpy_pic(mpi2.planes[0], mpi->planes[0], mpi->w * bpp / 8, mpi->h, mpi2.stride[0], mpi->stride[0]);
- if (mpi->imgfmt == IMGFMT_YV12) {
- memcpy_pic(mpi2.planes[1], mpi->planes[1], mpi->w >> 1, mpi->h >> 1, mpi2.stride[1], mpi->stride[1]);
- memcpy_pic(mpi2.planes[2], mpi->planes[2], mpi->w >> 1, mpi->h >> 1, mpi2.stride[2], mpi->stride[2]);
+ if (is_yuv) {
+ memcpy_pic(mpi2.planes[1], mpi->planes[1], mpi->w >> xs, mpi->h >> ys, mpi2.stride[1], mpi->stride[1]);
+ memcpy_pic(mpi2.planes[2], mpi->planes[2], mpi->w >> xs, mpi->h >> ys, mpi2.stride[2], mpi->stride[2]);
}
if (ati_hack) { // since we have to do a full upload we need to clear the borders
clear_border(mpi2.planes[0], mpi->w * bpp / 8, mpi2.stride[0], mpi->h, mpi2.height, 0);
- if (mpi->imgfmt == IMGFMT_YV12) {
- clear_border(mpi2.planes[1], mpi->w >> 1, mpi2.stride[1], mpi->h >> 1, mpi2.height >> 1, 128);
- clear_border(mpi2.planes[2], mpi->w >> 1, mpi2.stride[2], mpi->h >> 1, mpi2.height >> 1, 128);
+ if (is_yuv) {
+ clear_border(mpi2.planes[1], mpi->w >> xs, mpi2.stride[1], mpi->h >> ys, mpi2.height >> ys, 128);
+ clear_border(mpi2.planes[2], mpi->w >> xs, mpi2.stride[2], mpi->h >> ys, mpi2.height >> ys, 128);
}
}
mpi = &mpi2;
@@ -909,7 +925,9 @@ static uint32_t draw_image(mp_image_t *m
}
glUploadTex(gl_target, gl_format, gl_type, planes[0], stride[0],
mpi->x, mpi->y, w, h, slice);
- if (mpi->imgfmt == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
if ((mpi->flags & MP_IMGFLAG_DIRECT) && !(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) {
BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[0]);
UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@@ -917,7 +935,7 @@ static uint32_t draw_image(mp_image_t *m
}
ActiveTexture(GL_TEXTURE1);
glUploadTex(gl_target, gl_format, gl_type, planes[1], stride[1],
- mpi->x / 2, mpi->y / 2, w / 2, h / 2, slice);
+ mpi->x >> xs, mpi->y >> ys, w >> xs, h >> ys, slice);
if ((mpi->flags & MP_IMGFLAG_DIRECT) && !(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) {
BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[1]);
UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@@ -925,7 +943,7 @@ static uint32_t draw_image(mp_image_t *m
}
ActiveTexture(GL_TEXTURE2);
glUploadTex(gl_target, gl_format, gl_type, planes[2], stride[2],
- mpi->x / 2, mpi->y / 2, w / 2, h / 2, slice);
+ mpi->x >> xs, mpi->y >> ys, w >> xs, h >> ys, slice);
ActiveTexture(GL_TEXTURE0);
}
if (mpi->flags & MP_IMGFLAG_DIRECT) {
@@ -953,7 +971,7 @@ query_format(uint32_t format)
caps |= VFCAP_OSD | VFCAP_EOSD | (scaled_osd ? 0 : VFCAP_EOSD_UNSCALED);
if (format == IMGFMT_RGB24 || format == IMGFMT_RGBA)
return caps;
- if (use_yuv && format == IMGFMT_YV12)
+ if (use_yuv && mp_get_chroma_shift(format, NULL, NULL))
return caps;
// HACK, otherwise we get only b&w with some filters (e.g. -vf eq)
// ideally MPlayer should be fixed instead not to use Y800 when it has the choice
@@ -1184,7 +1202,7 @@ static int control(uint32_t request, voi
resize(vo_dwidth, vo_dheight);
return VO_TRUE;
case VOCTRL_GET_EQUALIZER:
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
int i;
va_list va;
int *value;
@@ -1200,7 +1218,7 @@ static int control(uint32_t request, voi
}
break;
case VOCTRL_SET_EQUALIZER:
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
int i;
va_list va;
int value;
Modified: trunk/libvo/vo_gl2.c
==============================================================================
--- trunk/libvo/vo_gl2.c Wed Dec 30 12:08:44 2009 (r30138)
+++ trunk/libvo/vo_gl2.c Wed Dec 30 12:32:24 2009 (r30139)
@@ -88,6 +88,7 @@ static int isGL12 = GL_FALSE;
static int gl_bilinear=1;
static int gl_antialias=0;
static int use_yuv;
+static int is_yuv;
static int use_glFinish;
static void (*draw_alpha_fnc)
@@ -184,7 +185,7 @@ static int initTextures(void)
s*=2;
texture_height=s;
- if (image_format != IMGFMT_YV12)
+ if (!is_yuv)
gl_internal_format = getInternalFormat();
/* Test the max texture size */
@@ -263,7 +264,7 @@ static int initTextures(void)
glGenTextures (1, &(tsq->texobj));
glBindTexture (GL_TEXTURE_2D, tsq->texobj);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
glGenTextures(2, tsq->uvtexobjs);
ActiveTexture(GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[0]);
@@ -276,13 +277,15 @@ static int initTextures(void)
texture_width, texture_height, 0);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
ActiveTexture(GL_TEXTURE1);
glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
ActiveTexture(GL_TEXTURE2);
glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
ActiveTexture(GL_TEXTURE0);
}
@@ -381,7 +384,7 @@ static void drawTextureDisplay (void)
glColor3f(1.0,1.0,1.0);
- if (image_format == IMGFMT_YV12)
+ if (is_yuv)
glEnableYUVConversion(GL_TEXTURE_2D, use_yuv);
for (y = 0; y < texnumy; y++) {
int thish = texture_height;
@@ -392,7 +395,7 @@ static void drawTextureDisplay (void)
if (x == texnumx - 1 && image_width % texture_width)
thisw = image_width % texture_width;
glBindTexture (GL_TEXTURE_2D, square->texobj);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
ActiveTexture(GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[0]);
ActiveTexture(GL_TEXTURE2);
@@ -409,11 +412,11 @@ static void drawTextureDisplay (void)
glDrawTex(square->fx, square->fy, square->fw, square->fh,
0, 0, texture_width, texture_height,
texture_width, texture_height,
- 0, image_format == IMGFMT_YV12, 0);
+ 0, is_yuv, 0);
square++;
} /* for all texnumx */
} /* for all texnumy */
- if (image_format == IMGFMT_YV12)
+ if (is_yuv)
glDisableYUVConversion(GL_TEXTURE_2D, use_yuv);
texdirty = 0;
}
@@ -565,10 +568,11 @@ static int initGl(uint32_t d_width, uint
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
glEnable (GL_TEXTURE_2D);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
gl_conversion_params_t params = {GL_TEXTURE_2D, use_yuv,
0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
- texture_width, texture_height};
+ texture_width, texture_height, 0, 0, 0};
switch (use_yuv) {
case YUV_CONVERSION_FRAGMENT_LOOKUP:
glGenTextures(1, &lookupTex);
@@ -586,6 +590,9 @@ static int initGl(uint32_t d_width, uint
BindProgram(GL_FRAGMENT_PROGRAM, fragprog);
break;
}
+ mp_get_chroma_shift(image_format, &xs, &ys);
+ params.chrom_texw = params.texw >> xs;
+ params.chrom_texh = params.texh >> ys;
glSetupYUVConversion(¶ms);
}
@@ -613,11 +620,14 @@ static int initGl(uint32_t d_width, uint
static int
config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
{
+ int xs, ys;
const unsigned char * glVersion;
image_height = height;
image_width = width;
image_format = format;
+ is_yuv = mp_get_chroma_shift(image_format, &xs, &ys) > 0;
+ is_yuv |= (xs << 8) | (ys << 16);
int_pause = 0;
@@ -750,6 +760,8 @@ static int draw_slice(uint8_t *src[], in
int rem_h = h;
struct TexSquare *texline = &texgrid[y / texture_height * texnumx];
int subtex_y = y % texture_width;
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
while (rem_h > 0) {
int rem_w = w;
struct TexSquare *tsq = &texline[x / texture_width];
@@ -769,24 +781,24 @@ static int draw_slice(uint8_t *src[], in
ActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[0]);
glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type,
- uptr, ustride, subtex_x / 2, subtex_y / 2,
- subtex_w / 2, subtex_h / 2, 0);
+ uptr, ustride, subtex_x >> xs, subtex_y >> ys,
+ subtex_w >> xs, subtex_h >> ys, 0);
ActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[1]);
glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type,
- vptr, vstride, subtex_x / 2, subtex_y / 2,
- subtex_w / 2, subtex_h / 2, 0);
+ vptr, vstride, subtex_x >> xs, subtex_y >> ys,
+ subtex_w >> xs, subtex_h >> ys, 0);
subtex_x = 0;
yptr += subtex_w;
- uptr += subtex_w / 2;
- vptr += subtex_w / 2;
+ uptr += subtex_w >> xs;
+ vptr += subtex_w >> xs;
tsq++;
rem_w -= subtex_w;
}
subtex_y = 0;
yptr += subtex_h * ystride - w;
- uptr += subtex_h / 2 * ustride - w / 2;
- vptr += subtex_h / 2 * vstride - w / 2;
+ uptr += (subtex_h >> ys) * ustride - (w >> xs);
+ vptr += (subtex_h >> ys) * vstride - (w >> xs);
texline += texnumx;
rem_h -= subtex_h;
}
@@ -797,7 +809,7 @@ static int draw_slice(uint8_t *src[], in
static int
draw_frame(uint8_t *src[])
{
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
mp_msg(MSGT_VO, MSGL_ERR, "[gl2] error: draw_frame called for YV12!\n");
return 0;
}
@@ -810,12 +822,10 @@ draw_frame(uint8_t *src[])
static int
query_format(uint32_t format)
{
+ if (use_yuv && mp_get_chroma_shift(format, NULL, NULL))
+ return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
+ VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;
switch(format) {
- case IMGFMT_YV12:
- if (use_yuv)
- return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
- VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;
- break;
#ifdef __APPLE__
case IMGFMT_RGB32:
#else
1
0
Author: reimar
Date: Wed Dec 30 12:08:44 2009
New Revision: 30138
Log:
Add a helper function to get the chroma scale shift and use to simplify mpi setup.
Modified:
trunk/libmpcodecs/img_format.c
trunk/libmpcodecs/img_format.h
trunk/libmpcodecs/mp_image.h
Modified: trunk/libmpcodecs/img_format.c
==============================================================================
--- trunk/libmpcodecs/img_format.c Tue Dec 29 23:16:28 2009 (r30137)
+++ trunk/libmpcodecs/img_format.c Wed Dec 30 12:08:44 2009 (r30138)
@@ -79,3 +79,40 @@ const char *vo_format_name(int format)
snprintf(unknown_format,20,"Unknown 0x%04x",format);
return unknown_format;
}
+
+int mp_get_chroma_shift(int format, int *x_shift, int *y_shift)
+{
+ int xs = 0, ys = 0;
+ int err = 0;
+ switch (format) {
+ case IMGFMT_I420:
+ case IMGFMT_IYUV:
+ case IMGFMT_YV12:
+ xs = 1;
+ ys = 1;
+ break;
+ case IMGFMT_IF09:
+ case IMGFMT_YVU9:
+ xs = 2;
+ ys = 2;
+ break;
+ case IMGFMT_444P:
+ xs = 0;
+ ys = 0;
+ break;
+ case IMGFMT_422P:
+ xs = 1;
+ ys = 0;
+ break;
+ case IMGFMT_411P:
+ xs = 2;
+ ys = 0;
+ break;
+ default:
+ err = 1;
+ break;
+ }
+ if (x_shift) *x_shift = xs;
+ if (y_shift) *y_shift = ys;
+ return err ? 0 : 8 + (16 >> (xs + ys));
+}
Modified: trunk/libmpcodecs/img_format.h
==============================================================================
--- trunk/libmpcodecs/img_format.h Tue Dec 29 23:16:28 2009 (r30137)
+++ trunk/libmpcodecs/img_format.h Wed Dec 30 12:08:44 2009 (r30138)
@@ -133,4 +133,11 @@ typedef struct {
const char *vo_format_name(int format);
+/**
+ * Calculates the scale shifts for the chroma planes for planar YUV
+ *
+ * \return bits-per-pixel for format if successful (i.e. format is 3 or 4-planes planar YUV), 0 otherwise
+ */
+int mp_get_chroma_shift(int format, int *x_shift, int *y_shift);
+
#endif /* MPLAYER_IMG_FORMAT_H */
Modified: trunk/libmpcodecs/mp_image.h
==============================================================================
--- trunk/libmpcodecs/mp_image.h Tue Dec 29 23:16:28 2009 (r30137)
+++ trunk/libmpcodecs/mp_image.h Wed Dec 30 12:08:44 2009 (r30138)
@@ -133,51 +133,24 @@ static inline void mp_image_setfmt(mp_im
}
mpi->flags|=MP_IMGFLAG_YUV;
mpi->num_planes=3;
+ if (mp_get_chroma_shift(out_fmt, NULL, NULL)) {
+ mpi->flags|=MP_IMGFLAG_PLANAR;
+ mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift);
+ mpi->chroma_width = mpi->width >> mpi->chroma_x_shift;
+ mpi->chroma_height = mpi->height >> mpi->chroma_y_shift;
+ }
switch(out_fmt){
case IMGFMT_I420:
case IMGFMT_IYUV:
mpi->flags|=MP_IMGFLAG_SWAPPED;
case IMGFMT_YV12:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=12;
- mpi->chroma_width=(mpi->width>>1);
- mpi->chroma_height=(mpi->height>>1);
- mpi->chroma_x_shift=1;
- mpi->chroma_y_shift=1;
return;
case IMGFMT_IF09:
mpi->num_planes=4;
case IMGFMT_YVU9:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=9;
- mpi->chroma_width=(mpi->width>>2);
- mpi->chroma_height=(mpi->height>>2);
- mpi->chroma_x_shift=2;
- mpi->chroma_y_shift=2;
- return;
case IMGFMT_444P:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=24;
- mpi->chroma_width=(mpi->width);
- mpi->chroma_height=(mpi->height);
- mpi->chroma_x_shift=0;
- mpi->chroma_y_shift=0;
- return;
case IMGFMT_422P:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=16;
- mpi->chroma_width=(mpi->width>>1);
- mpi->chroma_height=(mpi->height);
- mpi->chroma_x_shift=1;
- mpi->chroma_y_shift=0;
- return;
case IMGFMT_411P:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=12;
- mpi->chroma_width=(mpi->width>>2);
- mpi->chroma_height=(mpi->height);
- mpi->chroma_x_shift=2;
- mpi->chroma_y_shift=0;
return;
case IMGFMT_Y800:
case IMGFMT_Y8:
1
0
Author: diego
Date: Tue Dec 29 19:09:07 2009
New Revision: 30136
Log:
cosmetics: tabs to spaces, K&R function declarations, cuddle else clauses
Modified:
trunk/vobsub.c
Modified: trunk/vobsub.c
==============================================================================
--- trunk/vobsub.c Tue Dec 29 14:43:03 2009 (r30135)
+++ trunk/vobsub.c Tue Dec 29 19:09:07 2009 (r30136)
@@ -39,171 +39,167 @@ 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 */
if (strcmp("r", mode) && strcmp("rb", mode)) {
- errno = EINVAL;
- return NULL;
+ errno = EINVAL;
+ return NULL;
}
stream = malloc(sizeof(rar_stream_t));
if (stream == NULL)
- return NULL;
+ return NULL;
/* first try normal access */
stream->file = fopen(filename, mode);
if (stream->file == NULL) {
- char *rar_filename;
- const char *p;
- int rc;
- /* Guess the RAR archive filename */
- rar_filename = NULL;
- p = strrchr(filename, '.');
- if (p) {
- ptrdiff_t l = p - filename;
- rar_filename = malloc(l + 5);
- if (rar_filename == NULL) {
- free(stream);
- return NULL;
- }
- strncpy(rar_filename, filename, l);
- strcpy(rar_filename + l, ".rar");
- }
- else {
- rar_filename = malloc(strlen(filename) + 5);
- if (rar_filename == NULL) {
- free(stream);
- return NULL;
- }
- strcpy(rar_filename, filename);
- strcat(rar_filename, ".rar");
- }
- /* get rid of the path if there is any */
- if ((p = strrchr(filename, '/')) == NULL) {
- p = filename;
- } else {
- p++;
- }
- rc = unrar_exec_get(&stream->data, &stream->size, p, rar_filename);
- if (!rc) {
- /* There is no matching filename in the archive. However, sometimes
- * the files we are looking for have been given arbitrary names in the archive.
- * Let's look for a file with an exact match in the extension only. */
- int i, num_files, name_len;
- ArchiveList_struct *list, *lp;
- num_files = unrar_exec_list(rar_filename, &list);
- if (num_files > 0) {
- char *demanded_ext;
- demanded_ext = strrchr (p, '.');
- if (demanded_ext) {
- int demanded_ext_len = strlen (demanded_ext);
- for (i=0, lp=list; i<num_files; i++, lp=lp->next) {
- name_len = strlen (lp->item.Name);
- 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,
+ char *rar_filename;
+ const char *p;
+ int rc;
+ /* Guess the RAR archive filename */
+ rar_filename = NULL;
+ p = strrchr(filename, '.');
+ if (p) {
+ ptrdiff_t l = p - filename;
+ rar_filename = malloc(l + 5);
+ if (rar_filename == NULL) {
+ free(stream);
+ return NULL;
+ }
+ strncpy(rar_filename, filename, l);
+ strcpy(rar_filename + l, ".rar");
+ } else {
+ rar_filename = malloc(strlen(filename) + 5);
+ if (rar_filename == NULL) {
+ free(stream);
+ return NULL;
+ }
+ strcpy(rar_filename, filename);
+ strcat(rar_filename, ".rar");
+ }
+ /* get rid of the path if there is any */
+ if ((p = strrchr(filename, '/')) == NULL) {
+ p = filename;
+ } else {
+ p++;
+ }
+ rc = unrar_exec_get(&stream->data, &stream->size, p, rar_filename);
+ if (!rc) {
+ /* There is no matching filename in the archive. However, sometimes
+ * the files we are looking for have been given arbitrary names in the archive.
+ * Let's look for a file with an exact match in the extension only. */
+ int i, num_files, name_len;
+ ArchiveList_struct *list, *lp;
+ num_files = unrar_exec_list(rar_filename, &list);
+ if (num_files > 0) {
+ char *demanded_ext;
+ demanded_ext = strrchr (p, '.');
+ if (demanded_ext) {
+ int demanded_ext_len = strlen (demanded_ext);
+ for (i = 0, lp = list; i < num_files; i++, lp = lp->next) {
+ name_len = strlen (lp->item.Name);
+ 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;
- }
- }
- }
- unrar_exec_freelist(list);
- }
- if (!rc) {
- free(rar_filename);
- free(stream);
- return NULL;
- }
- }
+ if (rc)
+ break;
+ }
+ }
+ }
+ unrar_exec_freelist(list);
+ }
+ if (!rc) {
+ free(rar_filename);
+ free(stream);
+ return NULL;
+ }
+ }
- free(rar_filename);
- stream->pos = 0;
+ free(rar_filename);
+ stream->pos = 0;
}
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);
+ return fclose(stream->file);
free(stream->data);
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 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 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);
+ return fseek(stream->file, offset, whence);
switch (whence) {
case SEEK_SET:
- if (offset < 0) {
- errno = EINVAL;
- return -1;
- }
- stream->pos = offset;
- break;
+ if (offset < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ stream->pos = offset;
+ break;
case SEEK_CUR:
- if (offset < 0 && stream->pos < (unsigned long) -offset) {
- errno = EINVAL;
- return -1;
- }
- stream->pos += offset;
- break;
+ if (offset < 0 && stream->pos < (unsigned long) -offset) {
+ errno = EINVAL;
+ return -1;
+ }
+ stream->pos += offset;
+ break;
case SEEK_END:
- if (offset < 0 && stream->size < (unsigned long) -offset) {
- errno = EINVAL;
- return -1;
- }
- stream->pos = stream->size + offset;
- break;
+ if (offset < 0 && stream->size < (unsigned long) -offset) {
+ errno = EINVAL;
+ return -1;
+ }
+ stream->pos = stream->size + offset;
+ break;
default:
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
}
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);
+ return getc(stream->file);
if (rar_eof(stream))
- return EOF;
+ return EOF;
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;
if (stream->file)
- return fread(ptr, size, nmemb, stream->file);
+ return fread(ptr, size, nmemb, stream->file);
if (rar_eof(stream))
- return 0;
+ return 0;
res = size * nmemb;
remain = stream->size - stream->pos;
if (res > remain)
- res = remain / size * size;
+ res = remain / size * size;
memcpy(ptr, stream->data + stream->pos, res);
stream->pos += res;
res /= size;
@@ -212,53 +208,51 @@ rar_read(void *ptr, size_t size, size_t
#else
typedef FILE rar_stream_t;
-#define rar_open fopen
-#define rar_close fclose
-#define rar_eof feof
-#define rar_tell ftell
-#define rar_seek fseek
-#define rar_getc getc
-#define rar_read fread
+#define rar_open fopen
+#define rar_close fclose
+#define rar_eof feof
+#define rar_tell ftell
+#define rar_seek fseek
+#define rar_getc getc
+#define rar_read fread
#endif
/**********************************************************************/
-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;
if (*lineptr == NULL) {
- *lineptr = malloc(4096);
- if (*lineptr)
- *n = 4096;
- }
- else if (*n == 0) {
- char *tmp = realloc(*lineptr, 4096);
- if (tmp) {
- *lineptr = tmp;
- *n = 4096;
- }
+ *lineptr = malloc(4096);
+ if (*lineptr)
+ *n = 4096;
+ } else if (*n == 0) {
+ char *tmp = realloc(*lineptr, 4096);
+ if (tmp) {
+ *lineptr = tmp;
+ *n = 4096;
+ }
}
if (*lineptr == NULL || *n == 0)
- return -1;
+ return -1;
for (c = rar_getc(stream); c != EOF; c = rar_getc(stream)) {
- if (res + 1 >= *n) {
- char *tmp = realloc(*lineptr, *n * 2);
- if (tmp == NULL)
- return -1;
- *lineptr = tmp;
- *n *= 2;
- }
- (*lineptr)[res++] = c;
- if (c == '\n') {
- (*lineptr)[res] = 0;
- return res;
- }
+ if (res + 1 >= *n) {
+ char *tmp = realloc(*lineptr, *n * 2);
+ if (tmp == NULL)
+ return -1;
+ *lineptr = tmp;
+ *n *= 2;
+ }
+ (*lineptr)[res++] = c;
+ if (c == '\n') {
+ (*lineptr)[res] = 0;
+ return res;
+ }
}
if (res == 0)
- return -1;
+ return -1;
(*lineptr)[res] = 0;
return res;
}
@@ -276,51 +270,46 @@ 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;
if (!err) {
- res->pts = 0;
- res->aid = -1;
- res->packet = NULL;
- res->packet_size = 0;
- res->packet_reserve = 0;
- res->stream = rar_open(filename, "rb");
- err = res->stream == NULL;
- if (err)
- perror("fopen Vobsub file failed");
- if (err)
- free(res);
+ res->pts = 0;
+ res->aid = -1;
+ res->packet = NULL;
+ res->packet_size = 0;
+ res->packet_reserve = 0;
+ res->stream = rar_open(filename, "rb");
+ err = res->stream == NULL;
+ if (err)
+ perror("fopen Vobsub file failed");
+ if (err)
+ free(res);
}
return err ? NULL : res;
}
-static void
-mpeg_free(mpeg_t *mpeg)
+static void mpeg_free(mpeg_t *mpeg)
{
if (mpeg->packet)
- free(mpeg->packet);
+ free(mpeg->packet);
if (mpeg->stream)
- rar_close(mpeg->stream);
+ rar_close(mpeg->stream);
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;
@@ -331,145 +320,137 @@ mpeg_run(mpeg_t *mpeg)
mpeg->aid = -1;
mpeg->packet_size = 0;
if (rar_read(buf, 4, 1, mpeg->stream) != 1)
- return -1;
+ return -1;
while (memcmp(buf, wanted, sizeof(wanted)) != 0) {
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- memmove(buf, buf + 1, 3);
- buf[3] = c;
+ c = rar_getc(mpeg->stream);
+ if (c < 0)
+ return -1;
+ memmove(buf, buf + 1, 3);
+ buf[3] = c;
}
switch (buf[3]) {
- case 0xb9: /* System End Code */
- break;
- case 0xba: /* Packet start code */
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- if ((c & 0xc0) == 0x40)
- version = 4;
- else if ((c & 0xf0) == 0x20)
- version = 2;
- else {
- mp_msg(MSGT_VOBSUB,MSGL_ERR, "VobSub: Unsupported MPEG version: 0x%02x\n", c);
- return -1;
- }
- if (version == 4) {
- if (rar_seek(mpeg->stream, 9, SEEK_CUR))
- return -1;
- }
- else if (version == 2) {
- if (rar_seek(mpeg->stream, 7, SEEK_CUR))
- return -1;
- }
- else
- abort();
- break;
- case 0xbd: /* packet */
- if (rar_read(buf, 2, 1, mpeg->stream) != 1)
- return -1;
- len = buf[0] << 8 | buf[1];
- idx = mpeg_tell(mpeg);
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- if ((c & 0xC0) == 0x40) { /* skip STD scale & size */
- if (rar_getc(mpeg->stream) < 0)
- return -1;
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- }
- if ((c & 0xf0) == 0x20) { /* System-1 stream timestamp */
- /* Do we need this? */
- abort();
- }
- else if ((c & 0xf0) == 0x30) {
- /* Do we need this? */
- abort();
- }
- else if ((c & 0xc0) == 0x80) { /* System-2 (.VOB) stream */
- unsigned int pts_flags, hdrlen, dataidx;
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- pts_flags = c;
- c = rar_getc(mpeg->stream);
- if (c < 0)
- return -1;
- hdrlen = c;
- dataidx = mpeg_tell(mpeg) + hdrlen;
- if (dataidx > idx + len) {
- mp_msg(MSGT_VOBSUB,MSGL_ERR, "Invalid header length: %d (total length: %d, idx: %d, dataidx: %d)\n",
- hdrlen, len, idx, dataidx);
- return -1;
- }
- if ((pts_flags & 0xc0) == 0x80) {
- if (rar_read(buf, 5, 1, mpeg->stream) != 1)
- return -1;
- if (!(((buf[0] & 0xf0) == 0x20) && (buf[0] & 1) && (buf[2] & 1) && (buf[4] & 1))) {
- 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
- 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) */ {
- /* what's this? */
- /* abort(); */
- }
- rar_seek(mpeg->stream, dataidx, SEEK_SET);
- mpeg->aid = rar_getc(mpeg->stream);
- if (mpeg->aid < 0) {
- mp_msg(MSGT_VOBSUB,MSGL_ERR, "Bogus aid %d\n", mpeg->aid);
- return -1;
- }
- mpeg->packet_size = len - ((unsigned int) mpeg_tell(mpeg) - idx);
- if (mpeg->packet_reserve < mpeg->packet_size) {
- if (mpeg->packet)
- free(mpeg->packet);
- mpeg->packet = malloc(mpeg->packet_size);
- if (mpeg->packet)
- mpeg->packet_reserve = mpeg->packet_size;
- }
- if (mpeg->packet == NULL) {
- mp_msg(MSGT_VOBSUB,MSGL_FATAL,"malloc failure");
- mpeg->packet_reserve = 0;
- mpeg->packet_size = 0;
- return -1;
- }
- if (rar_read(mpeg->packet, mpeg->packet_size, 1, mpeg->stream) != 1) {
- mp_msg(MSGT_VOBSUB,MSGL_ERR,"fread failure");
- mpeg->packet_size = 0;
- return -1;
- }
- idx = len;
- }
- break;
- case 0xbe: /* Padding */
- if (rar_read(buf, 2, 1, mpeg->stream) != 1)
- return -1;
- len = buf[0] << 8 | buf[1];
- if (len > 0 && rar_seek(mpeg->stream, len, SEEK_CUR))
- return -1;
- break;
+ case 0xb9: /* System End Code */
+ break;
+ case 0xba: /* Packet start code */
+ c = rar_getc(mpeg->stream);
+ if (c < 0)
+ return -1;
+ if ((c & 0xc0) == 0x40)
+ version = 4;
+ else if ((c & 0xf0) == 0x20)
+ version = 2;
+ else {
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "VobSub: Unsupported MPEG version: 0x%02x\n", c);
+ return -1;
+ }
+ if (version == 4) {
+ if (rar_seek(mpeg->stream, 9, SEEK_CUR))
+ return -1;
+ } else if (version == 2) {
+ if (rar_seek(mpeg->stream, 7, SEEK_CUR))
+ return -1;
+ } else
+ abort();
+ break;
+ case 0xbd: /* packet */
+ if (rar_read(buf, 2, 1, mpeg->stream) != 1)
+ return -1;
+ len = buf[0] << 8 | buf[1];
+ idx = mpeg_tell(mpeg);
+ c = rar_getc(mpeg->stream);
+ if (c < 0)
+ return -1;
+ if ((c & 0xC0) == 0x40) { /* skip STD scale & size */
+ if (rar_getc(mpeg->stream) < 0)
+ return -1;
+ c = rar_getc(mpeg->stream);
+ if (c < 0)
+ return -1;
+ }
+ if ((c & 0xf0) == 0x20) { /* System-1 stream timestamp */
+ /* Do we need this? */
+ abort();
+ } else if ((c & 0xf0) == 0x30) {
+ /* Do we need this? */
+ abort();
+ } else if ((c & 0xc0) == 0x80) { /* System-2 (.VOB) stream */
+ unsigned int pts_flags, hdrlen, dataidx;
+ c = rar_getc(mpeg->stream);
+ if (c < 0)
+ return -1;
+ pts_flags = c;
+ c = rar_getc(mpeg->stream);
+ if (c < 0)
+ return -1;
+ hdrlen = c;
+ dataidx = mpeg_tell(mpeg) + hdrlen;
+ if (dataidx > idx + len) {
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "Invalid header length: %d (total length: %d, idx: %d, dataidx: %d)\n",
+ hdrlen, len, idx, dataidx);
+ return -1;
+ }
+ if ((pts_flags & 0xc0) == 0x80) {
+ if (rar_read(buf, 5, 1, mpeg->stream) != 1)
+ return -1;
+ if (!(((buf[0] & 0xf0) == 0x20) && (buf[0] & 1) && (buf[2] & 1) && (buf[4] & 1))) {
+ 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
+ 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) */ {
+ /* what's this? */
+ /* abort(); */
+ }
+ rar_seek(mpeg->stream, dataidx, SEEK_SET);
+ mpeg->aid = rar_getc(mpeg->stream);
+ if (mpeg->aid < 0) {
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "Bogus aid %d\n", mpeg->aid);
+ return -1;
+ }
+ mpeg->packet_size = len - ((unsigned int) mpeg_tell(mpeg) - idx);
+ if (mpeg->packet_reserve < mpeg->packet_size) {
+ if (mpeg->packet)
+ free(mpeg->packet);
+ mpeg->packet = malloc(mpeg->packet_size);
+ if (mpeg->packet)
+ mpeg->packet_reserve = mpeg->packet_size;
+ }
+ if (mpeg->packet == NULL) {
+ mp_msg(MSGT_VOBSUB, MSGL_FATAL, "malloc failure");
+ mpeg->packet_reserve = 0;
+ mpeg->packet_size = 0;
+ return -1;
+ }
+ if (rar_read(mpeg->packet, mpeg->packet_size, 1, mpeg->stream) != 1) {
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "fread failure");
+ mpeg->packet_size = 0;
+ return -1;
+ }
+ idx = len;
+ }
+ break;
+ case 0xbe: /* Padding */
+ if (rar_read(buf, 2, 1, mpeg->stream) != 1)
+ return -1;
+ len = buf[0] << 8 | buf[1];
+ if (len > 0 && rar_seek(mpeg->stream, len, SEEK_CUR))
+ return -1;
+ break;
default:
- if (0xc0 <= buf[3] && buf[3] < 0xf0) {
- /* MPEG audio or video */
- if (rar_read(buf, 2, 1, mpeg->stream) != 1)
- return -1;
- len = buf[0] << 8 | buf[1];
- if (len > 0 && rar_seek(mpeg->stream, len, SEEK_CUR))
- return -1;
-
- }
- 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;
- }
+ if (0xc0 <= buf[3] && buf[3] < 0xf0) {
+ /* MPEG audio or video */
+ if (rar_read(buf, 2, 1, mpeg->stream) != 1)
+ return -1;
+ len = buf[0] << 8 | buf[1];
+ if (len > 0 && rar_seek(mpeg->stream, len, SEEK_CUR))
+ return -1;
+ } 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;
+ }
}
return 0;
}
@@ -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);
+ 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,66 +497,61 @@ packet_queue_construct(packet_queue_t *q
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--)
- packet_destroy(queue->packets + queue->packets_size);
- free(queue->packets);
+ while (queue->packets_size--)
+ packet_destroy(queue->packets + queue->packets_size);
+ free(queue->packets);
}
return;
}
/* 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) {
- packet_t *tmp = realloc(queue->packets, 2 * queue->packets_reserve * sizeof(packet_t));
- if (tmp == NULL) {
- mp_msg(MSGT_VOBSUB,MSGL_FATAL,"realloc failure");
- return -1;
- }
- queue->packets = tmp;
- queue->packets_reserve *= 2;
- }
- else {
- queue->packets = malloc(sizeof(packet_t));
- if (queue->packets == NULL) {
- mp_msg(MSGT_VOBSUB,MSGL_FATAL,"malloc failure");
- return -1;
- }
- queue->packets_reserve = 1;
- }
+ if (queue->packets) {
+ packet_t *tmp = realloc(queue->packets, 2 * queue->packets_reserve * sizeof(packet_t));
+ if (tmp == NULL) {
+ mp_msg(MSGT_VOBSUB, MSGL_FATAL, "realloc failure");
+ return -1;
+ }
+ queue->packets = tmp;
+ queue->packets_reserve *= 2;
+ } else {
+ queue->packets = malloc(sizeof(packet_t));
+ if (queue->packets == NULL) {
+ mp_msg(MSGT_VOBSUB, MSGL_FATAL, "malloc failure");
+ return -1;
+ }
+ queue->packets_reserve = 1;
+ }
}
return 0;
}
/* 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;
+ return -1;
packet_construct(queue->packets + queue->packets_size);
++queue->packets_size;
return 0;
}
/* 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)
- return -1;
+ return -1;
/* XXX packet_size does not reflect the real thing here, it will be updated a bit later */
memmove(queue->packets + queue->current_index + 2,
- queue->packets + queue->current_index + 1,
- sizeof(packet_t) * (queue->packets_size - queue->current_index - 1));
+ queue->packets + queue->current_index + 1,
+ sizeof(packet_t) * (queue->packets_size - queue->current_index - 1));
pkts = queue->packets + queue->current_index;
++queue->packets_size;
++queue->current_index;
@@ -606,173 +579,167 @@ 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 */
- if (vob->spu_streams) {
- packet_queue_t *tmp = realloc(vob->spu_streams, (index + 1) * sizeof(packet_queue_t));
- if (tmp == NULL) {
- mp_msg(MSGT_VOBSUB,MSGL_ERR,"vobsub_ensure_spu_stream: realloc failure");
- return -1;
- }
- vob->spu_streams = tmp;
- }
- 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");
- return -1;
- }
- }
- while (vob->spu_streams_size <= index) {
- packet_queue_construct(vob->spu_streams + vob->spu_streams_size);
- ++vob->spu_streams_size;
- }
+ /* This is a new stream */
+ if (vob->spu_streams) {
+ packet_queue_t *tmp = realloc(vob->spu_streams, (index + 1) * sizeof(packet_queue_t));
+ if (tmp == NULL) {
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "vobsub_ensure_spu_stream: realloc failure");
+ return -1;
+ }
+ vob->spu_streams = tmp;
+ } 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");
+ return -1;
+ }
+ }
+ while (vob->spu_streams_size <= index) {
+ packet_queue_construct(vob->spu_streams + vob->spu_streams_size);
+ ++vob->spu_streams_size;
+ }
}
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;
+ return -1;
if (id && idlen) {
- if (vob->spu_streams[index].id)
- free(vob->spu_streams[index].id);
- vob->spu_streams[index].id = malloc(idlen + 1);
- if (vob->spu_streams[index].id == NULL) {
- mp_msg(MSGT_VOBSUB,MSGL_FATAL,"vobsub_add_id: malloc failure");
- return -1;
- }
- vob->spu_streams[index].id[idlen] = 0;
- memcpy(vob->spu_streams[index].id, id, idlen);
+ if (vob->spu_streams[index].id)
+ free(vob->spu_streams[index].id);
+ vob->spu_streams[index].id = malloc(idlen + 1);
+ if (vob->spu_streams[index].id == NULL) {
+ mp_msg(MSGT_VOBSUB, MSGL_FATAL, "vobsub_add_id: malloc failure");
+ return -1;
+ }
+ vob->spu_streams[index].id[idlen] = 0;
+ memcpy(vob->spu_streams[index].id, id, idlen);
}
vob->spu_streams_current = index;
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VOBSUB_ID=%d\n", index);
if (id && idlen)
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VSID_%d_LANG=%s\n", index, vob->spu_streams[index].id);
- mp_msg(MSGT_VOBSUB,MSGL_V,"[vobsub] subtitle (vobsubid): %d language %s\n",
- index, vob->spu_streams[index].id);
+ mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VSID_%d_LANG=%s\n", index, vob->spu_streams[index].id);
+ mp_msg(MSGT_VOBSUB, MSGL_V, "[vobsub] subtitle (vobsubid): %d language %s\n",
+ index, vob->spu_streams[index].id);
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;
if (vob->spu_streams == 0) {
- mp_msg(MSGT_VOBSUB,MSGL_WARN,"[vobsub] warning, binning some index entries. Check your index file\n");
- return -1;
+ mp_msg(MSGT_VOBSUB, MSGL_WARN, "[vobsub] warning, binning some index entries. Check your index file\n");
+ return -1;
}
queue = vob->spu_streams + vob->spu_streams_current;
if (packet_queue_grow(queue) >= 0) {
- pkt = queue->packets + (queue->packets_size - 1);
- pkt->filepos = filepos;
- pkt->pts100 = ms < 0 ? UINT_MAX : (unsigned int)ms * 90;
- return 0;
+ pkt = queue->packets + (queue->packets_size - 1);
+ pkt->filepos = filepos;
+ pkt->pts100 = ms < 0 ? UINT_MAX : (unsigned int)ms * 90;
+ return 0;
}
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;
const char *p, *q;
p = line;
while (isspace(*p))
- ++p;
+ ++p;
q = p;
while (isalpha(*q))
- ++q;
+ ++q;
idlen = q - p;
if (idlen == 0)
- return -1;
+ return -1;
++q;
while (isspace(*q))
- ++q;
+ ++q;
if (strncmp("index:", q, 6))
- return -1;
+ return -1;
q += 6;
while (isspace(*q))
- ++q;
+ ++q;
if (!isdigit(*q))
- return -1;
+ return -1;
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;
int h, m, s, ms;
off_t filepos;
while (isspace(*line))
- ++line;
+ ++line;
p = line;
while (isdigit(*p))
- ++p;
+ ++p;
if (p - line != 2)
- return -1;
+ return -1;
h = atoi(line);
if (*p != ':')
- return -1;
+ return -1;
line = ++p;
while (isdigit(*p))
- ++p;
+ ++p;
if (p - line != 2)
- return -1;
+ return -1;
m = atoi(line);
if (*p != ':')
- return -1;
+ return -1;
line = ++p;
while (isdigit(*p))
- ++p;
+ ++p;
if (p - line != 2)
- return -1;
+ return -1;
s = atoi(line);
if (*p != ':')
- return -1;
+ return -1;
line = ++p;
while (isdigit(*p))
- ++p;
+ ++p;
if (p - line != 3)
- return -1;
+ return -1;
ms = atoi(line);
if (*p != ',')
- return -1;
+ return -1;
line = p + 1;
while (isspace(*line))
- ++line;
+ ++line;
if (strncmp("filepos:", line, 8))
- return -1;
+ return -1;
line += 8;
while (isspace(*line))
- ++line;
+ ++line;
if (! isxdigit(*line))
- return -1;
+ return -1;
filepos = strtol(line, NULL, 16);
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;
while (isspace(*line))
- ++line;
+ ++line;
if (!isdigit(*line))
- return -1;
+ return -1;
vob->origin_x = strtoul(line, &p, 10);
if (*p != ',')
- return -1;
+ return -1;
++p;
vob->origin_y = strtoul(p, NULL, 10);
return 0;
@@ -805,297 +772,289 @@ unsigned int vobsub_rgb_to_yuv(unsigned
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) == '-'){
- forward = -1;
- line++;
+ if (*(line + 7) == '+') {
+ forward = 1;
+ line++;
+ } else if (*(line + 7) == '-') {
+ forward = -1;
+ line++;
}
- mp_msg(MSGT_SPUDEC,MSGL_V, "forward=%d", forward);
+ mp_msg(MSGT_SPUDEC, MSGL_V, "forward=%d", forward);
h = atoi(line + 7);
- mp_msg(MSGT_VOBSUB,MSGL_V, "h=%d," ,h);
+ mp_msg(MSGT_VOBSUB, MSGL_V, "h=%d,", h);
m = atoi(line + 10);
- mp_msg(MSGT_VOBSUB,MSGL_V, "m=%d,", m);
+ mp_msg(MSGT_VOBSUB, MSGL_V, "m=%d,", m);
s = atoi(line + 13);
- mp_msg(MSGT_VOBSUB,MSGL_V, "s=%d,", s);
+ mp_msg(MSGT_VOBSUB, MSGL_V, "s=%d,", s);
ms = atoi(line + 16);
- mp_msg(MSGT_VOBSUB,MSGL_V, "ms=%d", ms);
+ mp_msg(MSGT_VOBSUB, MSGL_V, "ms=%d", ms);
vob->delay = (ms + 1000 * (s + 60 * (m + 60 * h))) * forward;
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;
- size_t line_reserve = 0;
- char *line = NULL;
+ size_t line_reserve = 0;
+ char *line = NULL;
do {
- line_size = vobsub_getline(&line, &line_reserve, fd);
- if (line_size < 0 || line_size > 1000000 ||
- *extradata_len+line_size > 10000000) {
- break;
- }
+ line_size = vobsub_getline(&line, &line_reserve, fd);
+ if (line_size < 0 || line_size > 1000000 ||
+ *extradata_len+line_size > 10000000) {
+ break;
+ }
- *extradata = realloc(*extradata, *extradata_len+line_size+1);
- memcpy(*extradata+*extradata_len, line, line_size);
- *extradata_len += line_size;
- (*extradata)[*extradata_len] = 0;
+ *extradata = realloc(*extradata, *extradata_len+line_size+1);
+ memcpy(*extradata+*extradata_len, line, line_size);
+ *extradata_len += line_size;
+ (*extradata)[*extradata_len] = 0;
- if (*line == 0 || *line == '\r' || *line == '\n' || *line == '#')
- continue;
- else if (strncmp("langidx:", line, 8) == 0)
- res = vobsub_set_lang(line);
- else if (strncmp("delay:", line, 6) == 0)
- res = vobsub_parse_delay(vob, line);
- else if (strncmp("id:", line, 3) == 0)
- res = vobsub_parse_id(vob, line + 3);
- else if (strncmp("org:", line, 4) == 0)
- res = vobsub_parse_origin(vob, line + 4);
- else if (strncmp("timestamp:", line, 10) == 0)
- res = vobsub_parse_timestamp(vob, line + 10);
- else {
- mp_msg(MSGT_VOBSUB,MSGL_V, "vobsub: ignoring %s", line);
- continue;
- }
- if (res < 0)
- mp_msg(MSGT_VOBSUB,MSGL_ERR, "ERROR in %s", line);
- break;
+ if (*line == 0 || *line == '\r' || *line == '\n' || *line == '#')
+ continue;
+ else if (strncmp("langidx:", line, 8) == 0)
+ res = vobsub_set_lang(line);
+ else if (strncmp("delay:", line, 6) == 0)
+ res = vobsub_parse_delay(vob, line);
+ else if (strncmp("id:", line, 3) == 0)
+ res = vobsub_parse_id(vob, line + 3);
+ else if (strncmp("org:", line, 4) == 0)
+ res = vobsub_parse_origin(vob, line + 4);
+ else if (strncmp("timestamp:", line, 10) == 0)
+ res = vobsub_parse_timestamp(vob, line + 10);
+ else {
+ mp_msg(MSGT_VOBSUB, MSGL_V, "vobsub: ignoring %s", line);
+ continue;
+ }
+ if (res < 0)
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "ERROR in %s", line);
+ break;
} while (1);
if (line)
free(line);
return res;
}
-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_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;
int res = -1;
rar_stream_t *fd = rar_open(name, "rb");
if (fd == NULL) {
if (force)
- mp_msg(MSGT_VOBSUB,MSGL_WARN, "VobSub: Can't open IFO file\n");
+ mp_msg(MSGT_VOBSUB, MSGL_WARN, "VobSub: Can't open IFO file\n");
} else {
- // parse IFO header
- unsigned char block[0x800];
- const char *const ifo_magic = "DVDVIDEO-VTS";
- if (rar_read(block, sizeof(block), 1, fd) != 1) {
- if (force)
- mp_msg(MSGT_VOBSUB,MSGL_ERR, "VobSub: Can't read IFO header\n");
- } else if (memcmp(block, ifo_magic, strlen(ifo_magic) + 1))
- mp_msg(MSGT_VOBSUB,MSGL_ERR, "VobSub: Bad magic in IFO header\n");
- else {
- unsigned long pgci_sector = block[0xcc] << 24 | block[0xcd] << 16
- | block[0xce] << 8 | block[0xcf];
- int standard = (block[0x200] & 0x30) >> 4;
- int resolution = (block[0x201] & 0x0c) >> 2;
- *height = standard ? 576 : 480;
- *width = 0;
- switch (resolution) {
- case 0x0:
- *width = 720;
- break;
- case 0x1:
- *width = 704;
- break;
- case 0x2:
- *width = 352;
- break;
- case 0x3:
- *width = 352;
- *height /= 2;
- break;
- default:
- mp_msg(MSGT_VOBSUB,MSGL_WARN,"Vobsub: Unknown resolution %d \n", resolution);
- }
- if (langid && 0 <= sid && sid < 32) {
- unsigned char *tmp = block + 0x256 + sid * 6 + 2;
- langid[0] = tmp[0];
- langid[1] = tmp[1];
- langid[2] = 0;
- }
- if (rar_seek(fd, pgci_sector * sizeof(block), SEEK_SET)
- || rar_read(block, sizeof(block), 1, fd) != 1)
- mp_msg(MSGT_VOBSUB,MSGL_ERR, "VobSub: Can't read IFO PGCI\n");
- else {
- unsigned long idx;
- unsigned long pgc_offset = block[0xc] << 24 | block[0xd] << 16
- | block[0xe] << 8 | block[0xf];
- for (idx = 0; idx < 16; ++idx) {
- unsigned char *p = block + pgc_offset + 0xa4 + 4 * idx;
- palette[idx] = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
- }
- if(vob)
- vob->have_palette = 1;
- res = 0;
- }
- }
- rar_close(fd);
+ // parse IFO header
+ unsigned char block[0x800];
+ const char *const ifo_magic = "DVDVIDEO-VTS";
+ if (rar_read(block, sizeof(block), 1, fd) != 1) {
+ if (force)
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "VobSub: Can't read IFO header\n");
+ } else if (memcmp(block, ifo_magic, strlen(ifo_magic) + 1))
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "VobSub: Bad magic in IFO header\n");
+ else {
+ unsigned long pgci_sector = block[0xcc] << 24 | block[0xcd] << 16
+ | block[0xce] << 8 | block[0xcf];
+ int standard = (block[0x200] & 0x30) >> 4;
+ int resolution = (block[0x201] & 0x0c) >> 2;
+ *height = standard ? 576 : 480;
+ *width = 0;
+ switch (resolution) {
+ case 0x0:
+ *width = 720;
+ break;
+ case 0x1:
+ *width = 704;
+ break;
+ case 0x2:
+ *width = 352;
+ break;
+ case 0x3:
+ *width = 352;
+ *height /= 2;
+ break;
+ default:
+ mp_msg(MSGT_VOBSUB, MSGL_WARN, "Vobsub: Unknown resolution %d \n", resolution);
+ }
+ if (langid && 0 <= sid && sid < 32) {
+ unsigned char *tmp = block + 0x256 + sid * 6 + 2;
+ langid[0] = tmp[0];
+ langid[1] = tmp[1];
+ langid[2] = 0;
+ }
+ if (rar_seek(fd, pgci_sector * sizeof(block), SEEK_SET)
+ || rar_read(block, sizeof(block), 1, fd) != 1)
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "VobSub: Can't read IFO PGCI\n");
+ else {
+ unsigned long idx;
+ unsigned long pgc_offset = block[0xc] << 24 | block[0xd] << 16
+ | block[0xe] << 8 | block[0xf];
+ for (idx = 0; idx < 16; ++idx) {
+ unsigned char *p = block + pgc_offset + 0xa4 + 4 * idx;
+ palette[idx] = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
+ }
+ if (vob)
+ vob->have_palette = 1;
+ res = 0;
+ }
+ }
+ rar_close(fd);
}
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;
vobsub_t *vob = calloc(1, sizeof(vobsub_t));
- if(spu)
- *spu = NULL;
+ if (spu)
+ *spu = NULL;
if (vobsubid == -2)
- vobsubid = vobsub_id;
+ vobsubid = vobsub_id;
if (vob) {
- char *buf;
- buf = malloc(strlen(name) + 5);
- if (buf) {
- rar_stream_t *fd;
- mpeg_t *mpg;
- /* read in the info file */
- if(!ifo) {
- strcpy(buf, name);
- strcat(buf, ".ifo");
- vobsub_parse_ifo(vob,buf, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force, -1, NULL);
- } else
- vobsub_parse_ifo(vob,ifo, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force, -1, NULL);
- /* read in the index */
- strcpy(buf, name);
- strcat(buf, ".idx");
- fd = rar_open(buf, "rb");
- if (fd == NULL) {
- if(force)
- mp_msg(MSGT_VOBSUB,MSGL_ERR,"VobSub: Can't open IDX file\n");
- else {
- free(buf);
- free(vob);
- return NULL;
- }
- } else {
- while (vobsub_parse_one_line(vob, fd, &extradata, &extradata_len) >= 0)
- /* NOOP */ ;
- rar_close(fd);
- }
- if (spu)
- *spu = spudec_new_scaled(vob->palette, vob->orig_frame_width, vob->orig_frame_height, extradata, extradata_len);
- if (extradata)
- free(extradata);
-
- /* read the indexed mpeg_stream */
- strcpy(buf, name);
- strcat(buf, ".sub");
- mpg = mpeg_open(buf);
- if (mpg == NULL) {
- if(force)
- mp_msg(MSGT_VOBSUB,MSGL_ERR,"VobSub: Can't open SUB file\n");
- else {
+ char *buf;
+ buf = malloc(strlen(name) + 5);
+ if (buf) {
+ rar_stream_t *fd;
+ mpeg_t *mpg;
+ /* read in the info file */
+ if (!ifo) {
+ strcpy(buf, name);
+ strcat(buf, ".ifo");
+ vobsub_parse_ifo(vob, buf, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force, -1, NULL);
+ } else
+ vobsub_parse_ifo(vob, ifo, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force, -1, NULL);
+ /* read in the index */
+ strcpy(buf, name);
+ strcat(buf, ".idx");
+ fd = rar_open(buf, "rb");
+ if (fd == NULL) {
+ if (force)
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "VobSub: Can't open IDX file\n");
+ else {
+ free(buf);
+ free(vob);
+ return NULL;
+ }
+ } else {
+ while (vobsub_parse_one_line(vob, fd, &extradata, &extradata_len) >= 0)
+ /* NOOP */ ;
+ rar_close(fd);
+ }
+ if (spu)
+ *spu = spudec_new_scaled(vob->palette, vob->orig_frame_width, vob->orig_frame_height, extradata, extradata_len);
+ if (extradata)
+ free(extradata);
- free(buf);
- free(vob);
- return NULL;
- }
- } else {
- long last_pts_diff = 0;
- while (!mpeg_eof(mpg)) {
- off_t pos = mpeg_tell(mpg);
- if (mpeg_run(mpg) < 0) {
- if (!mpeg_eof(mpg))
- mp_msg(MSGT_VOBSUB,MSGL_ERR,"VobSub: mpeg_run error\n");
- break;
- }
- if (mpg->packet_size) {
- if ((mpg->aid & 0xe0) == 0x20) {
- unsigned int sid = mpg->aid & 0x1f;
- if (vobsub_ensure_spu_stream(vob, sid) >= 0) {
- packet_queue_t *queue = vob->spu_streams + sid;
- /* get the packet to fill */
- if (queue->packets_size == 0 && packet_queue_grow(queue) < 0)
- abort();
- while (queue->current_index + 1 < queue->packets_size
- && queue->packets[queue->current_index + 1].filepos <= pos)
- ++queue->current_index;
- if (queue->current_index < queue->packets_size) {
- packet_t *pkt;
- if (queue->packets[queue->current_index].data) {
- /* insert a new packet and fix the PTS ! */
- packet_queue_insert(queue);
- queue->packets[queue->current_index].pts100 =
- mpg->pts + last_pts_diff;
- }
- pkt = queue->packets + queue->current_index;
- if (pkt->pts100 != UINT_MAX) {
- if (queue->packets_size > 1)
- last_pts_diff = pkt->pts100 - mpg->pts;
- else
- pkt->pts100 = mpg->pts;
- /* FIXME: should not use mpg_sub internal informations, make a copy */
- pkt->data = mpg->packet;
- pkt->size = mpg->packet_size;
- mpg->packet = NULL;
- mpg->packet_reserve = 0;
- mpg->packet_size = 0;
- }
- }
- }
- else
- mp_msg(MSGT_VOBSUB,MSGL_WARN, "don't know what to do with subtitle #%u\n", sid);
- }
- }
- }
- vob->spu_streams_current = vob->spu_streams_size;
- while (vob->spu_streams_current-- > 0) {
- vob->spu_streams[vob->spu_streams_current].current_index = 0;
- if (vobsubid == vob->spu_streams_current ||
- vob->spu_streams[vob->spu_streams_current].packets_size > 0)
- ++vob->spu_valid_streams_size;
- }
- mpeg_free(mpg);
- }
- free(buf);
- }
+ /* read the indexed mpeg_stream */
+ strcpy(buf, name);
+ strcat(buf, ".sub");
+ mpg = mpeg_open(buf);
+ if (mpg == NULL) {
+ if (force)
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "VobSub: Can't open SUB file\n");
+ else {
+ free(buf);
+ free(vob);
+ return NULL;
+ }
+ } else {
+ long last_pts_diff = 0;
+ while (!mpeg_eof(mpg)) {
+ off_t pos = mpeg_tell(mpg);
+ if (mpeg_run(mpg) < 0) {
+ if (!mpeg_eof(mpg))
+ mp_msg(MSGT_VOBSUB, MSGL_ERR, "VobSub: mpeg_run error\n");
+ break;
+ }
+ if (mpg->packet_size) {
+ if ((mpg->aid & 0xe0) == 0x20) {
+ unsigned int sid = mpg->aid & 0x1f;
+ if (vobsub_ensure_spu_stream(vob, sid) >= 0) {
+ packet_queue_t *queue = vob->spu_streams + sid;
+ /* get the packet to fill */
+ if (queue->packets_size == 0 && packet_queue_grow(queue) < 0)
+ abort();
+ while (queue->current_index + 1 < queue->packets_size
+ && queue->packets[queue->current_index + 1].filepos <= pos)
+ ++queue->current_index;
+ if (queue->current_index < queue->packets_size) {
+ packet_t *pkt;
+ if (queue->packets[queue->current_index].data) {
+ /* insert a new packet and fix the PTS ! */
+ packet_queue_insert(queue);
+ queue->packets[queue->current_index].pts100 =
+ mpg->pts + last_pts_diff;
+ }
+ pkt = queue->packets + queue->current_index;
+ if (pkt->pts100 != UINT_MAX) {
+ if (queue->packets_size > 1)
+ last_pts_diff = pkt->pts100 - mpg->pts;
+ else
+ pkt->pts100 = mpg->pts;
+ /* FIXME: should not use mpg_sub internal informations, make a copy */
+ pkt->data = mpg->packet;
+ pkt->size = mpg->packet_size;
+ mpg->packet = NULL;
+ mpg->packet_reserve = 0;
+ mpg->packet_size = 0;
+ }
+ }
+ } else
+ mp_msg(MSGT_VOBSUB, MSGL_WARN, "don't know what to do with subtitle #%u\n", sid);
+ }
+ }
+ }
+ vob->spu_streams_current = vob->spu_streams_size;
+ while (vob->spu_streams_current-- > 0) {
+ vob->spu_streams[vob->spu_streams_current].current_index = 0;
+ if (vobsubid == vob->spu_streams_current ||
+ vob->spu_streams[vob->spu_streams_current].packets_size > 0)
+ ++vob->spu_valid_streams_size;
+ }
+ mpeg_free(mpg);
+ }
+ free(buf);
+ }
}
return vob;
}
-void
-vobsub_close(void *this)
+void vobsub_close(void *this)
{
vobsub_t *vob = (vobsub_t *)this;
if (vob->spu_streams) {
- while (vob->spu_streams_size--)
- packet_queue_destroy(vob->spu_streams + vob->spu_streams_size);
- free(vob->spu_streams);
+ while (vob->spu_streams_size--)
+ packet_queue_destroy(vob->spu_streams + vob->spu_streams_size);
+ free(vob->spu_streams);
}
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,122 +1089,121 @@ int vobsub_get_index_by_id(void *vobhand
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;
- while(lang && strlen(lang) >= 2){
- for(i=0; i < vob->spu_streams_size; i++)
- if (vob->spu_streams[i].id)
- if ((strncmp(vob->spu_streams[i].id, lang, 2)==0)){
- vobsub_id=i;
- mp_msg(MSGT_VOBSUB, MSGL_INFO, "Selected VOBSUB language: %d language: %s\n", i, vob->spu_streams[i].id);
- return 0;
- }
- lang+=2;while (lang[0]==',' || lang[0]==' ') ++lang;
+ while (lang && strlen(lang) >= 2) {
+ for (i = 0; i < vob->spu_streams_size; i++)
+ if (vob->spu_streams[i].id)
+ if ((strncmp(vob->spu_streams[i].id, lang, 2) == 0)) {
+ vobsub_id = i;
+ mp_msg(MSGT_VOBSUB, MSGL_INFO, "Selected VOBSUB language: %d language: %s\n", i, vob->spu_streams[i].id);
+ return 0;
+ }
+ lang+=2;while (lang[0]==',' || lang[0]==' ') ++lang;
}
mp_msg(MSGT_VOBSUB, MSGL_WARN, "No matching VOBSUB language found!\n");
return -1;
}
/// 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;
if (queue->current_index > 0
- && (queue->packets[queue->current_index].pts100 == UINT_MAX
- || queue->packets[queue->current_index].pts100 > pts100)) {
+ && (queue->packets[queue->current_index].pts100 == UINT_MAX
+ || queue->packets[queue->current_index].pts100 > pts100)) {
// possible pts seek previous, try to check it.
int i = 1;
while (queue->current_index >= i
- && queue->packets[queue->current_index-i].pts100 == UINT_MAX)
+ && queue->packets[queue->current_index-i].pts100 == UINT_MAX)
++i;
if (queue->current_index >= i
- && queue->packets[queue->current_index-i].pts100 > pts100)
- // pts seek previous confirmed, reseek from beginning
- queue->current_index = 0;
+ && queue->packets[queue->current_index-i].pts100 > pts100)
+ // pts seek previous confirmed, reseek from beginning
+ queue->current_index = 0;
}
while (queue->current_index < queue->packets_size
- && queue->packets[queue->current_index].pts100 <= pts100) {
- lastpts = queue->packets[queue->current_index].pts100;
- ++queue->current_index;
- ++reseek_count;
+ && queue->packets[queue->current_index].pts100 <= pts100) {
+ lastpts = queue->packets[queue->current_index].pts100;
+ ++queue->current_index;
+ ++reseek_count;
}
while (reseek_count-- && --queue->current_index) {
- if (queue->packets[queue->current_index-1].pts100 != UINT_MAX &&
- queue->packets[queue->current_index-1].pts100 != lastpts)
- break;
+ if (queue->packets[queue->current_index-1].pts100 != UINT_MAX &&
+ queue->packets[queue->current_index-1].pts100 != lastpts)
+ break;
}
}
-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) {
- packet_queue_t *queue = vob->spu_streams + vobsub_id;
+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) {
+ packet_queue_t *queue = vob->spu_streams + vobsub_id;
- vobsub_queue_reseek(queue, pts100);
+ vobsub_queue_reseek(queue, pts100);
- while (queue->current_index < queue->packets_size) {
- packet_t *pkt = queue->packets + queue->current_index;
- if (pkt->pts100 != UINT_MAX)
- if (pkt->pts100 <= pts100) {
- ++queue->current_index;
- *data = pkt->data;
- *timestamp = pkt->pts100;
- return pkt->size;
- } else break;
- else
- ++queue->current_index;
+ while (queue->current_index < queue->packets_size) {
+ packet_t *pkt = queue->packets + queue->current_index;
+ if (pkt->pts100 != UINT_MAX)
+ if (pkt->pts100 <= pts100) {
+ ++queue->current_index;
+ *data = pkt->data;
+ *timestamp = pkt->pts100;
+ return pkt->size;
+ } else
+ break;
+ else
+ ++queue->current_index;
+ }
}
- }
- return -1;
+ 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) {
- 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;
+ vobsub_t *vob = (vobsub_t *)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;
+ return -1;
}
void vobsub_seek(void * vobhandle, float pts)
{
- vobsub_t * vob = (vobsub_t *)vobhandle;
- packet_queue_t * queue;
- int seek_pts100 = pts * 90000;
+ vobsub_t * vob = (vobsub_t *)vobhandle;
+ packet_queue_t * queue;
+ int seek_pts100 = pts * 90000;
- if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) {
- /* do not seek if we don't know the id */
- if (vobsub_get_id(vob, vobsub_id) == NULL)
- return;
- queue = vob->spu_streams + vobsub_id;
- queue->current_index = 0;
- vobsub_queue_reseek(queue, seek_pts100);
- }
+ if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) {
+ /* do not seek if we don't know the id */
+ if (vobsub_get_id(vob, vobsub_id) == NULL)
+ return;
+ queue = vob->spu_streams + vobsub_id;
+ queue->current_index = 0;
+ vobsub_queue_reseek(queue, seek_pts100);
+ }
}
-void
-vobsub_reset(void *vobhandle)
+void vobsub_reset(void *vobhandle)
{
vobsub_t *vob = (vobsub_t *)vobhandle;
if (vob->spu_streams) {
- unsigned int n = vob->spu_streams_size;
- while (n-- > 0)
- vob->spu_streams[n].current_index = 0;
+ unsigned int n = vob->spu_streams_size;
+ while (n-- > 0)
+ vob->spu_streams[n].current_index = 0;
}
}
@@ -1259,213 +1217,207 @@ 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,
- "# VobSub index file, v7 (do not modify this line!)\n"
- "#\n"
- "# Generated by MPlayer " VERSION "\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",
- orig_width, orig_height);
+ "# VobSub index file, v7 (do not modify this line!)\n"
+ "#\n"
+ "# Generated by MPlayer " VERSION "\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",
+ 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);
+ 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");
+ 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)
+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);
+ 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);
- }
+ }
+ 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)
+void vobsub_out_close(void *me)
{
vobsub_out_t *vob = (vobsub_out_t*)me;
if (vob->fidx)
- fclose(vob->fidx);
+ fclose(vob->fidx);
if (vob->fsub)
- fclose(vob->fsub);
+ fclose(vob->fsub);
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;
vobsub_out_t *vob = (vobsub_out_t*)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 overfolws 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;
+ /* 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 overfolws 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));
+ /* 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 completly 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 ommiting the PTS field */
- datalen -= pts_len;
- pts_len = 0;
- pad_len = 0;
- }
- else if (pad_len > 6)
- pad_len = 0;
- datalen += pad_len;
+ 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 completly 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 ommiting 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++ = 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;
+ *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 happenned...\n"
- " I wrote a %i data bytes spu packet and that's too long\n", 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 happenned...\n"
+ " I wrote a %i data bytes spu packet and that's too long\n", len);
}
}
3
3
Author: cehoyos
Date: Tue Dec 22 21:56:59 2009
New Revision: 30100
Log:
Do not use correct-pts by default for demuxer lavf, it breaks all PAFF files.
Modified:
trunk/libmpdemux/demux_lavf.c
Modified: trunk/libmpdemux/demux_lavf.c
==============================================================================
--- trunk/libmpdemux/demux_lavf.c Mon Dec 21 02:59:34 2009 (r30099)
+++ trunk/libmpdemux/demux_lavf.c Tue Dec 22 21:56:59 2009 (r30100)
@@ -612,8 +612,6 @@ static int demux_lavf_control(demuxer_t
lavf_priv_t *priv = demuxer->priv;
switch (cmd) {
- case DEMUXER_CTRL_CORRECT_PTS:
- return DEMUXER_CTRL_OK;
case DEMUXER_CTRL_GET_TIME_LENGTH:
if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
return DEMUXER_CTRL_DONTKNOW;
4
9
Author: cehoyos
Date: Mon Dec 28 14:49:08 2009
New Revision: 30134
Log:
Do not use correct-pts for mpeg-ts and matroska: It breaks PAFF samples.
Modified:
trunk/libmpdemux/demux_lavf.c
Modified: trunk/libmpdemux/demux_lavf.c
==============================================================================
--- trunk/libmpdemux/demux_lavf.c Mon Dec 28 14:39:26 2009 (r30133)
+++ trunk/libmpdemux/demux_lavf.c Mon Dec 28 14:49:08 2009 (r30134)
@@ -613,6 +613,9 @@ static int demux_lavf_control(demuxer_t
switch (cmd) {
case DEMUXER_CTRL_CORRECT_PTS:
+ if (!strcmp("matroska", priv->avif->name) ||
+ !strcmp("mpegts", priv->avif->name))
+ return DEMUXER_CTRL_NOTIMPL;
return DEMUXER_CTRL_OK;
case DEMUXER_CTRL_GET_TIME_LENGTH:
if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
1
0
Author: cehoyos
Date: Mon Dec 28 14:39:26 2009
New Revision: 30133
Log:
Revert r30100: It breaks some mov and asf samples.
Modified:
trunk/libmpdemux/demux_lavf.c
Modified: trunk/libmpdemux/demux_lavf.c
==============================================================================
--- trunk/libmpdemux/demux_lavf.c Mon Dec 28 13:05:20 2009 (r30132)
+++ trunk/libmpdemux/demux_lavf.c Mon Dec 28 14:39:26 2009 (r30133)
@@ -612,6 +612,8 @@ static int demux_lavf_control(demuxer_t
lavf_priv_t *priv = demuxer->priv;
switch (cmd) {
+ case DEMUXER_CTRL_CORRECT_PTS:
+ return DEMUXER_CTRL_OK;
case DEMUXER_CTRL_GET_TIME_LENGTH:
if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
return DEMUXER_CTRL_DONTKNOW;
1
0
Author: compn
Date: Sun Dec 27 21:57:03 2009
New Revision: 30131
Log:
add lavc yuv rawcodecs to codecs.conf
Modified:
trunk/etc/codecs.conf
Modified: trunk/etc/codecs.conf
==============================================================================
--- trunk/etc/codecs.conf Sun Dec 27 16:28:01 2009 (r30130)
+++ trunk/etc/codecs.conf Sun Dec 27 21:57:03 2009 (r30131)
@@ -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
1
0
r30130 - in trunk: libmpcodecs/ad_ffmpeg.c libmpdemux/aviheader.c libmpdemux/demux_mpg.c libmpdemux/demux_ts.c libmpdemux/demuxer.c libmpdemux/demuxer.h libmpdemux/stheader.h
by reimar 27 Dec '09
by reimar 27 Dec '09
27 Dec '09
Author: reimar
Date: Sun Dec 27 16:28:01 2009
New Revision: 30130
Log:
Add support for parsing audio streams (though should be easy to extend to video)
via libavcodec.
Parsing can be done at the demuxer stage (currently disabled) or at the decoder
(ad_ffmpeg, enabled).
Should allow using the libavcodec AAC, DTS, ... decoders independent of container
format.
Modified:
trunk/libmpcodecs/ad_ffmpeg.c
trunk/libmpdemux/aviheader.c
trunk/libmpdemux/demux_mpg.c
trunk/libmpdemux/demux_ts.c
trunk/libmpdemux/demuxer.c
trunk/libmpdemux/demuxer.h
trunk/libmpdemux/stheader.h
Modified: trunk/libmpcodecs/ad_ffmpeg.c
==============================================================================
--- trunk/libmpcodecs/ad_ffmpeg.c Sun Dec 27 15:42:37 2009 (r30129)
+++ trunk/libmpcodecs/ad_ffmpeg.c Sun Dec 27 16:28:01 2009 (r30130)
@@ -167,7 +167,17 @@ static int decode_audio(sh_audio_t *sh_a
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_a
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 *)
Modified: trunk/libmpdemux/aviheader.c
==============================================================================
--- trunk/libmpdemux/aviheader.c Sun Dec 27 15:42:37 2009 (r30129)
+++ trunk/libmpdemux/aviheader.c Sun Dec 27 16:28:01 2009 (r30130)
@@ -219,6 +219,7 @@ while(1){
mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "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;
Modified: trunk/libmpdemux/demux_mpg.c
==============================================================================
--- trunk/libmpdemux/demux_mpg.c Sun Dec 27 15:42:37 2009 (r30129)
+++ trunk/libmpdemux/demux_mpg.c Sun Dec 27 16:28:01 2009 (r30130)
@@ -270,6 +270,7 @@ static void new_audio_stream(demuxer_t *
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
Modified: trunk/libmpdemux/demux_ts.c
==============================================================================
--- trunk/libmpdemux/demux_ts.c Sun Dec 27 15:42:37 2009 (r30129)
+++ trunk/libmpdemux/demux_ts.c Sun Dec 27 16:28:01 2009 (r30130)
@@ -305,6 +305,7 @@ static void ts_add_stream(demuxer_t * de
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;
Modified: trunk/libmpdemux/demuxer.c
==============================================================================
--- trunk/libmpdemux/demuxer.c Sun Dec 27 15:42:37 2009 (r30129)
+++ trunk/libmpdemux/demuxer.c Sun Dec 27 16:28:01 2009 (r30130)
@@ -53,6 +53,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);
@@ -278,6 +285,10 @@ 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);
}
@@ -315,6 +326,10 @@ void free_sh_audio(demuxer_t *demuxer, i
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, d
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)
{
@@ -514,6 +636,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
Modified: trunk/libmpdemux/demuxer.h
==============================================================================
--- trunk/libmpdemux/demuxer.h Sun Dec 27 15:42:37 2009 (r30129)
+++ trunk/libmpdemux/demuxer.h Sun Dec 27 16:28:01 2009 (r30130)
@@ -382,6 +382,7 @@ int ds_get_packet(demux_stream_t *ds,uns
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);
Modified: trunk/libmpdemux/stheader.h
==============================================================================
--- trunk/libmpdemux/stheader.h Sun Dec 27 15:42:37 2009 (r30129)
+++ trunk/libmpdemux/stheader.h Sun Dec 27 16:28:01 2009 (r30130)
@@ -31,6 +31,10 @@
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; \
1
0