source: svn/trunk/newcon3bcm2_21bu/BSEAV/lib/bcmplayer/utils/printvc1.c @ 2

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

first commit

  • Property svn:executable set to *
File size: 9.7 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2002-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: printvc1.c $
11 * $brcm_Revision: 2 $
12 * $brcm_Date: 10/28/09 1:30p $
13 *
14 * Module Description: print out contents of PES stream
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/lib/bcmplayer/utils/printvc1.c $
19 *
20 * 2   10/28/09 1:30p erickson
21 * SW7405-3287: move common code to ts_utils
22 *
23 * Irvine_BSEAVSW_Devel/2   6/30/06 9:39a erickson
24 * PR21941: fix start code detection algorithm, and eliminate duplication
25 * by moving to ts_utils
26 *
27 * Irvine_BSEAVSW_Devel/1   3/7/06 6:53a erickson
28 * PR17108: fix warnings
29 *
30 *************************************************************************/
31#include <stdlib.h>
32#include <stdio.h>
33#include <string.h>
34#include <errno.h>
35#include <stdbool.h>
36#include <stdint.h>
37#include "ts_utils.h"
38
39/* TODO: don't know actual max */
40#define MAX_HEADER_SIZE 100
41#define TOTAL_PAYLOAD MAX_HEADER_SIZE
42
43/* start code suffixes */
44const char *scs_str[] = {
45    "reserved",
46    "reserved","reserved","reserved","reserved","reserved","reserved","reserved","reserved","reserved",
47    "End of Sequence",
48    "Slice",
49    "Field",
50    "Frame",
51    "Entry-point",
52    "Sequence",
53    "reserved","reserved","reserved","reserved","reserved","reserved","reserved","reserved","reserved","reserved","reserved",
54    "Slice User Data",
55    "Field User Data",
56    "Frame User Data",
57    "Entry-point User Data",
58    "Sequence User Data" /* 0x1f */
59};
60
61const char *ptype_str[] = {
62    "I",
63    "P",
64    "B",
65    "BI",
66    "skipped"
67};
68
69const char *fptype_str[] = {
70    "I,I",
71    "I,P",
72    "P,I",
73    "P,P",
74    "B,B",
75    "B,BI",
76    "BI,B",
77    "BI,BI"
78};
79
80bool g_seq_interlace = false;
81
82struct vc1_vlc_code {
83    unsigned long bitstring;
84    int length;
85};
86
87struct vc1_vlc_code g_fcm[] = {
88    {0x0, 1}, /* 0 - progressive */
89    {0x2, 2}, /* 10 - frame-interlace */
90    {0x3, 2}, /* 11 - field-interlace */
91    {0,0} /* terminal */
92};
93struct vc1_vlc_code g_ptype[] = {
94    {0x6, 3}, /* I */
95    {0x0, 1}, /* P */
96    {0x2, 2}, /* B */
97    {0xE, 4}, /* BI */
98    {0xF, 4}, /* skipped */
99    {0,0} /* terminal */
100};
101struct vc1_vlc_code g_fptype[] = {
102    {0x0, 3}, /* I,I */
103    {010, 3}, /* I,P */
104    {0x2, 3}, /* P,I */
105    {0x3, 3}, /* P,P */
106    {0x4, 3}, /* B,B */
107    {0x5, 3}, /* B,BI */
108    {0x6, 3}, /* BI,B */
109    {0x7, 3}, /* BI,BI */
110    {0,0} /* terminal */
111};
112
113unsigned char g_mask[] = {0,1,3,7,0xf};
114
115int b_vc1_vlc_decode(
116    const uint8_t *data,            /* [size_is(size)] Array of bytes which contain a vlc encoded value */
117    unsigned size,          /* Size of data */
118    unsigned current_index, /* The starting index the data array. */
119    unsigned current_bit,   /* The bit in data[current_index] where the vlc decode should start.
120                                vlc decode proceeds from MSB to LSB, so the first
121                                bit will be 7. */
122    unsigned *next_index, /* [out] the index in data which should be used for an
123                                adjacent vlc decode. Can be NULL. */
124    unsigned *next_bit,     /* [out] the bit in data[index] which should be used for an
125                                adjacent vlc decode. Can be NULL. */
126    const struct vc1_vlc_code *pattern
127    )
128{
129    int i;
130    size = 0; /* avoid warning */
131
132    /* TODO: make it span bytes, if needed. don't think so for vc1. */
133    for (i=0;pattern[i].length;i++) {
134        unsigned char d = data[0] >> (current_bit - pattern[i].length + 1);
135        d &= g_mask[pattern[i].length];
136        if (d == pattern[i].bitstring) {
137            *next_index = current_index;
138            *next_bit = current_bit - pattern[i].length;
139            return i;
140        }
141    }
142    return -1;
143}
144
145void print_scs(const unsigned char *buf, unsigned long offset)
146{
147    unsigned char sc = buf[0];
148    const unsigned char *payload = &buf[1];
149    unsigned index = 0, bit = 7;
150
151    if (sc > 0x1f) {
152        /* reserved and forbidden */
153        return;
154    }
155
156    printf("0x%08lx %s (SC %02x)\n", offset, scs_str[sc], sc);
157
158    switch (sc) {
159    case 0x0D: /* frame */
160        {
161        int fcm, ptype;
162
163        fcm = b_vc1_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit, g_fcm);
164        printf("  fcm %d\n", fcm);
165        switch (fcm) {
166        case 0: /* progressive */
167        case 1: /* frame interlace */
168            ptype = b_vc1_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit, g_ptype);
169            if (ptype < 5) {
170                printf("  PTYPE %s\n", ptype_str[ptype]);
171            }
172            else {
173                printf("  invalid PTYPE %d\n", ptype);
174            }
175            break;
176        case 2: /* field interlace */
177            ptype = b_vc1_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit, g_fptype);
178            if (ptype < 8) {
179                printf("  FPTYPE %s\n", fptype_str[ptype]);
180            }
181            else {
182                printf("  invalid FPTYPE %d\n", ptype);
183            }
184            break;
185        default:
186            printf("  invalid FCM %d\n", fcm);
187            return;
188        }
189        }
190        break;
191
192    case 0x0F: /* sequence */
193        {
194        g_seq_interlace = buf[5] & 0x40; /* 42nd bit after SC */
195        printf("  interlace? %s\n", g_seq_interlace?"yes":"no");
196        }
197        break;
198    }
199}
200
201#if 0
202void print_pictypes(const unsigned char *buf)
203{
204    unsigned char sc = buf[0];
205    const unsigned char *payload = &buf[1];
206
207    switch (nal_unit_type) {
208    case 1: /* non-IDR slice */
209    case 5: /* IDR slice */
210        {
211        unsigned first_mb_in_slice, slice_type, pic_parameter_set_id;
212
213        /* vlc decode the payload */
214        first_mb_in_slice = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
215        slice_type = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
216        pic_parameter_set_id = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
217
218        if (first_mb_in_slice == 0) {
219            if (nal_unit_type == 5)
220                printf("IDR\n");
221            else
222                printf("non-IDR\n");
223        }
224        }
225        break;
226    case 7: /* sequence parameter set */
227    case 8: /* picture parameter set */
228    case 9: /* access unit delimiter */
229        break;
230    }
231}
232
233int g_slices = 0;
234void complete_picture()
235{
236    printf("%d\n", g_slices);
237    g_slices = 0;
238}
239
240void count_slices(const unsigned char *buf)
241{
242    unsigned char sc = buf[0];
243    const unsigned char *payload = &buf[1];
244    int nal_ref_idc;
245    int nal_unit_type;
246    unsigned index = 0, bit = 7;
247
248    nal_ref_idc = (sc >> 5) & 0x3;
249    nal_unit_type = sc & 0x1F;
250
251    switch (nal_unit_type) {
252    case 1: /* non-IDR slice */
253    case 5: /* IDR slice */
254        {
255        unsigned first_mb_in_slice;
256
257        /* vlc decode the payload */
258        first_mb_in_slice = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
259        if (first_mb_in_slice==0 && g_slices) {
260            complete_picture();
261        }
262        g_slices++;
263
264        }
265        break;
266    case 7: /* sequence parameter set */
267    case 8: /* picture parameter set */
268    case 9: /* access unit delimiter */
269        if (g_slices) {
270            complete_picture();
271        }
272        break;
273    }
274}
275#endif
276
277void print_usage()
278{
279    printf("Usage: printvc1 [-slices] [VC1_ES_FILENAME]\n");
280    printf("\n");
281#if 0
282    printf("-slices            print the # of slices per picture\n");
283    printf("-pictypes          print the type of each picture\n");
284#endif
285    printf("VC1_ES_FILENAME    optional filename, otherwise stdin\n");
286}
287
288int main(int argc, char **argv) {
289    FILE *fin = stdin;
290#define BUFSIZE 4096
291    unsigned char buf[BUFSIZE];
292    int sccount = 0;
293    int curarg = 1;
294    int slices = 0;
295    int pictypes = 0;
296    uint64_t fileoffset = 0;
297
298    while (curarg < argc) {
299        if (!strcmp(argv[curarg], "-slices")) {
300            slices = 1;
301            curarg++;
302        }
303        else if (!strcmp(argv[curarg], "--help")) {
304            print_usage();
305            exit(0);
306        }
307        else if (!strcmp(argv[curarg], "-pictypes")) {
308            pictypes = 1;
309            curarg++;
310        }
311    }
312
313    if (curarg < argc) {
314        fin = fopen(argv[curarg], "r");
315        if (!fin)
316            return printf("Unable to open %s: %d\n", argv[curarg], errno);
317    }
318    else {
319        fin = stdin;
320    }
321
322    while (!feof(fin)) {
323        int i;
324        int n;
325
326        n = fread(buf, 1, BUFSIZE, fin);
327        if (n == -1) break;
328
329        /* search for start codes */
330        for (i=0; i<n; i++) {
331            if (sccount == 3) {
332                /* check if we have enough to process the header */
333                if (n - i < MAX_HEADER_SIZE) {
334                    /* move the remainder of the old read to the head of the buffer */
335                    memcpy(buf, &buf[i], n-i);
336                    fileoffset += i;
337                    n -= i;
338                    i = 0;
339
340                    /* read more */
341                    n += fread(&buf[n], 1, BUFSIZE-n, fin);
342                    if (n < MAX_HEADER_SIZE)
343                        break;
344                }
345#if 0
346                if (slices) {
347                    count_slices(&buf[i]);
348                }
349                else if (pictypes) {
350                    print_pictypes(&buf[i]);
351                }
352                else
353#endif
354                {
355                    print_scs(&buf[i], fileoffset+i-3);
356                }
357
358                sccount = 0;
359            }
360
361            sccount = b_check_for_start_code(buf[i], sccount);
362        }
363        fileoffset += n;
364    }
365    return 0;
366}
367
Note: See TracBrowser for help on using the repository browser.