示例#1
0
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
    unsigned char *start=NULL;
    int y,len=-1;
    while(len<minlen){
	AVPacket pkt;
	int len2=maxlen;
	double pts;
	int x=ds_get_packet_pts(sh_audio->ds,&start, &pts);
	if(x<=0) {
	    start = NULL;
	    x = 0;
	    ds_parse(sh_audio->ds, &start, &x, MP_NOPTS_VALUE, 0);
	    if (x <= 0)
	        break; // error
	} else {
	    int in_size = x;
	    int consumed = ds_parse(sh_audio->ds, &start, &x, pts, 0);
	    sh_audio->ds->buffer_pos -= in_size - consumed;
	}

	av_init_packet(&pkt);
	pkt.data = start;
	pkt.size = x;
	if (pts != MP_NOPTS_VALUE) {
	    sh_audio->pts = pts;
	    sh_audio->pts_bytes = 0;
	}
	y=avcodec_decode_audio3(sh_audio->context,(int16_t*)buf,&len2,&pkt);
//printf("return:%d samples_out:%d bitstream_in:%d sample_sum:%d\n", y, len2, x, len); fflush(stdout);
	// LATM may need many packets to find mux info
	if (y == AVERROR(EAGAIN))
	    continue;
	if(y<0){ mp_msg(MSGT_DECAUDIO,MSGL_V,"lavc_audio: error\n");break; }
	if(!sh_audio->parser && y<x)
	    sh_audio->ds->buffer_pos+=y-x;  // put back data (HACK!)
	if(len2>0){
	  if (((AVCodecContext *)sh_audio->context)->channels >= 5) {
            int samplesize = av_get_bytes_per_sample(((AVCodecContext *)
                                    sh_audio->context)->sample_fmt);
            reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_LAVC_DEFAULT,
                                AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
                                ((AVCodecContext *)sh_audio->context)->channels,
                                len2 / samplesize, samplesize);
	  }
	  //len=len2;break;
	  if(len<0) len=len2; else len+=len2;
	  buf+=len2;
	  maxlen -= len2;
	  sh_audio->pts_bytes += len2;
	}
        mp_dbg(MSGT_DECAUDIO,MSGL_DBG2,"Decoded %d -> %d  \n",y,len2);

        if (setup_format(sh_audio, sh_audio->context))
            break;
    }
  return len;
}
示例#2
0
文件: ad_spdif.c 项目: maletor/mpv
static int decode_audio(sh_audio_t *sh, unsigned char *buf,
                        int minlen, int maxlen)
{
    struct spdifContext *spdif_ctx = sh->context;
    AVFormatContext     *lavf_ctx  = spdif_ctx->lavf_ctx;
    AVPacket            pkt;
    double              pts;
    int                 ret, in_size, consumed, x;
    unsigned char       *start = NULL;

    consumed = spdif_ctx->out_buffer_len  = 0;
    spdif_ctx->out_buffer_size = maxlen;
    spdif_ctx->out_buffer      = buf;
    while (spdif_ctx->out_buffer_len + spdif_ctx->iec61937_packet_size < maxlen
           && spdif_ctx->out_buffer_len < minlen) {
        if (sh->ds->eof)
            break;
        x = ds_get_packet_pts(sh->ds, &start, &pts);
        if (x <= 0) {
            x = 0;
            ds_parse(sh->ds, &start, &x, MP_NOPTS_VALUE, 0);
            if (x == 0)
                continue; // END_NOT_FOUND
            in_size = x;
        } else {
            in_size = x;
            consumed = ds_parse(sh->ds, &start, &x, pts, 0);
            if (x == 0) {
                mp_msg(MSGT_DECAUDIO,MSGL_V,
                       "start[%p] in_size[%d] consumed[%d] x[%d].\n",
                       start, in_size, consumed, x);
                continue; // END_NOT_FOUND
            }
            sh->ds->buffer_pos -= in_size - consumed;
        }
        av_init_packet(&pkt);
        pkt.data = start;
        pkt.size = x;
        mp_msg(MSGT_DECAUDIO,MSGL_V,
               "start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n",
               start, pkt.size, in_size, consumed, x);
        if (pts != MP_NOPTS_VALUE) {
            sh->pts       = pts;
            sh->pts_bytes = 0;
        }
        ret = lavf_ctx->oformat->write_packet(lavf_ctx, &pkt);
        if (ret < 0)
            break;
    }
    sh->pts_bytes += spdif_ctx->out_buffer_len;
    return spdif_ctx->out_buffer_len;
}
示例#3
0
文件: ad_spdif.c 项目: maletor/mpv
static int init(sh_audio_t *sh, const char *decoder)
{
    int x, in_size, srate, bps, *dtshd_rate;
    unsigned char *start;
    double pts;
    AVFormatContext     *lavf_ctx  = NULL;
    AVStream            *stream    = NULL;
    const AVOption      *opt       = NULL;
    struct spdifContext *spdif_ctx = NULL;

    spdif_ctx = av_mallocz(sizeof(*spdif_ctx));
    if (!spdif_ctx)
        goto fail;
    spdif_ctx->lavf_ctx = avformat_alloc_context();
    if (!spdif_ctx->lavf_ctx)
        goto fail;

    sh->context = spdif_ctx;
    lavf_ctx    = spdif_ctx->lavf_ctx;

    lavf_ctx->oformat = av_guess_format(FILENAME_SPDIFENC, NULL, NULL);
    if (!lavf_ctx->oformat)
        goto fail;
    lavf_ctx->priv_data = av_mallocz(lavf_ctx->oformat->priv_data_size);
    if (!lavf_ctx->priv_data)
        goto fail;
    lavf_ctx->pb = avio_alloc_context(spdif_ctx->pb_buffer, OUTBUF_SIZE, 1, spdif_ctx,
                            read_packet, write_packet, seek);
    if (!lavf_ctx->pb)
        goto fail;
    stream = avformat_new_stream(lavf_ctx, 0);
    if (!stream)
        goto fail;
    lavf_ctx->duration   = AV_NOPTS_VALUE;
    lavf_ctx->start_time = AV_NOPTS_VALUE;
    lavf_ctx->streams[0]->codec->codec_id = mp_codec_to_av_codec_id(decoder);
    lavf_ctx->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
    if (AVERROR_PATCHWELCOME == lavf_ctx->oformat->write_header(lavf_ctx)) {
        mp_msg(MSGT_DECAUDIO,MSGL_INFO,
               "This codec is not supported by spdifenc.\n");
        goto fail;
    }

    // get sample_rate & bitrate from parser
    x = ds_get_packet_pts(sh->ds, &start, &pts);
    in_size = x;
    if (x <= 0) {
        pts = MP_NOPTS_VALUE;
        x = 0;
    }
    ds_parse(sh->ds, &start, &x, pts, 0);
    srate = 48000;    //fake value
    bps   = 768000/8; //fake value
    if (x && sh->avctx) { // we have parser and large enough buffer
        if (sh->avctx->sample_rate < 44100) {
            mp_msg(MSGT_DECAUDIO,MSGL_INFO,
                   "This stream sample_rate[%d Hz] may be broken. "
                   "Force reset 48000Hz.\n",
                   sh->avctx->sample_rate);
            srate = 48000; //fake value
        } else
            srate = sh->avctx->sample_rate;
        bps = sh->avctx->bit_rate/8;
    }
    sh->ds->buffer_pos -= in_size;

    switch (lavf_ctx->streams[0]->codec->codec_id) {
    case AV_CODEC_ID_AAC:
        spdif_ctx->iec61937_packet_size = 16384;
        sh->sample_format               = AF_FORMAT_IEC61937_LE;
        sh->samplerate                  = srate;
        sh->channels                    = 2;
        sh->i_bps                       = bps;
        break;
    case AV_CODEC_ID_AC3:
        spdif_ctx->iec61937_packet_size = 6144;
        sh->sample_format               = AF_FORMAT_AC3_LE;
        sh->samplerate                  = srate;
        sh->channels                    = 2;
        sh->i_bps                       = bps;
        break;
    case AV_CODEC_ID_DTS:
        if(sh->opts->dtshd) {
            opt = av_opt_find(&lavf_ctx->oformat->priv_class,
                              "dtshd_rate", NULL, 0, 0);
            if (!opt)
                goto fail;
            dtshd_rate                      = (int*)(((uint8_t*)lavf_ctx->priv_data) +
                                              opt->offset);
            *dtshd_rate                     = 192000*4;
            spdif_ctx->iec61937_packet_size = 32768;
            sh->sample_format               = AF_FORMAT_IEC61937_LE;
            sh->samplerate                  = 192000; // DTS core require 48000
            sh->channels                    = 2*4;
            sh->i_bps                       = bps;
        } else {
            spdif_ctx->iec61937_packet_size = 32768;
            sh->sample_format               = AF_FORMAT_AC3_LE;
            sh->samplerate                  = srate;
            sh->channels                    = 2;
            sh->i_bps                       = bps;
        }
        break;
    case AV_CODEC_ID_EAC3:
        spdif_ctx->iec61937_packet_size = 24576;
        sh->sample_format               = AF_FORMAT_IEC61937_LE;
        sh->samplerate                  = 192000;
        sh->channels                    = 2;
        sh->i_bps                       = bps;
        break;
    case AV_CODEC_ID_MP3:
        spdif_ctx->iec61937_packet_size = 4608;
        sh->sample_format               = AF_FORMAT_MPEG2;
        sh->samplerate                  = srate;
        sh->channels                    = 2;
        sh->i_bps                       = bps;
        break;
    case AV_CODEC_ID_TRUEHD:
        spdif_ctx->iec61937_packet_size = 61440;
        sh->sample_format               = AF_FORMAT_IEC61937_LE;
        sh->samplerate                  = 192000;
        sh->channels                    = 8;
        sh->i_bps                       = bps;
        break;
    default:
        break;
    }

    return 1;

fail:
    uninit(sh);
    return 0;
}
示例#4
0
static int decode_new_packet(struct sh_audio *sh)
{
    struct priv *priv = sh->context;
    AVCodecContext *avctx = priv->avctx;
    double pts = MP_NOPTS_VALUE;
    int insize;
    bool packet_already_used = priv->previous_data_left;
    struct demux_packet *mpkt = ds_get_packet2(sh->ds,
                                               priv->previous_data_left);
    unsigned char *start;
    if (!mpkt) {
        assert(!priv->previous_data_left);
        start = NULL;
        insize = 0;
        ds_parse(sh->ds, &start, &insize, pts, 0);
        if (insize <= 0)
            return -1;  // error or EOF
    } else {
        assert(mpkt->len >= priv->previous_data_left);
        if (!priv->previous_data_left) {
            priv->previous_data_left = mpkt->len;
            pts = mpkt->pts;
        }
        insize = priv->previous_data_left;
        start = mpkt->buffer + mpkt->len - priv->previous_data_left;
        int consumed = ds_parse(sh->ds, &start, &insize, pts, 0);
        priv->previous_data_left -= consumed;
        priv->previous_data_left = FFMAX(priv->previous_data_left, 0);
    }

    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.data = start;
    pkt.size = insize;
    if (mpkt && mpkt->avpacket) {
        pkt.side_data = mpkt->avpacket->side_data;
        pkt.side_data_elems = mpkt->avpacket->side_data_elems;
    }
    if (pts != MP_NOPTS_VALUE && !packet_already_used) {
        sh->pts = pts;
        sh->pts_bytes = 0;
    }
    int got_frame = 0;
    int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt);
    // LATM may need many packets to find mux info
    if (ret == AVERROR(EAGAIN))
        return 0;
    if (ret < 0) {
        mp_msg(MSGT_DECAUDIO, MSGL_V, "lavc_audio: error\n");
        return -1;
    }
    // The "insize >= ret" test is sanity check against decoder overreads
    if (!sh->parser && insize >= ret)
        priv->previous_data_left = insize - ret;
    if (!got_frame)
        return 0;

    int format_result = setup_format(sh);
    if (format_result < 0)
        return format_result;

#ifdef CONFIG_LIBAVRESAMPLE
    if (priv->avr) {
        int ret;
        uint64_t needed_size = av_samples_get_buffer_size(
                NULL, priv->resample_channels, priv->avframe->nb_samples,
                priv->resample_fmt, 0);
        if (needed_size > priv->resample_buf_size) {
            priv->resample_buf = talloc_realloc(priv, priv->resample_buf,
                                                uint8_t, needed_size);
            priv->resample_buf_size = needed_size;
        }

        ret = avresample_convert(priv->avr, &priv->resample_buf,
                priv->resample_buf_size, priv->avframe->nb_samples,
                priv->avframe->extended_data, priv->avframe->linesize[0],
                priv->avframe->nb_samples);
        if (ret < 0) {
            uint8_t error[128];
            av_strerror(ret, error, sizeof(error));
            mp_msg(MSGT_DECAUDIO, MSGL_ERR,
                   "Error during sample format conversion: %s.\n", error);
            return -1;
        }

        assert(ret == priv->avframe->nb_samples);

        priv->output = priv->resample_buf;
        priv->output_left = priv->unitsize * ret;
    } else
#endif
    {
        uint64_t unitsize = av_get_bytes_per_sample(avctx->sample_fmt) *
                            (uint64_t)avctx->channels;
        if (unitsize > 100000)
            abort();
        priv->unitsize = unitsize;
        uint64_t output_left = unitsize * priv->avframe->nb_samples;
        if (output_left > 500000000)
            abort();
        priv->output_left = output_left;
        priv->output = priv->avframe->data[0];
    }

    mp_dbg(MSGT_DECAUDIO, MSGL_DBG2, "Decoded %d -> %d  \n", insize,
           priv->output_left);
    return format_result;
}
示例#5
0
static int decode_new_packet(struct sh_audio *sh)
{
    struct priv *priv = sh->context;
    AVCodecContext *avctx = priv->avctx;
    double pts = MP_NOPTS_VALUE;
    int insize;
    bool packet_already_used = priv->previous_data_left;
    struct demux_packet *mpkt = ds_get_packet2(sh->ds,
                                               priv->previous_data_left);
    unsigned char *start;
    if (!mpkt) {
        assert(!priv->previous_data_left);
        start = NULL;
        insize = 0;
        ds_parse(sh->ds, &start, &insize, pts, 0);
        if (insize <= 0)
            return -1;  // error or EOF
    } else {
        assert(mpkt->len >= priv->previous_data_left);
        if (!priv->previous_data_left) {
            priv->previous_data_left = mpkt->len;
            pts = mpkt->pts;
        }
        insize = priv->previous_data_left;
        start = mpkt->buffer + mpkt->len - priv->previous_data_left;
        int consumed = ds_parse(sh->ds, &start, &insize, pts, 0);
        priv->previous_data_left -= consumed;
    }

    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.data = start;
    pkt.size = insize;
    if (mpkt && mpkt->avpacket) {
        pkt.side_data = mpkt->avpacket->side_data;
        pkt.side_data_elems = mpkt->avpacket->side_data_elems;
    }
    if (pts != MP_NOPTS_VALUE && !packet_already_used) {
        sh->pts = pts;
        sh->pts_bytes = 0;
    }
    int got_frame = 0;
    int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt);
    // LATM may need many packets to find mux info
    if (ret == AVERROR(EAGAIN))
        return 0;
    if (ret < 0) {
        mp_msg(MSGT_DECAUDIO, MSGL_V, "lavc_audio: error\n");
        return -1;
    }
    if (!sh->parser)
        priv->previous_data_left += insize - ret;
    if (!got_frame)
        return 0;
    /* An error is reported later from output format checking, but make
     * sure we don't crash by overreading first plane. */
    if (av_sample_fmt_is_planar(avctx->sample_fmt) && avctx->channels > 1)
        return 0;
    uint64_t unitsize = (uint64_t)av_get_bytes_per_sample(avctx->sample_fmt) *
                        avctx->channels;
    if (unitsize > 100000)
        abort();
    priv->unitsize = unitsize;
    uint64_t output_left = unitsize * priv->avframe->nb_samples;
    if (output_left > 500000000)
        abort();
    priv->output_left = output_left;
    priv->output = priv->avframe->data[0];
    mp_dbg(MSGT_DECAUDIO, MSGL_DBG2, "Decoded %d -> %d  \n", insize,
           priv->output_left);
    return 0;
}