Esempio n. 1
0
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
  af_extrastereo_t* s   = (af_extrastereo_t*)af->setup;

  switch(cmd){
  case AF_CONTROL_REINIT:{
    // Sanity check
    if(!arg) return AF_ERROR;

    mp_audio_copy_config(af->data, (struct mp_audio*)arg);
    mp_audio_set_num_channels(af->data, 2);
    if (af->data->format == AF_FORMAT_FLOAT_NE)
    {
	af->play = play_float;
    }// else
    {
        mp_audio_set_format(af->data, AF_FORMAT_S16_NE);
	af->play = play_s16;
    }

    return af_test_output(af,(struct mp_audio*)arg);
  }
  case AF_CONTROL_COMMAND_LINE:{
    float f;
    sscanf((char*)arg,"%f", &f);
    s->mul = f;
    return AF_OK;
  }
  }
  return AF_UNKNOWN;
}
Esempio n. 2
0
File: af_hrtf.c Progetto: 0x0all/mpv
/* Initialization and runtime control */
static int control(struct af_instance *af, int cmd, void* arg)
{
    af_hrtf_t *s = af->priv;
    int test_output_res;

    switch(cmd) {
    case AF_CONTROL_REINIT:
        reset(s);
        af->data->rate = 48000;
        mp_audio_set_channels_old(af->data, ((struct mp_audio*)arg)->nch);
        if(af->data->nch == 2) {
            /* 2 channel input */
            if(s->decode_mode != HRTF_MIX_MATRIX2CH) {
                /* Default behavior is stereo mixing. */
                s->decode_mode = HRTF_MIX_STEREO;
            }
        } else if (af->data->nch < 5) {
            mp_audio_set_channels_old(af->data, 5);
        }
        mp_audio_set_format(af->data, AF_FORMAT_S16);
        test_output_res = af_test_output(af, (struct mp_audio*)arg);
        // after testing input set the real output format
        mp_audio_set_num_channels(af->data, 2);
        s->print_flag = 1;
        return test_output_res;
    case AF_CONTROL_RESET:
        reset(s);
        return AF_OK;
    }

    return AF_UNKNOWN;
}
Esempio n. 3
0
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
  switch(cmd){
  case AF_CONTROL_REINIT:{
    // Sanity check
    if(!arg) return AF_ERROR;

    mp_audio_copy_config(af->data, (struct mp_audio*)arg);
    mp_audio_set_num_channels(af->data, 1);
#if 0
    if (((struct mp_audio*)arg)->format == AF_FORMAT_FLOAT)
    {
	af->data->format = AF_FORMAT_FLOAT;
	af->data->bps = 4;
	af->play = play_float;
    }// else
#endif
    {
        mp_audio_set_format(af->data, AF_FORMAT_S16);
	af->filter = play_s16;
    }

    return af_test_output(af,(struct mp_audio*)arg);
  }
  }
  return AF_UNKNOWN;
}
Esempio n. 4
0
/* Initialization and runtime control */
static int control(struct af_instance *af, int cmd, void* arg)
{
    af_hrtf_t *s = af->setup;
    int test_output_res;
    char mode;

    switch(cmd) {
    case AF_CONTROL_REINIT:
	af->data->rate   = ((struct mp_audio*)arg)->rate;
	if(af->data->rate != 48000) {
	    // automatic samplerate adjustment in the filter chain
	    // is not yet supported.
	    mp_msg(MSGT_AFILTER, MSGL_ERR,
		   "[hrtf] ERROR: Sampling rate is not 48000 Hz (%d)!\n",
		   af->data->rate);
	    return AF_ERROR;
	}
	mp_audio_set_channels_old(af->data, ((struct mp_audio*)arg)->nch);
	    if(af->data->nch == 2) {
 	       /* 2 channel input */
 	       if(s->decode_mode != HRTF_MIX_MATRIX2CH) {
   		  /* Default behavior is stereo mixing. */
 		  s->decode_mode = HRTF_MIX_STEREO;
	       }
	    }
	    else if (af->data->nch < 5)
	      mp_audio_set_channels_old(af->data, 5);
        mp_audio_set_format(af->data, AF_FORMAT_S16);
	test_output_res = af_test_output(af, (struct mp_audio*)arg);
	// after testing input set the real output format
        mp_audio_set_num_channels(af->data, 2);
	s->print_flag = 1;
	return test_output_res;
    case AF_CONTROL_COMMAND_LINE:
	sscanf((char*)arg, "%c", &mode);
	switch(mode) {
	case 'm':
	    /* Use matrix rear decoding. */
	    s->matrix_mode = 1;
	    break;
	case 's':
	    /* Input needs matrix decoding. */
	    s->decode_mode = HRTF_MIX_MATRIX2CH;
	    break;
	case '0':
	    s->matrix_mode = 0;
	    break;
	default:
	    mp_msg(MSGT_AFILTER, MSGL_ERR,
		   "[hrtf] Mode is neither 'm', 's', nor '0' (%c).\n",
		   mode);
	    return AF_ERROR;
	}
	s->print_flag = 1;
	return AF_OK;
    }

    return AF_UNKNOWN;
}
Esempio n. 5
0
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
  switch(cmd){
  case AF_CONTROL_REINIT:{
    // Sanity check
    if(!arg) return AF_ERROR;

    mp_audio_copy_config(af->data, (struct mp_audio*)arg);
    mp_audio_force_interleaved_format(af->data);
    mp_audio_set_num_channels(af->data, 2);
    if (af->data->format != AF_FORMAT_FLOAT)
        mp_audio_set_format(af->data, AF_FORMAT_S16);

    return af_test_output(af,(struct mp_audio*)arg);
  }
  }
  return AF_UNKNOWN;
}
Esempio n. 6
0
/* libmpg123 has a new format ready; query and store, return return value
   of mpg123_getformat() */
static int set_format(struct dec_audio *da)
{
    struct ad_mpg123_context *con = da->priv;
    int ret;
    long rate;
    int channels;
    int encoding;
    ret = mpg123_getformat(con->handle, &rate, &channels, &encoding);
    if (ret == MPG123_OK) {
        mp_audio_set_num_channels(&da->decoded, channels);
        da->decoded.rate = rate;
        int af = mpg123_format_to_af(encoding);
        if (!af) {
            /* This means we got a funny custom build of libmpg123 that only supports an unknown format. */
            MP_ERR(da, "Bad encoding from mpg123: %i.\n", encoding);
            return MPG123_ERR;
        }
        mp_audio_set_format(&da->decoded, af);
        con->sample_size = channels * af_fmt2bps(af);
    }
    return ret;
}
Esempio n. 7
0
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
  af_sinesuppress_t* s   = (af_sinesuppress_t*)af->setup;

  switch(cmd){
  case AF_CONTROL_REINIT:{
    // Sanity check
    if(!arg) return AF_ERROR;

    mp_audio_copy_config(af->data, (struct mp_audio*)arg);
    mp_audio_set_num_channels(af->data, 1);
#if 0
    if (((struct mp_audio*)arg)->format == AF_FORMAT_FLOAT_NE)
    {
	af->data->format = AF_FORMAT_FLOAT_NE;
	af->data->bps = 4;
	af->play = play_float;
    }// else
#endif
    {
        mp_audio_set_format(af->data, AF_FORMAT_S16_NE);
	af->play = play_s16;
    }

    return af_test_output(af,(struct mp_audio*)arg);
  }
  case AF_CONTROL_COMMAND_LINE:{
    float f1,f2;
    sscanf((char*)arg,"%f:%f", &f1,&f2);
    s->freq = f1;
    s->decay = f2;
    return AF_OK;
  }
  }
  return AF_UNKNOWN;
}
Esempio n. 8
0
// Initialization and runtime control
static int control(struct af_instance *af, int cmd, void *arg)
{
    af_ac3enc_t *s  = af->priv;
    static const int default_bit_rate[AC3_MAX_CHANNELS+1] = \
        {0, 96000, 192000, 256000, 384000, 448000, 448000};

    switch (cmd){
    case AF_CONTROL_REINIT: {
        struct mp_audio *in = arg;
        struct mp_audio orig_in = *in;

        if (AF_FORMAT_IS_SPECIAL(in->format) || in->nch < s->cfg_min_channel_num)
            return AF_DETACH;

        mp_audio_set_format(in, s->in_sampleformat);

        if (in->rate != 48000 && in->rate != 44100 && in->rate != 32000)
            in->rate = 48000;
        af->data->rate = in->rate;

        mp_chmap_reorder_to_lavc(&in->channels);
        if (in->nch > AC3_MAX_CHANNELS)
            mp_audio_set_num_channels(in, AC3_MAX_CHANNELS);

        mp_audio_set_format(af->data, AF_FORMAT_AC3_BE);
        mp_audio_set_num_channels(af->data, 2);

        if (!mp_audio_config_equals(in, &orig_in))
            return AF_FALSE;

        s->in_samples = AC3_FRAME_SIZE;
        if (s->cfg_add_iec61937_header) {
            s->out_samples = AC3_FRAME_SIZE;
        } else {
            s->out_samples = AC3_MAX_CODED_FRAME_SIZE / af->data->sstride;
        }
        af->mul = s->out_samples / (double)s->in_samples;

        mp_audio_buffer_reinit(s->pending, in);

        MP_DBG(af, "af_lavcac3enc reinit: %d, %d, %f, %d.\n",
               in->nch, in->rate, af->mul, s->in_samples);

        int bit_rate = s->bit_rate ? s->bit_rate : default_bit_rate[in->nch];

        if (s->lavc_actx->channels != in->nch ||
            s->lavc_actx->sample_rate != in->rate ||
            s->lavc_actx->bit_rate != bit_rate)
        {
            avcodec_close(s->lavc_actx);

            // Put sample parameters
            s->lavc_actx->channels = in->nch;
            s->lavc_actx->channel_layout = mp_chmap_to_lavc(&in->channels);
            s->lavc_actx->sample_rate = in->rate;
            s->lavc_actx->bit_rate = bit_rate;

            if (avcodec_open2(s->lavc_actx, s->lavc_acodec, NULL) < 0) {
                MP_ERR(af, "Couldn't open codec %s, br=%d.\n", "ac3", bit_rate);
                return AF_ERROR;
            }
        }
        if (s->lavc_actx->frame_size != AC3_FRAME_SIZE) {
            MP_ERR(af, "lavcac3enc: unexpected ac3 "
                   "encoder frame size %d\n", s->lavc_actx->frame_size);
            return AF_ERROR;
        }
        return AF_OK;
    }
    }
    return AF_UNKNOWN;
}
Esempio n. 9
0
/* Filter data through filter

Two "tricks" are used to compensate the "color" of the KEMAR data:

1. The KEMAR data is refiltered to ensure that the front L, R channels
on the same side of the ear are equalized (especially in the high
frequencies).

2. A bass compensation is introduced to ensure that 0-200 Hz are not
damped (without any real 3D acoustical image, however).
*/
static struct mp_audio* play(struct af_instance *af, struct mp_audio *data)
{
    af_hrtf_t *s = af->setup;
    short *in = data->planes[0]; // Input audio data
    short *out = NULL; // Output audio data
    short *end = in + data->samples * data->nch; // Loop end
    float common, left, right, diff, left_b, right_b;
    const int dblen = s->dlbuflen, hlen = s->hrflen, blen = s->basslen;

    mp_audio_realloc_min(af->data, data->samples);

    if(s->print_flag) {
	s->print_flag = 0;
	switch (s->decode_mode) {
	case HRTF_MIX_51:
	  mp_msg(MSGT_AFILTER, MSGL_INFO,
		 "[hrtf] Using HRTF to mix %s discrete surround into "
		 "L, R channels\n", s->matrix_mode ? "5+1" : "5");
	  break;
	case HRTF_MIX_STEREO:
	  mp_msg(MSGT_AFILTER, MSGL_INFO,
		 "[hrtf] Using HRTF to mix stereo into "
		 "L, R channels\n");
	  break;
	case HRTF_MIX_MATRIX2CH:
	  mp_msg(MSGT_AFILTER, MSGL_INFO,
		 "[hrtf] Using active matrix to decode 2 channel "
		 "input, HRTF to mix %s matrix surround into "
		 "L, R channels\n", "3/2");
	  break;
	default:
	  mp_msg(MSGT_AFILTER, MSGL_WARN,
		 "[hrtf] bogus decode_mode: %d\n", s->decode_mode);
	  break;
	}

       if(s->matrix_mode)
	  mp_msg(MSGT_AFILTER, MSGL_INFO,
		 "[hrtf] Using active matrix to decode rear center "
		 "channel\n");
    }

    out = af->data->planes[0];

    /* MPlayer's 5 channel layout (notation for the variable):
     *
     * 0: L (LF), 1: R (RF), 2: Ls (LR), 3: Rs (RR), 4: C (CF), matrix
     * encoded: Cs (CR)
     *
     * or: L = left, C = center, R = right, F = front, R = rear
     *
     * Filter notation:
     *
     *      CF
     * OF        AF
     *      Ear->
     * OR        AR
     *      CR
     *
     * or: C = center, A = same side, O = opposite, F = front, R = rear
     */

    while(in < end) {
	const int k = s->cyc_pos;

	update_ch(s, in, k);

	/* Simulate a 7.5 ms -20 dB echo of the center channel in the
	   front channels (like reflection from a room wall) - a kind of
	   psycho-acoustically "cheating" to focus the center front
	   channel, which is normally hard to be perceived as front */
	s->lf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];
	s->rf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];

	switch (s->decode_mode) {
	case HRTF_MIX_51:
	case HRTF_MIX_MATRIX2CH:
	   /* Mixer filter matrix */
	   common = conv(dblen, hlen, s->cf, s->cf_ir, k + s->cf_o);
	   if(s->matrix_mode) {
	      /* In matrix decoding mode, the rear channel gain must be
		 renormalized, as there is an additional channel. */
	      matrix_decode(in, k, 2, 3, 0, s->dlbuflen,
			    s->lr_fwr, s->rr_fwr,
			    s->lrprr_fwr, s->lrmrr_fwr,
			    &(s->adapt_lr_gain), &(s->adapt_rr_gain),
			    &(s->adapt_lrprr_gain), &(s->adapt_lrmrr_gain),
			    s->lr, s->rr, NULL, NULL, s->cr);
	      common +=
		 conv(dblen, hlen, s->cr, s->cr_ir, k + s->cr_o) *
		 M1_76DB;
	      left    =
		 ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
		   conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) +
		   (conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) +
		    conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o)) *
		   M1_76DB + common);
	      right   =
		 ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
		   conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) +
		   (conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) +
		    conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o)) *
		   M1_76DB + common);
	   } else {
	      left    =
		 ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
		   conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) +
		   conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) +
		   conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o) +
		   common);
	      right   =
		 ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
		   conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) +
		   conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) +
		   conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o) +
		   common);
	   }
	   break;
	case HRTF_MIX_STEREO:
	   left    =
	      ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
		conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o));
	   right   =
	      ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
		conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o));
	   break;
	default:
	    /* make gcc happy */
	    left = 0.0;
	    right = 0.0;
	    break;
	}

	/* Bass compensation for the lower frequency cut of the HRTF.  A
	   cross talk of the left and right channel is introduced to
	   match the directional characteristics of higher frequencies.
	   The bass will not have any real 3D perception, but that is
	   OK (note at 180 Hz, the wavelength is about 2 m, and any
	   spatial perception is impossible). */
	left_b  = conv(dblen, blen, s->ba_l, s->ba_ir, k);
	right_b = conv(dblen, blen, s->ba_r, s->ba_ir, k);
	left  += (1 - BASSCROSS) * left_b  + BASSCROSS * right_b;
	right += (1 - BASSCROSS) * right_b + BASSCROSS * left_b;
	/* Also mix the LFE channel (if available) */
	if(data->nch >= 6) {
	    left  += in[5] * M3_01DB;
	    right += in[5] * M3_01DB;
	}

	/* Amplitude renormalization. */
	left  *= AMPLNORM;
	right *= AMPLNORM;

	switch (s->decode_mode) {
	case HRTF_MIX_51:
	case HRTF_MIX_STEREO:
	   /* "Cheating": linear stereo expansion to amplify the 3D
	      perception.  Note: Too much will destroy the acoustic space
	      and may even result in headaches. */
	   diff = STEXPAND2 * (left - right);
	   out[0] = av_clip_int16(left  + diff);
	   out[1] = av_clip_int16(right - diff);
	   break;
	case HRTF_MIX_MATRIX2CH:
	   /* Do attempt any stereo expansion with matrix encoded
	      sources.  The L, R channels are already stereo expanded
	      by the steering, any further stereo expansion will sound
	      very unnatural. */
	   out[0] = av_clip_int16(left);
	   out[1] = av_clip_int16(right);
	   break;
	}

	/* Next sample... */
	in = &in[data->nch];
	out = &out[af->data->nch];
	(s->cyc_pos)--;
	if(s->cyc_pos < 0)
	    s->cyc_pos += dblen;
    }

    /* Set output data */
    data->planes[0] = af->data->planes[0];
    mp_audio_set_num_channels(data, 2);

    return data;
}
Esempio n. 10
0
static int init_filter(struct dec_audio *da, AVPacket *pkt)
{
    struct spdifContext *spdif_ctx = da->priv;

    int profile = FF_PROFILE_UNKNOWN;
    if (spdif_ctx->codec_id == AV_CODEC_ID_DTS)
        profile = determine_codec_profile(da, pkt);

    AVFormatContext *lavf_ctx  = avformat_alloc_context();
    if (!lavf_ctx)
        goto fail;

    spdif_ctx->lavf_ctx = lavf_ctx;

    lavf_ctx->oformat = av_guess_format("spdif", NULL, NULL);
    if (!lavf_ctx->oformat)
        goto fail;

    void *buffer = av_mallocz(OUTBUF_SIZE);
    if (!buffer)
        abort();
    lavf_ctx->pb = avio_alloc_context(buffer, OUTBUF_SIZE, 1, spdif_ctx, NULL,
                                      write_packet, NULL);
    if (!lavf_ctx->pb) {
        av_free(buffer);
        goto fail;
    }

    // Request minimal buffering (not available on Libav)
#if LIBAVFORMAT_VERSION_MICRO >= 100
    lavf_ctx->pb->direct = 1;
#endif

    AVStream *stream = avformat_new_stream(lavf_ctx, 0);
    if (!stream)
        goto fail;

    stream->codecpar->codec_id = spdif_ctx->codec_id;

    AVDictionary *format_opts = NULL;

    int num_channels = 0;
    int sample_format = 0;
    int samplerate = 0;
    switch (spdif_ctx->codec_id) {
    case AV_CODEC_ID_AAC:
        sample_format                   = AF_FORMAT_S_AAC;
        samplerate                      = 48000;
        num_channels                    = 2;
        break;
    case AV_CODEC_ID_AC3:
        sample_format                   = AF_FORMAT_S_AC3;
        samplerate                      = 48000;
        num_channels                    = 2;
        break;
    case AV_CODEC_ID_DTS: {
        bool is_hd = profile == FF_PROFILE_DTS_HD_HRA ||
                     profile == FF_PROFILE_DTS_HD_MA ||
                     profile == FF_PROFILE_UNKNOWN;
        if (spdif_ctx->use_dts_hd && is_hd) {
            av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000
            sample_format               = AF_FORMAT_S_DTSHD;
            samplerate                  = 192000;
            num_channels                = 2*4;
        } else {
            sample_format               = AF_FORMAT_S_DTS;
            samplerate                  = 48000;
            num_channels                = 2;
        }
        break;
    }
    case AV_CODEC_ID_EAC3:
        sample_format                   = AF_FORMAT_S_EAC3;
        samplerate                      = 192000;
        num_channels                    = 2;
        break;
    case AV_CODEC_ID_MP3:
        sample_format                   = AF_FORMAT_S_MP3;
        samplerate                      = 48000;
        num_channels                    = 2;
        break;
    case AV_CODEC_ID_TRUEHD:
        sample_format                   = AF_FORMAT_S_TRUEHD;
        samplerate                      = 192000;
        num_channels                    = 8;
        break;
    default:
        abort();
    }
    mp_audio_set_num_channels(&spdif_ctx->fmt, num_channels);
    mp_audio_set_format(&spdif_ctx->fmt, sample_format);
    spdif_ctx->fmt.rate = samplerate;

    if (avformat_write_header(lavf_ctx, &format_opts) < 0) {
        MP_FATAL(da, "libavformat spdif initialization failed.\n");
        av_dict_free(&format_opts);
        goto fail;
    }
    av_dict_free(&format_opts);

    spdif_ctx->need_close = true;

    return 0;

fail:
    uninit(da);
    return -1;
}
Esempio n. 11
0
// Initialization and runtime control
static int control(struct af_instance *af, int cmd, void *arg)
{
    af_ac3enc_t *s  = af->priv;
    static const int default_bit_rate[AC3_MAX_CHANNELS+1] = \
        {0, 96000, 192000, 256000, 384000, 448000, 448000};

    switch (cmd){
    case AF_CONTROL_REINIT: {
        struct mp_audio *in = arg;
        struct mp_audio orig_in = *in;

        if (!af_fmt_is_pcm(in->format) || in->nch < s->cfg_min_channel_num)
            return AF_DETACH;

        // At least currently, the AC3 encoder doesn't export sample rates.
        in->rate = 48000;
        select_encode_format(s->lavc_actx, in);

        af->data->rate = in->rate;
        mp_audio_set_format(af->data, AF_FORMAT_S_AC3);
        mp_audio_set_num_channels(af->data, 2);

        if (!mp_audio_config_equals(in, &orig_in))
            return AF_FALSE;

        if (s->cfg_add_iec61937_header) {
            s->out_samples = AC3_FRAME_SIZE;
        } else {
            s->out_samples = AC3_MAX_CODED_FRAME_SIZE / af->data->sstride;
        }

        mp_audio_copy_config(s->input, in);

        talloc_free(s->pending);
        s->pending = NULL;

        MP_DBG(af, "reinit: %d, %d, %d.\n", in->nch, in->rate, s->in_samples);

        int bit_rate = s->bit_rate ? s->bit_rate : default_bit_rate[in->nch];

        if (s->lavc_actx->channels != in->nch ||
            s->lavc_actx->sample_rate != in->rate ||
            s->lavc_actx->bit_rate != bit_rate)
        {
            avcodec_close(s->lavc_actx);

            // Put sample parameters
            s->lavc_actx->sample_fmt = af_to_avformat(in->format);
            s->lavc_actx->channels = in->nch;
            s->lavc_actx->channel_layout = mp_chmap_to_lavc(&in->channels);
            s->lavc_actx->sample_rate = in->rate;
            s->lavc_actx->bit_rate = bit_rate;

            if (avcodec_open2(s->lavc_actx, s->lavc_acodec, NULL) < 0) {
                MP_ERR(af, "Couldn't open codec %s, br=%d.\n", "ac3", bit_rate);
                return AF_ERROR;
            }

            if (s->lavc_actx->frame_size < 1) {
                MP_ERR(af, "encoder didn't specify input frame size\n");
                return AF_ERROR;
            }
        }
        s->in_samples = s->lavc_actx->frame_size;
        mp_audio_realloc(s->input, s->in_samples);
        s->input->samples = 0;
        s->encoder_buffered = 0;
        return AF_OK;
    }
    case AF_CONTROL_RESET:
        if (avcodec_is_open(s->lavc_actx))
            avcodec_flush_buffers(s->lavc_actx);
        talloc_free(s->pending);
        s->pending = NULL;
        s->input->samples = 0;
        s->encoder_buffered = 0;
        return AF_OK;
    }
    return AF_UNKNOWN;
}
Esempio n. 12
0
static int init(struct dec_audio *da, const char *decoder)
{
    struct spdifContext *spdif_ctx = talloc_zero(NULL, struct spdifContext);
    da->priv = spdif_ctx;
    spdif_ctx->log = da->log;

    AVFormatContext *lavf_ctx  = avformat_alloc_context();
    if (!lavf_ctx)
        goto fail;

    lavf_ctx->oformat = av_guess_format("spdif", NULL, NULL);
    if (!lavf_ctx->oformat)
        goto fail;

    spdif_ctx->lavf_ctx = lavf_ctx;

    void *buffer = av_mallocz(OUTBUF_SIZE);
    if (!buffer)
        abort();
    lavf_ctx->pb = avio_alloc_context(buffer, OUTBUF_SIZE, 1, spdif_ctx, NULL,
                                      write_packet, NULL);
    if (!lavf_ctx->pb) {
        av_free(buffer);
        goto fail;
    }

    // Request minimal buffering (not available on Libav)
#if LIBAVFORMAT_VERSION_MICRO >= 100
    lavf_ctx->pb->direct = 1;
#endif

    AVStream *stream = avformat_new_stream(lavf_ctx, 0);
    if (!stream)
        goto fail;

    stream->codec->codec_id = mp_codec_to_av_codec_id(decoder);

    AVDictionary *format_opts = NULL;

    int num_channels = 0;
    int sample_format = 0;
    int samplerate = 0;
    switch (stream->codec->codec_id) {
    case AV_CODEC_ID_AAC:
        spdif_ctx->iec61937_packet_size = 16384;
        sample_format                   = AF_FORMAT_IEC61937_LE;
        samplerate                      = 48000;
        num_channels                    = 2;
        break;
    case AV_CODEC_ID_AC3:
        spdif_ctx->iec61937_packet_size = 6144;
        sample_format                   = AF_FORMAT_AC3_LE;
        samplerate                      = 48000;
        num_channels                    = 2;
        break;
    case AV_CODEC_ID_DTS:
        if (da->opts->dtshd) {
            av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000
            spdif_ctx->iec61937_packet_size = 32768;
            sample_format                   = AF_FORMAT_IEC61937_LE;
            samplerate                      = 192000;
            num_channels                    = 2*4;
        } else {
            spdif_ctx->iec61937_packet_size = 32768;
            sample_format                   = AF_FORMAT_AC3_LE;
            samplerate                      = 48000;
            num_channels                    = 2;
        }
        break;
    case AV_CODEC_ID_EAC3:
        spdif_ctx->iec61937_packet_size = 24576;
        sample_format                   = AF_FORMAT_IEC61937_LE;
        samplerate                      = 192000;
        num_channels                    = 2;
        break;
    case AV_CODEC_ID_MP3:
        spdif_ctx->iec61937_packet_size = 4608;
        sample_format                   = AF_FORMAT_MPEG2;
        samplerate                      = 48000;
        num_channels                    = 2;
        break;
    case AV_CODEC_ID_TRUEHD:
        spdif_ctx->iec61937_packet_size = 61440;
        sample_format                   = AF_FORMAT_IEC61937_LE;
        samplerate                      = 192000;
        num_channels                    = 8;
        break;
    default:
        abort();
    }
    mp_audio_set_num_channels(&da->decoded, num_channels);
    mp_audio_set_format(&da->decoded, sample_format);
    da->decoded.rate = samplerate;

    if (avformat_write_header(lavf_ctx, &format_opts) < 0) {
        MP_FATAL(da, "libavformat spdif initialization failed.\n");
        av_dict_free(&format_opts);
        goto fail;
    }
    av_dict_free(&format_opts);

    spdif_ctx->need_close = true;

    return 1;

fail:
    uninit(da);
    return 0;
}