| 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: printts.c $ |
|---|
| 11 | * $brcm_Revision: 5 $ |
|---|
| 12 | * $brcm_Date: 3/28/09 8:44a $ |
|---|
| 13 | * |
|---|
| 14 | * Module Description: |
|---|
| 15 | * |
|---|
| 16 | * Revision History: |
|---|
| 17 | * |
|---|
| 18 | * $brcm_Log: /BSEAV/lib/bcmplayer/utils/printts.c $ |
|---|
| 19 | * |
|---|
| 20 | * 5 3/28/09 8:44a erickson |
|---|
| 21 | * PR42679: fixed cc check |
|---|
| 22 | * |
|---|
| 23 | * 4 7/12/07 11:57a erickson |
|---|
| 24 | * PR30310: added note re: 204 byte packet streams |
|---|
| 25 | * |
|---|
| 26 | * 3 4/30/07 1:09p erickson |
|---|
| 27 | * PR30310: added TIMING_MARKER, PICTURE_TAG. changed debug code to |
|---|
| 28 | * function. |
|---|
| 29 | * |
|---|
| 30 | * 2 1/30/07 12:28p erickson |
|---|
| 31 | * PR27189: extend -hdr feature |
|---|
| 32 | * |
|---|
| 33 | * Irvine_BSEAVSW_Devel/25 5/4/06 4:48p erickson |
|---|
| 34 | * PR17108: added cc check |
|---|
| 35 | * |
|---|
| 36 | * Irvine_BSEAVSW_Devel/24 3/7/06 6:52a erickson |
|---|
| 37 | * PR17108: fix warnings |
|---|
| 38 | * |
|---|
| 39 | * Irvine_BSEAVSW_Devel/23 2/6/06 1:00p ahulse |
|---|
| 40 | * PR16207: Update to support 7411D BTP packets. Fix typecast warnings on |
|---|
| 41 | * compile |
|---|
| 42 | * |
|---|
| 43 | * Irvine_BSEAVSW_Devel/22 1/6/06 10:17a erickson |
|---|
| 44 | * PR17108: updated for magnum basemodules and 64 bit cpus |
|---|
| 45 | * |
|---|
| 46 | * Irvine_BSEAVSW_Devel/21 9/14/05 2:24p erickson |
|---|
| 47 | * PR17148: converted to BCHP_7411_REV |
|---|
| 48 | * |
|---|
| 49 | * Irvine_BSEAVSW_Devel/20 9/2/05 12:44p erickson |
|---|
| 50 | * PR16964: added -q and -pidonly options |
|---|
| 51 | * |
|---|
| 52 | * Irvine_BSEAVSW_Devel/19 9/1/05 3:37p erickson |
|---|
| 53 | * PR16964: refactor |
|---|
| 54 | * |
|---|
| 55 | * Irvine_BSEAVSW_Devel/18 7/13/05 3:04p erickson |
|---|
| 56 | * PR16207: added 7411d support and cleaned up btp packet printout |
|---|
| 57 | * (interpret the data instead of a raw dump) |
|---|
| 58 | * |
|---|
| 59 | ****************************************************************/ |
|---|
| 60 | #include "bstd.h" |
|---|
| 61 | #include <stdio.h> |
|---|
| 62 | #include <string.h> |
|---|
| 63 | #include <stdlib.h> |
|---|
| 64 | #include "ts_utils.h" |
|---|
| 65 | |
|---|
| 66 | #define NULL_PID 0x1fff |
|---|
| 67 | |
|---|
| 68 | void printPacket(const unsigned char *pkt, int packetsize) |
|---|
| 69 | { |
|---|
| 70 | static int cnt = 0; |
|---|
| 71 | |
|---|
| 72 | BSTD_UNUSED(packetsize); |
|---|
| 73 | printf("packet %d: pid 0x%x\n", cnt++, b_get_pid(pkt)); |
|---|
| 74 | |
|---|
| 75 | if (b_is_btp(pkt)) |
|---|
| 76 | { |
|---|
| 77 | uint32_t *pktdata = (uint32_t *)&pkt[12]; |
|---|
| 78 | int mode = b_get_btp_word(pkt, 0); |
|---|
| 79 | |
|---|
| 80 | if (!(pkt[5] & 0x80)) |
|---|
| 81 | printf(" discontinuity_indicator is cleared\n"); |
|---|
| 82 | #if BCHP_7411_VER == BCHP_VER_C0 |
|---|
| 83 | if (mode == 3) /* PROCESS */ |
|---|
| 84 | printf(" BTP packet: %s, start_byte %ld, packets %ld, end_byte_count %ld, PTS %#lx\n", |
|---|
| 85 | b_btp_mode_str(mode), (long)be(pktdata[4])&0xFFFF, (long)be(pktdata[5])&0xFFFFFF, (long)be(pktdata[6])&0xFFFF, (long)be(pktdata[9])); |
|---|
| 86 | else if (mode == 2) /* BUILD_REF */ |
|---|
| 87 | printf(" BTP packet: %s, skip %ld\n", |
|---|
| 88 | b_btp_mode_str(mode), (long)be(pktdata[1])&0xFFFF); |
|---|
| 89 | else |
|---|
| 90 | printf(" BTP packet: %s, skip %ld, display %ld, PTS %#lx\n", |
|---|
| 91 | b_btp_mode_str(mode), (long)be(pktdata[1])&0xFFFF, (long)be(pktdata[2])&0xFFFF, (long)be(pktdata[9])); |
|---|
| 92 | #elif defined BCHP_7411_VER |
|---|
| 93 | if (mode == 3) /* PROCESS */ |
|---|
| 94 | printf(" BTP packet: %s, start_byte %ld, packets %ld, end_byte_count %ld PTS %#lx\n", |
|---|
| 95 | b_btp_mode_str(mode), (long)be(pktdata[4]), (long)be(pktdata[5]), (long)be(pktdata[6]), (long)be(pktdata[9]) ); |
|---|
| 96 | else if (mode == 2) /* BUILD_REF */ |
|---|
| 97 | printf(" BTP packet: %s, skip %ld\n", |
|---|
| 98 | b_btp_mode_str(mode), (long)be(pktdata[1])); |
|---|
| 99 | else |
|---|
| 100 | printf(" BTP packet: %s, skip %ld, display %ld, PTS %#lx\n", |
|---|
| 101 | b_btp_mode_str(mode), (long)be(pktdata[1]), (long)be(pktdata[2]), (long)be(pktdata[9])); |
|---|
| 102 | #else |
|---|
| 103 | printf(" BTP packet: %s, skip %u, display %u, discard head=%u, tail=%u, PTS %#lx\n", |
|---|
| 104 | b_btp_mode_str(mode), be(pktdata[1]), be(pktdata[2]), be(pktdata[7]), be(pktdata[8]), (unsigned long)be(pktdata[9])); |
|---|
| 105 | #endif |
|---|
| 106 | } |
|---|
| 107 | } |
|---|
| 108 | |
|---|
| 109 | void printTransportHeader(const unsigned char *buf) |
|---|
| 110 | { |
|---|
| 111 | /* TODO: fill this out */ |
|---|
| 112 | printf(" transport_error: %d\n", (buf[2] & 0x80)?1:0); |
|---|
| 113 | printf(" transport_scrambling_control: %d\n", (buf[3] & 0xb0)>>6); |
|---|
| 114 | printf(" continuity_counter: %d\n", buf[3] & 0x0F); |
|---|
| 115 | printf(" adaptation_field: %s\n", |
|---|
| 116 | (buf[3] & 0x30) == 0x00 ? "reserved" : |
|---|
| 117 | (buf[3] & 0x30) == 0x10 ? "none" : |
|---|
| 118 | (buf[3] & 0x30) == 0x20 ? "w/o payload" : |
|---|
| 119 | "w/ payload"); |
|---|
| 120 | if (buf[3] & 0x20) { |
|---|
| 121 | /* print adaptation field */ |
|---|
| 122 | printf(" length %d\n", buf[4]); |
|---|
| 123 | printf(" discontinuity %d\n", buf[5] & 0x80?1:0); |
|---|
| 124 | printf(" random_access %d\n", buf[5] & 0x40?1:0); |
|---|
| 125 | } |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | void printRawPacket(const unsigned char *buf, int packetsize) |
|---|
| 129 | { |
|---|
| 130 | int i; |
|---|
| 131 | for (i=0;i<packetsize;i++) |
|---|
| 132 | printf("%02x ", buf[i]); |
|---|
| 133 | printf("\n"); |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | void printUsage() { |
|---|
| 137 | printf( |
|---|
| 138 | "Usage: printts OPTIONS [FILENAME] [SKIP]\n" |
|---|
| 139 | "Options:\n" |
|---|
| 140 | " -all Don't stop when you hit a bad packet\n" |
|---|
| 141 | " -bad Only print bad packets\n" |
|---|
| 142 | " -hdr Print the contents of the transport header\n" |
|---|
| 143 | " -pid XXX Only print pid # XXX\n" |
|---|
| 144 | ); |
|---|
| 145 | printf( |
|---|
| 146 | " -pktsz XXX Use packet size XXX (default 188)\n" |
|---|
| 147 | " Use 204 to ignore appended 16 byte FEC data\n" |
|---|
| 148 | " -timestamp Transport stream contains 4 byte prepended timestamps.\n" |
|---|
| 149 | " -raw Print raw contents of packet\n" |
|---|
| 150 | " -pidonly Only print the number of the pid (useful for counting pids)\n" |
|---|
| 151 | " -cc Perform CC check (only works on single pid streams. preprocess your multipid stream with filterts first.)\n" |
|---|
| 152 | " -q Quiet. Only print data.\n" |
|---|
| 153 | "\n" |
|---|
| 154 | ); |
|---|
| 155 | printf( |
|---|
| 156 | "Parameters:\n" |
|---|
| 157 | " FILENAME name of MPEG2 Transport file (default is stdin)\n" |
|---|
| 158 | " SKIP # of transport packets to skip (default is 0)\n" |
|---|
| 159 | ); |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | int main(int argc, char **argv) { |
|---|
| 163 | #define MAX_PACKET_SIZE (204+4) |
|---|
| 164 | unsigned char buf[MAX_PACKET_SIZE]; |
|---|
| 165 | FILE *file; |
|---|
| 166 | const char *filename = NULL; |
|---|
| 167 | int i; |
|---|
| 168 | int skip = 0; |
|---|
| 169 | int all = 0; |
|---|
| 170 | int quiet = 0; |
|---|
| 171 | int pidonly = 0; |
|---|
| 172 | int onlyPrintBad = 0; |
|---|
| 173 | int timestamp_offset = 0; |
|---|
| 174 | unsigned short pidFilter = NULL_PID; |
|---|
| 175 | int do_printTransportHeader = 0; |
|---|
| 176 | int packetsize = 188; |
|---|
| 177 | int raw = 0; |
|---|
| 178 | int cc_check = 0; |
|---|
| 179 | struct { |
|---|
| 180 | int next; |
|---|
| 181 | bool discontinuity; |
|---|
| 182 | } current_cc = {0, true}; |
|---|
| 183 | |
|---|
| 184 | for (i=1;i<argc;i++) { |
|---|
| 185 | if (!strcmp(argv[i], "--help")) { |
|---|
| 186 | printUsage(); |
|---|
| 187 | exit(0); |
|---|
| 188 | } |
|---|
| 189 | else if (!strcasecmp("-all", argv[i])) |
|---|
| 190 | all = 1; |
|---|
| 191 | else if (!strcasecmp("-q", argv[i])) |
|---|
| 192 | quiet = 1; |
|---|
| 193 | else if (!strcasecmp("-raw", argv[i])) |
|---|
| 194 | raw = 1; |
|---|
| 195 | else if (!strcasecmp("-bad", argv[i])) |
|---|
| 196 | onlyPrintBad = 1; |
|---|
| 197 | else if (!strcasecmp("-pidonly", argv[i])) |
|---|
| 198 | pidonly = 1; |
|---|
| 199 | else if (!strcasecmp("-cc", argv[i])) |
|---|
| 200 | cc_check = 1; |
|---|
| 201 | else if (!strcasecmp("-timestamp", argv[i])) { |
|---|
| 202 | timestamp_offset = 4; |
|---|
| 203 | packetsize += timestamp_offset; |
|---|
| 204 | } |
|---|
| 205 | else if (!strcasecmp("-pid", argv[i]) && i+1<argc) |
|---|
| 206 | pidFilter = strtoul(argv[++i], NULL, 16); |
|---|
| 207 | else if (!strcasecmp("-pktsz", argv[i]) && i+1<argc) |
|---|
| 208 | packetsize = atoi(argv[++i]); |
|---|
| 209 | else if (!strcasecmp("-hdr", argv[i])) |
|---|
| 210 | do_printTransportHeader = 1; |
|---|
| 211 | else if (!filename) |
|---|
| 212 | filename = argv[i]; |
|---|
| 213 | else |
|---|
| 214 | skip = atoi(argv[i]); |
|---|
| 215 | } |
|---|
| 216 | |
|---|
| 217 | if (!quiet) { |
|---|
| 218 | printf( |
|---|
| 219 | "printts, (C)2002-2005 Broadcom, Corp.\n" |
|---|
| 220 | "Prints MPEG2 Transport packets.\n"); |
|---|
| 221 | } |
|---|
| 222 | if (!filename || !strcmp(filename, "-")) { |
|---|
| 223 | filename = "stdin"; |
|---|
| 224 | file = stdin; |
|---|
| 225 | } |
|---|
| 226 | else |
|---|
| 227 | file = fopen(filename, "rb"); |
|---|
| 228 | if (file) { |
|---|
| 229 | if (!quiet) { |
|---|
| 230 | printf("Reading from %s\n", filename); |
|---|
| 231 | } |
|---|
| 232 | } |
|---|
| 233 | else { |
|---|
| 234 | printf("Cannot open %s\n", filename); |
|---|
| 235 | } |
|---|
| 236 | |
|---|
| 237 | if (file) { |
|---|
| 238 | int cnt = 0; |
|---|
| 239 | const unsigned char *pkt = &buf[timestamp_offset]; |
|---|
| 240 | |
|---|
| 241 | fseek(file, packetsize * skip, SEEK_SET); |
|---|
| 242 | cnt = skip; |
|---|
| 243 | |
|---|
| 244 | while (!feof(file)) { |
|---|
| 245 | if (fread(buf, 1, packetsize, file) != (size_t)packetsize) |
|---|
| 246 | break; |
|---|
| 247 | /* after reading into buf, always access pkt which skips any timestamp_offset */ |
|---|
| 248 | |
|---|
| 249 | if (pkt[0] != 0x47) { |
|---|
| 250 | printf("packet %d: no header: %x\n", cnt, pkt[0]); |
|---|
| 251 | if (!all) |
|---|
| 252 | break; |
|---|
| 253 | } |
|---|
| 254 | |
|---|
| 255 | if (pidFilter != NULL_PID && pidFilter != b_get_pid(pkt)) |
|---|
| 256 | continue; |
|---|
| 257 | |
|---|
| 258 | if (cc_check) { |
|---|
| 259 | int this_cc = pkt[3] & 0xF; |
|---|
| 260 | int adaptation_field_control = (pkt[3] & 0x30) >> 4; |
|---|
| 261 | |
|---|
| 262 | if (adaptation_field_control != 0 && adaptation_field_control != 2) { |
|---|
| 263 | if (!current_cc.discontinuity && this_cc != current_cc.next) { |
|---|
| 264 | printf("Bad CC %d at packet %d\n", this_cc, cnt); |
|---|
| 265 | } |
|---|
| 266 | current_cc.next = this_cc + 1; |
|---|
| 267 | if (current_cc.next == 0x10) current_cc.next = 0x0; |
|---|
| 268 | current_cc.discontinuity = false; |
|---|
| 269 | } |
|---|
| 270 | } |
|---|
| 271 | |
|---|
| 272 | if (pidonly) { |
|---|
| 273 | printf("pid 0x%x\n", b_get_pid(pkt)); |
|---|
| 274 | } |
|---|
| 275 | else { |
|---|
| 276 | if (!onlyPrintBad) |
|---|
| 277 | printPacket(pkt, packetsize); |
|---|
| 278 | if (do_printTransportHeader) |
|---|
| 279 | printTransportHeader(pkt); |
|---|
| 280 | if (raw) |
|---|
| 281 | printRawPacket(pkt, packetsize); |
|---|
| 282 | } |
|---|
| 283 | cnt++; |
|---|
| 284 | } |
|---|
| 285 | fclose(file); |
|---|
| 286 | } |
|---|
| 287 | return 0; |
|---|
| 288 | } |
|---|