Statistics
| Branch: | Revision:

chunker-player / chunk_transcoding / external_chunk_transcoding.c @ e11386c0

History | View | Annotate | Download (5.17 KB)

1
#include <string.h>
2
#include <stdint.h>
3
#include <stdio.h>
4

    
5
#include "external_chunk_transcoding.h"
6

    
7
int bit32_encoded_pull(uint8_t *p) {
8
        int tmp;
9
  
10
        memcpy(&tmp, p, CHUNK_TRANSCODING_INT_SIZE);
11
        tmp = ntohl(tmp);
12

    
13
        return tmp;
14
}
15

    
16

    
17
void bit32_encoded_push(uint32_t v, uint8_t *p) {
18
        uint32_t tmp;
19
  
20
        tmp = htonl(v);
21
        memcpy(p, &tmp, CHUNK_TRANSCODING_INT_SIZE);
22
}
23

    
24
static inline void int_cpy(uint8_t *p, int v)
25
{
26
  uint32_t tmp;
27
  
28
  tmp = htonl(v);
29
  memcpy(p, &tmp, 4);
30
}
31

    
32
static inline uint32_t int_rcpy(const uint8_t *p)
33
{
34
  uint32_t tmp;
35
  
36
  memcpy(&tmp, p, 4);
37
  tmp = ntohl(tmp);
38

    
39
  return tmp;
40
}
41

    
42
int encodeChunk(const struct chunk *c, uint8_t *buff, int buff_len)
43
{
44
  uint32_t half_ts;
45

    
46
  if (buff_len < 20 + c->size + c->attributes_size) {
47
    /* Not enough space... */
48
    return -1;
49
  }
50

    
51
  int_cpy(buff, c->id);
52
  half_ts = c->timestamp >> 32;
53
  int_cpy(buff + 4, half_ts);
54
  half_ts = c->timestamp;
55
  int_cpy(buff + 8, half_ts);
56
  int_cpy(buff + 12, c->size);
57
  int_cpy(buff + 16, c->attributes_size);
58
  memcpy(buff + 20, c->data, c->size);
59
  if (c->attributes_size) {
60
    memcpy(buff + 20 + c->size, c->attributes, c->attributes_size);
61
  }
62

    
63
  return 20 + c->size + c->attributes_size;
64
}
65

    
66
int decodeChunk(struct chunk *c, const uint8_t *buff, int buff_len)
67
{
68
  if (buff_len < 20) {
69
    return -1;
70
  }
71
  c->id = int_rcpy(buff);
72
  c->timestamp = int_rcpy(buff + 4);
73
  c->timestamp = c->timestamp << 32;
74
  c->timestamp |= int_rcpy(buff + 8); 
75
  c->size = int_rcpy(buff + 12);
76
  c->attributes_size = int_rcpy(buff + 16);
77

    
78
  if (buff_len < c->size + 20) {
79
    return -2;
80
  }
81
  c->data = malloc(c->size);
82
  if (c->data == NULL) {
83
    return -3;
84
  }
85
  memcpy(c->data, buff + 20, c->size);
86

    
87
  if (c->attributes_size > 0) {
88
    if (buff_len < c->size + c->attributes_size) {
89
      return -4;
90
    }
91
    c->attributes = malloc(c->attributes_size);
92
    if (c->attributes == NULL) {
93
      return -5;
94
    }
95
    memcpy(c->attributes, buff + 20 + c->size, c->attributes_size);
96
  }
97

    
98
  return 20 + c->size + c->attributes_size;
99
}
100

    
101
void print_block(const uint8_t *b, int size) {
102
int i=0;
103
fprintf(stderr,"BEGIN OF %d BYTES---\n", size);
104
for(i=0; i<size; i++) {
105
fprintf(stderr,"%d ", *(b+i));
106
}
107
fprintf(stderr,"END OF %d BYTES---\n", size);
108
}
109

    
110

    
111
void chunker_logger(const char *s) {
112
        fprintf(stderr,"%s\n", s);
113
}
114

    
115

    
116
void *packExternalChunkToAttributes(ExternalChunk *echunk, size_t attr_size) {
117
        void *attr_block = NULL;
118
        int64_t half_prio;
119
        int64_t prio = 0.0;
120
        
121
        if( (attr_block = malloc(attr_size)) == NULL ) {
122
                chunker_logger("attrib block malloc failed!");
123
                return NULL;
124
        }
125
        
126
        /* copy the content of the external_chunk structure into a proper attributes block */
127
        /* also network-encoding the 4bytes pieces */
128
        bit32_encoded_push(echunk->seq, attr_block);
129
        bit32_encoded_push(echunk->frames_num, attr_block + CHUNK_TRANSCODING_INT_SIZE);
130
        
131
        /* unfold the timeval structure fields */
132
        bit32_encoded_push(echunk->start_time.tv_sec, attr_block + CHUNK_TRANSCODING_INT_SIZE*2);
133
        bit32_encoded_push(echunk->start_time.tv_usec, attr_block + CHUNK_TRANSCODING_INT_SIZE*3);
134
        bit32_encoded_push(echunk->end_time.tv_sec, attr_block + CHUNK_TRANSCODING_INT_SIZE*4);
135
        bit32_encoded_push(echunk->end_time.tv_usec, attr_block + CHUNK_TRANSCODING_INT_SIZE*5);
136
        
137
        bit32_encoded_push(echunk->payload_len, attr_block + CHUNK_TRANSCODING_INT_SIZE*6);
138
        bit32_encoded_push(echunk->len, attr_block + CHUNK_TRANSCODING_INT_SIZE*7);
139
        bit32_encoded_push(echunk->category, attr_block + CHUNK_TRANSCODING_INT_SIZE*8);
140
        /* this is a double, should be 64bits, split it */
141
        prio = (uint64_t)echunk->priority;
142
        half_prio = prio >> 32;
143
        bit32_encoded_push(half_prio, attr_block + CHUNK_TRANSCODING_INT_SIZE*9);
144
        half_prio = prio;
145
        bit32_encoded_push(half_prio, attr_block + CHUNK_TRANSCODING_INT_SIZE*10);
146
        /* ref count is not needed over the wire */
147
        
148
        return attr_block;
149
}
150

    
151

    
152
ExternalChunk *grapesChunkToExternalChunk(Chunk *gchunk) {
153
        uint64_t tmp_prio;
154
        ExternalChunk *echunk = (ExternalChunk *)malloc(sizeof(ExternalChunk));
155
        if(!echunk) {
156
                fprintf(stderr,"Memory error in chunkToExternalchunk!\n");
157
                return NULL;
158
        }
159
        /* pull out info from the attributes block from the grapes chunk */
160
        echunk->seq = bit32_encoded_pull(gchunk->attributes);
161
        echunk->frames_num = bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE);
162
        echunk->start_time.tv_sec = bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE*2);
163
        echunk->start_time.tv_usec = bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE*3);
164
        echunk->end_time.tv_sec = bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE*4);
165
        echunk->end_time.tv_usec = bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE*5);
166
        echunk->payload_len = bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE*6);
167
        echunk->len = bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE*7);
168
        echunk->category = bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE*8);
169
        tmp_prio = bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE*9);
170
        tmp_prio = tmp_prio << 32;
171
        tmp_prio |= bit32_encoded_pull(gchunk->attributes + CHUNK_TRANSCODING_INT_SIZE*10);
172
        echunk->priority = (double)tmp_prio;
173

    
174
        /* pass the payload along */
175
        echunk->data = gchunk->data;
176

    
177
        return echunk;
178
}