grapes / src / Chunkiser / output-stream-raw.c @ 997c2b68
History | View | Annotate | Download (2.86 KB)
1 | 91e9c5d5 | Luca Abeni | /*
|
---|---|---|---|
2 | * Copyright (c) 2010 Luca Abeni
|
||
3 | *
|
||
4 | * This is free software; see gpl-3.0.txt
|
||
5 | */
|
||
6 | |||
7 | df7dffd7 | Luca Abeni | #include <sys/types.h> |
8 | #include <sys/stat.h> |
||
9 | #include <fcntl.h> |
||
10 | 91e9c5d5 | Luca Abeni | #include <unistd.h> |
11 | #include <stdint.h> |
||
12 | #include <stdlib.h> |
||
13 | 6b0140b8 | Luca Abeni | #include <string.h> |
14 | 91e9c5d5 | Luca Abeni | #include <stdio.h> |
15 | |||
16 | 0f79759c | Luca Abeni | #include "int_coding.h" |
17 | 6b0140b8 | Luca Abeni | #include "payload.h" |
18 | #include "config.h" |
||
19 | 91e9c5d5 | Luca Abeni | #include "dechunkiser_iface.h" |
20 | |||
21 | 127cb506 | Luca Abeni | enum pt {
|
22 | raw, |
||
23 | avf, |
||
24 | udp, |
||
25 | 8f782d31 | Luca Abeni | rtp, |
26 | 127cb506 | Luca Abeni | }; |
27 | |||
28 | 8b70c289 | Luca Abeni | struct dechunkiser_ctx {
|
29 | 91e9c5d5 | Luca Abeni | int fd;
|
30 | 127cb506 | Luca Abeni | enum pt payload_type;
|
31 | 91e9c5d5 | Luca Abeni | }; |
32 | |||
33 | 8b70c289 | Luca Abeni | static struct dechunkiser_ctx *raw_open(const char *fname, const char *config) |
34 | 91e9c5d5 | Luca Abeni | { |
35 | 8b70c289 | Luca Abeni | struct dechunkiser_ctx *res;
|
36 | 6b0140b8 | Luca Abeni | struct tag *cfg_tags;
|
37 | 91e9c5d5 | Luca Abeni | |
38 | 8b70c289 | Luca Abeni | res = malloc(sizeof(struct dechunkiser_ctx)); |
39 | 91e9c5d5 | Luca Abeni | if (res == NULL) { |
40 | return NULL; |
||
41 | } |
||
42 | res->fd = 1;
|
||
43 | 127cb506 | Luca Abeni | res->payload_type = raw; |
44 | e296176d | Luca Abeni | if (fname) {
|
45 | res->fd = open(fname, O_WRONLY | O_CREAT, S_IROTH | S_IWUSR | S_IRUSR); |
||
46 | df7dffd7 | Luca Abeni | if (res->fd < 0) { |
47 | res->fd = 1;
|
||
48 | } |
||
49 | } |
||
50 | 6b0140b8 | Luca Abeni | cfg_tags = config_parse(config); |
51 | if (cfg_tags) {
|
||
52 | const char *pt; |
||
53 | |||
54 | pt = config_value_str(cfg_tags, "payload");
|
||
55 | if (pt) {
|
||
56 | 1c6858bc | Luca Abeni | if (!strcmp(pt, "avf")) { |
57 | 127cb506 | Luca Abeni | res->payload_type = avf; |
58 | 9663d8d1 | Luca Abeni | } else if (!strcmp(pt, "udp")) { |
59 | res->payload_type = udp; |
||
60 | 8f782d31 | Luca Abeni | } else if (!strcmp(pt, "rtp")) { |
61 | res->payload_type = rtp; |
||
62 | 6b0140b8 | Luca Abeni | } |
63 | } |
||
64 | } |
||
65 | dcc42706 | Luca Abeni | free(cfg_tags); |
66 | 91e9c5d5 | Luca Abeni | |
67 | return res;
|
||
68 | } |
||
69 | |||
70 | 8b70c289 | Luca Abeni | static void raw_write(struct dechunkiser_ctx *o, int id, uint8_t *data, int size) |
71 | 91e9c5d5 | Luca Abeni | { |
72 | 6b0140b8 | Luca Abeni | int offset;
|
73 | |||
74 | 127cb506 | Luca Abeni | if (o->payload_type == avf) {
|
75 | 28e6b134 | Luca Abeni | int header_size;
|
76 | int frames;
|
||
77 | 6b0140b8 | Luca Abeni | int i;
|
78 | uint8_t codec; |
||
79 | |||
80 | 28e6b134 | Luca Abeni | if (data[0] == 0) { |
81 | fprintf(stderr, "Error! Strange chunk: %x!!!\n", codec);
|
||
82 | 6b0140b8 | Luca Abeni | return;
|
83 | 28e6b134 | Luca Abeni | } else if (data[0] < 127) { |
84 | int width, height, frame_rate_n, frame_rate_d;
|
||
85 | |||
86 | header_size = VIDEO_PAYLOAD_HEADER_SIZE; |
||
87 | video_payload_header_parse(data, &codec, &width, &height, &frame_rate_n, &frame_rate_d); |
||
88 | 6b0140b8 | Luca Abeni | // dprintf("Frame size: %dx%d -- Frame rate: %d / %d\n", width, height, frame_rate_n, frame_rate_d);
|
89 | 28e6b134 | Luca Abeni | } else {
|
90 | 64772949 | Luca Abeni | uint8_t channels; |
91 | int sample_rate, frame_size;
|
||
92 | |||
93 | 28e6b134 | Luca Abeni | header_size = AUDIO_PAYLOAD_HEADER_SIZE; |
94 | 64772949 | Luca Abeni | audio_payload_header_parse(data, &codec, &channels, &sample_rate, &frame_size); |
95 | // dprintf("Frame size: %d Sample rate: %d Channels: %d\n", frame_size, sample_rate, channels);
|
||
96 | 28e6b134 | Luca Abeni | } |
97 | |||
98 | frames = data[header_size - 1];
|
||
99 | 6b0140b8 | Luca Abeni | for (i = 0; i < frames; i++) { |
100 | int frame_size;
|
||
101 | int64_t pts, dts; |
||
102 | |||
103 | frame_header_parse(data, &frame_size, &pts, &dts); |
||
104 | // dprintf("Frame %d has size %d\n", i, frame_size);
|
||
105 | } |
||
106 | offset = header_size + frames * FRAME_HEADER_SIZE; |
||
107 | 9663d8d1 | Luca Abeni | } else if (o->payload_type == udp) { |
108 | offset = UDP_CHUNK_HEADER_SIZE; |
||
109 | 8f782d31 | Luca Abeni | } else if (o->payload_type == rtp) { |
110 | offset = UDP_CHUNK_HEADER_SIZE + 12;
|
||
111 | 6b0140b8 | Luca Abeni | } else {
|
112 | offset = 0;
|
||
113 | } |
||
114 | |||
115 | write(o->fd, data + offset, size - offset); |
||
116 | 91e9c5d5 | Luca Abeni | } |
117 | |||
118 | 8b70c289 | Luca Abeni | static void raw_close(struct dechunkiser_ctx *s) |
119 | 386bce8c | Luca Abeni | { |
120 | close(s->fd); |
||
121 | free(s); |
||
122 | } |
||
123 | |||
124 | 91e9c5d5 | Luca Abeni | struct dechunkiser_iface out_raw = {
|
125 | .open = raw_open, |
||
126 | .write = raw_write, |
||
127 | 386bce8c | Luca Abeni | .close = raw_close, |
128 | 91e9c5d5 | Luca Abeni | }; |