summaryrefslogtreecommitdiffstats
path: root/vobsub.c
diff options
context:
space:
mode:
authoratmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-07-08 21:44:51 +0000
committeratmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-07-08 21:44:51 +0000
commitf1a69972e94516389867a4daddd62e5530d08376 (patch)
tree82b72892f1b986bd1e028daacdd50261f34f7242 /vobsub.c
parent6e7e73bc904fe733ec61e310500963f00dd214cb (diff)
downloadmpv-f1a69972e94516389867a4daddd62e5530d08376.tar.bz2
mpv-f1a69972e94516389867a4daddd62e5530d08376.tar.xz
MEncoder vobsub ripping support, currently not compatible with windows vobsub, some bugs to be fixed. However it already works with mplayer, so it's a start.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6675 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'vobsub.c')
-rw-r--r--vobsub.c162
1 files changed, 156 insertions, 6 deletions
diff --git a/vobsub.c b/vobsub.c
index b573d7c264..15175d6ffa 100644
--- a/vobsub.c
+++ b/vobsub.c
@@ -14,6 +14,7 @@
#include <sys/types.h>
#include "config.h"
+#include "version.h"
#include "stream.h"
#include "vobsub.h"
@@ -229,7 +230,7 @@ mpeg_run(mpeg_t *mpeg)
}
else
mpeg->pts = ((buf[0] & 0x0e) << 29 | buf[1] << 22 | (buf[2] & 0xfe) << 14
- | buf[3] << 7 | (buf[4] >> 1)) / 900;
+ | buf[3] << 7 | (buf[4] >> 1));
}
else /* if ((pts_flags & 0xc0) == 0xc0) */ {
/* what's this? */
@@ -404,7 +405,7 @@ packet_queue_insert(packet_queue_t *queue)
}
/**********************************************************************
- * Vosub
+ * Vobsub
**********************************************************************/
typedef struct {
@@ -765,7 +766,8 @@ vobsub_parse_one_line(vobsub_t *vob, FILE *fd)
}
int
-vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force)
+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;
@@ -806,6 +808,12 @@ vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsi
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 (fseek(fd, pgci_sector * sizeof(block), SEEK_SET)
|| fread(block, sizeof(block), 1, fd) != 1)
mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't read IFO PGCI");
@@ -835,6 +843,8 @@ vobsub_open(const char *const name,const char *const ifo,const int force,void**
*spu = NULL;
if (vob) {
char *buf;
+ vob->custom = 0;
+ vob->have_palette = 0;
vob->orig_frame_width = 0;
vob->orig_frame_height = 0;
vob->spu_streams = NULL;
@@ -849,9 +859,9 @@ vobsub_open(const char *const name,const char *const ifo,const int force,void**
if(!ifo) {
strcpy(buf, name);
strcat(buf, ".ifo");
- vobsub_parse_ifo(vob,buf, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force);
+ 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);
+ 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");
@@ -917,7 +927,10 @@ vobsub_open(const char *const name,const char *const ifo,const int force,void**
mpg->pts + last_pts_diff;
}
pkt = queue->packets + queue->current_index;
- last_pts_diff = pkt->pts100 - mpg->pts;
+ 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;
@@ -983,3 +996,140 @@ vobsub_reset(void *vobhandle)
vob->spu_streams[n].current_index = 0;
}
}
+
+/**********************************************************************
+ * Vobsub output
+ **********************************************************************/
+
+typedef struct {
+ FILE *fsub;
+ FILE *fidx;
+ unsigned int aid;
+} vobsub_out_t;
+
+static void
+create_idx(vobsub_out_t *me, const unsigned int *palette, unsigned int orig_width, unsigned int orig_height)
+{
+ int i;
+ fprintf(me->fidx,
+ "# VobSub index file, v3 (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://vobsub.edensrising.com/> 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) {
+ if (i)
+ putc(',', me->fidx);
+ fprintf(me->fidx, " %06x", palette[i] & 0x00ffffff);
+ }
+ putc('\n', me->fidx);
+ }
+}
+
+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));
+ result->fsub = NULL;
+ result->fidx = NULL;
+ result->aid = 0;
+ if (result) {
+ result->aid = index;
+ strcpy(filename, basename);
+ strcat(filename, ".sub");
+ result->fsub = fopen(filename, "a");
+ if (result->fsub == NULL)
+ perror("Error: vobsub_out_open subtitle file open failed");
+ strcpy(filename, basename);
+ strcat(filename, ".idx");
+ result->fidx = fopen(filename, "a");
+ if (result->fidx) {
+ setvbuf(result->fidx, NULL, _IOLBF, 0);
+ if (ftell(result->fidx) == 0)
+ create_idx(result, palette, orig_width, orig_height);
+ fprintf(result->fidx, "\nid: %s, index: %u\n", id ? id : "xx", index);
+ }
+ else
+ perror("Error: vobsub_out_open index file open failed");
+ free(filename);
+ }
+ }
+ return result;
+}
+
+void
+vobsub_out_close(void *me)
+{
+ vobsub_out_t *vob = (vobsub_out_t*)me;
+ if (vob->fidx)
+ fclose(vob->fidx);
+ if (vob->fsub)
+ fclose(vob->fsub);
+ free(vob);
+}
+
+void
+vobsub_out_output(void *me, const unsigned char *packet, int len, double pts)
+{
+ vobsub_out_t *vob = (vobsub_out_t*)me;
+ if (vob->fsub) {
+ unsigned char buffer[2048];
+ if (vob->fidx) {
+ 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;
+ fprintf(vob->fidx, "timestamp: %02u:%02u:%02u:%03u, filepos: %09lx\n",
+ h, m, (unsigned int) s, ms, ftell(vob->fsub));
+ }
+ buffer[0] = 0;
+ buffer[1] = 0;
+ buffer[2] = 1;
+ buffer[3] = 0xbd;
+ buffer[4] = ((9 + len) >> 8) & 0xff; /* length of payload */
+ buffer[5] = (9 + len) & 0xff;
+ buffer[6] = 0x80; /* System-2 (.VOB) stream */
+ buffer[7] = 0x80; /* pts_flags */
+ buffer[8] = 5; /* hdrlen */
+ pts *= 90000;
+ buffer[9] = 0x21 | (((unsigned long)pts >> 29) & 0x0e);
+ buffer[10] = ((unsigned long)pts >> 22) & 0xff;
+ buffer[11] = 0x01 | (((unsigned long)pts >> 14) & 0xfe);
+ buffer[12] = ((unsigned long)pts >> 7) & 0xff;
+ buffer[13] = 0x01 | (((unsigned long)pts << 1) & 0xfe);
+ buffer[14] = 0x20 | vob->aid; /* aid */
+ if (fwrite(buffer, 15, 1, vob->fsub) != 1
+ || fwrite(packet, len, 1, vob->fsub) != 1)
+ perror("ERROR: vobsub write failed");
+ /* padding */
+ len = 2048 - 15 - len;
+ buffer[0] = 0x00;
+ buffer[1] = 0x00;
+ buffer[2] = 0x01;
+ buffer[3] = 0xbe;
+ buffer[4] = (len - 6) >> 8;
+ buffer[5] = (len - 6) & 0xff;
+ /* for better compression, blank this */
+ memset(buffer + 6, 0, len - 6);
+ if (fwrite(buffer, len, 1, vob->fsub) != 1)
+ perror("ERROR: vobsub padding write failed");
+ }
+}
+