source: svn/newcon3bcm2_21bu/BSEAV/lib/bcmplayer/src/bcmindexer_vc1.c @ 47

Last change on this file since 47 was 47, checked in by megakiss, 11 years ago

459Mhz로 OTC 주파수 변경

  • Property svn:executable set to *
File size: 9.0 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2006-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: bcmindexer_vc1.c $
11 * $brcm_Revision: 7 $
12 * $brcm_Date: 2/25/09 4:48p $
13 *
14 * Module Description: Converts startcode index to bcmplayer index
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/lib/bcmplayer/src/bcmindexer_vc1.c $
19 *
20 * 7   2/25/09 4:48p erickson
21 * PR52471: added const keyword
22 *
23 * 6   1/27/09 9:05a erickson
24 * PR51468: make global symbols static
25 *
26 * 5   1/26/09 1:55p erickson
27 * PR51468: global variable naming convention
28 *
29 * 4   10/22/08 4:59p vishk
30 * PR 48073: Coverity Defect ID:12258 DEADCODE bcmindexer_vc1.c
31 * Product=97401linux
32 *
33 * 3   2/26/08 11:21a katrep
34 * PR38691: Fixed compiler warnings
35 *
36 * 2   9/26/07 6:01p jtna
37 * PR35267: LIB-Coverity (CID 369): NEGATIVE_RETURNS
38 *
39 * Irvine_BSEAVSW_Devel/3   3/9/06 3:49p erickson
40 * PR19853: read correct interlace bit in SEQUENCE and then don't read FCM
41 * is !interlace
42 *
43 * Irvine_BSEAVSW_Devel/2   3/8/06 3:34p erickson
44 * PR19853: set SC offset correctly
45 *
46 * Irvine_BSEAVSW_Devel/1   3/6/06 1:21p erickson
47 * PR19853: added VC1 PES support
48 *
49 ****************************************************************************/
50#include "bstd.h"
51#include "bkni.h"
52#include "bcmindexer.h"
53#include "bcmindexerpriv.h"
54#include "mpeg2types.h"
55
56BDBG_MODULE(bcmindexer_vc1);
57
58#if 0
59#undef BDBG_MSG
60#define BDBG_MSG BDBG_WRN
61#endif
62
63struct vc1_vlc_code {
64    unsigned long bitstring;
65    int length;
66    eSCType frameType;
67};
68
69static const struct vc1_vlc_code g_fcm[] = {
70    {0x0, 1, 0}, /* 0 - progressive */
71    {0x2, 2, 0}, /* 10 - frame-interlace */
72    {0x3, 2, 0}, /* 11 - field-interlace */
73    {0,0,0} /* terminal */
74};
75static const struct vc1_vlc_code g_ptype[] = {
76    {0x6, 3, eSCTypeIFrame}, /* I */
77    {0x0, 1, eSCTypePFrame}, /* P */
78    {0x2, 2, eSCTypeBFrame}, /* B */
79    {0xE, 4, eSCTypeBFrame}, /* BI */
80    {0xF, 4, eSCTypeBFrame}, /* skipped */
81    {0,0,0} /* terminal */
82};
83static const struct vc1_vlc_code g_fptype[] = {
84    {0x0, 3, eSCTypeIFrame}, /* I,I */
85    {010, 3, eSCTypePFrame}, /* I,P */
86    {0x2, 3, eSCTypePFrame}, /* P,I */
87    {0x3, 3, eSCTypePFrame}, /* P,P */
88    {0x4, 3, eSCTypeBFrame}, /* B,B */
89    {0x5, 3, eSCTypeBFrame}, /* B,BI */
90    {0x6, 3, eSCTypeBFrame}, /* BI,B */
91    {0x7, 3, eSCTypeBFrame}, /* BI,BI */
92    {0,0,0} /* terminal */
93};
94
95static const unsigned char g_mask[] = {0,1,3,7,0xf};
96
97static int BNAV_Indexer_completeVC1Frame(BNAV_Indexer_Handle handle)
98{
99    return BNAV_Indexer_completeFrameAux(handle, &handle->avcEntry, sizeof(handle->avcEntry));
100}
101
102static int b_vc1_vlc_decode(const uint8_t *data, unsigned size, unsigned current_index,
103    unsigned current_bit, unsigned *next_index, unsigned *next_bit,const struct vc1_vlc_code *pattern)
104{
105    int i;
106    BSTD_UNUSED(size);
107    /* TODO: make it span bytes, if needed. don't think so for vc1. */
108    for (i=0;pattern[i].length;i++) {
109        unsigned char d = data[0] >> (current_bit - pattern[i].length + 1);
110        d &= g_mask[pattern[i].length];
111        if (d == pattern[i].bitstring) {
112            *next_index = current_index;
113            *next_bit = current_bit - pattern[i].length;
114            return i;
115        }
116    }
117    return -1;
118}
119
120static void BNAV_P_ProcessPES(BNAV_Indexer_Handle handle)
121{
122    unsigned char *buf = handle->pes.buf;
123    unsigned char sc = buf[0];
124    const unsigned char *payload = &buf[1];
125    unsigned index = 0, bit = 7;
126    BNAV_AVC_Entry *entry = &handle->avcEntry;
127
128#define VC1_SC_FRAME 0x0D
129#define VC1_SC_ENTRYPOINT 0x0E
130#define VC1_SC_SEQUENCE 0x0F
131
132    /* TODO: detect PES start code and capture PTS */
133
134    if (sc != VC1_SC_FRAME && sc != VC1_SC_ENTRYPOINT && sc != VC1_SC_SEQUENCE) {
135        return;
136    }
137
138    BDBG_MSG(("SC %02x", sc));
139
140    /* complete any pending SEQUENCE or ENTRYPOINT */
141    if (handle->pes.sequence_size == -1) {
142        handle->pes.sequence_size = handle->pes.offset - handle->pes.sequence_offset;
143    }
144    else if (handle->pes.entrypoint_size == -1) {
145        handle->pes.entrypoint_size = handle->pes.offset - handle->pes.entrypoint_offset;
146    }
147
148    /* complete any pending frame */
149    handle->picEnd = handle->pes.offset;
150    BNAV_Indexer_completeVC1Frame(handle);
151
152    /* coverity[dead_error_condition] */
153    switch (sc) {
154    case VC1_SC_FRAME:
155        {
156        int fcm, ptype;
157
158/* TODO: I/P or P/I after EP can be I */
159        if (handle->pes.vc1_interlace) {
160            fcm = b_vc1_vlc_decode(payload, MIN_PES_PAYLOAD, index, bit, &index, &bit, g_fcm);
161            BDBG_MSG(("  fcm %d", fcm));
162        }
163        else {
164            fcm = 0;
165        }
166
167        switch (fcm) {
168        case 0: /* progressive */
169        case 1: /* frame interlace */
170            ptype = b_vc1_vlc_decode(payload, MIN_PES_PAYLOAD, index, bit, &index, &bit, g_ptype);
171            if (ptype > -1 && ptype < 5) {
172                BNAV_set_frameType(entry, g_ptype[ptype].frameType);
173            }
174            else {
175                BDBG_ERR(("  invalid PTYPE %d", ptype));
176            }
177            break;
178        case 2: /* field interlace */
179            ptype = b_vc1_vlc_decode(payload, MIN_PES_PAYLOAD, index, bit, &index, &bit, g_fptype);
180            if (ptype > -1 && ptype < 8) {
181                BNAV_set_frameType(entry, g_fptype[ptype].frameType);
182            }
183            else {
184                BDBG_ERR(("  invalid FPTYPE %d", ptype));
185            }
186            break;
187        default:
188            BDBG_ERR(("  invalid FCM %d", fcm));
189            return;
190        }
191
192        if (BNAV_get_frameType(entry) == eSCTypeIFrame && handle->pes.entrypoint_size && handle->pes.sequence_size) {
193            handle->hitFirstISlice = 1;
194        }
195
196        handle->picStart = handle->pes.offset;
197        BNAV_set_frameOffsetLo(entry, handle->pes.offset & 0xFFFFFFFF);
198        BNAV_set_frameOffsetHi(entry, handle->pes.offset >> 32);
199
200        /* Set Sequence offset (using SeqHdr) and Entrypoint offset (using SPS) */
201        BNAV_set_seqHdrStartOffset(entry, (unsigned long)(handle->pes.offset - handle->pes.sequence_offset));
202        BNAV_set_seqHdrSize(entry, handle->pes.sequence_size);
203        BNAV_set_SPS_Offset(entry, (unsigned long)(handle->pes.offset - handle->pes.entrypoint_offset));
204        BNAV_set_SPS_Size(entry, handle->pes.entrypoint_size);
205        BDBG_MSG(("frame %x, %x, %x, %x, %x",handle->pes.offset,handle->pes.sequence_offset,handle->pes.sequence_size,
206            handle->pes.entrypoint_offset,handle->pes.entrypoint_size));
207        }
208        break;
209
210    case VC1_SC_ENTRYPOINT:
211        {
212        handle->pes.entrypoint_offset = handle->pes.offset;
213        handle->pes.entrypoint_size = -1; /* pending completion */
214        }
215        break;
216
217    case VC1_SC_SEQUENCE:
218        {
219        handle->pes.vc1_interlace = payload[5] & 0x40; /* 42nd bit after SC */
220        BDBG_MSG(("  interlace? %s", handle->pes.vc1_interlace?"yes":"no"));
221
222        handle->pes.sequence_offset = handle->pes.offset;
223        handle->pes.sequence_size = -1; /* pending completion */
224        }
225        break;
226    /* coverity[dead_error_begin] */
227    default:
228        break;
229    }
230}
231
232int BNAV_P_FeedPES_VC1(BNAV_Indexer_Handle handle, uint8_t *p_bfr, unsigned size)
233{
234    unsigned i;
235
236    BDBG_ASSERT(handle->settings.navVersion == BNAV_Version_VC1_PES);
237
238    /* search for start codes */
239    for (i=0; i<size; i++, handle->pes.offset++) {
240        if (handle->pes.sccount == 3) {
241            int required = MIN_PES_PAYLOAD - handle->pes.bufsize;
242            int available = size - i;
243            int n;
244
245            /* memcpy as much as possible, up to required */
246            n = required;
247            if (n > available) n = available;
248            BKNI_Memcpy((void*)&(handle->pes.buf[handle->pes.bufsize]), &p_bfr[i], n);
249            handle->pes.bufsize += n;
250
251            /* check if we have enough to process the header */
252            if (handle->pes.bufsize < MIN_PES_PAYLOAD) {
253                /* wait for next feed */
254                return 0;
255            }
256
257            /* process the start code & header */
258            handle->pes.offset -= 3; /* back up to start of 00 00 01 SC */
259            BNAV_P_ProcessPES(handle);
260            handle->pes.offset += 3;
261            handle->pes.sccount = 0;
262            handle->pes.bufsize = 0; /*: TODO: not actually correct */
263        }
264
265        switch (p_bfr[i]) {
266        case 0:
267            if (handle->pes.sccount >= 1)
268                handle->pes.sccount = 2;
269            else
270                handle->pes.sccount = 1;
271            break;
272        case 1:
273            if (handle->pes.sccount == 2) {
274                /* we've got a start code! */
275                handle->pes.sccount = 3;
276            }
277            break;
278        default:
279            handle->pes.sccount = 0;
280            break;
281        }
282    }
283    return 0;
284}
Note: See TracBrowser for help on using the repository browser.