summaryrefslogtreecommitdiff
path: root/cesar/ce/inc/cei.h
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/ce/inc/cei.h')
-rwxr-xr-xcesar/ce/inc/cei.h424
1 files changed, 424 insertions, 0 deletions
diff --git a/cesar/ce/inc/cei.h b/cesar/ce/inc/cei.h
new file mode 100755
index 0000000000..15e64a341b
--- /dev/null
+++ b/cesar/ce/inc/cei.h
@@ -0,0 +1,424 @@
+#ifndef ce_inc_cei_h
+#define ce_inc_cei_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file ce/inc/cei.h
+ * \brief static functions to create and decode cei messages
+ * \ingroup ce
+ *
+ */
+
+//#include "ce/inc/cei_param.h"
+#include "mac/common/tonemask.h"
+#include "mac/common/timings.h"
+//#include "ce/test/common/print_utils.h"
+#include "lib/bitstream.h"
+#include "cyg/kernel/kapi.h"
+#include "ce/inc/ecos_time.h"
+
+#define CM_CHAN_EST_IND 0x6014
+#define CM_TM_UPDATE_IND 0x6018
+
+//TODO Accelerate access in tonemap and tonemask management.
+
+struct cei_created_status_t
+{
+ /** Length of mm_entry. */
+ uint length;
+ /** type of created CEI to send.*/
+ uint mm_type;
+};
+typedef struct cei_created_status_t cei_created_status_t;
+
+
+BEGIN_DECLS
+
+#ifdef RXCE
+
+static inline void
+STREAM_WRITE (bitstream_t *ptr, uint val, uint length)
+{
+ uint to_write = val;
+ bitstream_access (ptr, &to_write, length);
+}
+
+
+/**
+ * Run Length Encoding tonemap cf Spec HPAV in CM_CHAN_EST.IND description.
+ * \param writer pointer on buffer that manages nibbles writing.
+ * \param tm tonemap to encode.
+ * \param mask tonemask
+ * \return the entry number.
+ *
+ */
+static uint
+cei_tmdata_encode (bitstream_t *ctx_stream, blk_t *tm, u8 *mask)
+{
+ uint nibbles[1155];
+ int c=0;
+ uint i, nibble, next_nibble;
+ int consecutive_nb = 0;
+ int entry_nb = 0;
+ u32 *tm_data = (u32 *) tm->data;
+ uint carrier_nb = tonemask_carrier_nb (mask);
+ for (i=0; i<128; i++)
+ {
+ uint eight_nibble = *(tm_data++);
+ u8 local_mask = mask[i];
+ uint j;
+ for (j=0; j<8; j++)
+ {
+ if ( (local_mask & 0x01) == 0x01 )
+ {
+ nibbles[c++] = eight_nibble & 0x0F;
+ }
+ eight_nibble = eight_nibble >> 4;
+ local_mask = local_mask >> 1;
+ }
+ }
+ tm_data = (u32 *) tm->next->data;
+ for (i=0; i<17; i++)
+ {
+ uint eight_nibble = *(tm_data++);
+ u8 local_mask = mask[(i+128)];
+ uint j;
+ for (j=0; j<8; j++)
+ {
+ if ( (local_mask & 0x01) == 0x01 )
+ {
+ nibbles[c++] = eight_nibble & 0x0F;
+ }
+ eight_nibble = eight_nibble >> 4;
+ local_mask = local_mask >> 1;
+ }
+ }
+ nibble = nibbles[0];
+ for (i=0; i<carrier_nb; i++)
+ {
+ next_nibble = nibbles[i+1];
+ consecutive_nb ++;
+
+ if ( (next_nibble != nibble) || (consecutive_nb == 74)
+ || (i==carrier_nb-1) )
+ {
+ entry_nb++;
+ if(consecutive_nb == 1)
+ {
+ bitstream_access (ctx_stream, &nibble, 4);
+ }
+ else if (consecutive_nb == 2)
+ {
+ bitstream_access (ctx_stream, &nibble, 4);
+ bitstream_access (ctx_stream, &nibble, 4);
+ entry_nb++;
+ }
+ else if (consecutive_nb <= 10)
+ {
+ uint tmp = (consecutive_nb - 3 )|8;
+ bitstream_access (ctx_stream, &nibble, 4);
+ bitstream_access (ctx_stream, &tmp, 4);
+ }
+ else if(consecutive_nb <= 74)
+ {
+ uint tmp = ((( consecutive_nb-3) >> 3) +7);
+ bitstream_access (ctx_stream, &nibble, 4);
+ bitstream_access (ctx_stream, &tmp, 4);
+ tmp = (consecutive_nb-3)|8;
+ bitstream_access (ctx_stream, &tmp, 4);
+ }
+ dbg_assert (consecutive_nb <= 74 );
+ consecutive_nb = 0;
+ }
+ nibble = next_nibble;
+ }
+ bitstream_finalise (ctx_stream);
+
+ return (entry_nb);
+}
+
+/**
+ * Write a cei message in a buffer. // Only mmentry.
+ * \param dest_mm_entry start of mmentry buffer.
+ * \param mask tonemask.
+ * \param rx_tonemaps Set of tonemap used to create the CEI.
+ * \param new_tmi Tonemap index of set whose data must be sent. If no tonemap
+ * data must be sent, new_tmi must be TONEMAP_INDEX_NULL.
+ * \param old_tmi Tonemap index from which the new tonemap has been computed.
+ * If old_tmi is TONEMAP_INDEX_NULL, a CM_CHAN_EST.IND must be created,
+ * else a CM_UPDATE_TM.IND must be created.
+ * \return cei_created_status necessary to send CEI via the CP.
+ *
+ * function calls cei_tmdata_encode for the Run Length Encoding. Encoding is done
+ * every time even if it is not interresting because it can be worst. (except
+ * for time ).
+ * TODO : Management of old_tmi to create a CM_UPDATE_TM.IND instead of
+ * CM_CHAN_EST.IND
+ */
+static cei_created_status_t
+cei_create (u8 *dest_mm_entry, u8 *mask, tonemaps_t *rx_tonemaps, uint new_tmi, uint old_tmi)
+{
+ bitstream_t stream_writer;
+ bitstream_t *w_ptr = &stream_writer;
+ int i=0;
+ u8 valid_tm_list_lg=0;
+ u8 respt = 0x00;
+ uint mme_len;
+ tonemap_t *new_tm;
+ uint entry_nb;
+ dbg_assert (dest_mm_entry);
+ dbg_assert (rx_tonemaps);
+ valid_tm_list_lg = tonemap_valid_nb (rx_tonemaps);
+ bitstream_init (w_ptr, dest_mm_entry, 1518, BITSTREAM_WRITE );
+ STREAM_WRITE (w_ptr, rx_tonemaps->max_fl_av, 16);
+ STREAM_WRITE (w_ptr, rx_tonemaps->rifs_av_one_sym_tck / MAC_TCK_PER_FL, 8);
+ STREAM_WRITE (w_ptr, rx_tonemaps->rifs_av_two_sym_tck / MAC_TCK_PER_FL, 8);
+ STREAM_WRITE (w_ptr, rx_tonemaps->rifs_av_g2_sym_tck / MAC_TCK_PER_FL, 8);
+ STREAM_WRITE(w_ptr, respt, 8);
+ STREAM_WRITE(w_ptr, rx_tonemaps->max_tm, 8);
+ STREAM_WRITE(w_ptr, rx_tonemaps->default_tmi, 8);
+ STREAM_WRITE(w_ptr, (u8)rx_tonemaps->scl_cp, 8);
+ STREAM_WRITE(w_ptr, (u8)rx_tonemaps->scl_cfp, 8);
+ STREAM_WRITE(w_ptr, valid_tm_list_lg, 8);
+ for (i=0; i<TONEMAP_INDEX_NB; i++) if (rx_tonemaps->tm[i])
+ {
+ STREAM_WRITE(w_ptr, i+4, 8);
+ }
+
+ tonemap_intervals_t *intervals = rx_tonemaps->intervals;
+ STREAM_WRITE(w_ptr, intervals->intervals_nb, 8);
+ for (i=0; i<(int)intervals->intervals_nb; i++)
+ {
+ STREAM_WRITE(w_ptr, intervals->interval[i].end_offset_atu, 16);
+ STREAM_WRITE(w_ptr, intervals->interval[i].tmi, 8);
+ }
+ if(new_tmi != TONEMAP_INDEX_NULL)
+ {
+ new_tm=rx_tonemaps->tm[new_tmi];
+ dbg_assert_ptr (new_tm);
+ STREAM_WRITE(w_ptr, new_tmi+4, 8);
+ STREAM_WRITE(w_ptr, new_tm->cpf, 8);
+ STREAM_WRITE(w_ptr, new_tm->fecrate, 8);
+ STREAM_WRITE(w_ptr, new_tm->gil, 8);
+ STREAM_WRITE(w_ptr, 0x01, 8);
+ u32 *entry_nb_address = stream_writer.stream;
+ u32 entry_nb_offset = stream_writer.bit_offset;
+ STREAM_WRITE(w_ptr, 0xFFFF, 16);
+ entry_nb = cei_tmdata_encode (&stream_writer, new_tm->tmdma_desc_head, mask);
+ bitstream_direct_write (entry_nb_address, entry_nb_offset, entry_nb, 16);
+ }
+ bitstream_finalise (&stream_writer);
+ mme_len = ((u32) stream_writer.stream) - ((u32)stream_writer.start) + ((stream_writer.bit_offset+7)/8);
+ cei_created_status_t ret;
+ ret.length = mme_len;
+ ret.mm_type = CM_CHAN_EST_IND;
+ return(ret);
+}
+#endif
+
+#ifdef TXCE
+
+static inline void
+cei_tone_write (bitstream_t *stream_writer, uint tone, uint *write_nb, u8 *next_data)
+{
+ bitstream_access (stream_writer, &tone, 4);
+ *write_nb = (*write_nb)+1;
+ if ( (*write_nb) == BLK_SIZE*2)
+ {
+ bitstream_finalise (stream_writer);
+ bitstream_init (stream_writer, next_data, BLK_SIZE, BITSTREAM_WRITE);
+ }
+}
+
+/**
+ * Update a set of tonemap from cei message.
+ * \param tx_tonemaps_to_update set of tonemaps to update.
+ * \param mm_type type of cei message
+ * \param mm_entry start address of mmentry.
+ * \param mask tonemask
+ * \return the valid tonemap. [A32...A0] bits set if valid.
+ */
+static u32 // valid_tonemap u32 as 32 tonemap max.
+cei_decode (tonemaps_t *tx_tonemaps_to_update, int mm_type, u8 *mm_entry, u8 *mask)
+{
+ //TODO switch MMTYPE
+ int i,j;
+ int new_tmi;
+ int valid_nb; // nb tonemap valid announced by mme
+ u32 tonemaps_valid_status; //return value : tonemap_valid_status that must be kept for release_old_tonemap done under lock_it
+ u32 sort; // local tonemap_valid_status that must be kept for release_old_tonemap done under lock_it
+ int next_nibble, next_next_nibble;
+ int entry_nb;
+ int mod; //modulation
+ int codage;
+ int tmp_default_tmi;
+ bitstream_t stream_reader;
+ bitstream_t stream_writer;
+ uint read;
+ uint write_nb = 0;
+ bitstream_init (&stream_reader, mm_entry, 1518, BITSTREAM_READ);
+ bitstream_access (&stream_reader, &read, 16);
+ tx_tonemaps_to_update->max_fl_av = read;
+ bitstream_access (&stream_reader, &read, 8);
+ tx_tonemaps_to_update->rifs_av_one_sym_tck = read*MAC_TCK_PER_FL;
+ bitstream_access (&stream_reader, &read, 8);
+ tx_tonemaps_to_update->rifs_av_two_sym_tck = read*MAC_TCK_PER_FL;
+ bitstream_access (&stream_reader, &read, 8);
+ tx_tonemaps_to_update->rifs_av_g2_sym_tck = read*MAC_TCK_PER_FL;
+ bitstream_access (&stream_reader, &read, 8);
+ bitstream_access (&stream_reader, &read, 8);
+ tx_tonemaps_to_update->max_tm = read;
+ bitstream_access (&stream_reader, &read, 8);
+ tmp_default_tmi = read;
+ bitstream_access (&stream_reader, &read, 8);
+ tx_tonemaps_to_update->scl_cp = read;
+ bitstream_access (&stream_reader, &read, 8);
+ tx_tonemaps_to_update->scl_cfp = read;
+
+ bitstream_access (&stream_reader, &valid_nb, 8);
+ tonemaps_valid_status = 0;
+ for (i=0; i<valid_nb; i++)
+ {
+ bitstream_access (&stream_reader, &read, 8);
+ tonemaps_valid_status = tonemaps_valid_status | ( 1 << (read - 4) );
+ }
+ sort = tonemaps_valid_status;
+ for (i=0; i<TONEMAP_INDEX_NB; i++)
+ {
+ if ( ((sort & 0x01) == 0x01) && (!tx_tonemaps_to_update->tm[i]) )
+ {
+ tx_tonemaps_to_update->tm[i] = tonemap_alloc();
+ }
+ if ( ((sort & 0x01) == 0x00) && (tx_tonemaps_to_update->tm[i]) ) tonemap_release (tx_tonemaps_to_update, i);
+ sort = sort >> 1;
+ }
+ tonemap_intervals_t *intervals = tx_tonemaps_to_update->intervals;
+ if (intervals != tx_tonemaps_to_update->swap_intervals) intervals++;
+ //intervals->intervals_nb = READ_U8;
+ bitstream_access (&stream_reader, &read, 8);
+ intervals->intervals_nb = read;
+ for (i=0; i<(int)intervals->intervals_nb; i++)
+ {
+ //intervals->interval[i].end_offset_atu = (READ_U8 <<8);
+ //intervals->interval[i].end_offset_atu += READ_U8;
+ bitstream_access (&stream_reader, &read, 16);
+ intervals->interval[i].end_offset_atu = read;
+ //intervals->interval[i].tmi = READ_U8;
+ bitstream_access (&stream_reader, &read, 8);
+ intervals->interval[i].tmi = read;
+ }
+
+ bitstream_access (&stream_reader, &new_tmi, 8);
+ if(new_tmi>=4)
+ {
+ new_tmi-=4;
+ dbg_assert (tx_tonemaps_to_update->tm[new_tmi]);
+ dbg_assert (tx_tonemaps_to_update->tm[new_tmi]->tmdma_desc_head);
+ bitstream_access (&stream_reader, &read, 8);
+ tx_tonemaps_to_update->tm[new_tmi]->cpf = read;
+ bitstream_access (&stream_reader, &read, 8);
+ tx_tonemaps_to_update->tm[new_tmi]->fecrate = read;
+ bitstream_access (&stream_reader, &read, 8);
+ tx_tonemaps_to_update->tm[new_tmi]->gil = read;
+ bitstream_access (&stream_reader, &codage, 8);
+
+ if (codage == 1 || codage == 0) // ABSOLUTE CODE(SAME DECODE IF COMPRESSED OR NOT)
+ {
+ bitstream_access (&stream_reader, &entry_nb, 16);
+
+ bitstream_init (&stream_writer, tx_tonemaps_to_update->tm[new_tmi]->tmdma_desc_head->data, BLK_SIZE, BITSTREAM_WRITE);
+ u8 *next_data = tx_tonemaps_to_update->tm[new_tmi]->tmdma_desc_head->next->data;
+ bitstream_access (&stream_reader, &mod, 4);
+
+ int c=0;
+ for (i=0; i<entry_nb; i++)
+ {
+ bitstream_access (&stream_reader, &next_nibble, 4);
+ if (next_nibble < 8 )
+ {
+ while ( ((mask[c/8] & (1<<(c%8)))) == 0)
+ {
+ cei_tone_write (&stream_writer, 0, &write_nb, next_data);
+ c++;
+ }
+ cei_tone_write (&stream_writer, mod, &write_nb, next_data);
+ c++;
+ mod = next_nibble;
+ }
+ else
+ {
+ bitstream_access (&stream_reader, &next_next_nibble, 4);
+ if (next_next_nibble < 8)
+ {
+ for (j=0; j<next_nibble-5; j++)
+ {
+ while (((mask[c/8] & (1<<(c%8)))) == 0)
+ {
+ cei_tone_write (&stream_writer, 0, &write_nb, next_data);
+ c++;
+ }
+ cei_tone_write (&stream_writer, mod, &write_nb, next_data);
+ c++;
+ }
+ mod = next_next_nibble;
+
+ }
+ else
+ {
+ for (j=0; j < (3 + ( ( (next_nibble-7) << 3) | ( next_next_nibble & 7) )); j++)
+ {
+ while ((mask[c/8] & (1<<(c%8))) == 0)
+ {
+ cei_tone_write (&stream_writer, 0, &write_nb, next_data);
+ c++;
+ }
+ cei_tone_write (&stream_writer, mod, &write_nb, next_data);
+ c++;
+ }
+ bitstream_access (&stream_reader, &mod, 4);
+ }
+ }
+ }
+ cei_tone_write (&stream_writer, 0, &write_nb, next_data);
+ }
+ else
+ {
+ // TODO: RELATIVE CODAGE
+ }
+ }
+ bitstream_finalise (&stream_writer);
+ // ATOMIC switch intervals
+ tx_tonemaps_to_update->intervals = intervals;
+ // ATOMIC set tonemap default;
+ tx_tonemaps_to_update->default_tmi = tmp_default_tmi;
+ tx_tonemaps_to_update->expiration_rtc_date = cyg_current_time() + S_TO_RTC (TONEMAPS_LIFE_DURATION_S);
+ return (tonemaps_valid_status);
+}
+#endif
+
+END_DECLS
+
+#endif /* ce_inc_cei_h */
+
+/*
+
+uint ref[75] //Nibble Encoding table reference.
+{
+ 0, 0, 0, // 00 - 02
+ 8, 9, 10, 11, 12, 13, 14, 15, // 03 - 10
+ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, // 11 - 18
+ 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, // 19 - 26
+ 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, // 27 - 34
+ 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, // 35 - 42
+ 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, // 43 - 50
+ 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, // 51 - 58
+ 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, // 59 - 66
+ 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF // 67 - 74
+};
+
+*/