Statistics
| Branch: | Revision:

streamers / output.c @ 0bee8166

History | View | Annotate | Download (3.34 KB)

1 8fed7779 CsabaKiraly
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *  Copyright (c) 2010 Csaba Kiraly
4
 *
5
 *  This is free software; see gpl-3.0.txt
6
 */
7 d3a583ca Luca
#include <unistd.h>
8
#include <stdlib.h>
9
#include <string.h>
10 89e893e2 Luca
#include <stdint.h>
11 c792c999 Luca
#include <stdio.h>
12 89e893e2 Luca
13
#include <chunk.h>
14
15 094f504c Csaba Kiraly
#include "measures.h"
16 54b631d9 Luca Abeni
#include "out-stream.h"
17 c792c999 Luca
#include "dbg.h"
18
19 d6a213f3 Csaba Kiraly
static int next_chunk = -1;
20 af2907a9 Csaba Kiraly
static int buff_size;
21 d3a583ca Luca
22 af2907a9 Csaba Kiraly
struct outbuf {
23 d3a583ca Luca
  void *data;
24
  int size;
25 c792c999 Luca
  int id;
26 af2907a9 Csaba Kiraly
};
27
static struct outbuf *buff;
28
29
void output_init(int bufsize)
30
{
31
  if (!buff) {
32 80b2d694 Csaba Kiraly
    int i;
33
34 af2907a9 Csaba Kiraly
    buff_size = bufsize;
35
    buff = malloc(sizeof(struct outbuf) * buff_size);
36
    if (!buff) {
37
     fprintf(stderr, "Error: can't allocate output buffer\n");
38
     exit(1);
39
    }
40 80b2d694 Csaba Kiraly
    for (i = 0; i < buff_size; i++) {
41
      buff[i].data = NULL;
42
    }
43 af2907a9 Csaba Kiraly
  } else {
44
   fprintf(stderr, "Error: output buffer re-init not allowed!\n");
45
   exit(1);
46
  }
47
}
48 d3a583ca Luca
49 fdcdce95 Csaba Kiraly
void buffer_print()
50
{
51 3c50e0b1 Csaba Kiraly
#ifdef DEBUG
52 fdcdce95 Csaba Kiraly
  int i;
53
54 0bee8166 Csaba Kiraly
  if (next_chunk < 0) {
55
    return;
56
  }
57
58 fdcdce95 Csaba Kiraly
  dprintf("\toutbuf: %d-> ",next_chunk);
59
  for (i = next_chunk; i < next_chunk + buff_size; i++) {
60
    if (buff[i % buff_size].data) {
61
      dprintf("%d",i % 10);
62
    } else {
63
      dprintf(".");
64
    }
65
  }
66
  dprintf("\n");
67 3c50e0b1 Csaba Kiraly
#endif
68 fdcdce95 Csaba Kiraly
}
69
70 c792c999 Luca
void buffer_free(int i)
71
{
72 298a8869 Luca Abeni
  dprintf("\t\tFlush Buf %d: %s\n", i, buff[i].data);
73 f05acd38 Csaba Kiraly
  chunk_write(buff[i].id, buff[i].data, buff[i].size);
74 c792c999 Luca
  free(buff[i].data);
75
  buff[i].data = NULL;
76 b76a7006 Luca
  dprintf("Next Chunk: %d -> %d\n", next_chunk, buff[i].id + 1);
77 094f504c Csaba Kiraly
  reg_chunk_playout(true);
78 c792c999 Luca
  next_chunk = buff[i].id + 1;
79
}
80
81 d3a583ca Luca
void buffer_flush(int id)
82
{
83
  int i = id % buff_size;
84
85
  while(buff[i].data) {
86 c792c999 Luca
    buffer_free(i);
87 d3a583ca Luca
    i = (i + 1) % buff_size;
88 c792c999 Luca
    if (i == id % buff_size) {
89 d3a583ca Luca
      break;
90
    }
91
  }
92
}
93
94 89e893e2 Luca
void output_deliver(const struct chunk *c)
95
{
96 af2907a9 Csaba Kiraly
  if (!buff) {
97
    fprintf(stderr, "Warning: code should use output_init!!! Setting output buffer to 8\n");
98
    output_init(8);
99
  }
100
101 c792c999 Luca
  dprintf("Chunk %d delivered\n", c->id);
102 9132cb6f Csaba Kiraly
  buffer_print();
103 c792c999 Luca
  if (c->id < next_chunk) {
104
    return;
105
  }
106
107
  if (c->id >= next_chunk + buff_size) {
108
    int i;
109
110 d6a213f3 Csaba Kiraly
    /* Initialize buffer with first chunk */
111
    if (next_chunk == -1) {
112
      next_chunk = c->id - buff_size + 1;
113
    }
114
115 c792c999 Luca
    /* We might need some space for storing this chunk,
116
     * or the stored chunks are too old
117
     */
118
    for (i = next_chunk; i <= c->id - buff_size; i++) {
119
      if (buff[i % buff_size].data) {
120
        buffer_free(i % buff_size);
121
      } else {
122 094f504c Csaba Kiraly
        reg_chunk_playout(false);
123 c792c999 Luca
        next_chunk++;
124
      }
125
    }
126
    buffer_flush(next_chunk);
127
    dprintf("Next is now %d, chunk is %d\n", next_chunk, c->id);
128
  }
129
130
  dprintf("%d == %d?\n", c->id, next_chunk);
131 d3a583ca Luca
  if (c->id == next_chunk) {
132 298a8869 Luca Abeni
    dprintf("\tOut Chunk[%d] - %d: %s\n", c->id, c->id % buff_size, c->data);
133 54b631d9 Luca Abeni
    chunk_write(c->id, c->data, c->size);
134 094f504c Csaba Kiraly
    reg_chunk_playout(true);
135 d3a583ca Luca
    next_chunk++;
136
    buffer_flush(next_chunk);
137
  } else {
138 c792c999 Luca
    dprintf("Storing %d (in %d)\n", c->id, c->id % buff_size);
139 e8654707 Luca
    if (buff[c->id % buff_size].data) {
140
      if (buff[c->id % buff_size].id == c->id) {
141
        /* Duplicate of a stored chunk */
142 13d85fc6 Csaba Kiraly
        dprintf("\tDuplicate!\n");
143 30c89aac Csaba Kiraly
        reg_chunk_duplicate();
144 e8654707 Luca
        return;
145
      }
146 c792c999 Luca
      fprintf(stderr, "Crap!\n");
147
      exit(-1);
148
    }
149
    /* We previously flushed, so we know that c->id is free */
150 d3a583ca Luca
    buff[c->id % buff_size].data = malloc(c->size);
151
    memcpy(buff[c->id % buff_size].data, c->data, c->size);
152
    buff[c->id % buff_size].size = c->size;
153 c792c999 Luca
    buff[c->id % buff_size].id = c->id;
154 d3a583ca Luca
  }
155 89e893e2 Luca
}