source: svn/newcon3bcm2_21bu/BSEAV/api/src/nexus/bsettop_playpump.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 14.4 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2004-2010, 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: bsettop_playpump.c $
11 * $brcm_Revision: 28 $
12 * $brcm_Date: 6/10/10 2:45p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /BSEAV/api/src/nexus/bsettop_playpump.c $
19 *
20 * 28   6/10/10 2:45p mphillip
21 * SW7550-380: Enable non-DMA PVR encryption for 7550 and similar
22 * platforms
23 *
24 * 27   2/11/10 2:54p erickson
25 * SW7550-252: fix dma/security testes
26 *
27 * 26   6/15/09 4:59p jtna
28 * PR43001: add support for TTS+encryption record/playback
29 *
30 * 25   6/12/09 11:10a jtna
31 * PR43001: support TS/TTS record
32 *
33 * 24   12/24/08 12:42p mphillip
34 * PR49607: Keyladder key derivation support added for encrypted PVR in
35 * nexus shim
36 *
37 * 23   12/24/08 11:56a jgarrett
38 * PR 50703: Allowing security module to be absent
39 *
40 * 22   10/31/08 12:30p jjordan
41 * PR47230: Add TTS Pacing
42 *
43 * PR47230/1   10/28/08 10:37a jjordan
44 * PR47230: Port TTS Pacing to Nexus
45 *
46 * 21   10/7/08 11:33p erickson
47 * PR47232: NEXUS_PlaypumpSettings.timestamp api change
48 *
49 * 20   7/24/08 7:21p lwhite
50 * PR45136: Use default settings in bplaypump_start
51 *
52 * 19   7/22/08 10:14a ssood
53 * PR42739: moving the rtp header stats function to ip applib
54 *
55 * 18   7/21/08 5:22p katrep
56 * PR42739: Fixed compilation errors in IP build
57 *
58 * 17   7/15/08 9:32a erickson
59 * PR42739: fix non-ip builds
60 *
61 * 16   7/14/08 4:29p lwhite
62 * PR42739: Added RTCP support
63 *
64 * 15   7/10/08 10:21p ssood
65 * PR42739: Adding support to absorb high jitter for Live IP
66 *
67 * 14   7/10/08 3:23p katrep
68 * PR43636: Add support MSDRM ND
69 *
70 * 13   6/27/08 3:36p mphillip
71 * PR42901: Free PVR keyslot on close/stop
72 *
73 * 12   6/26/08 6:21p mphillip
74 * PR42901: Encrypted PVR playback support
75 *
76 * 11   6/25/08 6:12p vsilyaev
77 * PR 41869: Use keySlotHandle instead of keySlot[Number]
78 *
79 * 10   6/24/08 4:29p erickson
80 * PR43222: add BDBG_CASSERT
81 *
82 * 9   6/12/08 9:07p katrep
83 * PR43636: Add support for MSDRM
84 *
85 * 8   5/2/08 9:20a erickson
86 * PR42339: fix pid channel alloc for PVR
87 *
88 * 7   4/28/08 11:54a erickson
89 * PR42197: remove NEXUS_ParserBand_ePlayback enums
90 *
91 * 6   4/7/08 10:40a jgarrett
92 * PR 41362: Revising pid channel management
93 *
94 * 5   4/3/08 5:41p jgarrett
95 * PR 41312: Setting callback events
96 *
97 * 4   12/4/07 3:09p erickson
98 * PR36068: remove packetize
99 *
100 * 3   11/14/07 1:29p erickson
101 * PR36068: added record
102 *
103 * 2   11/13/07 11:58a erickson
104 * PR36068: trick modes working
105 *
106 * 1   10/15/07 2:36p erickson
107 * PR36068: initial
108 *
109 *******************************************************************************/
110#include "bsettop_impl.h"
111
112#if defined(B_HAS_IP)
113#include "b_playback_ip_lib.h"
114#endif
115BDBG_MODULE(playpump);
116
117BDBG_OBJECT_ID(bplaypump);
118
119static void bplaypump_p_callback_handler(void *context);
120
121void bplaypump_get_open_params(bobject_t id, bplaypump_open_params *open_params)
122{
123    BSTD_UNUSED(id);
124    open_params->buffer_size = B_PVR_PLAYBACK_BUFFER;
125    open_params->num_descriptors = B_PVR_N_PLAYBACK_DESC;
126    open_params->alignment = 12; /* 4096 bytes (block size) aligment */
127}
128
129bplaypump_t bplaypump_open(bobject_t id, const bplaypump_open_params *open_params)
130{
131    bplaypump_t playpump;
132    NEXUS_PlaypumpOpenSettings openSettings;
133    unsigned index = B_ID_GET_INDEX(id);
134    bplaypump_open_params default_open_params;
135
136    if (!open_params) {
137        bplaypump_get_open_params(id, &default_open_params);
138        open_params = &default_open_params;
139    }
140
141    playpump = BKNI_Malloc(sizeof(*playpump));
142    BKNI_Memset(playpump, 0, sizeof(*playpump));
143    BDBG_OBJECT_SET(playpump, bplaypump);
144    playpump->index = index;
145
146    NEXUS_Playpump_GetDefaultOpenSettings(&openSettings);
147    openSettings.fifoSize = open_params->buffer_size;
148    openSettings.alignment = open_params->alignment;
149    openSettings.numDescriptors = open_params->num_descriptors;
150    playpump->nPlaypump = NEXUS_Playpump_Open(index, &openSettings);
151    if (!playpump->nPlaypump) {
152        BSETTOP_ERROR(berr_external_error);
153        BDBG_OBJECT_DESTROY(playpump, bplaypump);
154        BKNI_Free(playpump);
155        return NULL;
156    }
157
158    playpump->event = B_Event_Create(NULL);
159    if ( NULL == playpump->event )
160    {
161        BSETTOP_ERROR(berr_external_error);
162        NEXUS_Playpump_Close(playpump->nPlaypump);
163        BDBG_OBJECT_DESTROY(playpump, bplaypump);
164        BKNI_Free(playpump);
165        return NULL;
166    }
167    playpump->eventId = b_event_register(playpump->event, bplaypump_p_callback_handler, playpump);
168    if ( NULL == playpump->eventId )
169    {
170        BSETTOP_ERROR(berr_external_error);
171        B_Event_Destroy(playpump->event);
172        NEXUS_Playpump_Close(playpump->nPlaypump);
173        BDBG_OBJECT_DESTROY(playpump, bplaypump);
174        BKNI_Free(playpump);
175        return NULL;
176    }
177
178    return playpump;
179}
180
181void bplaypump_close(bplaypump_t playpump)
182{
183    BDBG_OBJECT_ASSERT(playpump, bplaypump);
184    b_event_unregister(playpump->eventId);
185    B_Event_Destroy(playpump->event);
186    NEXUS_Playpump_Close(playpump->nPlaypump);
187    BDBG_OBJECT_DESTROY(playpump, bplaypump);
188    BKNI_Free(playpump);
189}
190
191void bplaypump_params_init(bplaypump_params *params, bplaypump_t playpump)
192{
193    BDBG_OBJECT_ASSERT(playpump, bplaypump);
194    BKNI_Memset(params, 0, sizeof(*params));
195    params->route_through_parser_band = true;
196}
197
198void bplaypump_p_read_callback(void *context, int param)
199{
200    bplaypump_t playpump = (bplaypump_t)context;
201    BDBG_OBJECT_ASSERT(playpump, bplaypump);
202    B_Event_Set(playpump->event);
203    BSTD_UNUSED(param);
204}
205
206static void bplaypump_p_callback_handler(void *context)
207{
208    bplaypump_t playpump = (bplaypump_t)context;
209    BDBG_OBJECT_ASSERT(playpump, bplaypump);
210    if (playpump->params.read_callback) {
211        b_unlock();
212        (*playpump->params.read_callback)(playpump->params.callback_context);
213        b_lock();
214    }
215}
216
217bstream_t bplaypump_start(bplaypump_t playpump, const bstream_mpeg *mpeg, const bplaypump_params *params)
218{
219    NEXUS_Error rc;
220    NEXUS_PlaypumpSettings nSettings;
221
222    BDBG_OBJECT_ASSERT(playpump, bplaypump);
223    if (playpump->stream) {
224        BDBG_ERR(("already playing"));
225        return NULL;
226    }
227
228    NEXUS_Playpump_GetDefaultSettings(&nSettings);
229    nSettings.transportType = b_mpegtype2nexus(mpeg->mpeg_type);
230    nSettings.timestamp.pacing = params->timestamp_active;
231    nSettings.timestamp.type = params->timestamp_enabled ?
232        NEXUS_TransportTimestampType_eMod300 : /* TODO: DSS */
233        NEXUS_TransportTimestampType_eNone;
234#ifdef B_HAS_IP
235        if(params->timestamp_enabled && params->timestamp_active) {
236                nSettings.timestamp.pacingMaxError = params->pacing_max_error;
237                nSettings.timestamp.pacingOffsetAdjustDisable = true;
238                nSettings.timestamp.parityCheckDisable = true;
239                nSettings.timestamp.resetPacing = true;
240                nSettings.timestamp.type = NEXUS_TransportTimestampType_eBinary;
241        }
242#endif
243
244    if (nSettings.timestamp.type==NEXUS_TransportTimestampType_eNone) {
245        /* this affects playback TS => record TTS and should be harmless for all other cases.
246           necessary here because playpump is not aware of its consumers */
247        nSettings.timestamp.forceRestamping = true;
248    }
249
250    if (params->read_callback) {
251        nSettings.dataCallback.callback = bplaypump_p_read_callback;
252        nSettings.dataCallback.context = playpump;
253    }
254    else {
255        nSettings.dataCallback.callback = NULL;
256    }
257
258    if (mpeg->mpeg_type == bstream_mpeg_type_ts && mpeg->encryption.type != bencryption_type_none) {
259#if NEXUS_HAS_SECURITY
260        if (!mpeg->encryption.key_ladder) {
261            switch (mpeg->encryption.type) {
262            case bencryption_type_des:
263                if (mpeg->encryption.key_length != 64) {
264                    BSETTOP_ERROR(berr_invalid_parameter);
265                    return NULL;
266                }
267                break;
268            case bencryption_type_3des:
269                if (mpeg->encryption.key_length != 128) {
270                    BSETTOP_ERROR(berr_invalid_parameter);
271                    return NULL;
272                }
273                break;
274            case bencryption_type_aes:
275                if (mpeg->encryption.key_length != 128) {
276                    BSETTOP_ERROR(berr_invalid_parameter);
277                    return NULL;
278                }
279                break;
280            default:
281                BDBG_ERR(("Unsupported PVR encryption algorithm"));
282                BSETTOP_ERROR(berr_invalid_parameter);
283                return NULL;
284            }
285        } else if (mpeg->encryption.key_length != 8*sizeof(bcrypto_keyladder_data) || !mpeg->encryption.long_key) {
286            BSETTOP_ERROR(berr_invalid_parameter); return NULL;
287        }
288        nSettings.securityContext = b_keyslot_m2m_allocate(&mpeg->encryption, false,
289            nSettings.timestamp.type==NEXUS_TransportTimestampType_eNone?false:true);
290        playpump->hKeySlot = nSettings.securityContext;
291#if NEXUS_HAS_DMA
292        nSettings.securityDma = g_dma.hDma;
293        BDBG_MSG(("Enabling decryption on playback: slot: %p, dma: %p",nSettings.securityContext,nSettings.securityDma));
294#else
295        BDBG_MSG(("Enabling decryption on playback: slot: %p",nSettings.securityContext));
296#endif
297        if (!nSettings.securityContext
298#if NEXUS_HAS_DMA
299                || !nSettings.securityDma
300#endif
301                ) {
302            BDBG_ERR(("Enabling encryption on playback FAILED!"));
303#if NEXUS_HAS_DMA
304            BDBG_ERR(("slot: %p, dma: %p",nSettings.securityContext,nSettings.securityDma));
305#else
306            BDBG_ERR(("slot: %p",nSettings.securityContext));
307#endif
308            BSETTOP_ERROR(berr_external_error);
309            return NULL;
310        }
311#else
312        BDBG_ERR(("PVR encryption is not supported"));
313        BSETTOP_ERROR(berr_invalid_parameter);
314        return NULL;
315#endif
316    }
317#if B_HAS_MSDRM_PD || B_HAS_MSDRM_ND
318    if(mpeg->mpeg_type == bstream_mpeg_type_asf) {
319        nSettings.securityContext = (NEXUS_KeySlotHandle) (*(void **)mpeg->encryption.key);
320    }
321#endif
322
323    rc = NEXUS_Playpump_SetSettings(playpump->nPlaypump, &nSettings);
324    if (rc) {BSETTOP_ERROR(berr_external_error);return NULL;}
325
326    rc = NEXUS_Playpump_Start(playpump->nPlaypump);
327    if (rc) {BSETTOP_ERROR(berr_external_error);return NULL;}
328
329    playpump->stream = bstream_p_open(NULL, playpump, NULL, 0, mpeg);
330
331#ifdef B_HAS_IP
332    playpump->stream->producer.is_playback_ip = params->is_playback_ip;
333    playpump->stream->producer.use_live_playback_mode = params->use_live_playback_mode;
334    playpump->stream->producer.timestamp_active = params->timestamp_active;
335    playpump->stream->producer.timestamp_enabled = params->timestamp_enabled;
336#endif
337
338    playpump->params = *params;
339
340    return playpump->stream;
341}
342
343bresult bplaypump_stop(bplaypump_t playpump)
344{
345    BDBG_OBJECT_ASSERT(playpump, bplaypump);
346    NEXUS_Playpump_Stop(playpump->nPlaypump);
347    bstream_p_close(playpump->stream);
348    playpump->stream = NULL;
349
350    if (playpump->hKeySlot) {
351        b_keyslot_m2m_free(playpump->hKeySlot);
352        playpump->hKeySlot = NULL;
353    }
354
355    return 0;
356}
357
358bresult bplaypump_get_buffer(bplaypump_t playpump, void **buffer, size_t *size)
359{
360    NEXUS_Error rc;
361    BDBG_OBJECT_ASSERT(playpump, bplaypump);
362    rc = NEXUS_Playpump_GetBuffer(playpump->nPlaypump, buffer, size);
363    if (rc) return BSETTOP_ERROR(berr_external_error);
364    return 0;
365}
366
367bresult bplaypump_read_complete(bplaypump_t playpump, size_t skip, size_t amount)
368{
369    NEXUS_Error rc;
370    BDBG_OBJECT_ASSERT(playpump, bplaypump);
371    BDBG_CASSERT(sizeof(bplaypump_segment_desc) == sizeof(NEXUS_PlaypumpSegment));
372    rc = NEXUS_Playpump_ReadComplete(playpump->nPlaypump, skip, amount);
373    if (rc) return BSETTOP_ERROR(berr_external_error);
374    return 0;
375}
376
377bresult bplaypump_set(bplaypump_t playpump, const bplaypump_settings *settings)
378{
379    BDBG_OBJECT_ASSERT(playpump, bplaypump);
380    playpump->settings = *settings;
381    /* TODO */
382    return 0;
383}
384
385void bplaypump_get(bplaypump_t playpump, bplaypump_settings *settings)
386{
387    BDBG_OBJECT_ASSERT(playpump, bplaypump);
388    *settings = playpump->settings;
389}
390
391bresult bplaypump_set_state(bplaypump_t playpump, bplaypump_state state, bool forward)
392{
393    BDBG_OBJECT_ASSERT(playpump, bplaypump);
394    playpump->state = state;
395    playpump->forward = forward;
396    /* TODO */
397    return 0;
398}
399
400bresult bplaypump_set_decoder_rate(bplaypump_t playpump, unsigned rate)
401{
402    BDBG_OBJECT_ASSERT(playpump, bplaypump);
403    playpump->rate = rate;
404    /* TODO */
405    return 0;
406}
407
408bresult bplaypump_frame_advance(bplaypump_t playpump)
409{
410    BDBG_OBJECT_ASSERT(playpump, bplaypump);
411    if (playpump->stream->consumers.decode) {
412        /* TODO */
413    }
414    return 0;
415}
416
417bresult bplaypump_flush(bplaypump_t playpump)
418{
419    BDBG_OBJECT_ASSERT(playpump, bplaypump);
420    NEXUS_Playpump_Flush(playpump->nPlaypump);
421    if (playpump->stream->consumers.decode) {
422        /* TODO */
423    }
424    return 0;
425}
426
427bresult bplaypump_get_status(bplaypump_t p, bplaypump_status *status)
428{
429    NEXUS_PlaypumpStatus nStatus;
430    NEXUS_Error rc;
431
432    BDBG_OBJECT_ASSERT(p, bplaypump);
433    BKNI_Memset(status, 0, sizeof(*status));
434
435    rc = NEXUS_Playpump_GetStatus(p->nPlaypump, &nStatus);
436    if (rc) return BSETTOP_ERROR(berr_external_error);
437    status->fifo_depth = nStatus.fifoDepth;
438    status->fifo_size = nStatus.fifoSize;
439    status->buffer_base = nStatus.bufferBase;
440    status->bytes_played = nStatus.bytesPlayed;
441    status->running = nStatus.started;
442/* TODO:     status->noverflows; */
443    return 0;
444}
445
446bresult bplaypump_p_set_pwm_value(bplaypump_t p, int pwm_value)
447{
448    /* TODO */
449    BDBG_OBJECT_ASSERT(p, bplaypump);
450    BSTD_UNUSED(pwm_value);
451    return 0;
452}
453
454void bplaypump_get_source(bplaypump_t playpump, bplaypump_source *source)
455{
456    /* TODO */
457    BDBG_OBJECT_ASSERT(playpump, bplaypump);
458    BSTD_UNUSED(source);
459}
460
461bresult bplaypump_set_source(bplaypump_t playpump, const bplaypump_source *source)
462{
463    /* TODO */
464    BDBG_OBJECT_ASSERT(playpump, bplaypump);
465    BSTD_UNUSED(source);
466    return 0;
467}
468
469bresult bplaypump_get_rtp_hdr_data(bplaypump_t p, const bplaypump_rtp_hdr_data_t *rtp_header_data, unsigned *entry_cnt)
470{
471    /* This function now resides in IP Applib, so no need to implement it here */
472    BSTD_UNUSED(p);
473    BSTD_UNUSED(rtp_header_data);
474    BSTD_UNUSED(entry_cnt);
475    return BSETTOP_ERROR(berr_not_supported);
476}
477
Note: See TracBrowser for help on using the repository browser.