~ubuntu-branches/ubuntu/vivid/libav/vivid

« back to all changes in this revision

Viewing changes to debian/patches/support-opus-in-ogg.patch

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2014-05-08 21:40:28 UTC
  • mfrom: (1.3.41 sid)
  • Revision ID: package-import@ubuntu.com-20140508214028-xuainxb1ibzt9lbg
Tags: 6:9.13-1ubuntu1
* Merge from unstable, remaining changes:
  - build-depend on libtiff5-dev rather than libtiff4-dev,
    avoids FTBFS caused by imlib
* New release fixes security issues LP: #1277173

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
From ecab1c77410f023b437c6ed3a3281be8f039e574 Mon Sep 17 00:00:00 2001
2
 
From: Nicolas George <nicolas.george@normalesup.org>
3
 
Date: Sun, 24 Jun 2012 11:38:18 +0200
4
 
Subject: [PATCH] oggdec: add support for Opus in Ogg demuxing
5
 
Applied-Upstream: yes
6
 
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=720563
7
 
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=733884
8
 
 
9
 
 
10
 
---
11
 
 Changelog                  |    1 +
12
 
 libavformat/Makefile       |    1 +
13
 
 libavformat/oggdec.c       |    1 +
14
 
 libavformat/oggdec.h       |    1 +
15
 
 libavformat/oggparseopus.c |  142 ++++++++++++++++++++++++++++++++++++++++++++
16
 
 libavformat/version.h      |    4 +-
17
 
 6 files changed, 148 insertions(+), 2 deletions(-)
18
 
 create mode 100644 libavformat/oggparseopus.c
19
 
 
20
 
--- a/libavformat/Makefile
21
 
+++ b/libavformat/Makefile
22
 
@@ -203,6 +203,7 @@ OBJS-$(CONFIG_OGG_DEMUXER)
23
 
                                             oggparsedirac.o  \
24
 
                                             oggparseflac.o   \
25
 
                                             oggparseogm.o    \
26
 
+                                            oggparseopus.o   \
27
 
                                             oggparseskeleton.o \
28
 
                                             oggparsespeex.o  \
29
 
                                             oggparsetheora.o \
30
 
--- a/libavformat/oggdec.c
31
 
+++ b/libavformat/oggdec.c
32
 
@@ -46,6 +46,7 @@ static const struct ogg_codec * const og
33
 
     &ff_theora_codec,
34
 
     &ff_flac_codec,
35
 
     &ff_celt_codec,
36
 
+    &ff_opus_codec,
37
 
     &ff_old_dirac_codec,
38
 
     &ff_old_flac_codec,
39
 
     &ff_ogm_video_codec,
40
 
--- a/libavformat/oggdec.h
41
 
+++ b/libavformat/oggdec.h
42
 
@@ -116,6 +116,7 @@ extern const struct ogg_codec ff_ogm_tex
43
 
 extern const struct ogg_codec ff_ogm_video_codec;
44
 
 extern const struct ogg_codec ff_old_dirac_codec;
45
 
 extern const struct ogg_codec ff_old_flac_codec;
46
 
+extern const struct ogg_codec ff_opus_codec;
47
 
 extern const struct ogg_codec ff_skeleton_codec;
48
 
 extern const struct ogg_codec ff_speex_codec;
49
 
 extern const struct ogg_codec ff_theora_codec;
50
 
--- /dev/null
51
 
+++ b/libavformat/oggparseopus.c
52
 
@@ -0,0 +1,142 @@
53
 
+/*
54
 
+ * Opus parser for Ogg
55
 
+ * Copyright (c) 2012 Nicolas George
56
 
+ *
57
 
+ * This file is part of Libav.
58
 
+ *
59
 
+ * Libav is free software; you can redistribute it and/or
60
 
+ * modify it under the terms of the GNU Lesser General Public
61
 
+ * License as published by the Free Software Foundation; either
62
 
+ * version 2.1 of the License, or (at your option) any later version.
63
 
+ *
64
 
+ * Libav is distributed in the hope that it will be useful,
65
 
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
66
 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
67
 
+ * Lesser General Public License for more details.
68
 
+ *
69
 
+ * You should have received a copy of the GNU Lesser General Public
70
 
+ * License along with Libav; if not, write to the Free Software
71
 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
72
 
+ */
73
 
+
74
 
+#include <string.h>
75
 
+
76
 
+#include "libavutil/intreadwrite.h"
77
 
+#include "avformat.h"
78
 
+#include "internal.h"
79
 
+#include "oggdec.h"
80
 
+
81
 
+struct oggopus_private {
82
 
+    int need_comments;
83
 
+    unsigned pre_skip;
84
 
+    int64_t cur_dts;
85
 
+};
86
 
+
87
 
+#define OPUS_HEAD_SIZE 19
88
 
+
89
 
+static int opus_header(AVFormatContext *avf, int idx)
90
 
+{
91
 
+    struct ogg *ogg              = avf->priv_data;
92
 
+    struct ogg_stream *os        = &ogg->streams[idx];
93
 
+    AVStream *st                 = avf->streams[idx];
94
 
+    struct oggopus_private *priv = os->private;
95
 
+    uint8_t *packet              = os->buf + os->pstart;
96
 
+    uint8_t *extradata;
97
 
+
98
 
+    if (!priv) {
99
 
+        priv = os->private = av_mallocz(sizeof(*priv));
100
 
+        if (!priv)
101
 
+            return AVERROR(ENOMEM);
102
 
+    }
103
 
+    if (os->flags & OGG_FLAG_BOS) {
104
 
+        if (os->psize < OPUS_HEAD_SIZE || (AV_RL8(packet + 8) & 0xF0) != 0)
105
 
+            return AVERROR_INVALIDDATA;
106
 
+
107
 
+        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
108
 
+        st->codec->codec_id   = AV_CODEC_ID_OPUS;
109
 
+        st->codec->channels   = AV_RL8(packet + 9);
110
 
+        priv->pre_skip        = AV_RL16(packet + 10);
111
 
+
112
 
+        extradata = av_malloc(os->psize + FF_INPUT_BUFFER_PADDING_SIZE);
113
 
+        if (!extradata)
114
 
+            return AVERROR(ENOMEM);
115
 
+
116
 
+        memcpy(extradata, packet, os->psize);
117
 
+        st->codec->extradata      = extradata;
118
 
+        st->codec->extradata_size = os->psize;
119
 
+
120
 
+        st->codec->sample_rate = 48000;
121
 
+        avpriv_set_pts_info(st, 64, 1, 48000);
122
 
+        priv->need_comments = 1;
123
 
+        return 1;
124
 
+    }
125
 
+
126
 
+    if (priv->need_comments) {
127
 
+        if (os->psize < 8 || memcmp(packet, "OpusTags", 8))
128
 
+            return AVERROR_INVALIDDATA;
129
 
+        ff_vorbis_comment(avf, &st->metadata, packet + 8, os->psize - 8);
130
 
+        priv->need_comments--;
131
 
+        return 1;
132
 
+    }
133
 
+
134
 
+    return 0;
135
 
+}
136
 
+
137
 
+static int opus_packet(AVFormatContext *avf, int idx)
138
 
+{
139
 
+    struct ogg *ogg              = avf->priv_data;
140
 
+    struct ogg_stream *os        = &ogg->streams[idx];
141
 
+    AVStream *st                 = avf->streams[idx];
142
 
+    struct oggopus_private *priv = os->private;
143
 
+    uint8_t *packet              = os->buf + os->pstart;
144
 
+    unsigned toc, toc_config, toc_count, frame_size, nb_frames = 1;
145
 
+
146
 
+    if (!os->psize)
147
 
+        return AVERROR_INVALIDDATA;
148
 
+
149
 
+    toc        = *packet;
150
 
+    toc_config = toc >> 3;
151
 
+    toc_count  = toc & 3;
152
 
+    frame_size = toc_config < 12 ? FFMAX(480, 960 * (toc_config & 3)) :
153
 
+                 toc_config < 16 ? 480 << (toc_config & 1) :
154
 
+                                   120 << (toc_config & 3);
155
 
+    if (toc_count == 3) {
156
 
+        if (os->psize < 2)
157
 
+            return AVERROR_INVALIDDATA;
158
 
+        nb_frames = packet[1] & 0x3F;
159
 
+    } else if (toc_count) {
160
 
+        nb_frames = 2;
161
 
+    }
162
 
+
163
 
+    os->pduration = frame_size * nb_frames;
164
 
+    if (os->lastpts != AV_NOPTS_VALUE) {
165
 
+        if (st->start_time == AV_NOPTS_VALUE)
166
 
+            st->start_time = os->lastpts;
167
 
+        priv->cur_dts = os->lastdts = os->lastpts -= priv->pre_skip;
168
 
+    }
169
 
+
170
 
+    priv->cur_dts += os->pduration;
171
 
+    if ((os->flags & OGG_FLAG_EOS)) {
172
 
+        int64_t skip = priv->cur_dts - os->granule + priv->pre_skip;
173
 
+        skip = FFMIN(skip, os->pduration);
174
 
+        if (skip > 0) {
175
 
+            os->pduration = skip < os->pduration ? os->pduration - skip : 1;
176
 
+            av_log(avf, AV_LOG_WARNING,
177
 
+                   "Last packet is truncated to %d (because of unimplemented end trim support).\n",
178
 
+                   os->pduration);
179
 
+            return AVERROR_PATCHWELCOME;
180
 
+        }
181
 
+    }
182
 
+
183
 
+    return 0;
184
 
+}
185
 
+
186
 
+const struct ogg_codec ff_opus_codec = {
187
 
+    .name             = "Opus",
188
 
+    .magic            = "OpusHead",
189
 
+    .magicsize        = 8,
190
 
+    .header           = opus_header,
191
 
+    .packet           = opus_packet,
192
 
+    .granule_is_start = 1,
193
 
+    .nb_header        = 1,
194
 
+};