Beispiel #1
0
static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
{
    AVCodec *codec;
    AVCodecContext *context;
    hb_audio_t *audio = w->audio;

    hb_work_private_t *pv = calloc(1, sizeof(hb_work_private_t));
    w->private_data       = pv;
    pv->job               = job;
    pv->list              = hb_list_init();

    // channel count, layout and matrix encoding
    int matrix_encoding;
    uint64_t channel_layout   = hb_ff_mixdown_xlat(audio->config.out.mixdown,
                                                   &matrix_encoding);
    pv->out_discrete_channels =
        hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);

    // default settings and options
    AVDictionary *av_opts          = NULL;
    const char *codec_name         = NULL;
    enum AVCodecID codec_id        = AV_CODEC_ID_NONE;
    enum AVSampleFormat sample_fmt = AV_SAMPLE_FMT_FLTP;
    int bits_per_raw_sample        = 0;
    int profile                    = FF_PROFILE_UNKNOWN;

    // override with encoder-specific values
    switch (audio->config.out.codec)
    {
        case HB_ACODEC_AC3:
            codec_id = AV_CODEC_ID_AC3;
            if (matrix_encoding != AV_MATRIX_ENCODING_NONE)
                av_dict_set(&av_opts, "dsur_mode", "on", 0);
            break;

        case HB_ACODEC_FFEAC3:
            codec_id = AV_CODEC_ID_EAC3;
            if (matrix_encoding != AV_MATRIX_ENCODING_NONE)
                av_dict_set(&av_opts, "dsur_mode", "on", 0);
            break;

        case HB_ACODEC_FDK_AAC:
        case HB_ACODEC_FDK_HAAC:
            codec_name          = "libfdk_aac";
            sample_fmt          = AV_SAMPLE_FMT_S16;
            bits_per_raw_sample = 16;
            switch (audio->config.out.codec)
            {
                case HB_ACODEC_FDK_HAAC:
                    profile = FF_PROFILE_AAC_HE;
                    break;
                default:
                    profile = FF_PROFILE_AAC_LOW;
                    break;
            }
            // Libav's libfdk-aac wrapper expects back channels for 5.1
            // audio, and will error out unless we translate the layout
            if (channel_layout == AV_CH_LAYOUT_5POINT1)
                channel_layout  = AV_CH_LAYOUT_5POINT1_BACK;
            break;

        case HB_ACODEC_FFAAC:
            codec_name = "aac";
            av_dict_set(&av_opts, "stereo_mode", "ms_off", 0);
            break;

        case HB_ACODEC_FFFLAC:
        case HB_ACODEC_FFFLAC24:
            codec_id = AV_CODEC_ID_FLAC;
            switch (audio->config.out.codec)
            {
                case HB_ACODEC_FFFLAC24:
                    sample_fmt          = AV_SAMPLE_FMT_S32;
                    bits_per_raw_sample = 24;
                    break;
                default:
                    sample_fmt          = AV_SAMPLE_FMT_S16;
                    bits_per_raw_sample = 16;
                    break;
            }
            break;

        default:
            hb_error("encavcodecaInit: unsupported codec (0x%x)",
                     audio->config.out.codec);
            return 1;
    }
    if (codec_name != NULL)
    {
        codec = avcodec_find_encoder_by_name(codec_name);
        if (codec == NULL)
        {
            hb_error("encavcodecaInit: avcodec_find_encoder_by_name(%s) failed",
                     codec_name);
            return 1;
        }
    }
    else
    {
        codec = avcodec_find_encoder(codec_id);
        if (codec == NULL)
        {
            hb_error("encavcodecaInit: avcodec_find_encoder(%d) failed",
                     codec_id);
            return 1;
        }
    }
    // allocate the context and apply the settings
    context                      = avcodec_alloc_context3(codec);
    hb_ff_set_sample_fmt(context, codec, sample_fmt);
    context->bits_per_raw_sample = bits_per_raw_sample;
    context->profile             = profile;
    context->channel_layout      = channel_layout;
    context->channels            = pv->out_discrete_channels;
    context->sample_rate         = audio->config.out.samplerate;

    if (audio->config.out.bitrate > 0)
    {
        context->bit_rate = audio->config.out.bitrate * 1000;
    }
    else if (audio->config.out.quality >= 0)
    {
        context->global_quality = audio->config.out.quality * FF_QP2LAMBDA;
        context->flags |= CODEC_FLAG_QSCALE;
        if (audio->config.out.codec == HB_ACODEC_FDK_AAC ||
            audio->config.out.codec == HB_ACODEC_FDK_HAAC)
        {
            char vbr[2];
            snprintf(vbr, 2, "%.1g", audio->config.out.quality);
            av_dict_set(&av_opts, "vbr", vbr, 0);
        }
    }

    if (audio->config.out.compression_level >= 0)
    {
        context->compression_level = audio->config.out.compression_level;
    }

    // For some codecs, libav requires the following flag to be set
    // so that it fills extradata with global header information.
    // If this flag is not set, it inserts the data into each
    // packet instead.
    context->flags |= CODEC_FLAG_GLOBAL_HEADER;

    if (hb_avcodec_open(context, codec, &av_opts, 0))
    {
        hb_error("encavcodecaInit: hb_avcodec_open() failed");
        return 1;
    }
    // avcodec_open populates the opts dictionary with the
    // things it didn't recognize.
    AVDictionaryEntry *t = NULL;
    while ((t = av_dict_get(av_opts, "", t, AV_DICT_IGNORE_SUFFIX)))
    {
        hb_log("encavcodecaInit: Unknown avcodec option %s", t->key);
    }
    av_dict_free(&av_opts);

    pv->context           = context;
    audio->config.out.samples_per_frame =
    pv->samples_per_frame = context->frame_size;
    pv->input_samples     = context->frame_size * context->channels;
    pv->input_buf         = malloc(pv->input_samples * sizeof(float));
    // Some encoders in libav (e.g. fdk-aac) fail if the output buffer
    // size is not some minumum value.  8K seems to be enough :(
    pv->max_output_bytes  = MAX(FF_MIN_BUFFER_SIZE,
                                (pv->input_samples *
                                 av_get_bytes_per_sample(context->sample_fmt)));

    // sample_fmt conversion
    if (context->sample_fmt != AV_SAMPLE_FMT_FLT)
    {
        pv->output_buf = malloc(pv->max_output_bytes);
        pv->avresample = avresample_alloc_context();
        if (pv->avresample == NULL)
        {
            hb_error("encavcodecaInit: avresample_alloc_context() failed");
            return 1;
        }
        av_opt_set_int(pv->avresample, "in_sample_fmt",
                       AV_SAMPLE_FMT_FLT, 0);
        av_opt_set_int(pv->avresample, "out_sample_fmt",
                       context->sample_fmt, 0);
        av_opt_set_int(pv->avresample, "in_channel_layout",
                       context->channel_layout, 0);
        av_opt_set_int(pv->avresample, "out_channel_layout",
                       context->channel_layout, 0);
        if (hb_audio_dither_is_supported(audio->config.out.codec))
        {
            // dithering needs the sample rate
            av_opt_set_int(pv->avresample, "in_sample_rate",
                           context->sample_rate, 0);
            av_opt_set_int(pv->avresample, "out_sample_rate",
                           context->sample_rate, 0);
            av_opt_set_int(pv->avresample, "dither_method",
                           audio->config.out.dither_method, 0);
        }
        if (avresample_open(pv->avresample))
        {
            hb_error("encavcodecaInit: avresample_open() failed");
            avresample_free(&pv->avresample);
            return 1;
        }
    }
    else
    {
        pv->avresample = NULL;
        pv->output_buf = pv->input_buf;
    }

    if (context->extradata != NULL)
    {
        memcpy(w->config->extradata.bytes, context->extradata,
               context->extradata_size);
        w->config->extradata.length = context->extradata_size;
    }

    audio->config.out.delay = av_rescale_q(context->delay, context->time_base,
                                           (AVRational){1, 90000});

    return 0;
}
Beispiel #2
0
int decode_thread(void *arg) {

    VideoState *is = (VideoState *)arg;
    AVFormatContext *pFormatCtx = NULL;
    AVPacket pkt1, *packet = &pkt1;

    AVDictionary *io_dict = NULL;
    AVIOInterruptCB callback;

    int video_index = -1;
    int audio_index = -1;
    int i;

    is->videoStream = -1;
    is->audioStream = -1;
    is->audio_need_resample = 0;

    global_video_state = is;
    // will interrupt blocking functions if we quit!
    callback.callback = decode_interrupt_cb;
    callback.opaque = is;

    if(avio_open2(&is->io_context, is->filename, 0, &callback, &io_dict)) {
        fprintf(stderr, "Unable to open I/O for %s\n", is->filename);
        return -1;
    }

    // Open video file
    if(avformat_open_input(&pFormatCtx, is->filename, NULL, NULL) != 0) {
        return -1;    // Couldn't open file
    }

    is->pFormatCtx = pFormatCtx;

    // Retrieve stream information
    if(avformat_find_stream_info(pFormatCtx, NULL) < 0) {
        return -1;    // Couldn't find stream information
    }

    // Dump information about file onto standard error
    av_dump_format(pFormatCtx, 0, is->filename, 0);

    // Find the first video stream

    for(i = 0; i < pFormatCtx->nb_streams; i++) {
        if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
                video_index < 0) {
            video_index = i;
        }

        if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
                audio_index < 0) {
            audio_index = i;
        }
    }

    if(audio_index >= 0) {
        stream_component_open(is, audio_index);
    }

    if(video_index >= 0) {
        stream_component_open(is, video_index);
    }

    if(is->videoStream < 0 && is->audioStream < 0) {
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
        goto fail;
    }

#ifdef __RESAMPLER__

    if( audio_index >= 0
            && pFormatCtx->streams[audio_index]->codec->sample_fmt != AV_SAMPLE_FMT_S16) {
        is->audio_need_resample = 1;
        is->pResampledOut = NULL;
        is->pSwrCtx = NULL;

        printf("Configure resampler: ");

#ifdef __LIBAVRESAMPLE__
        printf("libAvResample\n");
        is->pSwrCtx = avresample_alloc_context();
#endif

#ifdef __LIBSWRESAMPLE__
        printf("libSwResample\n");
        is->pSwrCtx = swr_alloc();
#endif

        // Some MP3/WAV don't tell this so make assumtion that
        // They are stereo not 5.1
        if (pFormatCtx->streams[audio_index]->codec->channel_layout == 0
                && pFormatCtx->streams[audio_index]->codec->channels == 2) {
            pFormatCtx->streams[audio_index]->codec->channel_layout = AV_CH_LAYOUT_STEREO;

        } else if (pFormatCtx->streams[audio_index]->codec->channel_layout == 0
                   && pFormatCtx->streams[audio_index]->codec->channels == 1) {
            pFormatCtx->streams[audio_index]->codec->channel_layout = AV_CH_LAYOUT_MONO;

        } else if (pFormatCtx->streams[audio_index]->codec->channel_layout == 0
                   && pFormatCtx->streams[audio_index]->codec->channels == 0) {
            pFormatCtx->streams[audio_index]->codec->channel_layout = AV_CH_LAYOUT_STEREO;
            pFormatCtx->streams[audio_index]->codec->channels = 2;
        }

        av_opt_set_int(is->pSwrCtx, "in_channel_layout",
                       pFormatCtx->streams[audio_index]->codec->channel_layout, 0);
        av_opt_set_int(is->pSwrCtx, "in_sample_fmt",
                       pFormatCtx->streams[audio_index]->codec->sample_fmt, 0);
        av_opt_set_int(is->pSwrCtx, "in_sample_rate",
                       pFormatCtx->streams[audio_index]->codec->sample_rate, 0);

        av_opt_set_int(is->pSwrCtx, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
        av_opt_set_int(is->pSwrCtx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
        av_opt_set_int(is->pSwrCtx, "out_sample_rate", 44100, 0);

#ifdef __LIBAVRESAMPLE__

        if (avresample_open(is->pSwrCtx) < 0) {
#else

        if (swr_init(is->pSwrCtx) < 0) {
#endif
            fprintf(stderr, " ERROR!! From Samplert: %d Hz Sample format: %s\n",
                    pFormatCtx->streams[audio_index]->codec->sample_rate,
                    av_get_sample_fmt_name(pFormatCtx->streams[audio_index]->codec->sample_fmt));
            fprintf(stderr, "         To 44100 Sample format: s16\n");
            is->audio_need_resample = 0;
            is->pSwrCtx = NULL;;
        }

    }

#endif

    // main decode loop

    for(;;) {
        if(is->quit) {
            break;
        }

        // seek stuff goes here
        if(is->audioq.size > MAX_AUDIOQ_SIZE ||
                is->videoq.size > MAX_VIDEOQ_SIZE) {
            SDL_Delay(10);
            continue;
        }

        if(av_read_frame(is->pFormatCtx, packet) < 0) {
            if(is->pFormatCtx->pb->error == 0) {
                SDL_Delay(100); /* no error; wait for user input */
                continue;

            } else {
                break;
            }
        }

        // Is this a packet from the video stream?
        if(packet->stream_index == is->videoStream) {
            packet_queue_put(&is->videoq, packet);

        } else if(packet->stream_index == is->audioStream) {
            packet_queue_put(&is->audioq, packet);

        } else {
            av_free_packet(packet);
        }
    }

    /* all done - wait for it */
    while(!is->quit) {
        SDL_Delay(100);
    }

fail: {
        SDL_Event event;
        event.type = FF_QUIT_EVENT;
        event.user.data1 = is;
        SDL_PushEvent(&event);
    }
    return 0;
}

const char g_szClassName[] = "myWindowClass";

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

sem_t mutex;
HWND hwnd;

static void * window_manager(void * data) {
    printf("Window manager has been started!\n");
    WNDCLASSEX wc;

    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    //wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
                   MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
               WS_EX_CLIENTEDGE,
               g_szClassName,
               "The title of my window",
               WS_OVERLAPPEDWINDOW,
               CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
               NULL, NULL, NULL, NULL);
    sem_post(&mutex);
    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
                   MB_ICONEXCLAMATION | MB_OK);
        return 0;
    } else {
        printf("window hwnd = %d\n", hwnd);
    }

    ShowWindow(hwnd, TRUE);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    return Msg.wParam;
}
Beispiel #3
0
static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
                           struct mp_audio *out)
{
    struct af_resample *s = af->priv;

    close_lavrr(af);

    s->avrctx = avresample_alloc_context();
    s->avrctx_out = avresample_alloc_context();
    if (!s->avrctx || !s->avrctx_out)
        goto error;

    enum AVSampleFormat in_samplefmt = af_to_avformat(in->format);
    enum AVSampleFormat out_samplefmt = check_output_conversion(out->format);
    enum AVSampleFormat out_samplefmtp = av_get_planar_sample_fmt(out_samplefmt);

    if (in_samplefmt == AV_SAMPLE_FMT_NONE ||
        out_samplefmt == AV_SAMPLE_FMT_NONE ||
        out_samplefmtp == AV_SAMPLE_FMT_NONE)
        goto error;

    s->ctx.out_rate    = out->rate;
    s->ctx.in_rate_af  = in->rate;
    s->ctx.in_rate     = rate_from_speed(in->rate, s->playback_speed);
    s->ctx.out_format  = out->format;
    s->ctx.in_format   = in->format;
    s->ctx.out_channels= out->channels;
    s->ctx.in_channels = in->channels;
    s->ctx.filter_size = s->opts.filter_size;
    s->ctx.phase_shift = s->opts.phase_shift;
    s->ctx.linear      = s->opts.linear;
    s->ctx.cutoff      = s->opts.cutoff;

    av_opt_set_int(s->avrctx, "filter_size",        s->ctx.filter_size, 0);
    av_opt_set_int(s->avrctx, "phase_shift",        s->ctx.phase_shift, 0);
    av_opt_set_int(s->avrctx, "linear_interp",      s->ctx.linear, 0);

    av_opt_set_double(s->avrctx, "cutoff",          s->ctx.cutoff, 0);

#if HAVE_LIBSWRESAMPLE
    av_opt_set_double(s->avrctx, "rematrix_maxval", 1.0, 0);
#endif

    if (mp_set_avopts(af->log, s->avrctx, s->avopts) < 0)
        goto error;

    struct mp_chmap map_in = in->channels;
    struct mp_chmap map_out = out->channels;

    // Try not to do any remixing if at least one is "unknown".
    if (mp_chmap_is_unknown(&map_in) || mp_chmap_is_unknown(&map_out)) {
        mp_chmap_set_unknown(&map_in, map_in.num);
        mp_chmap_set_unknown(&map_out, map_out.num);
    }

    // unchecked: don't take any channel reordering into account
    uint64_t in_ch_layout = mp_chmap_to_lavc_unchecked(&map_in);
    uint64_t out_ch_layout = mp_chmap_to_lavc_unchecked(&map_out);

    struct mp_chmap in_lavc;
    mp_chmap_from_lavc(&in_lavc, in_ch_layout);
    if (in_lavc.num != map_in.num) {
        // For handling NA channels, we would have to add a planarization step.
        MP_FATAL(af, "Unsupported channel remapping.\n");
        goto error;
    }

    mp_chmap_get_reorder(s->reorder_in, &map_in, &in_lavc);
    transpose_order(s->reorder_in, map_in.num);

    struct mp_chmap out_lavc;
    mp_chmap_from_lavc(&out_lavc, out_ch_layout);
    if (mp_chmap_equals(&out_lavc, &map_out)) {
        // No intermediate step required - output new format directly.
        out_samplefmtp = out_samplefmt;
    } else {
        // Verify that we really just reorder and/or insert NA channels.
        struct mp_chmap withna = out_lavc;
        mp_chmap_fill_na(&withna, map_out.num);
        if (withna.num != map_out.num)
            goto error;
    }
    mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out);

    s->avrctx_fmt = *out;
    mp_audio_set_channels(&s->avrctx_fmt, &out_lavc);
    mp_audio_set_format(&s->avrctx_fmt, af_from_avformat(out_samplefmtp));

    s->pre_out_fmt = *out;
    mp_audio_set_format(&s->pre_out_fmt, af_from_avformat(out_samplefmt));

    // If there are NA channels, the final output will have more channels than
    // the avrctx output. Also, avrctx will output planar (out_samplefmtp was
    // not overwritten). Allocate the output frame with more channels, so the
    // NA channels can be trivially added.
    s->pool_fmt = s->avrctx_fmt;
    if (map_out.num > out_lavc.num)
        mp_audio_set_channels(&s->pool_fmt, &map_out);

    // Real conversion; output is input to avrctx_out.
    av_opt_set_int(s->avrctx, "in_channel_layout",  in_ch_layout, 0);
    av_opt_set_int(s->avrctx, "out_channel_layout", out_ch_layout, 0);
    av_opt_set_int(s->avrctx, "in_sample_rate",     s->ctx.in_rate, 0);
    av_opt_set_int(s->avrctx, "out_sample_rate",    s->ctx.out_rate, 0);
    av_opt_set_int(s->avrctx, "in_sample_fmt",      in_samplefmt, 0);
    av_opt_set_int(s->avrctx, "out_sample_fmt",     out_samplefmtp, 0);

    // Just needs the correct number of channels.
    int fake_out_ch_layout = av_get_default_channel_layout(map_out.num);
    if (!fake_out_ch_layout)
        goto error;

    // Deplanarize if needed.
    av_opt_set_int(s->avrctx_out, "in_channel_layout",  fake_out_ch_layout, 0);
    av_opt_set_int(s->avrctx_out, "out_channel_layout", fake_out_ch_layout, 0);
    av_opt_set_int(s->avrctx_out, "in_sample_fmt",      out_samplefmtp, 0);
    av_opt_set_int(s->avrctx_out, "out_sample_fmt",     out_samplefmt, 0);
    av_opt_set_int(s->avrctx_out, "in_sample_rate",     s->ctx.out_rate, 0);
    av_opt_set_int(s->avrctx_out, "out_sample_rate",    s->ctx.out_rate, 0);

    // API has weird requirements, quoting avresample.h:
    //  * This function can only be called when the allocated context is not open.
    //  * Also, the input channel layout must have already been set.
    avresample_set_channel_mapping(s->avrctx, s->reorder_in);

    if (avresample_open(s->avrctx) < 0 ||
        avresample_open(s->avrctx_out) < 0)
    {
        MP_ERR(af, "Cannot open Libavresample Context. \n");
        goto error;
    }
    return AF_OK;

error:
    close_lavrr(af);
    return AF_ERROR;
}
Beispiel #4
0
static av_cold int opus_decode_init(AVCodecContext *avctx)
{
    OpusContext *c = avctx->priv_data;
    int ret, i, j;

    avctx->sample_fmt  = AV_SAMPLE_FMT_FLTP;
    avctx->sample_rate = 48000;

    c->fdsp = avpriv_float_dsp_alloc(0);
    if (!c->fdsp)
        return AVERROR(ENOMEM);

    /* find out the channel configuration */
    ret = ff_opus_parse_extradata(avctx, c);
    if (ret < 0)
        return ret;

    /* allocate and init each independent decoder */
    c->streams = av_mallocz_array(c->nb_streams, sizeof(*c->streams));
    if (!c->streams) {
        c->nb_streams = 0;
        ret = AVERROR(ENOMEM);
        goto fail;
    }

    for (i = 0; i < c->nb_streams; i++) {
        OpusStreamContext *s = &c->streams[i];
        uint64_t layout;

        s->output_channels = (i < c->nb_stereo_streams) ? 2 : 1;

        s->avctx = avctx;

        for (j = 0; j < s->output_channels; j++) {
            s->silk_output[j]       = s->silk_buf[j];
            s->celt_output[j]       = s->celt_buf[j];
            s->redundancy_output[j] = s->redundancy_buf[j];
        }

        s->fdsp = c->fdsp;

#if CONFIG_SWRESAMPLE
        s->swr =swr_alloc();
        if (!s->swr)
            goto fail;

        layout = (s->output_channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
        av_opt_set_int(s->swr, "in_sample_fmt",      avctx->sample_fmt,  0);
        av_opt_set_int(s->swr, "out_sample_fmt",     avctx->sample_fmt,  0);
        av_opt_set_int(s->swr, "in_channel_layout",  layout,             0);
        av_opt_set_int(s->swr, "out_channel_layout", layout,             0);
        av_opt_set_int(s->swr, "out_sample_rate",    avctx->sample_rate, 0);
        av_opt_set_int(s->swr, "filter_size",        16,                 0);
#elif CONFIG_AVRESAMPLE
        s->avr = avresample_alloc_context();
        if (!s->avr)
            goto fail;

        layout = (s->output_channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
        av_opt_set_int(s->avr, "in_sample_fmt",      avctx->sample_fmt,  0);
        av_opt_set_int(s->avr, "out_sample_fmt",     avctx->sample_fmt,  0);
        av_opt_set_int(s->avr, "in_channel_layout",  layout,             0);
        av_opt_set_int(s->avr, "out_channel_layout", layout,             0);
        av_opt_set_int(s->avr, "out_sample_rate",    avctx->sample_rate, 0);
#endif

        ret = ff_silk_init(avctx, &s->silk, s->output_channels);
        if (ret < 0)
            goto fail;

        ret = ff_celt_init(avctx, &s->celt, s->output_channels);
        if (ret < 0)
            goto fail;

        s->celt_delay = av_audio_fifo_alloc(avctx->sample_fmt,
                                            s->output_channels, 1024);
        if (!s->celt_delay) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }
    }

    return 0;
fail:
    opus_decode_close(avctx);
    return ret;
}
Beispiel #5
0
 inline ResampleContext *resample_alloc() { return avresample_alloc_context(); }
Beispiel #6
0
int decode_thread(void *arg) {

    VideoState *is = (VideoState *)arg;
    AVFormatContext *pFormatCtx = NULL;
    AVPacket pkt1, *packet = &pkt1;

    AVDictionary *io_dict = NULL;
    AVIOInterruptCB callback;

    int video_index = -1;
    int audio_index = -1;
    int i;

    is->videoStream=-1;
    is->audioStream=-1;
    is->audio_need_resample = 0;

    global_video_state = is;
    // will interrupt blocking functions if we quit!
    callback.callback = decode_interrupt_cb;
    callback.opaque = is;
    if (avio_open2(&is->io_context, is->filename, 0, &callback, &io_dict)) {
        fprintf(stderr, "Unable to open I/O for %s\n", is->filename);
        return -1;
    }

    // Open video file
    if(avformat_open_input(&pFormatCtx, is->filename, NULL, NULL)!=0)
        return -1; // Couldn't open file

    is->pFormatCtx = pFormatCtx;

    // Retrieve stream information
    if(avformat_find_stream_info(pFormatCtx, NULL)<0)
        return -1; // Couldn't find stream information

    // Dump information about file onto standard error
    av_dump_format(pFormatCtx, 0, is->filename, 0);

    // Find the first video stream
    for(i=0; i<pFormatCtx->nb_streams; i++) {
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO &&
                video_index < 0) {
            video_index=i;
        } else if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
                  audio_index < 0) {
            audio_index=i;
        }
    }
    if(audio_index >= 0) {
        stream_component_open(is, audio_index);
    }
    if(video_index >= 0) {
        stream_component_open(is, video_index);
    }

    if(is->videoStream < 0 && is->audioStream < 0) {
        fprintf(stderr, "%s: could not open codecs\n", is->filename);
        goto fail;
    }

#ifdef __RESAMPLER__
    if( audio_index >= 0
            && pFormatCtx->streams[audio_index]->codec->sample_fmt != AV_SAMPLE_FMT_S16) {
        is->audio_need_resample=1;
        is->pResampledOut=NULL;
        is->pSwrCtx = NULL;

        printf("Configure resampler: ");

#ifdef __LIBAVRESAMPLE__
        printf("libAvResample\n");
        is->pSwrCtx = avresample_alloc_context();
#endif

#ifdef __LIBSWRESAMPLE__
        printf("libSwResample\n");
        is->pSwrCtx = swr_alloc();
#endif

        // Some MP3/WAV don't tell this so make assumtion that
        // They are stereo not 5.1
        if (pFormatCtx->streams[audio_index]->codec->channel_layout == 0
                && pFormatCtx->streams[audio_index]->codec->channels == 2) {
            pFormatCtx->streams[audio_index]->codec->channel_layout = AV_CH_LAYOUT_STEREO;
        } else if (pFormatCtx->streams[audio_index]->codec->channel_layout == 0
                   && pFormatCtx->streams[audio_index]->codec->channels == 1) {
            pFormatCtx->streams[audio_index]->codec->channel_layout = AV_CH_LAYOUT_MONO;
        } else if (pFormatCtx->streams[audio_index]->codec->channel_layout == 0
                   && pFormatCtx->streams[audio_index]->codec->channels == 0) {
            pFormatCtx->streams[audio_index]->codec->channel_layout = AV_CH_LAYOUT_STEREO;
            pFormatCtx->streams[audio_index]->codec->channels = 2;
        }

        av_opt_set_int(is->pSwrCtx,"in_channel_layout",
                       pFormatCtx->streams[audio_index]->codec->channel_layout, 0);
        av_opt_set_int(is->pSwrCtx,"in_sample_fmt",
                       pFormatCtx->streams[audio_index]->codec->sample_fmt, 0);
        av_opt_set_int(is->pSwrCtx,"in_sample_rate",
                       pFormatCtx->streams[audio_index]->codec->sample_rate, 0);

        av_opt_set_int(is->pSwrCtx,"out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
        av_opt_set_int(is->pSwrCtx,"out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
        av_opt_set_int(is->pSwrCtx,"out_sample_rate", 44100, 0);

#ifdef __LIBAVRESAMPLE__
        if (avresample_open(is->pSwrCtx) < 0) {
#else
        if (swr_init(is->pSwrCtx) < 0) {
#endif
            fprintf(stderr, " ERROR!! From Samplert: %d Hz Sample format: %s\n",
                    pFormatCtx->streams[audio_index]->codec->sample_rate,
                    av_get_sample_fmt_name(pFormatCtx->streams[audio_index]->codec->sample_fmt));
            fprintf(stderr, "         To 44100 Sample format: s16\n");
            is->audio_need_resample=0;
            is->pSwrCtx = NULL;;
        }

    }
#endif

    // main decode loop

    for(;;) {
        if(is->quit) {
            break;
        }
        // seek stuff goes here
        if(is->seek_req) {
            int stream_index= -1;

            int64_t seek_target = is->seek_pos;

            if     (is->videoStream >= 0) stream_index = is->videoStream;
            else if(is->audioStream >= 0) stream_index = is->audioStream;

            if(stream_index>=0) {
                seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q,
                                          pFormatCtx->streams[stream_index]->time_base);
            }
            printf("Seek_target: %ld/%ld stream_index: %ld\n",is->seek_pos, seek_target, stream_index);

            if(av_seek_frame(is->pFormatCtx, stream_index, seek_target,
                             is->seek_flags) < 0) {
                fprintf(stderr, "%s: error while seeking\n", is->pFormatCtx->filename);
            } else {
                if(is->audioStream >= 0) {
                    packet_queue_flush(&is->audioq);
                    packet_queue_put(&is->audioq, &flush_pkt);
                }
                if(is->videoStream >= 0) {
                    packet_queue_flush(&is->videoq);
                    packet_queue_put(&is->videoq, &flush_pkt);
                }
            }
            is->seek_req = 0;
        }

        if(is->audioq.size > MAX_AUDIOQ_SIZE ||
                is->videoq.size > MAX_VIDEOQ_SIZE) {
            SDL_Delay(10);
            continue;
        }
        if(av_read_frame(is->pFormatCtx, packet) < 0) {
            if(is->pFormatCtx->pb->error == 0) {
                SDL_Delay(100); /* no error; wait for user input */
                continue;
            } else {
                break;
            }
        }
        // Is this a packet from the video stream?
        if(packet->stream_index == is->videoStream) {
            packet_queue_put(&is->videoq, packet);
        } else if(packet->stream_index == is->audioStream) {
            packet_queue_put(&is->audioq, packet);
        } else {
            av_free_packet(packet);
        }
    }
    /* all done - wait for it */
    while(!is->quit) {
        SDL_Delay(100);
    }
fail: {
        SDL_Event event;
        event.type = FF_QUIT_EVENT;
        event.user.data1 = is;
        SDL_PushEvent(&event);
    }
    return 0;
}

void stream_seek(VideoState *is, int64_t pos, int rel) {

  if(!is->seek_req) {
    is->seek_pos = pos;
    is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
    is->seek_req = 1;
  }
}
int main(int argc, char *argv[]) {

  SDL_Event       event;
  //double          pts;
  VideoState      *is;

  is = av_mallocz(sizeof(VideoState));

  if(argc < 2) {
    fprintf(stderr, "Usage: test <file>\n");
    exit(1);
  }
  // Register all formats and codecs
  av_register_all();
  
  if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
    fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
    exit(1);
  }

  // Make a screen to put our video
#ifndef __DARWIN__
  screen = SDL_SetVideoMode(640, 480, 0, 0);
#else
  screen = SDL_SetVideoMode(640, 480, 24, 0);
#endif
  if(!screen) {
    fprintf(stderr, "SDL: could not set video mode - exiting\n");
    exit(1);
  }

  av_strlcpy(is->filename, argv[1], 1024);

  is->pictq_mutex = SDL_CreateMutex();
  is->pictq_cond = SDL_CreateCond();

  schedule_refresh(is, 40);

  is->av_sync_type = DEFAULT_AV_SYNC_TYPE;
  is->parse_tid = SDL_CreateThread(decode_thread, is);
  if(!is->parse_tid) {
    av_free(is);
    return -1;
  }

  av_init_packet(&flush_pkt);
  flush_pkt.data = (unsigned char *)"FLUSH";
  
  for(;;) {
    double incr, pos;
    SDL_WaitEvent(&event);
    switch(event.type) {
    case SDL_KEYDOWN:
      switch(event.key.keysym.sym) {
      case SDLK_LEFT:
	incr = -10.0;
	goto do_seek;
      case SDLK_RIGHT:
	incr = 10.0;
	goto do_seek;
      case SDLK_UP:
	incr = 60.0;
	goto do_seek;
      case SDLK_DOWN:
	incr = -60.0;
	goto do_seek;
      do_seek:
	if(global_video_state) {
	  pos = get_master_clock(global_video_state);
	  pos += incr;
	  stream_seek(global_video_state, (int64_t)(pos * AV_TIME_BASE), incr);
	}
	break;
      default:
	break;
      }
      break;
    case FF_QUIT_EVENT:
    case SDL_QUIT:
      is->quit = 1;
      /*
       * If the video has finished playing, then both the picture and
       * audio queues are waiting for more data.  Make them stop
       * waiting and terminate normally.
       */
      SDL_CondSignal(is->audioq.cond);
      SDL_CondSignal(is->videoq.cond);
      SDL_Quit();
      exit(0);
      break;
    case FF_ALLOC_EVENT:
      alloc_picture(event.user.data1);
      break;
    case FF_REFRESH_EVENT:
      video_refresh_timer(event.user.data1);
      break;
    default:
      break;
    }
  }
  return 0;
}
Beispiel #7
0
void CMixer::Init(DWORD out_layout, DWORD in_layout, enum AVSampleFormat in_sf)
{
    avresample_free(&m_pAVRCxt);

    int ret = 0;
    // Allocate Resample Context and set options.
    m_pAVRCxt = avresample_alloc_context();
    av_opt_set_int(m_pAVRCxt, "in_channel_layout", in_layout, 0);
    av_opt_set_int(m_pAVRCxt, "in_sample_fmt", in_sf, 0);
    av_opt_set_int(m_pAVRCxt, "out_channel_layout", out_layout, 0);
    av_opt_set_int(m_pAVRCxt, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0); // forced float output

    // Open Resample Context
    ret = avresample_open(m_pAVRCxt);
    if (ret < 0) {
        TRACE(_T("Mixer: avresample_open failed\n"));
        avresample_free(&m_pAVRCxt);
        return;
    }

    // Create Matrix
    int in_ch  = av_popcount(in_layout);
    int out_ch = av_popcount(out_layout);
    double* matrix_dbl = (double*)av_mallocz(in_ch * out_ch * sizeof(*matrix_dbl));
    // expand stereo
    if (in_layout == AV_CH_LAYOUT_STEREO && (out_layout == AV_CH_LAYOUT_QUAD || out_layout == AV_CH_LAYOUT_5POINT1 || out_layout == AV_CH_LAYOUT_7POINT1)) {
        matrix_dbl[0] = 1.0;
        matrix_dbl[1] = 0.0;
        matrix_dbl[2] = 0.0;
        matrix_dbl[3] = 1.0;
        if (out_layout == AV_CH_LAYOUT_QUAD) {
            matrix_dbl[4] = 0.5;
            matrix_dbl[5] = (-0.5);
            matrix_dbl[6] = (-0.5);
            matrix_dbl[7] = 0.5;
        } else if (out_layout == AV_CH_LAYOUT_5POINT1 || out_layout == AV_CH_LAYOUT_7POINT1) {
            matrix_dbl[4] = 0.5;
            matrix_dbl[5] = 0.5;
            matrix_dbl[6] = 0.0;
            matrix_dbl[7] = 0.0;
            matrix_dbl[8] = 0.5;
            matrix_dbl[9] = (-0.5);
            matrix_dbl[10] = (-0.5);
            matrix_dbl[11] = 0.5;
            if (out_layout == AV_CH_LAYOUT_7POINT1) {
                matrix_dbl[12] = 0.5;
                matrix_dbl[13] = (-0.5);
                matrix_dbl[14] = (-0.5);
                matrix_dbl[15] = 0.5;
            }
        }
    } else {
        const double center_mix_level   = M_SQRT1_2;
        const double surround_mix_level = M_SQRT1_2;
        const double lfe_mix_level      = M_SQRT1_2;
        const int normalize = 0;
        ret = avresample_build_matrix(in_layout, out_layout, center_mix_level, surround_mix_level, lfe_mix_level, normalize, matrix_dbl, in_ch, AV_MATRIX_ENCODING_NONE);
        if (ret < 0) {
            TRACE(_T("Mixer: avresample_build_matrix failed\n"));
            av_free(matrix_dbl);
            avresample_free(&m_pAVRCxt);
            return;
        }
    }

#ifdef _DEBUG
    CString matrix_str;
    for (int j = 0; j < out_ch; j++) {
        matrix_str.AppendFormat(_T("%d:"), j + 1);
        for (int i = 0; i < in_ch; i++) {
            double k = matrix_dbl[j * in_ch + i];
            matrix_str.AppendFormat(_T(" %.4f"), k);
        }
        matrix_str += _T("\n");
    }
    TRACE(matrix_str);
#endif

    // Set Matrix on the context
    ret = avresample_set_matrix(m_pAVRCxt, matrix_dbl, in_ch);
    av_free(matrix_dbl);
    if (ret < 0) {
        TRACE(_T("Mixer: avresample_set_matrix failed\n"));
        avresample_free(&m_pAVRCxt);
        return;
    }

    last_in_layout  = in_layout;
    last_out_layout = out_layout;
    last_in_sf      = in_sf;
}
Beispiel #8
0
/*
 * add an audio output stream
 */
static void add_audio_stream(OutputStream *ost, AVFormatContext *oc,
                             enum AVCodecID codec_id)
{
    AVCodecContext *c;
    AVCodec *codec;
    int ret;

    /* find the audio encoder */
    codec = avcodec_find_encoder(codec_id);
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

    ost->st = avformat_new_stream(oc, NULL);
    if (!ost->st) {
        fprintf(stderr, "Could not alloc stream\n");
        exit(1);
    }

    c = avcodec_alloc_context3(codec);
    if (!c) {
        fprintf(stderr, "Could not alloc an encoding context\n");
        exit(1);
    }
    ost->enc = c;

    /* put sample parameters */
    c->sample_fmt     = codec->sample_fmts           ? codec->sample_fmts[0]           : AV_SAMPLE_FMT_S16;
    c->sample_rate    = codec->supported_samplerates ? codec->supported_samplerates[0] : 44100;
    c->channel_layout = codec->channel_layouts       ? codec->channel_layouts[0]       : AV_CH_LAYOUT_STEREO;
    c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
    c->bit_rate       = 64000;

    ost->st->time_base = (AVRational){ 1, c->sample_rate };

    // some formats want stream headers to be separate
    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
        c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

    /* initialize sample format conversion;
     * to simplify the code, we always pass the data through lavr, even
     * if the encoder supports the generated format directly -- the price is
     * some extra data copying;
     */
    ost->avr = avresample_alloc_context();
    if (!ost->avr) {
        fprintf(stderr, "Error allocating the resampling context\n");
        exit(1);
    }

    av_opt_set_int(ost->avr, "in_sample_fmt",      AV_SAMPLE_FMT_S16,   0);
    av_opt_set_int(ost->avr, "in_sample_rate",     44100,               0);
    av_opt_set_int(ost->avr, "in_channel_layout",  AV_CH_LAYOUT_STEREO, 0);
    av_opt_set_int(ost->avr, "out_sample_fmt",     c->sample_fmt,       0);
    av_opt_set_int(ost->avr, "out_sample_rate",    c->sample_rate,      0);
    av_opt_set_int(ost->avr, "out_channel_layout", c->channel_layout,   0);

    ret = avresample_open(ost->avr);
    if (ret < 0) {
        fprintf(stderr, "Error opening the resampling context\n");
        exit(1);
    }
}
Beispiel #9
0
int hb_audio_resample_update(hb_audio_resample_t *resample)
{
    if (resample == NULL)
    {
        hb_error("hb_audio_resample_update: resample is NULL");
        return 1;
    }

    int ret, resample_changed;

    resample->resample_needed =
        (resample->out.sample_fmt != resample->in.sample_fmt ||
         resample->out.channel_layout != resample->in.channel_layout);

    resample_changed =
        (resample->resample_needed &&
         (resample->resample.sample_fmt != resample->in.sample_fmt ||
          resample->resample.channel_layout != resample->in.channel_layout ||
          resample->resample.lfe_mix_level != resample->in.lfe_mix_level ||
          resample->resample.center_mix_level != resample->in.center_mix_level ||
          resample->resample.surround_mix_level != resample->in.surround_mix_level));

    if (resample_changed || (resample->resample_needed &&
                             resample->avresample == NULL))
    {
        if (resample->avresample == NULL)
        {
            resample->avresample = avresample_alloc_context();
            if (resample->avresample == NULL)
            {
                hb_error("hb_audio_resample_update: avresample_alloc_context() failed");
                return 1;
            }

            av_opt_set_int(resample->avresample, "out_sample_fmt",
                           resample->out.sample_fmt, 0);
            av_opt_set_int(resample->avresample, "out_channel_layout",
                           resample->out.channel_layout, 0);
            av_opt_set_int(resample->avresample, "matrix_encoding",
                           resample->out.matrix_encoding, 0);
            av_opt_set_int(resample->avresample, "normalize_mix_level",
                           resample->out.normalize_mix_level, 0);
        }
        else if (resample_changed)
        {
            avresample_close(resample->avresample);
        }

        av_opt_set_int(resample->avresample, "in_sample_fmt",
                       resample->in.sample_fmt, 0);
        av_opt_set_int(resample->avresample, "in_channel_layout",
                       resample->in.channel_layout, 0);
        av_opt_set_double(resample->avresample, "lfe_mix_level",
                          resample->in.lfe_mix_level, 0);
        av_opt_set_double(resample->avresample, "center_mix_level",
                          resample->in.center_mix_level, 0);
        av_opt_set_double(resample->avresample, "surround_mix_level",
                          resample->in.surround_mix_level, 0);

        if ((ret = avresample_open(resample->avresample)))
        {
            char err_desc[64];
            av_strerror(ret, err_desc, 63);
            hb_error("hb_audio_resample_update: avresample_open() failed (%s)",
                     err_desc);
            // avresample won't open, start over
            avresample_free(&resample->avresample);
            return ret;
        }

        resample->resample.sample_fmt         = resample->in.sample_fmt;
        resample->resample.channel_layout     = resample->in.channel_layout;
        resample->resample.channels           =
            av_get_channel_layout_nb_channels(resample->in.channel_layout);
        resample->resample.lfe_mix_level      = resample->in.lfe_mix_level;
        resample->resample.center_mix_level   = resample->in.center_mix_level;
        resample->resample.surround_mix_level = resample->in.surround_mix_level;
    }

    return 0;
}
Beispiel #10
0
void as_setup_audio_rendering
(
    lw_audio_output_handler_t *aohp,
    AVCodecContext            *ctx,
    VideoInfo                 *vi,
    IScriptEnvironment        *env,
    const char                *filter_name,
    uint64_t                   channel_layout,
    int                        sample_rate
)
{
    /* Channel layout. */
    if( ctx->channel_layout == 0 )
        ctx->channel_layout = av_get_default_channel_layout( ctx->channels );
    if( channel_layout != 0 )
        aohp->output_channel_layout = channel_layout;
    /* Sample rate. */
    if( sample_rate > 0 )
        aohp->output_sample_rate = sample_rate;
    /* Decide output Bits Per Sample. */
    aohp->output_sample_format = as_decide_audio_output_sample_format( aohp->output_sample_format );
    if( aohp->output_sample_format == AV_SAMPLE_FMT_S32
     && (aohp->output_bits_per_sample == 0 || aohp->output_bits_per_sample == 24) )
    {
        /* 24bit signed integer output */
        aohp->s24_output             = 1;
        aohp->output_bits_per_sample = 24;
    }
    else
        aohp->output_bits_per_sample = av_get_bytes_per_sample( aohp->output_sample_format ) * 8;
    /* Set up the number of planes and the block alignment of decoded and output data. */
    int input_channels = av_get_channel_layout_nb_channels( ctx->channel_layout );
    if( av_sample_fmt_is_planar( ctx->sample_fmt ) )
    {
        aohp->input_planes      = input_channels;
        aohp->input_block_align = av_get_bytes_per_sample( ctx->sample_fmt );
    }
    else
    {
        aohp->input_planes      = 1;
        aohp->input_block_align = av_get_bytes_per_sample( ctx->sample_fmt ) * input_channels;
    }
    int output_channels = av_get_channel_layout_nb_channels( aohp->output_channel_layout );
    aohp->output_block_align = (output_channels * aohp->output_bits_per_sample) / 8;
    /* Set up resampler. */
    AVAudioResampleContext *avr_ctx = aohp->avr_ctx;
    avr_ctx = avresample_alloc_context();
    if( !avr_ctx )
        env->ThrowError( "%s: failed to avresample_alloc_context.", filter_name );
    aohp->avr_ctx = avr_ctx;
    av_opt_set_int( avr_ctx, "in_channel_layout",   ctx->channel_layout,         0 );
    av_opt_set_int( avr_ctx, "in_sample_fmt",       ctx->sample_fmt,             0 );
    av_opt_set_int( avr_ctx, "in_sample_rate",      ctx->sample_rate,            0 );
    av_opt_set_int( avr_ctx, "out_channel_layout",  aohp->output_channel_layout, 0 );
    av_opt_set_int( avr_ctx, "out_sample_fmt",      aohp->output_sample_format,  0 );
    av_opt_set_int( avr_ctx, "out_sample_rate",     aohp->output_sample_rate,    0 );
    av_opt_set_int( avr_ctx, "internal_sample_fmt", AV_SAMPLE_FMT_FLTP,          0 );
    if( avresample_open( avr_ctx ) < 0 )
        env->ThrowError( "%s: failed to open resampler.", filter_name );
    /* Set up AviSynth output format. */
    vi->nchannels                = output_channels;
    vi->audio_samples_per_second = aohp->output_sample_rate;
    switch ( aohp->output_sample_format )
    {
        case AV_SAMPLE_FMT_U8 :
        case AV_SAMPLE_FMT_U8P :
            vi->sample_type = SAMPLE_INT8;
            break;
        case AV_SAMPLE_FMT_S16 :
        case AV_SAMPLE_FMT_S16P :
            vi->sample_type = SAMPLE_INT16;
            break;
        case AV_SAMPLE_FMT_S32 :
        case AV_SAMPLE_FMT_S32P :
            vi->sample_type = aohp->s24_output ? SAMPLE_INT24 : SAMPLE_INT32;
            break;
        case AV_SAMPLE_FMT_FLT :
        case AV_SAMPLE_FMT_FLTP :
            vi->sample_type = SAMPLE_FLOAT;
            break;
        default :
            env->ThrowError( "%s: %s is not supported.", filter_name, av_get_sample_fmt_name( ctx->sample_fmt ) );
    }
}
static int config_output(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    AVFilterLink *inlink = ctx->inputs[0];
    ResampleContext   *s = ctx->priv;
    char buf1[64], buf2[64];
    int ret;

    int64_t resampling_forced;

    if (s->avr) {
        avresample_close(s->avr);
        avresample_free(&s->avr);
    }

    if (inlink->channel_layout == outlink->channel_layout &&
        inlink->sample_rate    == outlink->sample_rate    &&
        (inlink->format        == outlink->format ||
        (av_get_channel_layout_nb_channels(inlink->channel_layout)  == 1 &&
         av_get_channel_layout_nb_channels(outlink->channel_layout) == 1 &&
         av_get_planar_sample_fmt(inlink->format) ==
         av_get_planar_sample_fmt(outlink->format))))
        return 0;

    if (!(s->avr = avresample_alloc_context()))
        return AVERROR(ENOMEM);

    if (s->options) {
        int ret;
        AVDictionaryEntry *e = NULL;
        while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
            av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value);

        ret = av_opt_set_dict(s->avr, &s->options);
        if (ret < 0)
            return ret;
    }

    av_opt_set_int(s->avr,  "in_channel_layout", inlink ->channel_layout, 0);
    av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0);
    av_opt_set_int(s->avr,  "in_sample_fmt",     inlink ->format,         0);
    av_opt_set_int(s->avr, "out_sample_fmt",     outlink->format,         0);
    av_opt_set_int(s->avr,  "in_sample_rate",    inlink ->sample_rate,    0);
    av_opt_set_int(s->avr, "out_sample_rate",    outlink->sample_rate,    0);

    if ((ret = avresample_open(s->avr)) < 0)
        return ret;

    av_opt_get_int(s->avr, "force_resampling", 0, &resampling_forced);
    s->resampling = resampling_forced || (inlink->sample_rate != outlink->sample_rate);

    if (s->resampling) {
        outlink->time_base = (AVRational){ 1, outlink->sample_rate };
        s->next_pts        = AV_NOPTS_VALUE;
        s->next_in_pts     = AV_NOPTS_VALUE;
    } else
        outlink->time_base = inlink->time_base;

    av_get_channel_layout_string(buf1, sizeof(buf1),
                                 -1, inlink ->channel_layout);
    av_get_channel_layout_string(buf2, sizeof(buf2),
                                 -1, outlink->channel_layout);
    av_log(ctx, AV_LOG_VERBOSE,
           "fmt:%s srate:%d cl:%s -> fmt:%s srate:%d cl:%s\n",
           av_get_sample_fmt_name(inlink ->format), inlink ->sample_rate, buf1,
           av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf2);

    return 0;
}
Beispiel #12
0
int decoder_init(PlayerCtx *ctx, const char *file)
{
	int i;

	memset(ctx, 0, sizeof(*ctx));

	ctx->video_idx = -1;
	ctx->audio_idx = -1;
	ctx->cur_seekid = 1;
	ctx->a_cur_pts = 0;

	AVInputFormat *format = NULL;
	if (!strncmp(file, "x11grab://", 10)) {
		printf("Using X11Grab\n");
		format = av_find_input_format("x11grab");
		file += 10;
	}

	if (avformat_open_input(&ctx->fmt_ctx, file, format, NULL) != 0) {
		printf("Couldn't open input file %s\n", file);
		return -1;
	}

	if (avformat_find_stream_info(ctx->fmt_ctx, NULL) < 0) {
		printf("Couldn't get stream info\n");
		return -1;
	}

	ctx->duration = ctx->fmt_ctx->duration/(double)AV_TIME_BASE;

	pthread_mutex_init(&ctx->seek_mutex, NULL);
	pthread_cond_init(&ctx->seek_cond, NULL);

	for (i = 0; i < ctx->fmt_ctx->nb_streams; i++) {
		switch (ctx->fmt_ctx->streams[i]->codec->codec_type) {
			case AVMEDIA_TYPE_VIDEO:
				if (ctx->video_idx == -1)
					ctx->video_idx = i;
				break;
			case AVMEDIA_TYPE_AUDIO:
				if (ctx->audio_idx == -1)
					ctx->audio_idx = i;
				break;
			default:
				break;
		}
	}

	if (ctx->video_idx == -1) {
		printf("No video streams\n");
		return -1;
	}

	if (ctx->audio_idx != -1) {
		ctx->a_stream = ctx->fmt_ctx->streams[ctx->audio_idx];
		ctx->a_codec_ctx = ctx->a_stream->codec;
		ctx->a_codec = avcodec_find_decoder(ctx->a_codec_ctx->codec_id);
		if (ctx->a_codec == NULL) {
			printf("No audio codec\n");
			return -1;
		}
		if (avcodec_open2(ctx->a_codec_ctx, ctx->a_codec, NULL) < 0) {
			printf("Failed to open audio codec\n");
			return -1;
		}

		printf("Audio srate: %d\n", ctx->a_codec_ctx->sample_rate);

		ctx->a_resampler = avresample_alloc_context();
		av_opt_set_int(ctx->a_resampler, "in_channel_layout", ctx->a_codec_ctx->channel_layout, 0);
		av_opt_set_int(ctx->a_resampler, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
		av_opt_set_int(ctx->a_resampler, "in_sample_rate", ctx->a_codec_ctx->sample_rate, 0);
		av_opt_set_int(ctx->a_resampler, "out_sample_rate", SAMPLE_RATE, 0);
		av_opt_set_int(ctx->a_resampler, "in_sample_fmt", ctx->a_codec_ctx->sample_fmt, 0);
		av_opt_set_int(ctx->a_resampler, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
		if (avresample_open(ctx->a_resampler))
			return -1;

		ctx->a_ratio = SAMPLE_RATE/(double)ctx->a_codec_ctx->sample_rate;

		ctx->a_resample_output[0] = malloc(2 * sizeof(short) * AVCODEC_MAX_AUDIO_FRAME_SIZE * (ctx->a_ratio * 1.1));
		ctx->a_resample_output[1] = 0;
		ctx->a_buf_len = AUDIO_BUF*SAMPLE_RATE;
		ctx->a_buf = malloc(sizeof(*ctx->a_buf) * ctx->a_buf_len);
		ctx->a_buf_put = 0;
		ctx->a_buf_get = 0;

		pthread_mutex_init(&ctx->a_buf_mutex, NULL);
		pthread_cond_init(&ctx->a_buf_not_full, NULL);
		pthread_cond_init(&ctx->a_buf_not_empty, NULL);
	}

	ctx->v_stream = ctx->fmt_ctx->streams[ctx->video_idx];
	ctx->v_codec_ctx = ctx->v_stream->codec;
	ctx->width = ctx->v_codec_ctx->width;
	ctx->height = ctx->v_codec_ctx->height;

	ctx->v_codec = avcodec_find_decoder(ctx->v_codec_ctx->codec_id);
	if (ctx->v_codec == NULL) {
		printf("No video codec\n");
		return -1;
	}

	if (avcodec_open2(ctx->v_codec_ctx, ctx->v_codec, NULL) < 0) {
		printf("Failed to open video codec\n");
		return -1;
	}

	ctx->v_pkt_pts = AV_NOPTS_VALUE;
    ctx->v_faulty_pts = ctx->v_faulty_dts = 0;
    ctx->v_last_pts = ctx->v_last_dts = INT64_MIN;

	ctx->v_buf_len = VIDEO_BUF;

	pthread_mutex_init(&ctx->v_buf_mutex, NULL);
	pthread_cond_init(&ctx->v_buf_not_full, NULL);
	pthread_cond_init(&ctx->v_buf_not_empty, NULL);

	if (pthread_create(&ctx->decoder_thread, NULL, decoder_thread, ctx) != 0)
		return -1;

	return 0;
}
Beispiel #13
0
static int open_card( decklink_opts_t *decklink_opts )
{
    decklink_ctx_t *decklink_ctx = &decklink_opts->decklink_ctx;
    int         found_mode;
    int         ret = 0;
    int         i;
    int         cpu_flags;
    const int   sample_rate = 48000;
    const char *model_name;
    BMDDisplayMode wanted_mode_id;

    IDeckLinkDisplayModeIterator *p_display_iterator = NULL;
    IDeckLinkIterator *decklink_iterator = NULL;
    HRESULT result;

    avcodec_register_all();
    decklink_ctx->dec = avcodec_find_decoder( AV_CODEC_ID_V210 );
    if( !decklink_ctx->dec )
    {
        fprintf( stderr, "[decklink] Could not find v210 decoder\n" );
        goto finish;
    }

    decklink_ctx->codec = avcodec_alloc_context3( decklink_ctx->dec );
    if( !decklink_ctx->codec )
    {
        fprintf( stderr, "[decklink] Could not allocate AVCodecContext\n" );
        goto finish;
    }

    decklink_ctx->codec->get_buffer = obe_get_buffer;
    decklink_ctx->codec->release_buffer = obe_release_buffer;
    decklink_ctx->codec->reget_buffer = obe_reget_buffer;
    decklink_ctx->codec->flags |= CODEC_FLAG_EMU_EDGE;

    /* TODO: setup custom strides */
    if( avcodec_open2( decklink_ctx->codec, decklink_ctx->dec, NULL ) < 0 )
    {
        fprintf( stderr, "[decklink] Could not open libavcodec\n" );
        goto finish;
    }

    decklink_iterator = CreateDeckLinkIteratorInstance();
    if( !decklink_iterator )
    {
        fprintf( stderr, "[decklink] DeckLink drivers not found\n" );
        ret = -1;
        goto finish;
    }

    if( decklink_opts->card_idx < 0 )
    {
        fprintf( stderr, "[decklink] Invalid card index %d \n", decklink_opts->card_idx );
        ret = -1;
        goto finish;
    }

    for( i = 0; i <= decklink_opts->card_idx; ++i )
    {
        if( decklink_ctx->p_card )
            decklink_ctx->p_card->Release();
        result = decklink_iterator->Next( &decklink_ctx->p_card );
        if( result != S_OK )
            break;
    }

    if( result != S_OK )
    {
        fprintf( stderr, "[decklink] DeckLink PCI card %d not found\n", decklink_opts->card_idx );
        ret = -1;
        goto finish;
    }

    result = decklink_ctx->p_card->GetModelName( &model_name );

    if( result != S_OK )
    {
        fprintf( stderr, "[decklink] Could not get model name\n" );
        ret = -1;
        goto finish;
    }

    syslog( LOG_INFO, "Opened DeckLink PCI card %d (%s)", decklink_opts->card_idx, model_name );

    if( decklink_ctx->p_card->QueryInterface( IID_IDeckLinkInput, (void**)&decklink_ctx->p_input) != S_OK )
    {
        fprintf( stderr, "[decklink] Card has no inputs\n" );
        ret = -1;
        goto finish;
    }

    /* Set up the video and audio sources. */
    if( decklink_ctx->p_card->QueryInterface( IID_IDeckLinkConfiguration, (void**)&decklink_ctx->p_config) != S_OK )
    {
        fprintf( stderr, "[decklink] Failed to get configuration interface\n" );
        ret = -1;
        goto finish;
    }

    /* Setup video connection */
    for( i = 0; video_conn_tab[i].obe_name != -1; i++ )
    {
        if( video_conn_tab[i].obe_name == decklink_opts->video_conn )
            break;
    }

    if( video_conn_tab[i].obe_name == -1 )
    {
        fprintf( stderr, "[decklink] Unsupported video input connection\n" );
        ret = -1;
        goto finish;
    }

    result = decklink_ctx->p_config->SetInt( bmdDeckLinkConfigVideoInputConnection, video_conn_tab[i].bmd_name );
    if( result != S_OK )
    {
        fprintf( stderr, "[decklink] Failed to set video input connection\n" );
        ret = -1;
        goto finish;
    }

    /* Setup audio connection */
    for( i = 0; audio_conn_tab[i].obe_name != -1; i++ )
    {
        if( audio_conn_tab[i].obe_name == decklink_opts->audio_conn )
            break;
    }

    if( audio_conn_tab[i].obe_name == -1 )
    {
        fprintf( stderr, "[decklink] Unsupported audio input connection\n" );
        ret = -1;
        goto finish;
    }

    result = decklink_ctx->p_config->SetInt( bmdDeckLinkConfigAudioInputConnection, audio_conn_tab[i].bmd_name );
    if( result != S_OK )
    {
        fprintf( stderr, "[decklink] Failed to set audio input connection\n" );
        ret = -1;
        goto finish;
    }

    /* Get the list of display modes. */
    result = decklink_ctx->p_input->GetDisplayModeIterator( &p_display_iterator );
    if( result != S_OK )
    {
        fprintf( stderr, "[decklink] Failed to enumerate display modes\n" );
        ret = -1;
        goto finish;
    }

    for( i = 0; video_format_tab[i].obe_name != -1; i++ )
    {
        if( video_format_tab[i].obe_name == decklink_opts->video_format )
            break;
    }

    if( video_format_tab[i].obe_name == -1 )
    {
        fprintf( stderr, "[decklink] Unsupported video format\n" );
        ret = -1;
        goto finish;
    }

    wanted_mode_id = video_format_tab[i].bmd_name;
    found_mode = false;
    decklink_opts->timebase_num = video_format_tab[i].timebase_num;
    decklink_opts->timebase_den = video_format_tab[i].timebase_den;

    for (;;)
    {
        IDeckLinkDisplayMode *p_display_mode;
        result = p_display_iterator->Next( &p_display_mode );
        if( result != S_OK || !p_display_mode )
            break;

        BMDDisplayMode mode_id = p_display_mode->GetDisplayMode();

        BMDTimeValue frame_duration, time_scale;
        result = p_display_mode->GetFrameRate( &frame_duration, &time_scale );
        if( result != S_OK )
        {
            fprintf( stderr, "[decklink] Failed to get frame rate\n" );
            ret = -1;
            p_display_mode->Release();
            goto finish;
        }

        if( wanted_mode_id == mode_id )
        {
            found_mode = true;
            decklink_opts->width = p_display_mode->GetWidth();
            decklink_opts->coded_height = p_display_mode->GetHeight();

            switch( p_display_mode->GetFieldDominance() )
            {
                case bmdProgressiveFrame:
                    decklink_opts->interlaced = 0;
                    decklink_opts->tff        = 0;
                    break;
                case bmdProgressiveSegmentedFrame:
                    /* Assume tff interlaced - this mode should not be used in broadcast */
                    decklink_opts->interlaced = 1;
                    decklink_opts->tff        = 1;
                    break;
                case bmdUpperFieldFirst:
                    decklink_opts->interlaced = 1;
                    decklink_opts->tff        = 1;
                    break;
                case bmdLowerFieldFirst:
                    decklink_opts->interlaced = 1;
                    decklink_opts->tff        = 0;
                    break;
                case bmdUnknownFieldDominance:
                default:
                    /* Assume progressive */
                    decklink_opts->interlaced = 0;
                    decklink_opts->tff        = 0;
                    break;
            }
        }

        p_display_mode->Release();
    }

    decklink_opts->height = decklink_opts->coded_height;
    if( decklink_opts->coded_height == 486 )
        decklink_opts->height = 480;

    if( !found_mode )
    {
        fprintf( stderr, "[decklink] Unsupported video mode\n" );
        ret = -1;
        goto finish;
    }

    cpu_flags = av_get_cpu_flags();

    /* Setup VBI and VANC unpack functions */
    if( IS_SD( decklink_opts->video_format ) )
    {
        decklink_ctx->unpack_line = obe_v210_line_to_uyvy_c;
        decklink_ctx->downscale_line = obe_downscale_line_c;
        decklink_ctx->blank_line = obe_blank_line_uyvy_c;

        if( cpu_flags & AV_CPU_FLAG_MMX )
            decklink_ctx->downscale_line = obe_downscale_line_mmx;

        if( cpu_flags & AV_CPU_FLAG_SSE2 )
            decklink_ctx->downscale_line = obe_downscale_line_sse2;
    }
    else
    {
        decklink_ctx->unpack_line = obe_v210_line_to_nv20_c;
        decklink_ctx->blank_line = obe_blank_line_nv20_c;
    }

    result = decklink_ctx->p_input->EnableVideoInput( wanted_mode_id, bmdFormat10BitYUV, 0 );
    if( result != S_OK )
    {
        fprintf( stderr, "[decklink] Failed to enable video input\n" );
        ret = -1;
        goto finish;
    }

    /* Set up audio. */
    result = decklink_ctx->p_input->EnableAudioInput( sample_rate, bmdAudioSampleType32bitInteger, decklink_opts->num_channels );
    if( result != S_OK )
    {
        fprintf( stderr, "[decklink] Failed to enable audio input\n" );
        ret = -1;
        goto finish;
    }

    if( !decklink_opts->probe )
    {
        decklink_ctx->avr = avresample_alloc_context();
        if( !decklink_ctx->avr )
        {
            fprintf( stderr, "[decklink-sdiaudio] couldn't setup sample rate conversion \n" );
            ret = -1;
            goto finish;
        }

        /* Give libavresample a made up channel map */
        av_opt_set_int( decklink_ctx->avr, "in_channel_layout",   (1 << decklink_opts->num_channels) - 1, 0 );
        av_opt_set_int( decklink_ctx->avr, "in_sample_fmt",       AV_SAMPLE_FMT_S32, 0 );
        av_opt_set_int( decklink_ctx->avr, "in_sample_rate",      48000, 0 );
        av_opt_set_int( decklink_ctx->avr, "out_channel_layout",  (1 << decklink_opts->num_channels) - 1, 0 );
        av_opt_set_int( decklink_ctx->avr, "out_sample_fmt",      AV_SAMPLE_FMT_S32P, 0 );

        if( avresample_open( decklink_ctx->avr ) < 0 )
        {
            fprintf( stderr, "Could not open AVResample\n" );
            goto finish;
        }
    }

    decklink_ctx->p_delegate = new DeckLinkCaptureDelegate( decklink_opts );
    decklink_ctx->p_input->SetCallback( decklink_ctx->p_delegate );

    result = decklink_ctx->p_input->StartStreams();
    if( result != S_OK )
    {
        fprintf( stderr, "[decklink] Could not start streaming from card\n" );
        ret = -1;
        goto finish;
    }

    ret = 0;

finish:
    if( decklink_iterator )
        decklink_iterator->Release();

    if( p_display_iterator )
        p_display_iterator->Release();

    if( ret )
        close_card( decklink_opts );

    return ret;
}
Beispiel #14
0
static void
audio_process_audio(audio_decoder_t *ad, media_buf_t *mb)
{
  const audio_class_t *ac = ad->ad_ac;
  AVFrame *frame = ad->ad_frame;
  media_pipe_t *mp = ad->ad_mp;
  media_queue_t *mq = &mp->mp_audio;
  int r;
  int got_frame;
  AVPacket avpkt;
  int offset = 0;

  if(mb->mb_skip || mb->mb_stream != mq->mq_stream) 
    return;

  while(offset < mb->mb_size) {

    if(mb->mb_cw == NULL) {
      frame->sample_rate = mb->mb_rate;
      frame->format = AV_SAMPLE_FMT_S16;
      switch(mb->mb_channels) {
      case 1:
	frame->channel_layout = AV_CH_LAYOUT_MONO;
	frame->nb_samples = mb->mb_size / 2;
	break;
      case 2:
	frame->channel_layout = AV_CH_LAYOUT_STEREO;
	frame->nb_samples = mb->mb_size / 4;
	break;
      default:
	abort();
      }
      frame->data[0] = mb->mb_data;
      frame->linesize[0] = 0;
      r = mb->mb_size;
      got_frame = 1;

    } else {

      media_codec_t *mc = mb->mb_cw;

      AVCodecContext *ctx = mc->ctx;

      if(mc->codec_id != ad->ad_in_codec_id) {
	AVCodec *codec = avcodec_find_decoder(mc->codec_id);
	TRACE(TRACE_DEBUG, "audio", "Codec changed to %s",
	      codec ? codec->name : "???");
	ad->ad_in_codec_id = mc->codec_id;

	audio_cleanup_spdif_muxer(ad);
  
	if(ac->ac_check_passthru != NULL && codec != NULL &&
	   ac->ac_check_passthru(ad, mc->codec_id)) {

	  audio_setup_spdif_muxer(ad, codec, mq);
	}
      }

      av_init_packet(&avpkt);
      avpkt.data = mb->mb_data + offset;
      avpkt.size = mb->mb_size - offset;

      if(ad->ad_spdif_muxer != NULL) {
	av_write_frame(ad->ad_spdif_muxer, &avpkt);
	avio_flush(ad->ad_spdif_muxer->pb);
	ad->ad_pts = mb->mb_pts;
	ad->ad_epoch = mb->mb_epoch;
	return;
      }

      if(ctx == NULL) {

	AVCodec *codec = avcodec_find_decoder(mc->codec_id);
	assert(codec != NULL); // Checked in libav.c

	ctx = mc->ctx = avcodec_alloc_context3(codec);

	if(ad->ad_stereo_downmix)
	  ctx->request_channels = 2;

	if(avcodec_open2(mc->ctx, codec, NULL) < 0) {
	  av_freep(&mc->ctx);
	  return;
	}
      }

      r = avcodec_decode_audio4(ctx, frame, &got_frame, &avpkt);
      if(r < 0)
	return;

      if(frame->sample_rate == 0) {
	frame->sample_rate = ctx->sample_rate;

	if(frame->sample_rate == 0 && mb->mb_cw->fmt_ctx)
	  frame->sample_rate = mb->mb_cw->fmt_ctx->sample_rate;
    
	if(frame->sample_rate == 0)
	  return;
      }

      if(frame->channel_layout == 0) {
	switch(ctx->channels) {
	case 1:
	  frame->channel_layout = AV_CH_LAYOUT_MONO;
	  break;
	case 2:
	  frame->channel_layout = AV_CH_LAYOUT_STEREO;
	  break;
	default:
	  return;
	}
      }

      if(mp->mp_stats)
	mp_set_mq_meta(mq, ctx->codec, ctx);

    }

    if(offset == 0 && mb->mb_pts != AV_NOPTS_VALUE) {
        
      int od = 0, id = 0;
          
      if(ad->ad_avr != NULL) {
	od = avresample_available(ad->ad_avr) *
	  1000000LL / ad->ad_out_sample_rate;
	id = avresample_get_delay(ad->ad_avr) *
	  1000000LL / frame->sample_rate;
      }
      ad->ad_pts = mb->mb_pts - od - id;
      ad->ad_epoch = mb->mb_epoch;
      //        printf("od=%-20d id=%-20d PTS=%-20ld oPTS=%-20ld\n",
      // od, id, mb->mb_pts, pts);
        
      if(mb->mb_drive_clock)
	mp_set_current_time(mp, mb->mb_pts - ad->ad_delay,
			    mb->mb_epoch, mb->mb_delta);
    }

    offset += r;

    if(got_frame) {

      if(frame->sample_rate    != ad->ad_in_sample_rate ||
	 frame->format         != ad->ad_in_sample_format ||
	 frame->channel_layout != ad->ad_in_channel_layout) {
          
	ad->ad_in_sample_rate    = frame->sample_rate;
	ad->ad_in_sample_format  = frame->format;
	ad->ad_in_channel_layout = frame->channel_layout;

	ac->ac_reconfig(ad);

	if(ad->ad_avr == NULL)
	  ad->ad_avr = avresample_alloc_context();
	else
	  avresample_close(ad->ad_avr);
          
	av_opt_set_int(ad->ad_avr, "in_sample_fmt",
		       ad->ad_in_sample_format, 0);
	av_opt_set_int(ad->ad_avr, "in_sample_rate", 
		       ad->ad_in_sample_rate, 0);
	av_opt_set_int(ad->ad_avr, "in_channel_layout",
		       ad->ad_in_channel_layout, 0);

	av_opt_set_int(ad->ad_avr, "out_sample_fmt",
		       ad->ad_out_sample_format, 0);
	av_opt_set_int(ad->ad_avr, "out_sample_rate",
		       ad->ad_out_sample_rate, 0);
	av_opt_set_int(ad->ad_avr, "out_channel_layout",
		       ad->ad_out_channel_layout, 0);
          
	char buf1[128];
	char buf2[128];

	av_get_channel_layout_string(buf1, sizeof(buf1), 
				     -1, ad->ad_in_channel_layout);
	av_get_channel_layout_string(buf2, sizeof(buf2), 
				     -1, ad->ad_out_channel_layout);

	TRACE(TRACE_DEBUG, "Audio",
	      "Converting from [%s %dHz %s] to [%s %dHz %s]",
	      buf1, ad->ad_in_sample_rate,
	      av_get_sample_fmt_name(ad->ad_in_sample_format),
	      buf2, ad->ad_out_sample_rate,
	      av_get_sample_fmt_name(ad->ad_out_sample_format));

	if(avresample_open(ad->ad_avr)) {
	  TRACE(TRACE_ERROR, "AudioQueue", "Unable to open resampler");
	  avresample_free(&ad->ad_avr);
	}

	if(ac->ac_set_volume != NULL) {
	  prop_set(mp->mp_prop_ctrl, "canAdjustVolume", PROP_SET_INT, 1);
	  ac->ac_set_volume(ad, ad->ad_vol_scale);
	}
      }
      if(ad->ad_avr != NULL)
	avresample_convert(ad->ad_avr, NULL, 0, 0,
			   frame->data, frame->linesize[0],
			   frame->nb_samples);
    }
  }
}