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

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

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 9.6 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: printavc.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/printavc.c $
19 *
20 * 2   10/28/09 1:30p erickson
21 * SW7405-3287: move common code to ts_utils
22 *
23 * Irvine_BSEAVSW_Devel/7   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/6   2/13/06 12:47p erickson
28 * PR17108: added -pictypes
29 *
30 * Irvine_BSEAVSW_Devel/5   2/6/06 5:15p erickson
31 * PR17108: added -slices, implemented stdin
32 *
33 * Irvine_BSEAVSW_Devel/4   1/6/06 10:16a erickson
34 * PR17108: updated for magnum basemodules and 64 bit cpus
35 *
36 * Irvine_BSEAVSW_Devel/3   12/14/05 1:12p erickson
37 * PR17108: add startcode to normal print
38 *
39 * Irvine_BSEAVSW_Devel/2   9/2/05 5:34p erickson
40 * PR16964: print all start codes (even if not NAL headers)
41 *
42 * Irvine_BSEAVSW_Devel/1   9/1/05 3:38p erickson
43 * PR16964: added printavc to print NAL headers from AVC ES streams
44 *
45 * Irvine_BSEAVSW_Devel/2   8/19/05 4:00p erickson
46 * PR16208: fixed cmdline
47 *
48 * Irvine_BSEAVSW_Devel/1   8/8/05 3:57p erickson
49 * PR16138: added printpes util
50 *
51 *************************************************************************/
52#include <stdlib.h>
53#include <stdio.h>
54#include <string.h>
55#include <errno.h>
56#include <stdbool.h>
57#include <stdint.h>
58#include "bvlc.h"
59#include "bkni.h"
60#include "ts_utils.h"
61
62/* TODO: don't know actual max */
63#define MAX_HEADER_SIZE 100
64#define TOTAL_PAYLOAD MAX_HEADER_SIZE
65
66const char *nal_unit_type_str[] = {
67    "unspecified",
68    "non-IDR slice",
69    "slice partition A",
70    "slice partition B",
71    "slice partition C",
72    "IDR slice",
73    "SEI",
74    "SPS",
75    "PPS",
76    "AU",
77    "EndOfSequence",
78    "EndOfStream",
79    "Filler",
80    "Reserved","Reserved","Reserved","Reserved","Reserved","Reserved","Reserved","Reserved","Reserved","Reserved","Reserved",
81    "Unspecified","Unspecified","Unspecified","Unspecified","Unspecified","Unspecified","Unspecified","Unspecified"
82};
83
84void print_nal_header(const unsigned char *buf, unsigned long offset)
85{
86    unsigned char sc = buf[0];
87    const unsigned char *payload = &buf[1];
88    int nal_ref_idc;
89    int nal_unit_type;
90    unsigned index = 0, bit = 7;
91
92    if (sc & 0x80) {
93        /* if forbidden_zero_bit is set, this is not an AVC start code */
94        printf("0x%08lx SC %#x\n", offset, sc);
95        return;
96    }
97
98    nal_ref_idc = (sc >> 5) & 0x3;
99    nal_unit_type = sc & 0x1F;
100
101    printf("0x%08lx %s (SC %02x)\n", offset, nal_unit_type_str[nal_unit_type], sc);
102
103    switch (nal_unit_type) {
104    case 1: /* non-IDR slice */
105    case 5: /* IDR slice */
106        {
107        unsigned first_mb_in_slice, slice_type, pic_parameter_set_id;
108
109        /* vlc decode the payload */
110        first_mb_in_slice = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
111        slice_type = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
112        pic_parameter_set_id = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
113
114        printf(
115            "  first_mb_in_slice = %d\n"
116            "  slice_type = %d\n"
117            "  pps_id %d\n",
118                first_mb_in_slice,
119                slice_type,
120                pic_parameter_set_id);
121        }
122        break;
123    case 7: /* sequence parameter set */
124        {
125        unsigned profile_idc, constraint_flags, level_idc, seq_parameter_set_id;
126
127        /* parse and vlc decode the payload */
128        profile_idc = payload[0];
129        constraint_flags = payload[1];
130        level_idc = payload[2];
131        index = 3;
132        seq_parameter_set_id = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
133
134        printf(
135            "  SPS=%d\n"
136            "  profile_idc=%d flags=0x%x level_idc=%d\n",
137            seq_parameter_set_id,
138            profile_idc, constraint_flags, level_idc);
139        }
140        break;
141    case 8: /* picture parameter set */
142        {
143        unsigned pic_parameter_set_id, seq_parameter_set_id;
144
145        /* vlc decode payload */
146        pic_parameter_set_id = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
147        seq_parameter_set_id = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
148
149        printf("  PPS=%d, SPS=%d\n", pic_parameter_set_id, seq_parameter_set_id);
150        }
151        break;
152
153    case 9: /* access unit delimiter */
154        {
155        static const char *primary_pic_type_str[] = {
156            "I",
157            "I,P",
158            "I,P,B",
159            "SI",
160            "SI,SP",
161            "I,SI",
162            "I,SI,P,SP",
163            "I,SI,P,SP,B"
164        };
165        int primary_pic_type;
166        primary_pic_type = (payload[0] >> 5) & 0x3;
167
168        printf("  primary_pic_type=%d (%s)\n", primary_pic_type, primary_pic_type_str[primary_pic_type]);
169        }
170        break;
171    }
172}
173
174void print_pictypes(const unsigned char *buf)
175{
176    unsigned char sc = buf[0];
177    const unsigned char *payload = &buf[1];
178    int nal_ref_idc;
179    int nal_unit_type;
180    unsigned index = 0, bit = 7;
181
182    nal_ref_idc = (sc >> 5) & 0x3;
183    nal_unit_type = sc & 0x1F;
184
185    switch (nal_unit_type) {
186    case 1: /* non-IDR slice */
187    case 5: /* IDR slice */
188        {
189        unsigned first_mb_in_slice, slice_type, pic_parameter_set_id;
190
191        /* vlc decode the payload */
192        first_mb_in_slice = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
193        slice_type = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
194        pic_parameter_set_id = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
195
196        if (first_mb_in_slice == 0) {
197            if (nal_unit_type == 5)
198                printf("IDR\n");
199            else
200                printf("non-IDR\n");
201        }
202        }
203        break;
204    case 7: /* sequence parameter set */
205    case 8: /* picture parameter set */
206    case 9: /* access unit delimiter */
207        break;
208    }
209}
210
211int g_slices = 0;
212void complete_picture()
213{
214    printf("%d\n", g_slices);
215    g_slices = 0;
216}
217
218void count_slices(const unsigned char *buf)
219{
220    unsigned char sc = buf[0];
221    const unsigned char *payload = &buf[1];
222    int nal_ref_idc;
223    int nal_unit_type;
224    unsigned index = 0, bit = 7;
225
226    nal_ref_idc = (sc >> 5) & 0x3;
227    nal_unit_type = sc & 0x1F;
228
229    switch (nal_unit_type) {
230    case 1: /* non-IDR slice */
231    case 5: /* IDR slice */
232        {
233        unsigned first_mb_in_slice;
234
235        /* vlc decode the payload */
236        first_mb_in_slice = b_vlc_decode(payload, TOTAL_PAYLOAD, index, bit, &index, &bit);
237        if (first_mb_in_slice==0 && g_slices) {
238            complete_picture();
239        }
240        g_slices++;
241
242        }
243        break;
244    case 7: /* sequence parameter set */
245    case 8: /* picture parameter set */
246    case 9: /* access unit delimiter */
247        if (g_slices) {
248            complete_picture();
249        }
250        break;
251    }
252}
253
254void print_usage()
255{
256    printf("Usage: printavc [-slices] [AVC_ES_FILENAME]\n");
257    printf("\n");
258    printf("-slices            print the # of slices per picture\n");
259    printf("-pictypes          print the type of each picture\n");
260    printf("AVC_ES_FILENAME    optional filename, otherwise stdin\n");
261}
262
263int main(int argc, char **argv) {
264    FILE *fin = stdin;
265#define BUFSIZE 4096
266    unsigned char buf[BUFSIZE];
267    int sccount = 0;
268    int curarg = 1;
269    int slices = 0;
270    int pictypes = 0;
271    uint64_t fileoffset = 0;
272
273    BKNI_Init();
274    BDBG_Init();
275
276    while (curarg < argc) {
277        if (!strcmp(argv[curarg], "-slices")) {
278            slices = 1;
279            curarg++;
280        }
281        else if (!strcmp(argv[curarg], "--help")) {
282            print_usage();
283            exit(0);
284        }
285        else if (!strcmp(argv[curarg], "-pictypes")) {
286            pictypes = 1;
287            curarg++;
288        }
289    }
290
291    if (curarg < argc) {
292        fin = fopen(argv[curarg], "r");
293        if (!fin)
294            return printf("Unable to open %s: %d\n", argv[curarg], errno);
295    }
296    else {
297        fin = stdin;
298    }
299
300    while (!feof(fin)) {
301        int i;
302        int n;
303
304        n = fread(buf, 1, BUFSIZE, fin);
305        if (n == -1) break;
306
307        /* search for start codes */
308        for (i=0; i<n; i++) {
309            if (sccount == 3) {
310                /* check if we have enough to process the header */
311                if (n - i < MAX_HEADER_SIZE) {
312                    /* move the remainder of the old read to the head of the buffer */
313                    memcpy(buf, &buf[i], n-i);
314                    fileoffset += i;
315                    n -= i;
316                    i = 0;
317
318                    /* read more */
319                    n += fread(&buf[n], 1, BUFSIZE-n, fin);
320                    if (n < MAX_HEADER_SIZE)
321                        break;
322                }
323                if (slices) {
324                    count_slices(&buf[i]);
325                }
326                else if (pictypes) {
327                    print_pictypes(&buf[i]);
328                }
329                else {
330                    print_nal_header(&buf[i], fileoffset+i-3);
331                }
332
333                sccount = 0;
334            }
335
336            sccount = b_check_for_start_code(buf[i], sccount);
337        }
338        fileoffset += n;
339    }
340    return 0;
341}
342
Note: See TracBrowser for help on using the repository browser.