source: svn/trunk/newcon3bcm2_21bu/BSEAV/lib/bcmplayer/utils/ts_utils.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 6.4 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 1998-2009, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: ts_utils.c $
11 * $brcm_Revision: 3 $
12 * $brcm_Date: 10/28/09 1:30p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/lib/bcmplayer/utils/ts_utils.c $
19 *
20 * 3   10/28/09 1:30p erickson
21 * SW7405-3287: add functions for getting and setting pes headers
22 *
23 * 2   4/30/07 1:09p erickson
24 * PR30310: added TIMING_MARKER, PICTURE_TAG. changed debug code to
25 * function.
26 *
27 * Irvine_BSEAVSW_Devel/2   6/30/06 9:39a erickson
28 * PR21941: fix start code detection algorithm, and eliminate duplication
29 * by moving to ts_utils
30 *
31 * Irvine_BSEAVSW_Devel/1   9/1/05 3:37p erickson
32 * PR16964: moved common ts functions to shared locations
33 *
34 ****************************************************************/
35#include "ts_utils.h"
36#include <string.h>
37#include <stdio.h>
38
39const char *b_btp_mode_str(int mode)
40{
41    switch (mode) {
42    case TT_MODE_PLAY: return "PLAY";
43    case TT_MODE_DISPLAY: return "DISPLAY";
44    case TT_MODE_BUILD_REFERENCE: return "BUILD REF";
45    case TT_MODE_PROCESS: return "PROCESS";
46    case TT_MODE_DISCARD_TILL_BTP: return "DISCARD TILL BTP";
47    case TT_MODE_DISPLAY_FORWARD: return "DISPLAY FWD";
48    case TT_MODE_DISPLAY_REWIND: return "DISPLAY REV";
49    case TT_MODE_DISPLAY_PAST_BUFFER: return "DISPLAY PAST BUFFER";
50    case TT_MODE_TIMING_MARKER: return "TIMING MARKER";
51    case TT_MODE_PICTURE_TAG: return "PICTURE TAG";
52    default: return "Unknown";
53    }
54}
55
56unsigned short b_get_pid(const unsigned char *pkt)
57{
58    return (((unsigned short)pkt[1]&0x1f) << 8) | pkt[2];
59}
60
61bool b_is_btp(const unsigned char *pkt)
62{
63    return !memcmp(&pkt[8], "BRCM", 4);
64}
65
66int b_get_btp_word(const unsigned char *pkt, int n)
67{
68    unsigned long *pktdata = (unsigned long *)&pkt[12];
69    return be(pktdata[n]);
70}
71
72int b_check_for_start_code(unsigned char data, int sccount)
73{
74    switch (data) {
75    case 0:
76        if (sccount >= 1)
77            sccount = 2;
78        else
79            sccount = 1;
80        break;
81    case 1:
82        if (sccount == 2) {
83            /* we've got a start code! */
84            sccount = 3;
85        }
86        else {
87            sccount = 0;
88        }
89        break;
90    default:
91        sccount = 0;
92        break;
93    }
94    return sccount;
95}
96
97bool b_is_pes_stream_id(unsigned char stream_id) {
98    return
99        ((stream_id & 0xFC) == 0xBC) || /* 1011 11xx */
100        ((stream_id & 0xC0) == 0xC0) || /* 110x xxxx */
101        ((stream_id & 0xF0) == 0xE0) || /* 1110 xxxx */
102        ((stream_id & 0xF0) == 0xF0);   /* 1111 xxxx */
103}
104
105#define CHECK(X) do {if (!(X)) fprintf(stderr, "### invalid PES header (codeline %d)\n", __LINE__); } while (0)
106
107static uint32_t b_get_pts(unsigned char *buf, int checkval)
108{
109    uint64_t pts;
110    /* check key value and marker bits */
111    CHECK(buf[0] >> 4 == checkval);
112    CHECK(buf[0] & 0x01);
113    CHECK(buf[2] & 0x01);
114    CHECK(buf[4] & 0x01);
115
116    /* read 33 bits of pts info */
117    pts = (buf[0] & 0x0E) >> 1; /* 3 bits */
118    pts <<= 8;
119    pts |= buf[1]; /* 8 bits */
120    pts <<= 7;
121    pts |= (buf[2] >> 1); /* 7 bits */
122    pts <<= 8;
123    pts |= buf[3]; /* 8 bits */
124    pts <<= 7;
125    pts |= (buf[4] >> 1); /* 7 bits */
126
127    /* downshift by one. we throw away the LSB. */
128    pts >>= 1;
129
130    return (uint32_t)pts;
131}
132
133static void b_set_pts(unsigned char *buf, unsigned pts_dts_flags, uint32_t pts)
134{
135    uint64_t full_pts = pts << 1; /* upshift by one so that bitshift math matches spec */
136
137    buf[0] = (((full_pts >> 30) & 0x7)  << 1) | 0x1 | (pts_dts_flags << 4);
138    buf[1] = (((full_pts >> 22) & 0xff));
139    buf[2] = (((full_pts >> 15) & 0x7f) << 1) | 0x1;
140    buf[3] = (((full_pts >>  7) & 0xff));
141    buf[4] = (((full_pts      ) & 0x7f) << 1) | 0x1;
142}
143
144/* decode and print the pes header. buf points to the stream_id and is guaranteed
145to point to whole pes header. */
146void b_get_pes_header(unsigned char *buf, b_pes_header *pes_header)
147{
148    memset(pes_header, 0, sizeof(*pes_header));
149
150    pes_header->pes_type = b_get_pes_type(buf[0]);
151    pes_header->packet_length = (((unsigned short)buf[1])<<8) + buf[2];
152
153    if (pes_header->pes_type == b_pes_packet_type_pes) {
154        pes_header->pts_dts_flags = buf[4] >> 6;
155        pes_header->header_data_length = buf[5];
156        CHECK((buf[3] & 0xD0) == 0x80); /* check for 10 */
157
158        if (pes_header->pts_dts_flags == 2) {
159            pes_header->pts = b_get_pts(&buf[6], 2);
160        }
161        else if (pes_header->pts_dts_flags == 3) {
162            pes_header->pts = b_get_pts(&buf[6], 3);
163            pes_header->dts = b_get_pts(&buf[11], 1);
164        }
165        /* TODO: ESCR flag, ES rate flag, DSM trick mode flag, etc. */
166    }
167}
168
169void b_set_pes_header(unsigned char *buf, const b_pes_header *pes_header)
170{
171    if (pes_header->pts_dts_flags == 2) {
172        b_set_pts(&buf[6], 2, pes_header->pts);
173    }
174    else if (pes_header->pts_dts_flags == 3) {
175        b_set_pts(&buf[6], 3, pes_header->pts);
176        b_set_pts(&buf[11], 1, pes_header->dts);
177    }
178}
179
180b_pes_packet_type b_get_pes_type(unsigned char stream_id) {
181    switch (stream_id) {
182    case 0xBE: return b_pes_packet_type_padding;
183    case 0xBA: return b_pes_packet_type_data; /* program_stream_map */
184    case 0xBB:
185    case 0xBC: return b_pes_packet_type_pes; /* private_stream_1, padding_stream */
186    case 0xBF: return b_pes_packet_type_data; /* private_stream_2 */
187    case 0xF0:           /* ECM */
188    case 0xF1: return b_pes_packet_type_data; /* EMM */
189    case 0xF2: return b_pes_packet_type_data; /* DSMCC */
190    case 0xF8: return b_pes_packet_type_data; /* ITU-T Rec. H.222.1 type E stream */
191    case 0xFF: return b_pes_packet_type_data; /* program_stream_directory */
192    }
193
194    if ((stream_id == 0xBD) ||  /* private_stream_1 */
195        ((stream_id & 0xC0) == 0xC0) || /* 110x xxxx - audio stream */
196        ((stream_id & 0xF0) == 0xE0) || /* 1110 xxxx - video stream */
197        (stream_id == 0xF3) ||              /* ISO 13522 stream */
198        (stream_id >= 0xF4 && stream_id <= 0xF7) || /* H.222.1 type A-D */
199        (stream_id >= 0xF9 && stream_id <= 0xFE)) /* reserved data stream */
200    {
201        return b_pes_packet_type_pes;
202    }
203
204    return b_pes_packet_type_invalid; /* not PES */
205}
Note: See TracBrowser for help on using the repository browser.