Statistics
| Branch: | Revision:

grapes / src / Chunkiser / output-stream-raw.c @ 176b8de8

History | View | Annotate | Download (2.95 KB)

1
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *
4
 *  This is free software; see gpl-3.0.txt
5
 */
6

    
7
#include <sys/types.h>
8
#include <sys/stat.h>
9
#include <fcntl.h>
10
#include <unistd.h>
11
#include <stdint.h>
12
#include <stdlib.h>
13
#include <string.h>
14
#include <stdio.h>
15

    
16
#include "int_coding.h"
17
#include "payload.h"
18
#include "grapes_config.h"
19
#include "dechunkiser_iface.h"
20

    
21
enum pt {
22
  raw,
23
  avf,
24
  udp,
25
  rtp,
26
};
27

    
28
struct dechunkiser_ctx {
29
  int fd;
30
  enum pt payload_type;
31
};
32

    
33
static struct dechunkiser_ctx *raw_open(const char *fname, const char *config)
34
{
35
  struct dechunkiser_ctx *res;
36
  struct tag *cfg_tags;
37

    
38
  res = malloc(sizeof(struct dechunkiser_ctx));
39
  if (res == NULL) {
40
    return NULL;
41
  }
42
  res->fd = 1;
43
  res->payload_type = raw;
44
  if (fname) {
45
#ifndef _WIN32
46
    res->fd = open(fname, O_WRONLY | O_CREAT, S_IROTH | S_IWUSR | S_IRUSR);
47
#else
48
    res->fd = open(fname, O_WRONLY | O_CREAT);
49
#endif
50

    
51
    if (res->fd < 0) {
52
      res->fd = 1;
53
    }
54
  }
55
  cfg_tags = grapes_config_parse(config);
56
  if (cfg_tags) {
57
    const char *pt;
58

    
59
    pt = grapes_config_value_str(cfg_tags, "payload");
60
    if (pt) {
61
      if (!strcmp(pt, "avf")) {
62
        res->payload_type = avf;
63
      } else if (!strcmp(pt, "udp")) {
64
        res->payload_type = udp;
65
      } else if (!strcmp(pt, "rtp")) {
66
        res->payload_type = rtp;
67
      }
68
    }
69
  }
70
  free(cfg_tags);
71

    
72
  return res;
73
}
74

    
75
static void raw_write(struct dechunkiser_ctx *o, int id, uint8_t *data, int size)
76
{
77
  int offset;
78

    
79
  if (o->payload_type == avf) {
80
    int header_size;
81
    int frames;
82
    int i;
83
    uint8_t codec;
84

    
85
    if (data[0] == 0) {
86
      fprintf(stderr, "Error! Strange chunk: %x!!!\n", codec);
87
      return;
88
    } else if (data[0] < 127) {
89
      int width, height, frame_rate_n, frame_rate_d;
90

    
91
      header_size = VIDEO_PAYLOAD_HEADER_SIZE;
92
      video_payload_header_parse(data, &codec, &width, &height, &frame_rate_n, &frame_rate_d);
93
//    dprintf("Frame size: %dx%d -- Frame rate: %d / %d\n", width, height, frame_rate_n, frame_rate_d);
94
    } else {
95
      uint8_t channels;
96
      int sample_rate, frame_size;
97

    
98
      header_size = AUDIO_PAYLOAD_HEADER_SIZE;
99
      audio_payload_header_parse(data, &codec, &channels, &sample_rate, &frame_size);
100
//    dprintf("Frame size: %d Sample rate: %d Channels: %d\n", frame_size, sample_rate, channels);
101
    }
102

    
103
    frames = data[header_size - 1];
104
    for (i = 0; i < frames; i++) {
105
      int frame_size;
106
      int64_t pts, dts;
107

    
108
      frame_header_parse(data, &frame_size, &pts, &dts);
109
//      dprintf("Frame %d has size %d\n", i, frame_size);
110
    }
111
    offset = header_size + frames * FRAME_HEADER_SIZE;
112
  } else if (o->payload_type == udp) {
113
    offset = UDP_PAYLOAD_HEADER_SIZE;
114
  } else if (o->payload_type == rtp) {
115
    offset = UDP_PAYLOAD_HEADER_SIZE + 12;
116
  } else {
117
    offset = 0;
118
  }
119

    
120
  write(o->fd, data + offset, size - offset);
121
}
122

    
123
static void raw_close(struct dechunkiser_ctx *s)
124
{
125
  close(s->fd);
126
  free(s);
127
}
128

    
129
struct dechunkiser_iface out_raw = {
130
  .open = raw_open,
131
  .write = raw_write,
132
  .close = raw_close,
133
};