コード例 #1
0
static int filter_frame(AVFilterLink *link, AVFrame *picref)
{
    AVFilterContext *ctx = link->dst;
    IDETContext *idet = ctx->priv;
    AVDictionary **metadata = avpriv_frame_get_metadatap(picref);

    if (idet->prev)
        av_frame_free(&idet->prev);
    idet->prev = idet->cur;
    idet->cur  = idet->next;
    idet->next = picref;

    if (!idet->cur)
        return 0;

    if (!idet->prev)
        idet->prev = av_frame_clone(idet->cur);

    if (!idet->csp)
        idet->csp = av_pix_fmt_desc_get(link->format);
    if (idet->csp->comp[0].depth_minus1 / 8 == 1){
        idet->filter_line = (ff_idet_filter_func)ff_idet_filter_line_c_16bit;
        if (ARCH_X86)
            ff_idet_init_x86(idet, 1);
    }

    filter(ctx);

    av_dict_set_int(metadata, "lavfi.idet.tff", idet->prestat[TFF], 0);
    av_dict_set_int(metadata, "lavfi.idet.bff", idet->prestat[BFF], 0);
    av_dict_set_int(metadata, "lavfi.idet.progressive", idet->prestat[PROGRESSIVE], 0);
    av_dict_set_int(metadata, "lavfi.idet.undetermined", idet->prestat[UNDETERMINED], 0);

    return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur));
}
コード例 #2
0
ファイル: ijkmeta.c プロジェクト: 1016135097/ijkplayer
void ijkmeta_set_int64_l(IjkMediaMeta *meta, const char *name, int64_t value)
{
    if (!meta)
        return;

    av_dict_set_int(&meta->dict, name, value, 0);
}
コード例 #3
0
ファイル: cinedec.c プロジェクト: 26mansi/FFmpeg
static int set_metadata_int(AVDictionary **dict, const char *key, int value, int allow_zero)
{
    if (value || allow_zero) {
        return av_dict_set_int(dict, key, value, 0);
    }
    return 0;
}
コード例 #4
0
ファイル: abstractstream.cpp プロジェクト: Anupam-/webcamoid
AbstractStream::AbstractStream(const AVFormatContext *formatContext,
                               uint index, qint64 id, Clock *globalClock,
                               bool noModify,
                               QObject *parent): QObject(parent)
{
    this->m_runPacketLoop = false;
    this->m_runDataLoop = false;
    this->m_paused = false;
    this->m_isValid = false;
    this->m_clockDiff = 0;
    this->m_maxData = 0;
    this->m_index = index;
    this->m_id = id;

    this->m_stream = (formatContext && index < formatContext->nb_streams)?
                         formatContext->streams[index]: NULL;

    this->m_mediaType = this->m_stream?
                            this->m_stream->codec->codec_type:
                            AVMEDIA_TYPE_UNKNOWN;

    this->m_codecContext = this->m_stream? this->m_stream->codec: NULL;

    this->m_codec = this->m_codecContext?
                        avcodec_find_decoder(this->m_codecContext->codec_id):
                        NULL;

    this->m_codecOptions = NULL;
    this->m_packetQueueSize = 0;
    this->m_globalClock = globalClock;

    if (!this->m_codec)
        return;

    if (this->m_stream)
        this->m_timeBase = AkFrac(this->m_stream->time_base.num,
                                  this->m_stream->time_base.den);

    if (!noModify) {
        this->m_stream->discard = AVDISCARD_DEFAULT;
        this->m_codecContext->workaround_bugs = 1;
        this->m_codecContext->idct_algo = FF_IDCT_AUTO;
        this->m_codecContext->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;

        if (this->m_codec->capabilities & CODEC_CAP_DR1)
            this->m_codecContext->flags |= CODEC_FLAG_EMU_EDGE;

        av_dict_set_int(&this->m_codecOptions, "refcounted_frames", 1, 0);
    }

    this->m_isValid = true;
}
コード例 #5
0
ファイル: media.c プロジェクト: AmesianX/obs-studio
static bool init_avformat(mp_media_t *m)
{
	AVInputFormat *format = NULL;

	if (m->format_name && *m->format_name) {
		format = av_find_input_format(m->format_name);
		if (!format)
			blog(LOG_INFO, "MP: Unable to find input format for "
					"'%s'", m->path);
	}

	AVDictionary *opts = NULL;
	if (m->buffering && !m->is_local_file)
		av_dict_set_int(&opts, "buffer_size", m->buffering, 0);

	m->fmt = avformat_alloc_context();
	m->fmt->interrupt_callback.callback = interrupt_callback;
	m->fmt->interrupt_callback.opaque = m;

	int ret = avformat_open_input(&m->fmt, m->path, format,
			opts ? &opts : NULL);
	av_dict_free(&opts);

	if (ret < 0) {
		blog(LOG_WARNING, "MP: Failed to open media: '%s'", m->path);
		return false;
	}

	if (avformat_find_stream_info(m->fmt, NULL) < 0) {
		blog(LOG_WARNING, "MP: Failed to find stream info for '%s'",
				m->path);
		return false;
	}

	m->has_video = mp_decode_init(m, AVMEDIA_TYPE_VIDEO, m->hw);
	m->has_audio = mp_decode_init(m, AVMEDIA_TYPE_AUDIO, m->hw);

	if (!m->has_video && !m->has_audio) {
		blog(LOG_WARNING, "MP: Could not initialize audio or video: "
				"'%s'", m->path);
		return false;
	}

	return true;
}
コード例 #6
0
ファイル: id3v1.c プロジェクト: markjreed/vice-emu
/**
 * Parse an ID3v1 tag
 *
 * @param buf ID3v1_TAG_SIZE long buffer containing the tag
 */
static int parse_tag(AVFormatContext *s, const uint8_t *buf)
{
    int genre;

    if (!(buf[0] == 'T' &&
          buf[1] == 'A' &&
          buf[2] == 'G'))
        return -1;
    get_string(s, "title",   buf +  3, 30);
    get_string(s, "artist",  buf + 33, 30);
    get_string(s, "album",   buf + 63, 30);
    get_string(s, "date",    buf + 93,  4);
    get_string(s, "comment", buf + 97, 30);
    if (buf[125] == 0 && buf[126] != 0) {
        av_dict_set_int(&s->metadata, "track", buf[126], 0);
    }
    genre = buf[127];
    if (genre <= ID3v1_GENRE_MAX)
        av_dict_set(&s->metadata, "genre", ff_id3v1_genre_str[genre], 0);
    return 0;
}
コード例 #7
0
ファイル: dict.c プロジェクト: 0day-ci/FFmpeg
int main(void)
{
    AVDictionary *dict = NULL;
    AVDictionaryEntry *e;
    char *buffer = NULL;

    printf("Testing av_dict_get_string() and av_dict_parse_string()\n");
    av_dict_get_string(dict, &buffer, '=', ',');
    printf("%s\n", buffer);
    av_freep(&buffer);
    av_dict_set(&dict, "aaa", "aaa", 0);
    av_dict_set(&dict, "b,b", "bbb", 0);
    av_dict_set(&dict, "c=c", "ccc", 0);
    av_dict_set(&dict, "ddd", "d,d", 0);
    av_dict_set(&dict, "eee", "e=e", 0);
    av_dict_set(&dict, "f,f", "f=f", 0);
    av_dict_set(&dict, "g=g", "g,g", 0);
    test_separators(dict, ',', '=');
    av_dict_free(&dict);
    av_dict_set(&dict, "aaa", "aaa", 0);
    av_dict_set(&dict, "bbb", "bbb", 0);
    av_dict_set(&dict, "ccc", "ccc", 0);
    av_dict_set(&dict, "\\,=\'\"", "\\,=\'\"", 0);
    test_separators(dict, '"',  '=');
    test_separators(dict, '\'', '=');
    test_separators(dict, ',', '"');
    test_separators(dict, ',', '\'');
    test_separators(dict, '\'', '"');
    test_separators(dict, '"', '\'');
    av_dict_free(&dict);

    printf("\nTesting av_dict_set()\n");
    av_dict_set(&dict, "a", "a", 0);
    av_dict_set(&dict, "b", av_strdup("b"), AV_DICT_DONT_STRDUP_VAL);
    av_dict_set(&dict, av_strdup("c"), "c", AV_DICT_DONT_STRDUP_KEY);
    av_dict_set(&dict, av_strdup("d"), av_strdup("d"), AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
    av_dict_set(&dict, "e", "e", AV_DICT_DONT_OVERWRITE);
    av_dict_set(&dict, "e", "f", AV_DICT_DONT_OVERWRITE);
    av_dict_set(&dict, "f", "f", 0);
    av_dict_set(&dict, "f", NULL, 0);
    av_dict_set(&dict, "ff", "f", 0);
    av_dict_set(&dict, "ff", "f", AV_DICT_APPEND);
    e = NULL;
    while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX)))
        printf("%s %s\n", e->key, e->value);
    av_dict_free(&dict);

    av_dict_set(&dict, NULL, "a", 0);
    av_dict_set(&dict, NULL, "b", 0);
    av_dict_get(dict, NULL, NULL, 0);
    e = NULL;
    while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX)))
        printf("'%s' '%s'\n", e->key, e->value);
    av_dict_free(&dict);


    //valgrind sensible test
    printf("\nTesting av_dict_set_int()\n");
    av_dict_set_int(&dict, "1", 1, AV_DICT_DONT_STRDUP_VAL);
    av_dict_set_int(&dict, av_strdup("2"), 2, AV_DICT_DONT_STRDUP_KEY);
    av_dict_set_int(&dict, av_strdup("3"), 3, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
    av_dict_set_int(&dict, "4", 4, 0);
    av_dict_set_int(&dict, "5", 5, AV_DICT_DONT_OVERWRITE);
    av_dict_set_int(&dict, "5", 6, AV_DICT_DONT_OVERWRITE);
    av_dict_set_int(&dict, "12", 1, 0);
    av_dict_set_int(&dict, "12", 2, AV_DICT_APPEND);
    e = NULL;
    while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX)))
        printf("%s %s\n", e->key, e->value);
    av_dict_free(&dict);

    //valgrind sensible test
    printf("\nTesting av_dict_set() with existing AVDictionaryEntry.key as key\n");
    av_dict_set(&dict, "key", "old", 0);
    e = av_dict_get(dict, "key", NULL, 0);
    av_dict_set(&dict, e->key, "new val OK", 0);
    e = av_dict_get(dict, "key", NULL, 0);
    printf("%s\n", e->value);
    av_dict_set(&dict, e->key, e->value, 0);
    e = av_dict_get(dict, "key", NULL, 0);
    printf("%s\n", e->value);
    av_dict_free(&dict);

    return 0;
}
コード例 #8
0
ファイル: backend_bt.c プロジェクト: hselasky/virtual_oss
static int
bt_play_open(struct voss_backend *pbe, const char *devname, int samplerate,
    int bufsize, int *pchannels, int *pformat)
{
	struct bt_config *cfg = pbe->arg;
	int retval;

	bt_init_cfg(cfg);

	retval = bt_open(pbe, devname, samplerate, bufsize, pchannels, pformat,
	    cfg, SDP_SERVICE_CLASS_AUDIO_SINK, 1);
	if (retval != 0)
		return (retval);

	/* setup codec */
	switch (cfg->codec) {
	case CODEC_SBC:
		cfg->handle.sbc_enc =
		    malloc(sizeof(*cfg->handle.sbc_enc));
		if (cfg->handle.sbc_enc == NULL)
			return (-1);
		memset(cfg->handle.sbc_enc, 0, sizeof(*cfg->handle.sbc_enc));
		break;
#ifdef HAVE_FFMPEG
	case CODEC_AAC:
		av_register_all();

		cfg->handle.av.codec = avcodec_find_encoder_by_name("aac");
		if (cfg->handle.av.codec == NULL) {
			DPRINTF("Codec AAC encoder not found\n");
			goto av_error_0;
		}
		cfg->handle.av.format = avformat_alloc_context();
		if (cfg->handle.av.format == NULL) {
			DPRINTF("Could not allocate format context\n");
			goto av_error_0;
		}
		cfg->handle.av.format->oformat =
		    av_guess_format("latm", NULL, NULL);
		if (cfg->handle.av.format->oformat == NULL) {
			DPRINTF("Could not guess output format\n");
			goto av_error_1;
		}
		cfg->handle.av.stream = avformat_new_stream(
		    cfg->handle.av.format, cfg->handle.av.codec);

		if (cfg->handle.av.stream == NULL) {
			DPRINTF("Could not create new stream\n");
			goto av_error_1;
		}
		cfg->handle.av.context = cfg->handle.av.stream->codec;
		if (cfg->handle.av.context == NULL) {
			DPRINTF("Could not allocate audio context\n");
			goto av_error_1;
		}
		avcodec_get_context_defaults3(cfg->handle.av.context,
		    cfg->handle.av.codec);

		cfg->handle.av.context->bit_rate = 128000;
		cfg->handle.av.context->sample_fmt = AV_SAMPLE_FMT_FLTP;
		cfg->handle.av.context->sample_rate = samplerate;
		switch (*pchannels) {
		case 1:
			cfg->handle.av.context->channel_layout = AV_CH_LAYOUT_MONO;
			cfg->handle.av.context->channels = 1;
			break;
		default:
			cfg->handle.av.context->channel_layout = AV_CH_LAYOUT_STEREO;
			cfg->handle.av.context->channels = 2;
			break;
		}

		cfg->handle.av.context->profile = FF_PROFILE_AAC_LOW;
		if (1) {
			AVDictionary *opts = NULL;

			av_dict_set(&opts, "strict", "-2", 0);
			av_dict_set_int(&opts, "latm", 1, 0);

			if (avcodec_open2(cfg->handle.av.context,
			    cfg->handle.av.codec, &opts) < 0) {
				av_dict_free(&opts);

				DPRINTF("Could not open codec\n");
				goto av_error_1;
			}
			av_dict_free(&opts);
		}
		cfg->handle.av.frame = av_frame_alloc();
		if (cfg->handle.av.frame == NULL) {
			DPRINTF("Could not allocate audio frame\n");
			goto av_error_2;
		}
		cfg->handle.av.frame->nb_samples = cfg->handle.av.context->frame_size;
		cfg->handle.av.frame->format = cfg->handle.av.context->sample_fmt;
		cfg->handle.av.frame->channel_layout = cfg->handle.av.context->channel_layout;
		cfg->rem_in_size = av_samples_get_buffer_size(NULL,
		    cfg->handle.av.context->channels,
		    cfg->handle.av.context->frame_size,
		    cfg->handle.av.context->sample_fmt, 0);

		cfg->rem_in_data = av_malloc(cfg->rem_in_size);
		if (cfg->rem_in_data == NULL) {
			DPRINTF("Could not allocate %u bytes sample buffer\n",
			    (unsigned)cfg->rem_in_size);
			goto av_error_3;
		}
		retval = avcodec_fill_audio_frame(cfg->handle.av.frame,
		    cfg->handle.av.context->channels,
		    cfg->handle.av.context->sample_fmt,
		    cfg->rem_in_data, cfg->rem_in_size, 0);
		if (retval < 0) {
			DPRINTF("Could not setup audio frame\n");
			goto av_error_4;
		}
		break;
av_error_4:
		av_free(cfg->rem_in_data);
av_error_3:
		av_frame_free(&cfg->handle.av.frame);
av_error_2:
		avcodec_close(cfg->handle.av.context);
av_error_1:
		avformat_free_context(cfg->handle.av.format);
		cfg->handle.av.context = NULL;
av_error_0:
		bt_close(pbe);
		return (-1);
#endif
	default:
		bt_close(pbe);
		return (-1);
	}
	return (0);
}
コード例 #9
0
ファイル: libopenmpt.c プロジェクト: dsmudhar/FFmpeg
static int read_header_openmpt(AVFormatContext *s)
{
    AVStream *st;
    OpenMPTContext *openmpt = s->priv_data;
    int64_t size;
    char *buf;
#if OPENMPT_API_VERSION_AT_LEAST(0,3,0)
    int error;
#endif
    int ret;

    size = avio_size(s->pb);
    if (size <= 0)
        return AVERROR_INVALIDDATA;
    buf = av_malloc(size);
    if (!buf)
        return AVERROR(ENOMEM);
    size = avio_read(s->pb, buf, size);
    if (size < 0) {
        av_log(s, AV_LOG_ERROR, "Reading input buffer failed.\n");
        av_freep(&buf);
        return size;
    }

#if OPENMPT_API_VERSION_AT_LEAST(0,3,0)
    error = OPENMPT_ERROR_OK;
    openmpt->module = openmpt_module_create_from_memory2(buf, size, openmpt_logfunc, s, NULL, NULL, &error, NULL, NULL);
    av_freep(&buf);
    if (!openmpt->module) {
        if (error == OPENMPT_ERROR_OUT_OF_MEMORY)
            return AVERROR(ENOMEM);
        else if (error >= OPENMPT_ERROR_GENERAL)
            return AVERROR_INVALIDDATA;
        else
            return AVERROR_UNKNOWN;
    }
#else
    openmpt->module = openmpt_module_create_from_memory(buf, size, openmpt_logfunc, s, NULL);
    av_freep(&buf);
    if (!openmpt->module)
            return AVERROR_INVALIDDATA;
#endif

    openmpt->channels = av_get_channel_layout_nb_channels(openmpt->layout);

    if (openmpt->subsong >= openmpt_module_get_num_subsongs(openmpt->module)) {
        openmpt_module_destroy(openmpt->module);
        av_log(s, AV_LOG_ERROR, "Invalid subsong index: %d\n", openmpt->subsong);
        return AVERROR(EINVAL);
    }

    if (openmpt->subsong != -2) {
        if (openmpt->subsong >= 0) {
            av_dict_set_int(&s->metadata, "track", openmpt->subsong + 1, 0);
        }
        ret = openmpt_module_select_subsong(openmpt->module, openmpt->subsong);
        if (!ret){
            openmpt_module_destroy(openmpt->module);
            av_log(s, AV_LOG_ERROR, "Could not select requested subsong: %d", openmpt->subsong);
            return AVERROR(EINVAL);
        }
    }

    openmpt->duration = openmpt_module_get_duration_seconds(openmpt->module);

    add_meta(s, "artist",  openmpt_module_get_metadata(openmpt->module, "artist"));
    add_meta(s, "title",   openmpt_module_get_metadata(openmpt->module, "title"));
    add_meta(s, "encoder", openmpt_module_get_metadata(openmpt->module, "tracker"));
    add_meta(s, "comment", openmpt_module_get_metadata(openmpt->module, "message"));
    add_meta(s, "date",    openmpt_module_get_metadata(openmpt->module, "date"));

    st = avformat_new_stream(s, NULL);
    if (!st) {
        openmpt_module_destroy(openmpt->module);
        openmpt->module = NULL;
        return AVERROR(ENOMEM);
    }
    avpriv_set_pts_info(st, 64, 1, AV_TIME_BASE);
    st->duration = llrint(openmpt->duration*AV_TIME_BASE);

    st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
    st->codecpar->codec_id    = AV_NE(AV_CODEC_ID_PCM_F32BE, AV_CODEC_ID_PCM_F32LE);
    st->codecpar->channels    = openmpt->channels;
    st->codecpar->sample_rate = openmpt->sample_rate;

    return 0;
}
コード例 #10
0
ファイル: brstm.c プロジェクト: artclarke/humble-video
static int read_header(AVFormatContext *s)
{
    BRSTMDemuxContext *b = s->priv_data;
    int bom, major, minor, codec, chunk;
    int64_t h1offset, pos, toffset;
    uint32_t size, asize, start = 0;
    AVStream *st;
    int ret = AVERROR_EOF;
    int loop = 0;
    int bfstm = !strcmp("bfstm", s->iformat->name);

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

    avio_skip(s->pb, 4);

    bom = avio_rb16(s->pb);
    if (bom != 0xFEFF && bom != 0xFFFE) {
        av_log(s, AV_LOG_ERROR, "invalid byte order: %X\n", bom);
        return AVERROR_INVALIDDATA;
    }

    if (bom == 0xFFFE)
        b->little_endian = 1;

    if (!bfstm) {
        major = avio_r8(s->pb);
        minor = avio_r8(s->pb);
        avio_skip(s->pb, 4); // size of file
        size = read16(s);
        if (size < 14)
            return AVERROR_INVALIDDATA;

        avio_skip(s->pb, size - 14);
        pos = avio_tell(s->pb);
        if (avio_rl32(s->pb) != MKTAG('H','E','A','D'))
            return AVERROR_INVALIDDATA;
    } else {
        uint32_t info_offset = 0;
        uint16_t section_count, header_size, i;

        header_size = read16(s); // 6

        avio_skip(s->pb, 4); // Unknown constant 0x00030000
        avio_skip(s->pb, 4); // size of file
        section_count = read16(s);
        avio_skip(s->pb, 2); // padding
        for (i = 0; avio_tell(s->pb) < header_size
                    && !(start && info_offset)
                    && i < section_count; i++) {
            uint16_t flag = read16(s);
            avio_skip(s->pb, 2);
            switch (flag) {
            case 0x4000:
                info_offset = read32(s);
                /*info_size =*/ read32(s);
                break;
            case 0x4001:
                avio_skip(s->pb, 4); // seek offset
                avio_skip(s->pb, 4); // seek size
                break;
            case 0x4002:
                start = read32(s) + 8;
                avio_skip(s->pb, 4); //data_size = read32(s);
                break;
            case 0x4003:
                avio_skip(s->pb, 4); // REGN offset
                avio_skip(s->pb, 4); // REGN size
                break;
            }
        }

        if (!info_offset || !start)
            return AVERROR_INVALIDDATA;

        avio_skip(s->pb, info_offset - avio_tell(s->pb));
        pos = avio_tell(s->pb);
        if (avio_rl32(s->pb) != MKTAG('I','N','F','O'))
            return AVERROR_INVALIDDATA;
    }

    size = read32(s);
    if (size < 192)
        return AVERROR_INVALIDDATA;
    avio_skip(s->pb, 4); // unknown
    h1offset = read32(s);
    if (h1offset > size)
        return AVERROR_INVALIDDATA;
    avio_skip(s->pb, 12);
    toffset = read32(s) + 16LL;
    if (toffset > size)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, pos + h1offset + 8 - avio_tell(s->pb));
    codec = avio_r8(s->pb);

    switch (codec) {
    case 0: codec = AV_CODEC_ID_PCM_S8_PLANAR;    break;
    case 1: codec = b->little_endian ?
                    AV_CODEC_ID_PCM_S16LE_PLANAR :
                    AV_CODEC_ID_PCM_S16BE_PLANAR; break;
    case 2: codec = b->little_endian ?
                    AV_CODEC_ID_ADPCM_THP_LE :
                    AV_CODEC_ID_ADPCM_THP;        break;
    default:
        avpriv_request_sample(s, "codec %d", codec);
        return AVERROR_PATCHWELCOME;
    }

    loop = avio_r8(s->pb); // loop flag
    st->codec->codec_id = codec;
    st->codec->channels = avio_r8(s->pb);
    if (!st->codec->channels)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, 1); // padding

    st->codec->sample_rate = bfstm ? read32(s) : read16(s);
    if (st->codec->sample_rate <= 0)
        return AVERROR_INVALIDDATA;

    if (!bfstm)
        avio_skip(s->pb, 2); // padding

    if (loop) {
        if (av_dict_set_int(&s->metadata, "loop_start",
                            av_rescale(read32(s), AV_TIME_BASE,
                                       st->codec->sample_rate),
                            0) < 0)
            return AVERROR(ENOMEM);
    } else {
        avio_skip(s->pb, 4);
    }

    st->start_time = 0;
    st->duration = read32(s);
    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

    if (!bfstm)
        start = read32(s);
    b->current_block = 0;
    b->block_count = read32(s);
    if (b->block_count > UINT16_MAX) {
        av_log(s, AV_LOG_WARNING, "too many blocks: %u\n", b->block_count);
        return AVERROR_INVALIDDATA;
    }

    b->block_size = read32(s);
    if (b->block_size > UINT32_MAX / st->codec->channels)
        return AVERROR_INVALIDDATA;

    b->samples_per_block = read32(s);
    b->last_block_used_bytes = read32(s);
    b->last_block_samples = read32(s);
    b->last_block_size = read32(s);
    if (b->last_block_size > UINT32_MAX / st->codec->channels)
        return AVERROR_INVALIDDATA;
    if (b->last_block_used_bytes > b->last_block_size)
        return AVERROR_INVALIDDATA;


    if (codec == AV_CODEC_ID_ADPCM_THP || codec == AV_CODEC_ID_ADPCM_THP_LE) {
        int ch;

        avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
        if (!bfstm)
            toffset = read32(s) + 16LL;
        else
            toffset = toffset + read32(s) + st->codec->channels * 8 - 8;
        if (toffset > size)
            return AVERROR_INVALIDDATA;

        avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
        b->table = av_mallocz(32 * st->codec->channels);
        if (!b->table)
            return AVERROR(ENOMEM);

        for (ch = 0; ch < st->codec->channels; ch++) {
            if (avio_read(s->pb, b->table + ch * 32, 32) != 32) {
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            avio_skip(s->pb, bfstm ? 14 : 24);
        }
    }

    if (size < (avio_tell(s->pb) - pos)) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    avio_skip(s->pb, size - (avio_tell(s->pb) - pos));

    while (!avio_feof(s->pb)) {
        chunk = avio_rl32(s->pb);
        size  = read32(s);
        if (size < 8) {
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }
        size -= 8;
        switch (chunk) {
        case MKTAG('S','E','E','K'):
        case MKTAG('A','D','P','C'):
            if (codec != AV_CODEC_ID_ADPCM_THP &&
                codec != AV_CODEC_ID_ADPCM_THP_LE)
                goto skip;

            asize = b->block_count * st->codec->channels * 4;
            if (size < asize) {
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            if (b->adpc) {
                av_log(s, AV_LOG_WARNING, "skipping additional ADPC chunk\n");
                goto skip;
            } else {
                b->adpc = av_mallocz(asize);
                if (!b->adpc) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                if (bfstm && codec != AV_CODEC_ID_ADPCM_THP_LE) {
                    // Big-endian BFSTMs have little-endian SEEK tables
                    // for some strange reason.
                    int i;
                    for (i = 0; i < asize; i += 2) {
                        b->adpc[i+1] = avio_r8(s->pb);
                        b->adpc[i]   = avio_r8(s->pb);
                    }
                } else {
                    avio_read(s->pb, b->adpc, asize);
                }
                avio_skip(s->pb, size - asize);
            }
            break;
        case MKTAG('D','A','T','A'):
            if ((start < avio_tell(s->pb)) ||
                (!b->adpc && (codec == AV_CODEC_ID_ADPCM_THP ||
                              codec == AV_CODEC_ID_ADPCM_THP_LE))) {
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            avio_skip(s->pb, start - avio_tell(s->pb));

            if (bfstm && (codec == AV_CODEC_ID_ADPCM_THP ||
                          codec == AV_CODEC_ID_ADPCM_THP_LE))
                avio_skip(s->pb, 24);

            b->data_start = avio_tell(s->pb);

            if (!bfstm && (major != 1 || minor))
                avpriv_request_sample(s, "Version %d.%d", major, minor);

            return 0;
        default:
            av_log(s, AV_LOG_WARNING, "skipping unknown chunk: %X\n", chunk);
skip:
            avio_skip(s->pb, size);
        }
    }

fail:
    read_close(s);

    return ret;
}
コード例 #11
0
ファイル: ffserver_config.c プロジェクト: rcombs/FFmpeg
/* add a codec and set the default parameters */
static void add_codec(FFServerStream *stream, AVCodecContext *av,
                      FFServerConfig *config)
{
    AVStream *st;
    AVDictionary **opts, *recommended = NULL;
    char *enc_config;

    if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
        return;

    opts = av->codec_type == AVMEDIA_TYPE_AUDIO ?
           &config->audio_opts : &config->video_opts;
    av_dict_copy(&recommended, *opts, 0);
    av_opt_set_dict2(av->priv_data, opts, AV_OPT_SEARCH_CHILDREN);
    av_opt_set_dict2(av, opts, AV_OPT_SEARCH_CHILDREN);

    if (av_dict_count(*opts))
        av_log(NULL, AV_LOG_WARNING,
               "Something is wrong, %d options are not set!\n",
               av_dict_count(*opts));

    if (!config->stream_use_defaults) {
        switch(av->codec_type) {
        case AVMEDIA_TYPE_AUDIO:
            if (av->bit_rate == 0)
                report_config_error(config->filename, config->line_num,
                                    AV_LOG_ERROR, &config->errors,
                                    "audio bit rate is not set\n");
            if (av->sample_rate == 0)
                report_config_error(config->filename, config->line_num,
                                    AV_LOG_ERROR, &config->errors,
                                    "audio sample rate is not set\n");
            break;
        case AVMEDIA_TYPE_VIDEO:
            if (av->width == 0 || av->height == 0)
                report_config_error(config->filename, config->line_num,
                                    AV_LOG_ERROR, &config->errors,
                                    "video size is not set\n");
            break;
        default:
            av_assert0(0);
        }
        goto done;
    }

    /* stream_use_defaults = true */

    /* compute default parameters */
    switch(av->codec_type) {
    case AVMEDIA_TYPE_AUDIO:
        if (!av_dict_get(recommended, "b", NULL, 0)) {
            av->bit_rate = 64000;
            av_dict_set_int(&recommended, "b", av->bit_rate, 0);
            WARNING("Setting default value for audio bit rate = %d. "
                    "Use NoDefaults to disable it.\n",
                    av->bit_rate);
        }
        if (!av_dict_get(recommended, "ar", NULL, 0)) {
            av->sample_rate = 22050;
            av_dict_set_int(&recommended, "ar", av->sample_rate, 0);
            WARNING("Setting default value for audio sample rate = %d. "
                    "Use NoDefaults to disable it.\n",
                    av->sample_rate);
        }
        if (!av_dict_get(recommended, "ac", NULL, 0)) {
            av->channels = 1;
            av_dict_set_int(&recommended, "ac", av->channels, 0);
            WARNING("Setting default value for audio channel count = %d. "
                    "Use NoDefaults to disable it.\n",
                    av->channels);
        }
        break;
    case AVMEDIA_TYPE_VIDEO:
        if (!av_dict_get(recommended, "b", NULL, 0)) {
            av->bit_rate = 64000;
            av_dict_set_int(&recommended, "b", av->bit_rate, 0);
            WARNING("Setting default value for video bit rate = %d. "
                    "Use NoDefaults to disable it.\n",
                    av->bit_rate);
        }
        if (!av_dict_get(recommended, "time_base", NULL, 0)) {
            av->time_base.den = 5;
            av->time_base.num = 1;
            av_dict_set(&recommended, "time_base", "1/5", 0);
            WARNING("Setting default value for video frame rate = %d. "
                    "Use NoDefaults to disable it.\n",
                    av->time_base.den);
        }
        if (!av_dict_get(recommended, "video_size", NULL, 0)) {
            av->width = 160;
            av->height = 128;
            av_dict_set(&recommended, "video_size", "160x128", 0);
            WARNING("Setting default value for video size = %dx%d. "
                    "Use NoDefaults to disable it.\n",
                    av->width, av->height);
        }
        /* Bitrate tolerance is less for streaming */
        if (!av_dict_get(recommended, "bt", NULL, 0)) {
            av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
                                           (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
            av_dict_set_int(&recommended, "bt", av->bit_rate_tolerance, 0);
            WARNING("Setting default value for video bit rate tolerance = %d. "
                    "Use NoDefaults to disable it.\n",
                    av->bit_rate_tolerance);
        }

        if (!av_dict_get(recommended, "rc_eq", NULL, 0)) {
            av->rc_eq = av_strdup("tex^qComp");
            av_dict_set(&recommended, "rc_eq", "tex^qComp", 0);
            WARNING("Setting default value for video rate control equation = "
                    "%s. Use NoDefaults to disable it.\n",
                    av->rc_eq);
        }
        if (!av_dict_get(recommended, "maxrate", NULL, 0)) {
            av->rc_max_rate = av->bit_rate * 2;
            av_dict_set_int(&recommended, "maxrate", av->rc_max_rate, 0);
            WARNING("Setting default value for video max rate = %d. "
                    "Use NoDefaults to disable it.\n",
                    av->rc_max_rate);
        }

        if (av->rc_max_rate && !av_dict_get(recommended, "bufsize", NULL, 0)) {
            av->rc_buffer_size = av->rc_max_rate;
            av_dict_set_int(&recommended, "bufsize", av->rc_buffer_size, 0);
            WARNING("Setting default value for video buffer size = %d. "
                    "Use NoDefaults to disable it.\n",
                    av->rc_buffer_size);
        }
        break;
    default:
        abort();
    }

done:
    st = av_mallocz(sizeof(AVStream));
    if (!st)
        return;
    av_dict_get_string(recommended, &enc_config, '=', ',');
    av_dict_free(&recommended);
    av_stream_set_recommended_encoder_configuration(st, enc_config);
    st->codec = av;
    stream->streams[stream->nb_streams++] = st;
}
コード例 #12
0
ファイル: ffserver_config.c プロジェクト: Kofktu/FFmpeg_2.4
static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, const char **p,
                                        int line_num, FFServerStream **pstream)
{
    char arg[1024], arg2[1024];
    FFServerStream *stream;
    int val;

    av_assert0(pstream);
    stream = *pstream;

    if (!av_strcasecmp(cmd, "<Stream")) {
        char *q;
        FFServerStream *s;
        stream = av_mallocz(sizeof(FFServerStream));
        if (!stream)
            return AVERROR(ENOMEM);
        config->dummy_ctx = avcodec_alloc_context3(NULL);
        if (!config->dummy_ctx) {
            av_free(stream);
            return AVERROR(ENOMEM);
        }
        ffserver_get_arg(stream->filename, sizeof(stream->filename), p);
        q = strrchr(stream->filename, '>');
        if (q)
            *q = '\0';

        for (s = config->first_stream; s; s = s->next) {
            if (!strcmp(stream->filename, s->filename))
                ERROR("Stream '%s' already registered\n", s->filename);
        }

        stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL);
        if (stream->fmt) {
            config->audio_id = stream->fmt->audio_codec;
            config->video_id = stream->fmt->video_codec;
        } else {
            config->audio_id = AV_CODEC_ID_NONE;
            config->video_id = AV_CODEC_ID_NONE;
        }
        *pstream = stream;
        return 0;
    }
    av_assert0(stream);
    if (!av_strcasecmp(cmd, "Feed")) {
        FFServerStream *sfeed;
        ffserver_get_arg(arg, sizeof(arg), p);
        sfeed = config->first_feed;
        while (sfeed) {
            if (!strcmp(sfeed->filename, arg))
                break;
            sfeed = sfeed->next_feed;
        }
        if (!sfeed)
            ERROR("Feed with name '%s' for stream '%s' is not defined\n", arg,
                    stream->filename);
        else
            stream->feed = sfeed;
    } else if (!av_strcasecmp(cmd, "Format")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        if (!strcmp(arg, "status")) {
            stream->stream_type = STREAM_TYPE_STATUS;
            stream->fmt = NULL;
        } else {
            stream->stream_type = STREAM_TYPE_LIVE;
            /* JPEG cannot be used here, so use single frame MJPEG */
            if (!strcmp(arg, "jpeg"))
                strcpy(arg, "mjpeg");
            stream->fmt = ffserver_guess_format(arg, NULL, NULL);
            if (!stream->fmt)
                ERROR("Unknown Format: %s\n", arg);
        }
        if (stream->fmt) {
            config->audio_id = stream->fmt->audio_codec;
            config->video_id = stream->fmt->video_codec;
        }
    } else if (!av_strcasecmp(cmd, "InputFormat")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        stream->ifmt = av_find_input_format(arg);
        if (!stream->ifmt)
            ERROR("Unknown input format: %s\n", arg);
    } else if (!av_strcasecmp(cmd, "FaviconURL")) {
        if (stream->stream_type == STREAM_TYPE_STATUS)
            ffserver_get_arg(stream->feed_filename,
                    sizeof(stream->feed_filename), p);
        else
            ERROR("FaviconURL only permitted for status streams\n");
    } else if (!av_strcasecmp(cmd, "Author")    ||
               !av_strcasecmp(cmd, "Comment")   ||
               !av_strcasecmp(cmd, "Copyright") ||
               !av_strcasecmp(cmd, "Title")) {
        char key[32];
        int i;
        ffserver_get_arg(arg, sizeof(arg), p);
        for (i = 0; i < strlen(cmd); i++)
            key[i] = av_tolower(cmd[i]);
        key[i] = 0;
        WARNING("'%s' option in configuration file is deprecated, "
                "use 'Metadata %s VALUE' instead\n", cmd, key);
        if (av_dict_set(&stream->metadata, key, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "Metadata")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_get_arg(arg2, sizeof(arg2), p);
        if (av_dict_set(&stream->metadata, arg, arg2, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "Preroll")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        stream->prebuffer = atof(arg) * 1000;
    } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
        stream->send_on_key = 1;
    } else if (!av_strcasecmp(cmd, "AudioCodec")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        config->audio_id = opt_codec(arg, AVMEDIA_TYPE_AUDIO);
        if (config->audio_id == AV_CODEC_ID_NONE)
            ERROR("Unknown AudioCodec: %s\n", arg);
    } else if (!av_strcasecmp(cmd, "VideoCodec")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        config->video_id = opt_codec(arg, AVMEDIA_TYPE_VIDEO);
        if (config->video_id == AV_CODEC_ID_NONE)
            ERROR("Unknown VideoCodec: %s\n", arg);
    } else if (!av_strcasecmp(cmd, "MaxTime")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        stream->max_time = atof(arg) * 1000;
    } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
        float f;
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_float_param(&f, arg, 1000, 0, FLT_MAX, config, line_num,
                "Invalid %s: %s\n", cmd, arg);
        if (av_dict_set_int(&config->audio_conf, cmd, lrintf(f), 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "AudioChannels")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 0, 1, 8, config, line_num,
                "Invalid %s: %s, valid range is 1-8.", cmd, arg);
        if (av_dict_set(&config->audio_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 0, 0, INT_MAX, config, line_num,
                "Invalid %s: %s", cmd, arg);
        if (av_dict_set(&config->audio_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
        int minrate, maxrate;
        ffserver_get_arg(arg, sizeof(arg), p);
        if (sscanf(arg, "%d-%d", &minrate, &maxrate) == 2) {
            if (av_dict_set_int(&config->video_conf, "VideoBitRateRangeMin", minrate, 0) < 0 ||
                av_dict_set_int(&config->video_conf, "VideoBitRateRangeMax", maxrate, 0) < 0)
                goto nomem;
        } else
            ERROR("Incorrect format for VideoBitRateRange -- should be "
                    "<min>-<max>: %s\n", arg);
    } else if (!av_strcasecmp(cmd, "Debug")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 0, INT_MIN, INT_MAX, config, line_num,
                "Invalid %s: %s", cmd, arg);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "Strict")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 0, INT_MIN, INT_MAX, config, line_num,
                "Invalid %s: %s", cmd, arg);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 8*1024, 0, INT_MAX, config, line_num,
                "Invalid %s: %s", cmd, arg);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 1000, INT_MIN, INT_MAX, config,
                line_num, "Invalid %s: %s", cmd, arg);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 1000, 0, INT_MAX, config, line_num,
                "Invalid %s: %s", cmd, arg);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
           goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoSize")) {
        int ret, w, h;
        ffserver_get_arg(arg, sizeof(arg), p);
        ret = av_parse_video_size(&w, &h, arg);
        if (ret < 0)
            ERROR("Invalid video size '%s'\n", arg);
        else if ((w % 16) || (h % 16))
            ERROR("Image size must be a multiple of 16\n");
        if (av_dict_set_int(&config->video_conf, "VideoSizeWidth", w, 0) < 0 ||
            av_dict_set_int(&config->video_conf, "VideoSizeHeight", h, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
        AVRational frame_rate;
        ffserver_get_arg(arg, sizeof(arg), p);
        if (av_parse_video_rate(&frame_rate, arg) < 0) {
            ERROR("Incorrect frame rate: %s\n", arg);
        } else {
            if (av_dict_set_int(&config->video_conf, "VideoFrameRateNum", frame_rate.num, 0) < 0 ||
                av_dict_set_int(&config->video_conf, "VideoFrameRateDen", frame_rate.den, 0) < 0)
                goto nomem;
        }
    } else if (!av_strcasecmp(cmd, "PixelFormat")) {
        enum AVPixelFormat pix_fmt;
        ffserver_get_arg(arg, sizeof(arg), p);
        pix_fmt = av_get_pix_fmt(arg);
        if (pix_fmt == AV_PIX_FMT_NONE)
            ERROR("Unknown pixel format: %s\n", arg);
        if (av_dict_set_int(&config->video_conf, cmd, pix_fmt, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 0, INT_MIN, INT_MAX, config, line_num,
                "Invalid %s: %s", cmd, arg);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
        if (av_dict_set(&config->video_conf, cmd, "1", 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
        if (av_dict_set(&config->video_conf, cmd, "", 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
        if (av_dict_set(&config->video_conf, cmd, "", 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
               !av_strcasecmp(cmd, "AVOptionAudio")) {
        int ret;
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_get_arg(arg2, sizeof(arg2), p);
        if (!av_strcasecmp(cmd, "AVOptionVideo"))
            ret = ffserver_save_avoption(arg, arg2, &config->video_opts, AV_OPT_FLAG_VIDEO_PARAM ,config, line_num);
        else
            ret = ffserver_save_avoption(arg, arg2, &config->audio_opts, AV_OPT_FLAG_AUDIO_PARAM ,config, line_num);
        if (ret < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
               !av_strcasecmp(cmd, "AVPresetAudio")) {
        char **preset = NULL;
        ffserver_get_arg(arg, sizeof(arg), p);
        if (!av_strcasecmp(cmd, "AVPresetVideo")) {
            preset = &config->video_preset;
            ffserver_opt_preset(arg, NULL, 0, NULL, &config->video_id);
        } else {
            preset = &config->audio_preset;
            ffserver_opt_preset(arg, NULL, 0, &config->audio_id, NULL);
        }
        *preset = av_strdup(arg);
        if (!preset)
            return AVERROR(ENOMEM);
    } else if (!av_strcasecmp(cmd, "VideoTag")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        if (strlen(arg) == 4) {
            if (av_dict_set(&config->video_conf, "VideoTag", "arg", 0) < 0)
                goto nomem;
        }
    } else if (!av_strcasecmp(cmd, "BitExact")) {
        if (av_dict_set(&config->video_conf, cmd, "", 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "DctFastint")) {
        if (av_dict_set(&config->video_conf, cmd, "", 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "IdctSimple")) {
        if (av_dict_set(&config->video_conf, cmd, "", 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "Qscale")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 0, 1, 31, config, line_num,
                "%s out of range\n", cmd);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoQMax")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 0, 1, 31, config, line_num,
                "%s out of range\n", cmd);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "VideoQMin")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(NULL, arg, 0, 1, 31, config, line_num,
                "%s out of range\n", cmd);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "LumiMask")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_float_param(NULL, arg, 0, -FLT_MAX, FLT_MAX, config,
                line_num, "Invalid %s: %s", cmd, arg);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "DarkMask")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_float_param(NULL, arg, 0, -FLT_MAX, FLT_MAX, config,
                line_num, "Invalid %s: %s", cmd, arg);
        if (av_dict_set(&config->video_conf, cmd, arg, 0) < 0)
            goto nomem;
    } else if (!av_strcasecmp(cmd, "NoVideo")) {
        config->video_id = AV_CODEC_ID_NONE;
    } else if (!av_strcasecmp(cmd, "NoAudio")) {
        config->audio_id = AV_CODEC_ID_NONE;
    } else if (!av_strcasecmp(cmd, "ACL")) {
        ffserver_parse_acl_row(stream, NULL, NULL, *p, config->filename,
                line_num);
    } else if (!av_strcasecmp(cmd, "DynamicACL")) {
        ffserver_get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), p);
    } else if (!av_strcasecmp(cmd, "RTSPOption")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        av_freep(&stream->rtsp_option);
        stream->rtsp_option = av_strdup(arg);
    } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        if (resolve_host(&stream->multicast_ip, arg))
            ERROR("Invalid host/IP address: %s\n", arg);
        stream->is_multicast = 1;
        stream->loop = 1; /* default is looping */
    } else if (!av_strcasecmp(cmd, "MulticastPort")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(&val, arg, 0, 1, 65535, config, line_num,
                "Invalid MulticastPort: %s\n", arg);
        stream->multicast_port = val;
    } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
        ffserver_get_arg(arg, sizeof(arg), p);
        ffserver_set_int_param(&val, arg, 0, INT_MIN, INT_MAX, config,
                line_num, "Invalid MulticastTTL: %s\n", arg);
        stream->multicast_ttl = val;
    } else if (!av_strcasecmp(cmd, "NoLoop")) {
        stream->loop = 0;
    } else if (!av_strcasecmp(cmd, "</Stream>")) {
        if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm")) {
            if (config->audio_id != AV_CODEC_ID_NONE) {
                AVCodecContext *audio_enc = avcodec_alloc_context3(avcodec_find_encoder(config->audio_id));
                if (config->audio_preset &&
                    ffserver_opt_preset(arg, audio_enc, AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_ENCODING_PARAM,
                                        NULL, NULL) < 0)
                    ERROR("Could not apply preset '%s'\n", arg);
                ffserver_apply_stream_config(audio_enc, config->audio_conf,
                        &config->audio_opts);
                add_codec(stream, audio_enc);
            }
            if (config->video_id != AV_CODEC_ID_NONE) {
                AVCodecContext *video_enc = avcodec_alloc_context3(avcodec_find_encoder(config->video_id));
                if (config->video_preset &&
                    ffserver_opt_preset(arg, video_enc, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_ENCODING_PARAM,
                                        NULL, NULL) < 0)
                    ERROR("Could not apply preset '%s'\n", arg);
                ffserver_apply_stream_config(video_enc, config->video_conf,
                        &config->video_opts);
                add_codec(stream, video_enc);
            }
        }
        av_dict_free(&config->video_opts);
        av_dict_free(&config->video_conf);
        av_dict_free(&config->audio_opts);
        av_dict_free(&config->audio_conf);
        av_freep(&config->video_preset);
        av_freep(&config->audio_preset);
        avcodec_free_context(&config->dummy_ctx);
        *pstream = NULL;
    } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) {
        ffserver_get_arg(stream->feed_filename, sizeof(stream->feed_filename),
                p);
    } else {
        ERROR("Invalid entry '%s' inside <Stream></Stream>\n", cmd);
    }
    return 0;
  nomem:
    av_log(NULL, AV_LOG_ERROR, "Out of memory. Aborting.\n");
    av_dict_free(&config->video_opts);
    av_dict_free(&config->video_conf);
    av_dict_free(&config->audio_opts);
    av_dict_free(&config->audio_conf);
    av_freep(&config->video_preset);
    av_freep(&config->audio_preset);
    avcodec_free_context(&config->dummy_ctx);
    return AVERROR(ENOMEM);
}
コード例 #13
0
void MP4Encoder::EncodeStart() {
    //1. 注册所有组件
    av_register_all();
    //2. 初始化输出码流的AVFormatContext
    avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, this->mp4Path);

    //3. 打开待输出的视频文件
    if (avio_open(&pFormatCtx->pb, this->mp4Path, AVIO_FLAG_READ_WRITE)) {
        LOGE("open output file failed");
        return;
    }
    //4. 初始化视频码流
    pStream = avformat_new_stream(pFormatCtx, NULL);
    if (pStream == NULL) {
        LOGE("allocating output stream failed");
        return;
    }
    //5. 寻找编码器并打开编码器
    pCodec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
    if (!pCodec) {
        LOGE("could not find encoder");
        return;
    }

    //6. 分配编码器并设置参数
    pCodecCtx = avcodec_alloc_context3(pCodec);
    pCodecCtx->codec_id = pCodec->id;
    pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
    pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
    pCodecCtx->width = height;
    pCodecCtx->height = width;
    pCodecCtx->time_base.num = 1;
    pCodecCtx->time_base.den = 25;
    pCodecCtx->bit_rate = 400000;
    pCodecCtx->gop_size = 12;


    //将AVCodecContext的成员复制到AVCodecParameters结构体
    avcodec_parameters_from_context(pStream->codecpar, pCodecCtx);
    av_stream_set_r_frame_rate(pStream, {1, 25});

    //7. 打开编码器
    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
        LOGE("open encoder fail!");
        return;
    }

    //输出格式信息
    av_dump_format(pFormatCtx, 0, this->mp4Path, 1);

    //初始化帧
    pFrame = av_frame_alloc();
    pFrame->width = pCodecCtx->width;
    pFrame->height = pCodecCtx->height;
    pFrame->format = pCodecCtx->pix_fmt;
    int bufferSize = av_image_get_buffer_size(pCodecCtx->pix_fmt, pCodecCtx->width,
                                              pCodecCtx->height, 1);
    pFrameBuffer = (uint8_t *) av_malloc(bufferSize);
    av_image_fill_arrays(pFrame->data, pFrame->linesize, pFrameBuffer, pCodecCtx->pix_fmt,
                         pCodecCtx->width, pCodecCtx->height, 1);

    AVDictionary *opt = 0;
    //H.264
    if (pCodecCtx->codec_id == AV_CODEC_ID_H264) {
        av_dict_set_int(&opt, "video_track_timescale", 25, 0);
        av_dict_set(&opt, "preset", "slow", 0);
        av_dict_set(&opt, "tune", "zerolatency", 0);
    }
    //8. 写文件头
    avformat_write_header(pFormatCtx, &opt);

    //创建已编码帧
    av_new_packet(&avPacket, bufferSize * 3);

    //标记正在转换
    this->transform = true;
}