static int insert_trim(int64_t start_time, int64_t duration, AVFilterContext **last_filter, int *pad_idx, const char *filter_name) { AVFilterGraph *graph = (*last_filter)->graph; AVFilterContext *ctx; const AVFilter *trim; enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx); const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim"; int ret = 0; if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE) return 0; trim = avfilter_get_by_name(name); if (!trim) { av_log(NULL, AV_LOG_ERROR, "%s filter not present, cannot limit " "recording time.\n", name); return AVERROR_FILTER_NOT_FOUND; } ctx = avfilter_graph_alloc_filter(graph, trim, filter_name); if (!ctx) return AVERROR(ENOMEM); if (duration != INT64_MAX) { ret = av_opt_set_double(ctx, "duration", (double)duration / 1e6, AV_OPT_SEARCH_CHILDREN); } if (ret >= 0 && start_time != AV_NOPTS_VALUE) { ret = av_opt_set_double(ctx, "start", (double)start_time / 1e6, AV_OPT_SEARCH_CHILDREN); } if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name); return ret; } ret = avfilter_init_str(ctx, NULL); if (ret < 0) return ret; ret = avfilter_link(*last_filter, *pad_idx, ctx, 0); if (ret < 0) return ret; *last_filter = ctx; *pad_idx = 0; return 0; }
// Initialization and runtime control static int control(struct af_instance_s* af, int cmd, void* arg) { af_resample_t* s = (af_resample_t*)af->setup; af_data_t *data= (af_data_t*)arg; int out_rate, test_output_res; // helpers for checking input format switch(cmd){ case AF_CONTROL_REINIT: if((af->data->rate == data->rate) || (af->data->rate == 0)) return AF_DETACH; af->data->nch = data->nch; if (af->data->nch > AF_NCH) af->data->nch = AF_NCH; af->data->format = AF_FORMAT_S16_NE; af->data->bps = 2; af->mul = (double)af->data->rate / data->rate; af->delay = af->data->nch * s->filter_length / FFMIN(af->mul, 1); // *bps*.5 if (s->ctx_out_rate != af->data->rate || s->ctx_in_rate != data->rate || s->ctx_filter_size != s->filter_length || s->ctx_phase_shift != s->phase_shift || s->ctx_linear != s->linear || s->ctx_cutoff != s->cutoff) { swr_free(&s->swrctx); if((s->swrctx=swr_alloc()) == NULL) return AF_ERROR; av_opt_set_int(s->swrctx, "out_sample_rate", af->data->rate, 0); av_opt_set_int(s->swrctx, "in_sample_rate", data->rate, 0); av_opt_set_int(s->swrctx, "filter_size", s->filter_length, 0); av_opt_set_int(s->swrctx, "phase_shift", s->phase_shift, 0); av_opt_set_int(s->swrctx, "linear_interp", s->linear, 0); av_opt_set_double(s->swrctx, "cutoff", s->cutoff, 0); av_opt_set_sample_fmt(s->swrctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_sample_fmt(s->swrctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(s->swrctx, "in_channel_count", af->data->nch, 0); av_opt_set_int(s->swrctx, "out_channel_count", af->data->nch, 0); if(swr_init(s->swrctx) < 0) return AF_ERROR; s->ctx_out_rate = af->data->rate; s->ctx_in_rate = data->rate; s->ctx_filter_size = s->filter_length; s->ctx_phase_shift = s->phase_shift; s->ctx_linear = s->linear; s->ctx_cutoff = s->cutoff; } // hack to make af_test_output ignore the samplerate change out_rate = af->data->rate; af->data->rate = data->rate; test_output_res = af_test_output(af, (af_data_t*)arg); af->data->rate = out_rate; return test_output_res; case AF_CONTROL_COMMAND_LINE:{ s->cutoff= 0.0; sscanf((char*)arg,"%d:%d:%d:%d:%lf", &af->data->rate, &s->filter_length, &s->linear, &s->phase_shift, &s->cutoff); if(s->cutoff <= 0.0) s->cutoff= FFMAX(1.0 - 6.5/(s->filter_length+8), 0.80); return AF_OK; } case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET: af->data->rate = *(int*)arg; return AF_OK; } return AF_UNKNOWN; }
void Option::setDouble( const double value ) { int error = av_opt_set_double( _avContext, getName().c_str(), value, AV_OPT_SEARCH_CHILDREN ); std::ostringstream os; os << value; checkFFmpegSetOption( error, os.str() ); }
/* Update volume filter */ void BarPlayerSetVolume (player_t * const player) { assert (player != NULL); if (player->mode != PLAYER_PLAYING) { return; } int ret; #ifdef HAVE_AVFILTER_GRAPH_SEND_COMMAND /* ffmpeg and libav disagree on the type of this option (string vs. double) * -> print to string and let them parse it again */ char strbuf[16]; snprintf (strbuf, sizeof (strbuf), "%fdB", player->settings->volume + player->gain); assert (player->fgraph != NULL); if ((ret = avfilter_graph_send_command (player->fgraph, "volume", "volume", strbuf, NULL, 0, 0)) < 0) { #else /* convert from decibel */ const double volume = pow (10, (player->settings->volume + player->gain) / 20); /* libav does not provide other means to set this right now. it might not * even work everywhere. */ assert (player->fvolume != NULL); if ((ret = av_opt_set_double (player->fvolume->priv, "volume", volume, 0)) != 0) { #endif printError (player->settings, "Cannot set volume", ret); } } #define softfail(msg) \ printError (player->settings, msg, ret); \ return false; /* ffmpeg callback for blocking functions, returns 1 to abort function */ static int intCb (void * const data) { player_t * const player = data; assert (player != NULL); if (player->interrupted > 1) { /* got a sigint multiple times, quit pianobar (handled by main.c). */ player->doQuit = true; return 1; } else if (player->interrupted != 0) { /* the request is retried with the same player context */ player->interrupted = 0; return 1; } else { return 0; } }
void setOptionsToFFmpegObj(const QVariant& opt, void* obj) { if (!opt.isValid()) return; AVClass *c = obj ? *(AVClass**)obj : 0; if (c) qDebug() << QStringLiteral("%1.%2 options:").arg(QLatin1String(c->class_name)).arg(QLatin1String(c->item_name(obj))); else qDebug() << "options:"; if (opt.type() == QVariant::Map) { QVariantMap options(opt.toMap()); if (options.isEmpty()) return; QMapIterator<QString, QVariant> i(options); while (i.hasNext()) { i.next(); const QVariant::Type vt = i.value().type(); if (vt == QVariant::Map) continue; const QByteArray key(i.key().toUtf8()); qDebug("%s=>%s", i.key().toUtf8().constData(), i.value().toByteArray().constData()); if (vt == QVariant::Int || vt == QVariant::UInt || vt == QVariant::Bool) { // QVariant.toByteArray(): "true" or "false", can not recognized by avcodec av_opt_set_int(obj, key.constData(), i.value().toInt(), AV_OPT_SEARCH_CHILDREN); } else if (vt == QVariant::LongLong || vt == QVariant::ULongLong) { av_opt_set_int(obj, key.constData(), i.value().toLongLong(), AV_OPT_SEARCH_CHILDREN); } else if (vt == QVariant::Double) { av_opt_set_double(obj, key.constData(), i.value().toDouble(), AV_OPT_SEARCH_CHILDREN); } } return; } QVariantHash options(opt.toHash()); if (options.isEmpty()) return; QHashIterator<QString, QVariant> i(options); while (i.hasNext()) { i.next(); const QVariant::Type vt = i.value().type(); if (vt == QVariant::Hash) continue; const QByteArray key(i.key().toUtf8()); qDebug("%s=>%s", i.key().toUtf8().constData(), i.value().toByteArray().constData()); if (vt == QVariant::Int || vt == QVariant::UInt || vt == QVariant::Bool) { av_opt_set_int(obj, key.constData(), i.value().toInt(), AV_OPT_SEARCH_CHILDREN); } else if (vt == QVariant::LongLong || vt == QVariant::ULongLong) { av_opt_set_int(obj, key.constData(), i.value().toLongLong(), AV_OPT_SEARCH_CHILDREN); } } }
/* Update volume filter */ void BarPlayerSetVolume (player_t * const player) { assert (player != NULL); if (player->mode != PLAYER_PLAYING) { return; } int ret; #ifdef HAVE_AVFILTER_GRAPH_SEND_COMMAND /* ffmpeg and libav disagree on the type of this option (string vs. double) * -> print to string and let them parse it again */ char strbuf[16]; snprintf (strbuf, sizeof (strbuf), "%fdB", player->settings->volume + player->gain); assert (player->fgraph != NULL); if ((ret = avfilter_graph_send_command (player->fgraph, "volume", "volume", strbuf, NULL, 0, 0)) < 0) { #else /* convert from decibel */ const double volume = pow (10, (player->settings->volume + player->gain) / 20); /* libav does not provide other means to set this right now. it might not * even work everywhere. */ assert (player->fvolume != NULL); if ((ret = av_opt_set_double (player->fvolume->priv, "volume", volume, 0)) != 0) { #endif printError (player->settings, "Cannot set volume", ret); } } #define softfail(msg) \ printError (player->settings, msg, ret); \ return false; #ifndef HAVE_AV_TIMEOUT /* interrupt callback for libav, which lacks a timeout option * * obviously calling ping() a lot of times and then calling av_gettime here * again is rather inefficient. */ static int intCb (void * const data) { player_t * const player = data; assert (player != NULL); /* 10 seconds timeout (usec) */ return (av_gettime () - player->ping) > 10*1000000; }
static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop) { char name[128]; char *param; int fail = TRUE; PRINT("FFMPEG expert option: %s: ", prop->name); BLI_strncpy(name, prop->name, sizeof(name)); param = strchr(name, ':'); if (param) { *param++ = 0; } switch (prop->type) { case IDP_STRING: PRINT("%s.\n", IDP_String(prop)); fail = av_opt_set(c, prop->name, IDP_String(prop), 0); break; case IDP_FLOAT: PRINT("%g.\n", IDP_Float(prop)); fail = av_opt_set_double(c, prop->name, IDP_Float(prop), 0); break; case IDP_INT: PRINT("%d.\n", IDP_Int(prop)); if (param) { if (IDP_Int(prop)) { fail = av_opt_set(c, name, param, 0); } else { return; } } else { fail = av_opt_set_int(c, prop->name, IDP_Int(prop), 0); } break; } if (fail) { PRINT("ffmpeg-option not supported: %s! Skipping.\n", prop->name); } }
int video_encoder_refresh(codec_state *cs, int bps) { if (cs->video_encoder_ctx) avcodec_close(cs->video_encoder_ctx); cs->video_encoder = avcodec_find_encoder(VIDEO_CODEC); if (!cs->video_encoder) { printf("init video_encoder failed\n"); return -1; } cs->video_encoder_ctx = avcodec_alloc_context3(cs->video_encoder); if (!cs->video_encoder_ctx) { printf("init video_encoder_ctx failed\n"); return -1; } cs->video_encoder_ctx->bit_rate = bps; cs->video_encoder_ctx->rc_min_rate = cs->video_encoder_ctx->rc_max_rate = cs->video_encoder_ctx->bit_rate; av_opt_set_double(cs->video_encoder_ctx->priv_data, "max-intra-rate", 90, 0); av_opt_set(cs->video_encoder_ctx->priv_data, "quality", "realtime", 0); cs->video_encoder_ctx->thread_count = 4; cs->video_encoder_ctx->rc_buffer_aggressivity = 0.95; cs->video_encoder_ctx->rc_buffer_size = bps * 6; cs->video_encoder_ctx->profile = 0; cs->video_encoder_ctx->qmax = 54; cs->video_encoder_ctx->qmin = 4; AVRational myrational = {1, 25}; cs->video_encoder_ctx->time_base = myrational; cs->video_encoder_ctx->gop_size = 99999; cs->video_encoder_ctx->pix_fmt = PIX_FMT_YUV420P; cs->video_encoder_ctx->width = cs->webcam_decoder_ctx->width; cs->video_encoder_ctx->height = cs->webcam_decoder_ctx->height; if (avcodec_open2(cs->video_encoder_ctx, cs->video_encoder, NULL) < 0) { printf("opening video encoder failed\n"); return -1; } return 0; }
int32_t Property :: setProperty(void *aContext, const char* aName, double value) { int32_t retval = 0; try { if (!aContext) throw std::runtime_error("no context passed in"); if (!aName || !*aName) throw std::runtime_error("empty property name passed to setProperty"); retval = av_opt_set_double(aContext, aName, value, PROPERTY_SEARCH_CHILDREN); } catch (std::exception &e) { VS_LOG_DEBUG("Error: %s", e.what()); retval = -1; } return retval; }
static int configure_lavrr(struct af_instance *af, struct mp_audio *in, struct mp_audio *out, bool verbose) { 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->out_rate = out->rate; s->in_rate_af = in->rate; s->in_rate = rate_from_speed(in->rate, s->playback_speed); s->out_format = out->format; s->in_format = in->format; s->out_channels= out->channels; s->in_channels = in->channels; av_opt_set_int(s->avrctx, "filter_size", s->opts.filter_size, 0); av_opt_set_int(s->avrctx, "phase_shift", s->opts.phase_shift, 0); av_opt_set_int(s->avrctx, "linear_interp", s->opts.linear, 0); av_opt_set_double(s->avrctx, "cutoff", s->opts.cutoff, 0); int normalize = s->opts.normalize; if (normalize < 0) normalize = af->opts->audio_normalize; #if HAVE_LIBSWRESAMPLE av_opt_set_double(s->avrctx, "rematrix_maxval", normalize ? 1 : 1000, 0); #else av_opt_set_int(s->avrctx, "normalize_mix_level", !!normalize, 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, out_lavc; mp_chmap_from_lavc(&in_lavc, in_ch_layout); mp_chmap_from_lavc(&out_lavc, out_ch_layout); if (verbose && !mp_chmap_equals(&in_lavc, &out_lavc)) { MP_VERBOSE(af, "Remix: %s -> %s\n", mp_chmap_to_str(&in_lavc), mp_chmap_to_str(&out_lavc)); } 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); 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); out_ch_layout = fudge_layout_conversion(af, in_ch_layout, out_ch_layout); // 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->in_rate, 0); av_opt_set_int(s->avrctx, "out_sample_rate", s->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 for deplanarization. struct mp_chmap fake_chmap; mp_chmap_set_unknown(&fake_chmap, map_out.num); uint64_t fake_out_ch_layout = mp_chmap_to_lavc_unchecked(&fake_chmap); if (!fake_out_ch_layout) goto error; 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->out_rate, 0); av_opt_set_int(s->avrctx_out, "out_sample_rate", s->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; }
static int configure_lavrr(struct af_instance *af, struct mp_audio *in, struct mp_audio *out) { struct af_resample *s = af->priv; enum AVSampleFormat in_samplefmt = af_to_avformat(in->format); enum AVSampleFormat out_samplefmt = af_to_avformat(out->format); if (in_samplefmt == AV_SAMPLE_FMT_NONE || out_samplefmt == AV_SAMPLE_FMT_NONE) return AF_ERROR; avresample_close(s->avrctx); avresample_close(s->avrctx_out); s->ctx.out_rate = out->rate; s->ctx.in_rate = in->rate; 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 (parse_avopts(s->avrctx, s->avopts) < 0) { mp_msg(MSGT_VFILTER, MSGL_FATAL, "af_lavrresample: could not set opts: '%s'\n", s->avopts); return AF_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); 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_samplefmt, 0); struct mp_chmap in_lavc; mp_chmap_from_lavc(&in_lavc, in_ch_layout); mp_chmap_get_reorder(s->reorder_in, &map_in, &in_lavc); struct mp_chmap out_lavc; mp_chmap_from_lavc(&out_lavc, out_ch_layout); mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out); // Same configuration; we just reorder. av_opt_set_int(s->avrctx_out, "in_channel_layout", out_ch_layout, 0); av_opt_set_int(s->avrctx_out, "out_channel_layout", out_ch_layout, 0); av_opt_set_int(s->avrctx_out, "in_sample_fmt", out_samplefmt, 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); #if USE_SET_CHANNEL_MAPPING // 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); avresample_set_channel_mapping(s->avrctx_out, s->reorder_out); #endif if (avresample_open(s->avrctx) < 0 || avresample_open(s->avrctx_out) < 0) { mp_msg(MSGT_AFILTER, MSGL_ERR, "[lavrresample] Cannot open " "Libavresample Context. \n"); return AF_ERROR; } return AF_OK; }
/* Add a video output stream. * */ static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id, int width, int height, float crf) { AVCodecContext *c; AVStream *st; AVCodec *codec; /* find the video encoder */ codec = avcodec_find_encoder(codec_id); if (!codec) { LOGE("add_video_stream codec not found"); //fprintf(stderr, "codec not found\n"); exit(1); } st = avformat_new_stream(oc, codec); if (!st) { LOGE("add_video_stream could not alloc stream"); //fprintf(stderr, "Could not alloc stream\n"); exit(1); } c = st->codec; avcodec_get_context_defaults3(c, codec); //LOGI("start add_video_st fps: %d device_frame_rate: %d", c->time_base.den, device_frame_rate); c->codec_id = codec_id; /* Put sample parameters. */ c->bit_rate = 400000; /* Resolution must be a multiple of two. */ c->width = width; c->height = height; /* timebase: This is the fundamental unit of time (in seconds) in terms * of which frame timestamps are represented. For fixed-fps content, * timebase should be 1/framerate and timestamp increments should be * identical to 1. */ c->time_base.den = device_frame_rate; c->time_base.num = 1; c->gop_size = 12; /* emit one intra frame every twelve frames at most */ c->pix_fmt = STREAM_PIX_FMT; if(codec_id == CODEC_ID_H264){ av_opt_set(c->priv_data, "preset", "ultrafast", 0); if(crf) av_opt_set_double(c->priv_data, "crf", crf, 0); else av_opt_set_double(c->priv_data, "crf", 24.0, 0); } if (c->codec_id == CODEC_ID_MPEG2VIDEO) { /* just for testing, we also add B frames */ c->max_b_frames = 2; } if (c->codec_id == CODEC_ID_MPEG1VIDEO) { /* Needed to avoid using macroblocks in which some coeffs overflow. * This does not happen with normal video, it just happens here as * the motion of the chroma plane does not match the luma plane. */ c->mb_decision = 2; } /* Some formats want stream headers to be separate. */ if (oc->oformat->flags & AVFMT_GLOBALHEADER) c->flags |= CODEC_FLAG_GLOBAL_HEADER; //LOGI("end add_video_st fps: %d device_frame_rate: %d", st->codec->time_base.den, device_frame_rate); return st; }
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.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, "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.center_mix_level = resample->in.center_mix_level; resample->resample.surround_mix_level = resample->in.surround_mix_level; } return 0; }
static int init(sh_audio_t *sh_audio) { struct MPOpts *opts = sh_audio->opts; AVCodecContext *lavc_context; AVCodec *lavc_codec; if (sh_audio->codec->dll) { lavc_codec = avcodec_find_decoder_by_name(sh_audio->codec->dll); if (!lavc_codec) { mp_tmsg(MSGT_DECAUDIO, MSGL_ERR, "Cannot find codec '%s' in libavcodec...\n", sh_audio->codec->dll); return 0; } } else if (!sh_audio->libav_codec_id) { mp_tmsg(MSGT_DECAUDIO, MSGL_INFO, "No Libav codec ID known. " "Generic lavc decoder is not applicable.\n"); return 0; } else { lavc_codec = avcodec_find_decoder(sh_audio->libav_codec_id); if (!lavc_codec) { mp_tmsg(MSGT_DECAUDIO, MSGL_INFO, "Libavcodec has no decoder " "for this codec\n"); return 0; } } sh_audio->codecname = lavc_codec->long_name; if (!sh_audio->codecname) sh_audio->codecname = lavc_codec->name; struct priv *ctx = talloc_zero(NULL, struct priv); sh_audio->context = ctx; lavc_context = avcodec_alloc_context3(lavc_codec); ctx->avctx = lavc_context; ctx->avframe = avcodec_alloc_frame(); // Always try to set - option only exists for AC3 at the moment av_opt_set_double(lavc_context, "drc_scale", opts->drc_level, AV_OPT_SEARCH_CHILDREN); lavc_context->sample_rate = sh_audio->samplerate; lavc_context->bit_rate = sh_audio->i_bps * 8; if (sh_audio->wf) { lavc_context->channels = sh_audio->wf->nChannels; lavc_context->sample_rate = sh_audio->wf->nSamplesPerSec; lavc_context->bit_rate = sh_audio->wf->nAvgBytesPerSec * 8; lavc_context->block_align = sh_audio->wf->nBlockAlign; lavc_context->bits_per_coded_sample = sh_audio->wf->wBitsPerSample; } lavc_context->request_channels = opts->audio_output_channels; lavc_context->codec_tag = sh_audio->format; //FOURCC lavc_context->codec_type = AVMEDIA_TYPE_AUDIO; lavc_context->codec_id = lavc_codec->id; // not sure if required, imho not --A'rpi /* alloc extra data */ if (sh_audio->wf && sh_audio->wf->cbSize > 0) { lavc_context->extradata = av_mallocz(sh_audio->wf->cbSize + FF_INPUT_BUFFER_PADDING_SIZE); lavc_context->extradata_size = sh_audio->wf->cbSize; memcpy(lavc_context->extradata, sh_audio->wf + 1, lavc_context->extradata_size); } // for QDM2 if (sh_audio->codecdata_len && sh_audio->codecdata && !lavc_context->extradata) { lavc_context->extradata = av_malloc(sh_audio->codecdata_len + FF_INPUT_BUFFER_PADDING_SIZE); lavc_context->extradata_size = sh_audio->codecdata_len; memcpy(lavc_context->extradata, (char *)sh_audio->codecdata, lavc_context->extradata_size); } /* open it */ if (avcodec_open2(lavc_context, lavc_codec, NULL) < 0) { mp_tmsg(MSGT_DECAUDIO, MSGL_ERR, "Could not open codec.\n"); uninit(sh_audio); return 0; } mp_msg(MSGT_DECAUDIO, MSGL_V, "INFO: libavcodec \"%s\" init OK!\n", lavc_codec->name); if (sh_audio->format == 0x3343414D) { // MACE 3:1 sh_audio->ds->ss_div = 2 * 3; // 1 samples/packet sh_audio->ds->ss_mul = 2 * sh_audio->wf->nChannels; // 1 byte*ch/packet } else if (sh_audio->format == 0x3643414D) { // MACE 6:1 sh_audio->ds->ss_div = 2 * 6; // 1 samples/packet sh_audio->ds->ss_mul = 2 * sh_audio->wf->nChannels; // 1 byte*ch/packet } // Decode at least 1 byte: (to get header filled) for (int tries = 0;;) { int x = decode_audio(sh_audio, sh_audio->a_buffer, 1, sh_audio->a_buffer_size); if (x > 0) { sh_audio->a_buffer_len = x; break; } if (++tries >= 5) { mp_msg(MSGT_DECAUDIO, MSGL_ERR, "ad_ffmpeg: initial decode failed\n"); uninit(sh_audio); return 0; } } sh_audio->i_bps = lavc_context->bit_rate / 8; if (sh_audio->wf && sh_audio->wf->nAvgBytesPerSec) sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec; return 1; }
bool CDVDAudioCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) { AVCodec* pCodec = NULL; m_bOpenedCodec = false; bool allow_dtshd_decoding = true; #if defined(TARGET_RASPBERRY_PI) || defined(HAS_IMXVPU) allow_dtshd_decoding = CSettings::Get().GetBool("audiooutput.supportdtshdcpudecoding"); #endif if (hints.codec == AV_CODEC_ID_DTS && allow_dtshd_decoding) pCodec = avcodec_find_decoder_by_name("libdcadec"); if (!pCodec) pCodec = avcodec_find_decoder(hints.codec); if (!pCodec) { CLog::Log(LOGDEBUG,"CDVDAudioCodecFFmpeg::Open() Unable to find codec %d", hints.codec); return false; } m_pCodecContext = avcodec_alloc_context3(pCodec); m_pCodecContext->debug_mv = 0; m_pCodecContext->debug = 0; m_pCodecContext->workaround_bugs = 1; if (pCodec->capabilities & CODEC_CAP_TRUNCATED) m_pCodecContext->flags |= CODEC_FLAG_TRUNCATED; m_matrixEncoding = AV_MATRIX_ENCODING_NONE; m_channels = 0; m_pCodecContext->channels = hints.channels; m_pCodecContext->sample_rate = hints.samplerate; m_pCodecContext->block_align = hints.blockalign; m_pCodecContext->bit_rate = hints.bitrate; m_pCodecContext->bits_per_coded_sample = hints.bitspersample; if(m_pCodecContext->bits_per_coded_sample == 0) m_pCodecContext->bits_per_coded_sample = 16; if( hints.extradata && hints.extrasize > 0 ) { m_pCodecContext->extradata = (uint8_t*)av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE); if(m_pCodecContext->extradata) { m_pCodecContext->extradata_size = hints.extrasize; memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize); } } if (g_advancedSettings.m_audioApplyDrc >= 0.0) av_opt_set_double(m_pCodecContext, "drc_scale", g_advancedSettings.m_audioApplyDrc, AV_OPT_SEARCH_CHILDREN); if (avcodec_open2(m_pCodecContext, pCodec, NULL) < 0) { CLog::Log(LOGDEBUG,"CDVDAudioCodecFFmpeg::Open() Unable to open codec"); Dispose(); return false; } m_pFrame1 = av_frame_alloc(); m_bOpenedCodec = true; m_iSampleFormat = AV_SAMPLE_FMT_NONE; m_matrixEncoding = AV_MATRIX_ENCODING_NONE; return true; }
int init_send_video(codec_state *cs) { cs->video_input_format = av_find_input_format(VIDEO_DRIVER); if (avformat_open_input(&cs->video_format_ctx, DEFAULT_WEBCAM, cs->video_input_format, NULL) != 0) { printf("opening video_input_format failed\n"); return 0; } avformat_find_stream_info(cs->video_format_ctx, NULL); av_dump_format(cs->video_format_ctx, 0, DEFAULT_WEBCAM, 0); int i; for (i = 0; i < cs->video_format_ctx->nb_streams; ++i) { if (cs->video_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { cs->video_stream = i; break; } } cs->webcam_decoder_ctx = cs->video_format_ctx->streams[cs->video_stream]->codec; cs->webcam_decoder = avcodec_find_decoder(cs->webcam_decoder_ctx->codec_id); if (cs->webcam_decoder == NULL) { printf("Unsupported codec\n"); return 0; } if (cs->webcam_decoder_ctx == NULL) { printf("init webcam_decoder_ctx failed\n"); return 0; } if (avcodec_open2(cs->webcam_decoder_ctx, cs->webcam_decoder, NULL) < 0) { printf("opening webcam decoder failed\n"); return 0; } cs->video_encoder = avcodec_find_encoder(VIDEO_CODEC); if (!cs->video_encoder) { printf("init video_encoder failed\n"); return 0; } cs->video_encoder_ctx = avcodec_alloc_context3(cs->video_encoder); if (!cs->video_encoder_ctx) { printf("init video_encoder_ctx failed\n"); return 0; } cs->video_encoder_ctx->bit_rate = VIDEO_BITRATE; cs->video_encoder_ctx->rc_min_rate = cs->video_encoder_ctx->rc_max_rate = cs->video_encoder_ctx->bit_rate; av_opt_set_double(cs->video_encoder_ctx->priv_data, "max-intra-rate", 90, 0); av_opt_set(cs->video_encoder_ctx->priv_data, "quality", "realtime", 0); cs->video_encoder_ctx->thread_count = 4; cs->video_encoder_ctx->rc_buffer_aggressivity = 0.95; cs->video_encoder_ctx->rc_buffer_size = VIDEO_BITRATE * 6; cs->video_encoder_ctx->profile = 3; cs->video_encoder_ctx->qmax = 54; cs->video_encoder_ctx->qmin = 4; AVRational myrational = {1, 25}; cs->video_encoder_ctx->time_base = myrational; cs->video_encoder_ctx->gop_size = 99999; cs->video_encoder_ctx->pix_fmt = PIX_FMT_YUV420P; cs->video_encoder_ctx->width = cs->webcam_decoder_ctx->width; cs->video_encoder_ctx->height = cs->webcam_decoder_ctx->height; if (avcodec_open2(cs->video_encoder_ctx, cs->video_encoder, NULL) < 0) { printf("opening video encoder failed\n"); return 0; } printf("init video encoder successful\n"); return 1; }