1
/*****************************************************************************
3
*****************************************************************************/
5
/*****************************************************************************
6
* File name: mpeg_parse.c *
7
* Created: 2003-02-01 by Hampa Hug <hampa@hampa.ch> *
8
* Last modified: 2003-09-10 by Hampa Hug <hampa@hampa.ch> *
9
* Copyright: (C) 2003 by Hampa Hug <hampa@hampa.ch> *
10
*****************************************************************************/
12
/*****************************************************************************
13
* This program is free software. You can redistribute it and / or modify it *
14
* under the terms of the GNU General Public License version 2 as published *
15
* by the Free Software Foundation. *
17
* This program is distributed in the hope that it will be useful, but *
18
* WITHOUT ANY WARRANTY, without even the implied warranty of *
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
20
* Public License for more details. *
21
*****************************************************************************/
23
/* $Id: mpeg_parse.c 67 2004-01-02 18:20:15Z hampa $ */
25
// The code has been modified to use file descriptors instead of FILE streams.
26
// Only functionality needed in MediaTomb remains, all extra features are
31
#include "autoconfig.h"
39
#include <sys/types.h>
43
#include "mpeg_parse.h"
46
mpeg_demux_t *mpegd_open_fd (mpeg_demux_t *mpeg, int fd, int close_file)
49
mpeg = (mpeg_demux_t *) malloc (sizeof (mpeg_demux_t));
60
mpeg->close = close_file;
69
mpeg->mpeg_skip = NULL;
70
mpeg->mpeg_system_header = NULL;
71
mpeg->mpeg_packet = NULL;
72
mpeg->mpeg_packet_check = NULL;
73
mpeg->mpeg_pack = NULL;
74
mpeg->mpeg_end = NULL;
76
mpegd_reset_stats (mpeg);
81
mpeg_demux_t *mpegd_open (mpeg_demux_t *mpeg, const char *fname)
85
fd = open (fname, O_RDONLY);
90
mpeg = mpegd_open_fd (mpeg, fd, 1);
95
void mpegd_close (mpeg_demux_t *mpeg)
106
void mpegd_reset_stats (mpeg_demux_t *mpeg)
112
mpeg->packet_cnt = 0;
116
for (i = 0; i < 256; i++) {
117
mpeg->streams[i].packet_cnt = 0;
118
mpeg->streams[i].size = 0;
119
mpeg->substreams[i].packet_cnt = 0;
120
mpeg->substreams[i].size = 0;
125
int mpegd_buffer_fill (mpeg_demux_t *mpeg)
130
if ((mpeg->buf_i > 0) && (mpeg->buf_n > 0)) {
131
for (i = 0; i < mpeg->buf_n; i++) {
132
mpeg->buf[i] = mpeg->buf[mpeg->buf_i + i];
138
n = MPEG_DEMUX_BUFFER - mpeg->buf_n;
141
r = read (mpeg->fd, mpeg->buf + mpeg->buf_n, n);
146
mpeg->buf_n += (unsigned) r;
153
int mpegd_need_bits (mpeg_demux_t *mpeg, unsigned n)
157
if (n > mpeg->buf_n) {
158
mpegd_buffer_fill (mpeg);
161
if (n > mpeg->buf_n) {
168
unsigned long mpegd_get_bits (mpeg_demux_t *mpeg, unsigned i, unsigned n)
175
if (mpegd_need_bits (mpeg, i + n)) {
179
buf = mpeg->buf + mpeg->buf_i;
184
if (((i | n) & 7) == 0) {
188
r = (r << 8) | buf[i];
202
b_i = 8 - (i & 7) - b_n;
205
v = (buf[i >> 3] >> b_i) & m;
216
int mpegd_skip (mpeg_demux_t *mpeg, unsigned n)
222
if (n <= mpeg->buf_n) {
233
if (n <= MPEG_DEMUX_BUFFER) {
234
r = read (mpeg->fd ,mpeg->buf, n);
237
r = read (mpeg->fd, mpeg->buf, MPEG_DEMUX_BUFFER);
250
unsigned mpegd_read (mpeg_demux_t *mpeg, void *buf, unsigned n)
256
tmp = (unsigned char *) buf;
258
i = (n < mpeg->buf_n) ? n : mpeg->buf_n;
263
memcpy (tmp, &mpeg->buf[mpeg->buf_i], i);
272
ret += read (mpeg->fd, tmp, n);
280
int mpegd_set_offset (mpeg_demux_t *mpeg, unsigned long long ofs)
282
if (ofs == mpeg->ofs) {
286
if (ofs > mpeg->ofs) {
287
return (mpegd_skip (mpeg, (unsigned long) (ofs - mpeg->ofs)));
294
int mpegd_seek_header (mpeg_demux_t *mpeg)
296
unsigned long long ofs;
298
while (mpegd_get_bits (mpeg, 0, 24) != 1) {
301
if (mpeg->mpeg_skip != NULL) {
302
if (mpeg->mpeg_skip (mpeg)) {
307
if (mpegd_set_offset (mpeg, ofs)) {
318
int mpegd_parse_system_header (mpeg_demux_t *mpeg)
320
unsigned long long ofs;
322
mpeg->shdr.size = mpegd_get_bits (mpeg, 32, 16) + 6;
324
mpeg->shdr.fixed = mpegd_get_bits (mpeg, 78, 1);
325
mpeg->shdr.csps = mpegd_get_bits (mpeg, 79, 1);
329
ofs = mpeg->ofs + mpeg->shdr.size;
331
if (mpeg->mpeg_system_header != NULL) {
332
if (mpeg->mpeg_system_header (mpeg)) {
337
mpegd_set_offset (mpeg, ofs);
343
int mpegd_parse_packet1 (mpeg_demux_t *mpeg, unsigned i)
346
unsigned long long tmp;
348
mpeg->packet.type = 1;
350
if (mpegd_get_bits (mpeg, i, 2) == 0x01) {
354
val = mpegd_get_bits (mpeg, i, 8);
356
if ((val & 0xf0) == 0x20) {
357
tmp = mpegd_get_bits (mpeg, i + 4, 3);
358
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 8, 15);
359
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 24, 15);
361
mpeg->packet.have_pts = 1;
362
mpeg->packet.pts = tmp;
366
else if ((val & 0xf0) == 0x30) {
367
tmp = mpegd_get_bits (mpeg, i + 4, 3);
368
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 8, 15);
369
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 24, 15);
371
mpeg->packet.have_pts = 1;
372
mpeg->packet.pts = tmp;
374
tmp = mpegd_get_bits (mpeg, i + 44, 3);
375
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 48, 15);
376
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 64, 15);
378
mpeg->packet.have_dts = 1;
379
mpeg->packet.dts = tmp;
383
else if (val == 0x0f) {
387
mpeg->packet.offset = i / 8;
393
int mpegd_parse_packet2 (mpeg_demux_t *mpeg, unsigned i)
395
unsigned pts_dts_flag;
397
unsigned long long tmp;
399
mpeg->packet.type = 2;
401
pts_dts_flag = mpegd_get_bits (mpeg, i + 8, 2);
402
cnt = mpegd_get_bits (mpeg, i + 16, 8);
404
if (pts_dts_flag == 0x02) {
405
if (mpegd_get_bits (mpeg, i + 24, 4) == 0x02) {
406
tmp = mpegd_get_bits (mpeg, i + 28, 3);
407
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 32, 15);
408
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 48, 15);
410
mpeg->packet.have_pts = 1;
411
mpeg->packet.pts = tmp;
414
else if ((pts_dts_flag & 0x03) == 0x03) {
415
if (mpegd_get_bits (mpeg, i + 24, 4) == 0x03) {
416
tmp = mpegd_get_bits (mpeg, i + 28, 3);
417
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 32, 15);
418
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 48, 15);
420
mpeg->packet.have_pts = 1;
421
mpeg->packet.pts = tmp;
424
if (mpegd_get_bits (mpeg, i + 64, 4) == 0x01) {
425
tmp = mpegd_get_bits (mpeg, i + 68, 3);
426
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 72, 15);
427
tmp = (tmp << 15) | mpegd_get_bits (mpeg, i + 88, 15);
429
mpeg->packet.have_dts = 1;
430
mpeg->packet.dts = tmp;
436
mpeg->packet.offset = i / 8;
442
int mpegd_parse_packet (mpeg_demux_t *mpeg)
446
unsigned long long ofs;
448
mpeg->packet.type = 0;
450
sid = mpegd_get_bits (mpeg, 24, 8);
453
mpeg->packet.sid = sid;
454
mpeg->packet.ssid = ssid;
456
mpeg->packet.size = mpegd_get_bits (mpeg, 32, 16) + 6;
457
mpeg->packet.offset = 6;
459
mpeg->packet.have_pts = 0;
460
mpeg->packet.pts = 0;
462
mpeg->packet.have_dts = 0;
463
mpeg->packet.dts = 0;
467
if (((sid >= 0xc0) && (sid < 0xf0)) || (sid == 0xbd)) {
468
while (mpegd_get_bits (mpeg, i, 8) == 0xff) {
469
if (i > (48 + 16 * 8)) {
475
if (mpegd_get_bits (mpeg, i, 2) == 0x02) {
476
if (mpegd_parse_packet2 (mpeg, i)) {
481
if (mpegd_parse_packet1 (mpeg, i)) {
486
else if (sid == 0xbe) {
487
mpeg->packet.type = 1;
491
ssid = mpegd_get_bits (mpeg, 8 * mpeg->packet.offset, 8);
492
mpeg->packet.ssid = ssid;
495
if ((mpeg->mpeg_packet_check != NULL) && mpeg->mpeg_packet_check (mpeg)) {
496
if (mpegd_skip (mpeg, 1)) {
501
mpeg->packet_cnt += 1;
502
mpeg->streams[sid].packet_cnt += 1;
503
mpeg->streams[sid].size += mpeg->packet.size - mpeg->packet.offset;
506
mpeg->substreams[ssid].packet_cnt += 1;
507
mpeg->substreams[ssid].size += mpeg->packet.size - mpeg->packet.offset;
510
ofs = mpeg->ofs + mpeg->packet.size;
512
if (mpeg->mpeg_packet != NULL) {
513
if (mpeg->mpeg_packet (mpeg)) {
518
mpegd_set_offset (mpeg, ofs);
525
int mpegd_parse_pack (mpeg_demux_t *mpeg)
528
unsigned long long ofs;
530
if (mpegd_get_bits (mpeg, 32, 4) == 0x02) {
532
mpeg->pack.scr = mpegd_get_bits (mpeg, 36, 3);
533
mpeg->pack.scr = (mpeg->pack.scr << 15) | mpegd_get_bits (mpeg, 40, 15);
534
mpeg->pack.scr = (mpeg->pack.scr << 15) | mpegd_get_bits (mpeg, 56, 15);
535
mpeg->pack.mux_rate = mpegd_get_bits (mpeg, 73, 22);
536
mpeg->pack.stuff = 0;
537
mpeg->pack.size = 12;
539
else if (mpegd_get_bits (mpeg, 32, 2) == 0x01) {
541
mpeg->pack.scr = mpegd_get_bits (mpeg, 34, 3);
542
mpeg->pack.scr = (mpeg->pack.scr << 15) | mpegd_get_bits (mpeg, 38, 15);
543
mpeg->pack.scr = (mpeg->pack.scr << 15) | mpegd_get_bits (mpeg, 54, 15);
544
mpeg->pack.mux_rate = mpegd_get_bits (mpeg, 80, 22);
545
mpeg->pack.stuff = mpegd_get_bits (mpeg, 109, 3);
546
mpeg->pack.size = 14 + mpeg->pack.stuff;
551
mpeg->pack.mux_rate = 0;
555
ofs = mpeg->ofs + mpeg->pack.size;
559
if (mpeg->mpeg_pack != NULL) {
560
if (mpeg->mpeg_pack (mpeg)) {
565
mpegd_set_offset (mpeg, ofs);
567
mpegd_seek_header (mpeg);
569
if (mpegd_get_bits (mpeg, 0, 32) == MPEG_SYSTEM_HEADER) {
570
if (mpegd_parse_system_header (mpeg)) {
574
mpegd_seek_header (mpeg);
577
while (mpegd_get_bits (mpeg, 0, 24) == MPEG_PACKET_START) {
578
sid = mpegd_get_bits (mpeg, 24, 8);
580
if ((sid == 0xba) || (sid == 0xb9) || (sid == 0xbb)) {
584
mpegd_parse_packet (mpeg);
587
mpegd_seek_header (mpeg);
593
int mpegd_parse (mpeg_demux_t *mpeg)
595
unsigned long long ofs;
598
if (mpegd_seek_header (mpeg)) {
602
switch (mpegd_get_bits (mpeg, 0, 32)) {
603
case MPEG_PACK_START:
604
if (mpegd_parse_pack (mpeg)) {
614
if (mpeg->mpeg_end != NULL) {
615
if (mpeg->mpeg_end (mpeg)) {
620
if (mpegd_set_offset (mpeg, ofs)) {
628
if (mpeg->mpeg_skip != NULL) {
629
if (mpeg->mpeg_skip (mpeg)) {
634
if (mpegd_set_offset (mpeg, ofs)) {
645
#endif//HAVE_LIBDVDNAV