Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 290759 | Differences between
and this patch

Collapse All | Expand All

(-)src/demuxers/demux_ts.c (-44 / +149 lines)
Lines 32-37 Link Here
32
 *
32
 *
33
 * Date        Author
33
 * Date        Author
34
 * ----        ------
34
 * ----        ------
35
 *
36
 *  8-Apr-2009 Petri Hintukainen <phi@sdf-eu.org>
37
 *                  - support for 192-byte packets (HDMV/BluRay)
38
 *                  - support for audio inside PES PID 0xfd (HDMV/BluRay)
35
 *
39
 *
36
 * 28-Nov-2004 Mike Lampard <mlampard>
40
 * 28-Nov-2004 Mike Lampard <mlampard>
37
 *                  - Added support for PMT sections larger than 1 ts packet 
41
 *                  - Added support for PMT sections larger than 1 ts packet 
Lines 172-180 Link Here
172
#define SYNC_BYTE   0x47
176
#define SYNC_BYTE   0x47
173
177
174
#define MIN_SYNCS 3
178
#define MIN_SYNCS 3
175
#define NPKT_PER_READ 100
179
#define NPKT_PER_READ 96  // 96*188 = 94*192
176
180
177
#define BUF_SIZE (NPKT_PER_READ * PKT_SIZE)
181
#define BUF_SIZE (NPKT_PER_READ * (PKT_SIZE + 4))
178
182
179
#define MAX_PES_BUF_SIZE 2048
183
#define MAX_PES_BUF_SIZE 2048
180
184
Lines 220-225 Link Here
220
      ISO_14496_PART10_VIDEO = 0x1b,    /* ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264) */
224
      ISO_14496_PART10_VIDEO = 0x1b,    /* ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264) */
221
      STREAM_VIDEO_MPEG = 0x80,
225
      STREAM_VIDEO_MPEG = 0x80,
222
      STREAM_AUDIO_AC3 = 0x81,
226
      STREAM_AUDIO_AC3 = 0x81,
227
      STREAM_SPU_HDMV = 0x90,
223
    } streamType;
228
    } streamType;
224
229
225
#define WRAP_THRESHOLD       270000
230
#define WRAP_THRESHOLD       270000
Lines 287-292 Link Here
287
  input_plugin_t  *input;
292
  input_plugin_t  *input;
288
293
289
  int              status;
294
  int              status;
295
296
  int              hdmv;       /* -1 = unknown, 0 = mpeg-ts, 1 = hdmv/m2ts */
297
  int              pkt_size;   /* TS packet size */
298
  int              pkt_offset; /* TS packet offset */
290
299
291
  int              blockSize;
300
  int              blockSize;
292
  int              rate;
301
  int              rate;
Lines 446-457 Link Here
446
}
455
}
447
456
448
/* Send a BUF_SPU_DVB to let xine know of that channel. */
457
/* Send a BUF_SPU_DVB to let xine know of that channel. */
449
static void demux_send_special_spu_buf( demux_ts_t *this, int spu_channel )
458
static void demux_send_special_spu_buf( demux_ts_t *this, uint32_t spu_type, int spu_channel )
450
{
459
{
451
  buf_element_t *buf;
460
  buf_element_t *buf;
452
461
453
  buf = this->video_fifo->buffer_pool_alloc( this->video_fifo );
462
  buf = this->video_fifo->buffer_pool_alloc( this->video_fifo );
454
  buf->type = BUF_SPU_DVB|spu_channel;
463
  buf->type = spu_type|spu_channel;
455
  buf->content = buf->mem;
464
  buf->content = buf->mem;
456
  buf->size = 0;
465
  buf->size = 0;
457
  this->video_fifo->put( this->video_fifo, buf );
466
  this->video_fifo->put( this->video_fifo, buf );
Lines 741-747 Link Here
741
  p += header_len + 9;
750
  p += header_len + 9;
742
  packet_len -= header_len + 3;
751
  packet_len -= header_len + 3;
743
752
744
  if (stream_id == 0xbd) {
753
  if (stream_id == 0xbd || stream_id == 0xfd /* HDMV */) {
745
754
746
    int spu_id;
755
    int spu_id;
747
      
756
      
Lines 1291-1296 Link Here
1291
      return;
1300
      return;
1292
    }
1301
    }
1293
1302
1303
#ifdef TS_PMT_LOG
1304
    printf ("demux_ts: PMT: pid: 0x%.4x stream_type: 0x%.2x info_length: %d",
1305
	    pid, stream[0], stream_info_length);
1306
    if (stream_info_length > 0) {
1307
      printf (" info: ");
1308
      int ind;
1309
      for (ind = 5; ind < coded_length; ind++)
1310
	printf ("%.2x ", stream[ind]);
1311
      for (ind = 5; ind < coded_length; ind++)
1312
	printf ("%c", stream[ind] >= 32 && stream[ind] < 127 ? stream[ind] : '.');
1313
    }
1314
    printf ("\n");
1315
#endif
1316
1294
    /*
1317
    /*
1295
     * Squirrel away the first audio and the first video stream. TBD: there
1318
     * Squirrel away the first audio and the first video stream. TBD: there
1296
     * should really be a way to select the stream of interest.
1319
     * should really be a way to select the stream of interest.
Lines 1413-1419 Link Here
1413
		lang->media_index = this->media_num;
1436
		lang->media_index = this->media_num;
1414
		this->media[this->media_num].type = no;
1437
		this->media[this->media_num].type = no;
1415
		demux_ts_pes_new(this, this->media_num, pid, this->video_fifo, stream[0]);
1438
		demux_ts_pes_new(this, this->media_num, pid, this->video_fifo, stream[0]);
1416
		demux_send_special_spu_buf( this, no );
1439
		demux_send_special_spu_buf( this, BUF_SPU_DVB, no );
1417
#ifdef TS_LOG
1440
#ifdef TS_LOG
1418
		printf("demux_ts: DVBSUB: pid 0x%.4x: %s  page %ld %ld type %2.2x\n",
1441
		printf("demux_ts: DVBSUB: pid 0x%.4x: %s  page %ld %ld type %2.2x\n",
1419
		       pid, lang->desc.lang,
1442
		       pid, lang->desc.lang,
Lines 1426-1431 Link Here
1426
      }
1449
      }
1427
      break;
1450
      break;
1428
1451
1452
    case STREAM_SPU_HDMV:
1453
      if (this->hdmv > 0) {
1454
	if (pid >= 0x1200 && pid < 0x1300) {
1455
#if 0 /* disabled: no HDMV SPU decoder yet */
1456
	  /* HDMV Presentation Graphics / SPU */
1457
	  demux_ts_spu_lang *lang = &this->spu_langs[this->spu_langs_count];
1458
1459
	  memset(lang->desc.lang, 0, sizeof(lang->desc.lang));
1460
	  /*memcpy(lang->desc.lang, &stream[pos], 3);*/
1461
	  /*lang->desc.lang[3] = 0;*/
1462
	  lang->pid = pid;
1463
	  lang->media_index = this->media_num;
1464
	  this->media[this->media_num].type = this->spu_langs_count;
1465
	  demux_ts_pes_new(this, this->media_num, pid, this->video_fifo, stream[0]);
1466
	  demux_send_special_spu_buf( this, BUF_SPU_HDMV, this->spu_langs_count );
1467
	  this->spu_langs_count++;
1468
#endif
1469
#ifdef TS_PMT_LOG 
1470
	  printf("demux_ts: HDMV subtitle stream_type: 0x%.2x pid: 0x%.4x\n",
1471
		 stream[0], pid);
1472
#endif
1473
	  break;
1474
	}
1475
      }
1476
      /* fall thru */
1429
    default:
1477
    default:
1430
1478
1431
/* This following section handles all the cases where the audio track info is stored in PMT user info with stream id >= 0x80
1479
/* This following section handles all the cases where the audio track info is stored in PMT user info with stream id >= 0x80
Lines 1454-1461 Link Here
1454
                this->media[this->media_num].type = this->audio_tracks_count;
1502
                this->media[this->media_num].type = this->audio_tracks_count;
1455
                demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang,
1503
                demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang,
1456
                                       stream + 5, stream_info_length);
1504
                                       stream + 5, stream_info_length);
1505
#ifdef TS_PMT_LOG
1506
		printf ("demux_ts: PMT AC3? audio stream_type: 0x%.2x pid: 0x%.4x "
1507
			"format_identifier: 0x%.8x lang: %s\n",
1508
			stream[0], pid, format_identifier, 
1509
			this->audio_tracks[this->audio_tracks_count].lang); 
1510
#endif
1457
                this->audio_tracks_count++;
1511
                this->audio_tracks_count++;
1458
                break;
1512
                break;
1513
            } else {
1514
#ifdef TS_PMT_LOG
1515
		printf ("demux_ts: PMT unknown stream_type: 0x%.2x pid: 0x%.4x "
1516
			"format_identifier: 0x%.8x\n",
1517
			stream[0], pid, format_identifier);
1518
#endif
1459
            }
1519
            }
1460
        }
1520
        }
1461
      } else {
1521
      } else {
Lines 1512-1521 Link Here
1512
  xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: about to resync!\n");
1572
  xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: about to resync!\n");
1513
1573
1514
  for (p=0; p < npkt_read; p++) {
1574
  for (p=0; p < npkt_read; p++) {
1515
    for(n=0; n < PKT_SIZE; n++) {
1575
    for(n=0; n < this->pkt_size; n++) {
1516
      sync_ok = 1;
1576
      sync_ok = 1;
1517
      for (i=0; i < MIN(MIN_SYNCS, npkt_read - p); i++) {
1577
      for (i=0; i < MIN(MIN_SYNCS, npkt_read - p); i++) {
1518
	if (buf[n + ((i+p) * PKT_SIZE)] != SYNC_BYTE) {
1578
	if (buf[this->pkt_offset + n + ((i+p) * this->pkt_size)] != SYNC_BYTE) {
1519
	  sync_ok = 0;
1579
	  sync_ok = 0;
1520
	  break;
1580
	  break;
1521
	}
1581
	}
Lines 1527-1539 Link Here
1527
1587
1528
  if (sync_ok) {
1588
  if (sync_ok) {
1529
    /* Found sync, fill in */
1589
    /* Found sync, fill in */
1530
    memmove(&buf[0], &buf[n + p * PKT_SIZE],
1590
    memmove(&buf[0], &buf[n + p * this->pkt_size],
1531
	    ((PKT_SIZE * (npkt_read - p)) - n));
1591
	    ((this->pkt_size * (npkt_read - p)) - n));
1532
    read_length = this->input->read(this->input,
1592
    read_length = this->input->read(this->input,
1533
				    &buf[(PKT_SIZE * (npkt_read - p)) - n],
1593
				    &buf[(this->pkt_size * (npkt_read - p)) - n],
1534
				    n + p * PKT_SIZE);
1594
				    n + p * this->pkt_size);
1535
    /* FIXME: when read_length is not as required... we now stop demuxing */
1595
    /* FIXME: when read_length is not as required... we now stop demuxing */
1536
    if (read_length != (n + p * PKT_SIZE)) {
1596
    if (read_length != (n + p * this->pkt_size)) {
1537
      xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, 
1597
      xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, 
1538
	       "demux_ts_tsync_correct: sync found, but read failed\n");
1598
	       "demux_ts_tsync_correct: sync found, but read failed\n");
1539
      return 0;
1599
      return 0;
Lines 1552-1557 Link Here
1552
1612
1553
  sync_ok = 1;
1613
  sync_ok = 1;
1554
1614
1615
  if (this->hdmv) {
1616
    this->pkt_size   = PKT_SIZE + 4; /* ts packet + 4-byte header */
1617
    this->pkt_offset = 4;
1618
    for (i=0; i < MIN(MIN_SYNCS, npkt_read - 3); i++) {
1619
      if (buf[this->pkt_offset + i * this->pkt_size] != SYNC_BYTE) {
1620
	sync_ok = 0;
1621
	break;
1622
      }
1623
    }
1624
    if (sync_ok) {
1625
      if (this->hdmv < 0) {
1626
        /* fix npkt_read (packet size is 192, not 188) */
1627
        this->npkt_read = npkt_read * PKT_SIZE / this->pkt_size;
1628
      }
1629
      this->hdmv = 1;
1630
      return sync_ok;
1631
    }
1632
    if (this->hdmv > 0)
1633
      return sync_correct(this, buf, npkt_read);
1634
1635
    /* plain ts */
1636
    this->hdmv       = 0;
1637
    this->pkt_size   = PKT_SIZE;
1638
    this->pkt_offset = 0;
1639
  }
1640
1555
  for (i=0; i < MIN(MIN_SYNCS, npkt_read); i++) {
1641
  for (i=0; i < MIN(MIN_SYNCS, npkt_read); i++) {
1556
    if (buf[i * PKT_SIZE] != SYNC_BYTE) {
1642
    if (buf[i * PKT_SIZE] != SYNC_BYTE) {
1557
      sync_ok = 0;
1643
      sync_ok = 0;
Lines 1575-1589 Link Here
1575
    /* NEW: handle read returning less packets than NPKT_PER_READ... */
1661
    /* NEW: handle read returning less packets than NPKT_PER_READ... */
1576
    do {
1662
    do {
1577
      read_length = this->input->read(this->input, this->buf,
1663
      read_length = this->input->read(this->input, this->buf,
1578
				      PKT_SIZE * NPKT_PER_READ);
1664
				      this->pkt_size * NPKT_PER_READ);
1579
      if (read_length < 0 || read_length % PKT_SIZE) {
1665
      if (read_length < 0 || read_length % this->pkt_size) {
1580
	xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, 
1666
	xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, 
1581
		 "demux_ts: read returned %d bytes (not a multiple of %d!)\n",
1667
		 "demux_ts: read returned %d bytes (not a multiple of %d!)\n",
1582
		 read_length, PKT_SIZE);
1668
		 read_length, this->pkt_size);
1583
	this->status = DEMUX_FINISHED;
1669
	this->status = DEMUX_FINISHED;
1584
	return NULL;
1670
	return NULL;
1585
      }
1671
      }
1586
      this->npkt_read = read_length / PKT_SIZE;
1672
      this->npkt_read = read_length / this->pkt_size;
1587
1673
1588
#ifdef TS_READ_STATS
1674
#ifdef TS_READ_STATS
1589
      this->rstat[this->npkt_read]++;
1675
      this->rstat[this->npkt_read]++;
Lines 1610-1616 Link Here
1610
      return NULL;
1696
      return NULL;
1611
    }
1697
    }
1612
  }
1698
  }
1613
  return_pointer = &(this->buf)[PKT_SIZE * this->packet_number];
1699
  return_pointer = &(this->buf)[this->pkt_offset + this->pkt_size * this->packet_number];
1614
  this->packet_number++;
1700
  this->packet_number++;
1615
  return return_pointer;
1701
  return return_pointer;
1616
}
1702
}
Lines 1758-1764 Link Here
1758
  /*
1844
  /*
1759
   * Discard packets that are obviously bad.
1845
   * Discard packets that are obviously bad.
1760
   */
1846
   */
1761
  if (sync_byte != 0x47) {
1847
  if (sync_byte != SYNC_BYTE) {
1762
    xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, 
1848
    xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, 
1763
	     "demux error! invalid ts sync byte %.2x\n", sync_byte);
1849
	     "demux error! invalid ts sync byte %.2x\n", sync_byte);
1764
    return;
1850
    return;
Lines 2170-2200 Link Here
2170
    }
2256
    }
2171
}
2257
}
2172
2258
2259
static int detect_ts(uint8_t *buf, size_t len, int ts_size)
2260
{
2261
  int    i, j;
2262
  int    try_again, ts_detected = 0;
2263
  size_t packs = len / ts_size - 2;
2173
2264
2174
static demux_plugin_t *open_plugin (demux_class_t *class_gen, 
2265
  for (i = 0; i < ts_size; i++) {
2175
				    xine_stream_t *stream, 
2176
				    input_plugin_t *input) {
2177
  
2178
  demux_ts_t *this;
2179
  int         i;
2180
2181
  switch (stream->content_detection_method) {
2182
2183
  case METHOD_BY_CONTENT: {
2184
    uint8_t buf[2069];
2185
    int     i, j;
2186
    int     try_again, ts_detected;
2187
2188
    if (!_x_demux_read_header(input, buf, 2069))
2189
      return NULL;
2190
2191
    ts_detected = 0;
2192
2193
    for (i = 0; i < 188; i++) {
2194
      try_again = 0;
2266
      try_again = 0;
2195
      if (buf[i] == 0x47) {
2267
    if (buf[i] == SYNC_BYTE) {
2196
	for (j = 1; j <= 10; j++) {
2268
      for (j = 1; j < packs; j++) {
2197
	  if (buf[i + j*188] != 0x47) {
2269
	if (buf[i + j*ts_size] != SYNC_BYTE) {
2198
	    try_again = 1;
2270
	    try_again = 1;
2199
	    break;
2271
	    break;
2200
	  }
2272
	  }
Lines 2208-2220 Link Here
2208
      }
2280
      }
2209
    }
2281
    }
2210
2282
2211
    if (!ts_detected)
2283
  return ts_detected;
2284
}
2285
2286
static demux_plugin_t *open_plugin (demux_class_t *class_gen, 
2287
				    xine_stream_t *stream, 
2288
				    input_plugin_t *input) {
2289
  
2290
  demux_ts_t *this;
2291
  int         i;
2292
  int         hdmv = -1;
2293
2294
  switch (stream->content_detection_method) {
2295
2296
  case METHOD_BY_CONTENT: {
2297
    uint8_t buf[2069];
2298
2299
    if (!_x_demux_read_header(input, buf, sizeof(buf)))
2300
      return NULL;
2301
2302
    if (detect_ts(buf, sizeof(buf), PKT_SIZE))
2303
      hdmv = 0;
2304
    else if (detect_ts(buf, sizeof(buf), PKT_SIZE+4)) 
2305
      hdmv = 1;
2306
    else 
2212
      return NULL;
2307
      return NULL;
2213
  }
2308
  }
2214
    break;
2309
    break;
2215
2310
2216
  case METHOD_BY_EXTENSION: {
2311
  case METHOD_BY_EXTENSION: {
2217
    const char *const mrl = input->get_mrl (input);
2312
    const char *const mrl = input->get_mrl (input);
2313
2314
    if (_x_demux_check_extension (mrl, "m2ts mts"))
2315
      hdmv = 1;
2316
    else
2317
      hdmv = 0;
2218
2318
2219
    /* check extension */
2319
    /* check extension */
2220
    const char *const extensions = class_gen->get_extensions (class_gen);
2320
    const char *const extensions = class_gen->get_extensions (class_gen);
Lines 2302-2307 Link Here
2302
  /* dvb */
2402
  /* dvb */
2303
  this->event_queue = xine_event_new_queue (this->stream);
2403
  this->event_queue = xine_event_new_queue (this->stream);
2304
  
2404
  
2405
  /* HDMV */
2406
  this->hdmv       = hdmv;
2407
  this->pkt_offset = (hdmv > 0) ? 4 : 0;
2408
  this->pkt_size   = PKT_SIZE + this->pkt_offset;
2409
2305
  this->numPreview=0;
2410
  this->numPreview=0;
2306
  
2411
  
2307
  return &this->demux_plugin;
2412
  return &this->demux_plugin;
Lines 2320-2326 Link Here
2320
}
2425
}
2321
2426
2322
static const char *get_extensions (demux_class_t *this_gen) {
2427
static const char *get_extensions (demux_class_t *this_gen) {
2323
  return "ts m2t trp";
2428
  return "ts m2t trp m2ts mts";
2324
}
2429
}
2325
2430
2326
static const char *get_mimetypes (demux_class_t *this_gen) {
2431
static const char *get_mimetypes (demux_class_t *this_gen) {

Return to bug 290759