~medibuntu-maintainers/mplayer/medibuntu.precise

« back to all changes in this revision

Viewing changes to libmpcodecs/ad_spdif.c

  • Committer: Gauvain Pocentek
  • Date: 2012-03-06 11:59:12 UTC
  • mfrom: (66.1.15 precise)
  • Revision ID: gauvain@pocentek.net-20120306115912-h9d6kt9j0l532oo5
* Merge from Ubuntu:
  - put back faac support
  - recommends apport-hooks-medibuntu
  - change Maintainer, Uploaders & Vcs-* fields.
* New upstream snapshot
* upload to unstable
* Build against external libmpeg2
* drop 51_FTBFS_arm.patch again
* no longer build depend on libcdparanoia-dev on the Hurd
* Fix FTBFS on the hurd.
  Thanks to Samuel Thibault <sthibault@debian.org> (Closes: #654974)
* Fix FTBFS on arm
* New upstream snapshot, Closes: #650339, #643621, #481807
* Imported Upstream version 1.0~rc4+svn34492
* Bump standards version
* Bump dependency on libav >= 4:0.8~, Closes: #653887
* Fix build-indep
* Build mplayer-gui again, Closes: #568514
* Drop debian/all-lang-config-mak.sh, no longer needed
* include .dfsg1 in version number
* remove get-orig-source target
* no longer prune compiler flags from the environment
* No longer advertise nor build 3fdx, mga and dxr3 backends,
  Closes: #496106, #442181, #533546
* beautify mplayer version identification string
* Brown paperbag upload.
* Next try to fix build failure on sparce after recent binutils change.
* Brown paperbag upload.
* Really fix build failure on sparc after recent binutils change.
* Properly set Replaces/Conflicts on mplayer2{,-dbg} to avoid
  file overwrite errors.
* Adjust versioning of mplayer listed in the mplayer-dbg's Depends field.
* Fix build failure on sparc after recent binutils change.
* Urgency medium bumped because of RC-level bugfix
  and speeding up x264 transition.
* Update to my @debian.org email.
* Upload to unstable
* Enable joystick support on Linux only, Closes: #638408
* Rebuild fixes toolchain issue on arm, Closes: #637077
* New upstream snapshot
* following the discussion started by Diego Biurrun <diego@biurrun.de>
  in debian-devel, I have prepared a new packaging of 'mplayer'
  (with code that comes from CVS)
* the upstream tar.bz cannot be distributed by Debian, since it contains
   CSS code; so I am repackaging it 
* I have tried my best to address all known issues:
  - the package contains the detailed Copyright made by Diego Biurrun 
  - the package does not contain CSS code, or  AFAIK other code on which 
     there is active patent enforcement
  - there is a script  debian/cvs-changelog.sh  that shows all changes
     done to files included in this source.
    This should comply with GPLv2 sec 2.a  (in spirit if not in letter)
    For this reason, the source code contains CVS directories.
* needs   make (>= 3.80) for 'html-chunked-$(1)' in DOCS/xml/Makefile

* some corrections, as suggested Diego Biurrun
  - binary codecs should go into /usr/lib/codecs (upstream default)
  - better template 'mplayer/install_codecs'
  - an empty 'font=' in mplayer.conf breaks mplayer: postinst corrected
* correction in 'mplayer/cfgnote'
* better mplayer.postinst and mplayer.config

* New upstream release
* better debian/copyright file
* do not ship a skin
* New upstream release
* changed DEB_BUILD_OPTIONS to DEB_BUILD_CONFIGURE ,
  DEB_BUILD_OPTIONS is used as in debian policy
* use gcc-3.4
* changed xlibs-dev to a long list of dependencies, for Debian/etch
* try to adhere to  http://www.mplayerhq.hu/DOCS/tech/binary-packaging.txt
  (see README.Debian for details)
* removed dependency on xlibmesa-dev, disabled opengl
* New upstream release
* Simon McVittie <hacks@pseudorandom.co.uk> wonderful work:
- Work around Debian bug #267442 (glibc's sys/uio.h and gcc's altivec.h have
  conflicting uses for __vector) by re-ordering #includes
- Fix potential symlink attack in ./configure
- Disable support for binary codecs on platforms for which those codecs
  aren't available; also disable the corresponding Debconf note when it's
  inappropriate
- Changed Build-Depends: so it works in pbuilder
- Explicitly build-depend on libjpeg62-dev, libfontconfig1-dev,
  libungif4-dev 
- Tweak debian/rules to avoid certain errors being ignored
- Use --language=all
* provide a target  'debian/rules get-orig-source' 
  that recreates the orig.tar.gz ; then use the above orig.tar.gz
* rewrote some parts of debian/rules
* don't clean and recompile docs if upstream ships them
* mplayer-doc was shipping too much stuff
* translated man pages where not installed properly
* compile with libdv4-dev
* correct README.Debian
* Forgot build-dep on libtheora
* Must not depend on libxvidcore
* New upstream release
* new release.
* rc1 to become 0.90
* new pre-release
* new pre-release
* gtk bug fixed.
* new release.
* version bumped
* 0.60 pre2 release
* 0.60 pre-release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of MPlayer.
 
3
 *
 
4
 * MPlayer is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * MPlayer is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License along
 
15
 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
 
16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
17
 */
 
18
 
 
19
#include <string.h>
 
20
 
 
21
#include "config.h"
 
22
#include "mp_msg.h"
 
23
#include "ad_internal.h"
 
24
#include "av_helpers.h"
 
25
#include "libavformat/avformat.h"
 
26
#include "libavcodec/avcodec.h"
 
27
#include "libavutil/opt.h"
 
28
 
 
29
static const ad_info_t info = {
 
30
    "libavformat/spdifenc audio pass-through decoder.",
 
31
    "spdif",
 
32
    "Naoya OYAMA",
 
33
    "Naoya OYAMA",
 
34
    "For ALL hardware decoders"
 
35
};
 
36
 
 
37
LIBAD_EXTERN(spdif)
 
38
 
 
39
#define FILENAME_SPDIFENC "spdif"
 
40
#define OUTBUF_SIZE 65536
 
41
struct spdifContext {
 
42
    AVFormatContext *lavf_ctx;
 
43
    int              iec61937_packet_size;
 
44
    int              out_buffer_len;
 
45
    int              out_buffer_size;
 
46
    uint8_t         *out_buffer;
 
47
    uint8_t          pb_buffer[OUTBUF_SIZE];
 
48
};
 
49
 
 
50
static int read_packet(void *p, uint8_t *buf, int buf_size)
 
51
{
 
52
    // spdifenc does not use read callback.
 
53
    return 0;
 
54
}
 
55
 
 
56
static int write_packet(void *p, uint8_t *buf, int buf_size)
 
57
{
 
58
    int len;
 
59
    struct spdifContext *ctx = p;
 
60
 
 
61
    len = FFMIN(buf_size, ctx->out_buffer_size -ctx->out_buffer_len);
 
62
    memcpy(&ctx->out_buffer[ctx->out_buffer_len], buf, len);
 
63
    ctx->out_buffer_len += len;
 
64
    return len;
 
65
}
 
66
 
 
67
static int64_t seek(void *p, int64_t offset, int whence)
 
68
{
 
69
    // spdifenc does not use seek callback.
 
70
    return 0;
 
71
}
 
72
 
 
73
static int preinit(sh_audio_t *sh)
 
74
{
 
75
    sh->samplesize = 2;
 
76
    return 1;
 
77
}
 
78
 
 
79
static int init(sh_audio_t *sh)
 
80
{
 
81
    int i, x, in_size, srate, bps, *dtshd_rate;
 
82
    unsigned char *start;
 
83
    double pts;
 
84
    static const struct {
 
85
        const char *name; enum CodecID id;
 
86
    } fmt_id_type[] = {
 
87
        { "aac" , CODEC_ID_AAC    },
 
88
        { "ac3" , CODEC_ID_AC3    },
 
89
        { "dca" , CODEC_ID_DTS    },
 
90
        { "eac3", CODEC_ID_EAC3   },
 
91
        { "mpa" , CODEC_ID_MP3    },
 
92
        { "thd" , CODEC_ID_TRUEHD },
 
93
        { NULL  , 0 }
 
94
    };
 
95
    AVFormatContext     *lavf_ctx  = NULL;
 
96
    AVStream            *stream    = NULL;
 
97
    const AVOption      *opt       = NULL;
 
98
    struct spdifContext *spdif_ctx = NULL;
 
99
 
 
100
    spdif_ctx = av_mallocz(sizeof(*spdif_ctx));
 
101
    if (!spdif_ctx)
 
102
        goto fail;
 
103
    spdif_ctx->lavf_ctx = avformat_alloc_context();
 
104
    if (!spdif_ctx->lavf_ctx)
 
105
        goto fail;
 
106
 
 
107
    sh->context = spdif_ctx;
 
108
    lavf_ctx    = spdif_ctx->lavf_ctx;
 
109
 
 
110
    init_avformat();
 
111
    lavf_ctx->oformat = av_guess_format(FILENAME_SPDIFENC, NULL, NULL);
 
112
    if (!lavf_ctx->oformat)
 
113
        goto fail;
 
114
    lavf_ctx->priv_data = av_mallocz(lavf_ctx->oformat->priv_data_size);
 
115
    if (!lavf_ctx->priv_data)
 
116
        goto fail;
 
117
    lavf_ctx->pb = avio_alloc_context(spdif_ctx->pb_buffer, OUTBUF_SIZE, 1, spdif_ctx,
 
118
                            read_packet, write_packet, seek);
 
119
    if (!lavf_ctx->pb)
 
120
        goto fail;
 
121
    stream = avformat_new_stream(lavf_ctx, 0);
 
122
    if (!stream)
 
123
        goto fail;
 
124
    lavf_ctx->duration   = AV_NOPTS_VALUE;
 
125
    lavf_ctx->start_time = AV_NOPTS_VALUE;
 
126
    for (i = 0; fmt_id_type[i].name; i++) {
 
127
        if (!strcmp(sh->codec->dll, fmt_id_type[i].name)) {
 
128
            lavf_ctx->streams[0]->codec->codec_id = fmt_id_type[i].id;
 
129
            break;
 
130
        }
 
131
    }
 
132
    lavf_ctx->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
 
133
    if (AVERROR_PATCHWELCOME == lavf_ctx->oformat->write_header(lavf_ctx)) {
 
134
        mp_msg(MSGT_DECAUDIO,MSGL_INFO,
 
135
               "This codec is not supported by spdifenc.\n");
 
136
        goto fail;
 
137
    }
 
138
 
 
139
    // get sample_rate & bitrate from parser
 
140
    bps = srate = 0;
 
141
    x = ds_get_packet_pts(sh->ds, &start, &pts);
 
142
    in_size = x;
 
143
    if (x <= 0) {
 
144
        pts = MP_NOPTS_VALUE;
 
145
        x = 0;
 
146
    }
 
147
    ds_parse(sh->ds, &start, &x, pts, 0);
 
148
    if (x == 0) { // not enough buffer
 
149
        srate = 48000;    //fake value
 
150
        bps   = 768000/8; //fake value
 
151
    } else  if (sh->avctx) {
 
152
        if (sh->avctx->sample_rate < 44100) {
 
153
            mp_msg(MSGT_DECAUDIO,MSGL_INFO,
 
154
                   "This stream sample_rate[%d Hz] may be broken. "
 
155
                   "Force reset 48000Hz.\n",
 
156
                   sh->avctx->sample_rate);
 
157
            srate = 48000; //fake value
 
158
        } else
 
159
            srate = sh->avctx->sample_rate;
 
160
        bps = sh->avctx->bit_rate/8;
 
161
    }
 
162
    sh->ds->buffer_pos -= in_size;
 
163
 
 
164
    switch (lavf_ctx->streams[0]->codec->codec_id) {
 
165
    case CODEC_ID_AAC:
 
166
        spdif_ctx->iec61937_packet_size = 16384;
 
167
        sh->sample_format               = AF_FORMAT_IEC61937_LE;
 
168
        sh->samplerate                  = srate;
 
169
        sh->channels                    = 2;
 
170
        sh->i_bps                       = bps;
 
171
        break;
 
172
    case CODEC_ID_AC3:
 
173
        spdif_ctx->iec61937_packet_size = 6144;
 
174
        sh->sample_format               = AF_FORMAT_IEC61937_LE;
 
175
        sh->samplerate                  = srate;
 
176
        sh->channels                    = 2;
 
177
        sh->i_bps                       = bps;
 
178
        break;
 
179
    case CODEC_ID_DTS: // FORCE USE DTS-HD
 
180
        opt = av_opt_find(&lavf_ctx->oformat->priv_class,
 
181
                          "dtshd_rate", NULL, 0, 0);
 
182
        if (!opt)
 
183
            goto fail;
 
184
        dtshd_rate                      = (int*)(((uint8_t*)lavf_ctx->priv_data) +
 
185
                                          opt->offset);
 
186
        *dtshd_rate                     = 192000*4;
 
187
        spdif_ctx->iec61937_packet_size = 32768;
 
188
        sh->sample_format               = AF_FORMAT_IEC61937_LE;
 
189
        sh->samplerate                  = 192000; // DTS core require 48000
 
190
        sh->channels                    = 2*4;
 
191
        sh->i_bps                       = bps;
 
192
        break;
 
193
    case CODEC_ID_EAC3:
 
194
        spdif_ctx->iec61937_packet_size = 24576;
 
195
        sh->sample_format               = AF_FORMAT_IEC61937_LE;
 
196
        sh->samplerate                  = 192000;
 
197
        sh->channels                    = 2;
 
198
        sh->i_bps                       = bps;
 
199
        break;
 
200
    case CODEC_ID_MP3:
 
201
        spdif_ctx->iec61937_packet_size = 4608;
 
202
        sh->sample_format               = AF_FORMAT_MPEG2;
 
203
        sh->samplerate                  = srate;
 
204
        sh->channels                    = 2;
 
205
        sh->i_bps                       = bps;
 
206
        break;
 
207
    case CODEC_ID_TRUEHD:
 
208
        spdif_ctx->iec61937_packet_size = 61440;
 
209
        sh->sample_format               = AF_FORMAT_IEC61937_LE;
 
210
        sh->samplerate                  = 192000;
 
211
        sh->channels                    = 8;
 
212
        sh->i_bps                       = bps;
 
213
        break;
 
214
    default:
 
215
        break;
 
216
    }
 
217
 
 
218
    return 1;
 
219
 
 
220
fail:
 
221
    uninit(sh);
 
222
    return 0;
 
223
}
 
224
 
 
225
static int decode_audio(sh_audio_t *sh, unsigned char *buf,
 
226
                        int minlen, int maxlen)
 
227
{
 
228
    struct spdifContext *spdif_ctx = sh->context;
 
229
    AVFormatContext     *lavf_ctx  = spdif_ctx->lavf_ctx;
 
230
    AVPacket            pkt;
 
231
    double              pts;
 
232
    int                 ret, in_size, consumed, x;
 
233
    unsigned char       *start = NULL;
 
234
 
 
235
    consumed = spdif_ctx->out_buffer_len  = 0;
 
236
    spdif_ctx->out_buffer_size = maxlen;
 
237
    spdif_ctx->out_buffer      = buf;
 
238
    while (spdif_ctx->out_buffer_len + spdif_ctx->iec61937_packet_size < maxlen
 
239
           && spdif_ctx->out_buffer_len < minlen) {
 
240
        if (sh->ds->eof)
 
241
            break;
 
242
        x = ds_get_packet_pts(sh->ds, &start, &pts);
 
243
        if (x <= 0) {
 
244
            x = 0;
 
245
            ds_parse(sh->ds, &start, &x, MP_NOPTS_VALUE, 0);
 
246
            if (x == 0)
 
247
                continue; // END_NOT_FOUND
 
248
            in_size = x;
 
249
        } else {
 
250
            in_size = x;
 
251
            consumed = ds_parse(sh->ds, &start, &x, pts, 0);
 
252
            if (x == 0) {
 
253
                mp_msg(MSGT_DECAUDIO,MSGL_V,
 
254
                       "start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n",
 
255
                       start, pkt.size, in_size, consumed, x);
 
256
                continue; // END_NOT_FOUND
 
257
            }
 
258
            sh->ds->buffer_pos -= in_size - consumed;
 
259
        }
 
260
        av_init_packet(&pkt);
 
261
        pkt.data = start;
 
262
        pkt.size = x;
 
263
        mp_msg(MSGT_DECAUDIO,MSGL_V,
 
264
               "start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n",
 
265
               start, pkt.size, in_size, consumed, x);
 
266
        if (pts != MP_NOPTS_VALUE) {
 
267
            sh->pts       = pts;
 
268
            sh->pts_bytes = 0;
 
269
        }
 
270
        ret = lavf_ctx->oformat->write_packet(lavf_ctx, &pkt);
 
271
        if (ret < 0)
 
272
            break;
 
273
    }
 
274
    sh->pts_bytes += spdif_ctx->out_buffer_len;
 
275
    return spdif_ctx->out_buffer_len;
 
276
}
 
277
 
 
278
static int control(sh_audio_t *sh, int cmd, void* arg, ...)
 
279
{
 
280
    unsigned char *start;
 
281
    double pts;
 
282
 
 
283
    switch (cmd) {
 
284
    case ADCTRL_RESYNC_STREAM:
 
285
    case ADCTRL_SKIP_FRAME:
 
286
        ds_get_packet_pts(sh->ds, &start, &pts);
 
287
        return CONTROL_TRUE;
 
288
    }
 
289
    return CONTROL_UNKNOWN;
 
290
}
 
291
 
 
292
static void uninit(sh_audio_t *sh)
 
293
{
 
294
    struct spdifContext *spdif_ctx = sh->context;
 
295
    AVFormatContext     *lavf_ctx  = spdif_ctx->lavf_ctx;
 
296
 
 
297
    if (lavf_ctx) {
 
298
        if (lavf_ctx->oformat)
 
299
            lavf_ctx->oformat->write_trailer(lavf_ctx);
 
300
        av_freep(&lavf_ctx->pb);
 
301
        if (lavf_ctx->streams) {
 
302
            av_freep(&lavf_ctx->streams[0]->codec);
 
303
            av_freep(&lavf_ctx->streams[0]->info);
 
304
            av_freep(&lavf_ctx->streams[0]);
 
305
        }
 
306
        av_freep(&lavf_ctx->streams);
 
307
        av_freep(&lavf_ctx->priv_data);
 
308
    }
 
309
    av_freep(&lavf_ctx);
 
310
    av_freep(&spdif_ctx);
 
311
}