1 /* Icecast
2 *
3 * This program is distributed under the GNU General Public License,
4 * version 2. A copy of this license is included with this source.
5 * At your option, this specific source file can also be distributed
6 * under the GNU GPL version 3.
7 *
8 * Copyright 2012, David Richards, Mozilla Foundation,
9 * and others (see AUTHORS for details).
10 */
11
12
13 /* Ogg codec handler for opus streams */
14
15 #ifdef HAVE_CONFIG_H
16 #include <config.h>
17 #endif
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ogg/ogg.h>
22
23 typedef struct source_tag source_t;
24
25 #include "format_opus.h"
26 #include "refbuf.h"
27 #include "client.h"
28
29 #define CATMODULE "format-opus"
30 #include "logging.h"
31
opus_codec_free(ogg_state_t * ogg_info,ogg_codec_t * codec)32 static void opus_codec_free (ogg_state_t *ogg_info, ogg_codec_t *codec)
33 {
34 ogg_stream_clear (&codec->os);
35 free (codec);
36 }
37
38
process_opus_page(ogg_state_t * ogg_info,ogg_codec_t * codec,ogg_page * page)39 static refbuf_t *process_opus_page (ogg_state_t *ogg_info,
40 ogg_codec_t *codec, ogg_page *page)
41 {
42 refbuf_t *refbuf;
43
44 if (codec->headers < 2)
45 {
46 ogg_packet packet;
47
48 ogg_stream_pagein (&codec->os, page);
49 while (ogg_stream_packetout (&codec->os, &packet) > 0)
50 {
51 /* first time around (normal case) yields comments */
52 codec->headers++;
53 }
54 /* add header page to associated list */
55 format_ogg_attach_header (ogg_info, page);
56 return NULL;
57 }
58 refbuf = make_refbuf_with_page (page);
59 return refbuf;
60 }
61
62
initial_opus_page(format_plugin_t * plugin,ogg_page * page)63 ogg_codec_t *initial_opus_page (format_plugin_t *plugin, ogg_page *page)
64 {
65 ogg_state_t *ogg_info = plugin->_state;
66 ogg_codec_t *codec = calloc (1, sizeof (ogg_codec_t));
67 ogg_packet packet;
68
69 ogg_stream_init (&codec->os, ogg_page_serialno (page));
70 ogg_stream_pagein (&codec->os, page);
71
72 ogg_stream_packetout (&codec->os, &packet);
73
74 ICECAST_LOG_DEBUG("checking for opus codec");
75 if (packet.bytes < 8 || strncmp((char *)packet.packet, "OpusHead", 8) != 0)
76 {
77 ogg_stream_clear (&codec->os);
78 free (codec);
79 return NULL;
80 }
81 ICECAST_LOG_INFO("seen initial opus header");
82 codec->process_page = process_opus_page;
83 codec->codec_free = opus_codec_free;
84 codec->headers = 1;
85 codec->name = "Opus";
86 ogg_info->log_metadata = 1;
87 format_ogg_attach_header (ogg_info, page);
88 return codec;
89 }
90
91